Xlib programming

Introduction

X is a large system. It contains a full set of windowing facilities, the ability to handle colour, 2-D graphics drawing capacity, network access mechanisms, and the ability to respond to user preferences. X includes

Network connection


/* 
** File: info.c
** Purpose: give general information about the server
*/

/*    
** Needed for NULL pointer, as well as any IO to an xterm window    
*/    
#include <stdio.h>    
    
/*    
** General X include files    
*/    
#include <X11/Xlib.h>    
#include <X11/Xutil.h>    
    
    
/*    
** Global variables
*/    
Display	*display;	/* the display device */    
int	screen; 	/* the screen on the display */    
    
/*    
** Terminate the program gracefully    
*/    
void
quitX()    
{    
	XCloseDisplay(display);    
	exit(0);    
}    
    
/*    
** Connect to the server and get the display
** device and the screen number
*/    
void
initX()    
{    
	/* set the display name from the environment vbl DISPLAY */    
	display = XOpenDisplay(NULL);    
	if (display == NULL)    
	{	  fprintf(stderr, "Unable to open display %s\n",    
		  	  XDisplayName(NULL));    
		  exit(1);    
	}    
	screen = DefaultScreen(display);    
}    
    
/*    
** Give general info about the server characteristics    
*/    
void
report_info()    
{    
	printf("There are %d colour planes\n", 
		DefaultDepth(display, screen));
	printf("The display width in pixels is %d\n",    
		DisplayWidth(display, screen));    
	printf("The display depth in pixels is %d\n",    
		DisplayHeight(display, screen));    
	printf("The display name is %s\n",    
		XDisplayName(display));    
}    

int
main(argc, argv)    
int argc;    
char **argv;    
{    
	initX();    
	report_info();    
	quitX();    
}    
Compilation depends on the location of the libraries involved. The library required is usually libX11.a (on Unix systems) giving cc -o info info.c -lX11 But this may be different in your own environment.

Displaying windows (1)

Displaying windows (2)

In order to display windows with things inside them, a number of steps have to be performed.


#include <stdio.h>    
#include <X11/Xlib.h>    
#include <X11/Xutil.h>    
    
/*    
** Program wide constants    
*/    
char THE_WINDOW_NAME[] = "Window";    
char THE_ICON_NAME[] = "Icon";    
    
/*    
** Program wide globals    
*/    
Display *theDisplay;  /* the display device */    
int	  theScreen;  /* the screen on the display */    
int	  theDepth;  /* number of color planes */    
Window  theWindow;    
GC	  theGC;    
unsigned long  theForeground, theBackground;    

/*    
** function openWindow    
**    
** This opens a window on the display device, and returns    
** the window ID.    
**    
** It takes (x,y) coords, the width and height of the window,    
** and the width of the border    
**    
** Require:     
**	  0 $<=$ x $<$ DisplayWidth(theDisplay, theScreen)    
**	  0 $<=$ y $<$ DisplayHeight(theDisplay, theScreen)    
**	  0 $<$ width    
**	  0 $<$ height    
**	  0 $<=$ border_width    
*/    
    
Window    
openWindow(x, y, width, height, border_width, argc, argv)    
int x, y;  /* coords of the upper left corner in pixels */    
int width,   
    height;  /* size of the window in pixels */    
int border_width;  /* the border width is not included in the    
	  	  	     other dimensions */    
int argc;    
char **argv;    
{    
	  Window  theNewWindow;    
	  XSizeHints  theSizeHints;    
	      
	  /* now create the window */    
	  theForeground = BlackPixel(theDisplay, theScreen);    
	  theBackground = WhitePixel(theDisplay, theScreen);    
	  theNewWindow = XCreateSimpleWindow(theDisplay,     
	  	  	  DefaultRootWindow(theDisplay),    
	  	  	  x, y, width, height,    
	  	  	  border_width,    
	  	  	  theForeground, theBackground);    
    
	  /* set up the size hints for the window manager */    
	  theSizeHints.x = x;    
	  theSizeHints.y = y;    
	  theSizeHints.width = width;    
	  theSizeHints.height = height;    
	  /* and state what hints are included */    
	  theSizeHints.flags = PPosition | PSize;    
    
	  /* let the window manager know about the window */    
	  XSetStandardProperties(theDisplay, theNewWindow,    
	  	  THE_WINDOW_NAME, THE_ICON_NAME,    
	  	  None,	  /* no icon map */    
	  	  argv, argc, &theSizeHints);    
    
	  /* Return the window ID */    
	  return(theNewWindow);    
}    
    
/*    
** function getGC    
**    
** create a graphics context using default values, and    
** return it in the pointer theGC    
*/    
void    
getGC(theGC)    
GC *theGC;    
{    
	  XGCValues theGCValues;    
	  unsigned long  theForeground, theBackground;    
    
	  *theGC = XCreateGC(theDisplay, theWindow,     
	  	  	  (unsigned long) 0, &theGCValues);    
    
	  theForeground = BlackPixel(theDisplay, theScreen);    
	  theBackground = WhitePixel(theDisplay, theScreen);    
	  XSetBackground(theDisplay, *theGC, theBackground);    
	  XSetForeground(theDisplay, *theGC, theForeground);    
}    
    
/*    
** function quit    
**    
** terminate the program gracefully    
*/    
quitX()    
{    
	  XCloseDisplay(theDisplay);    
	  exit(0);    
}    
    
initX()    
{    
	  /* set the display name from the environment vbl DISPLAY */    
	  theDisplay = XOpenDisplay(NULL);    
	  if (theDisplay == NULL)    
	 {	  fprintf(stderr, "Unable to open display %s$backslash$n",    
	  	  	  XDisplayName(NULL));    
	  	  exit(1);    
	  }    
	  theScreen = DefaultScreen(theDisplay);    
	  /* Find the depth of the colour map */    
	  theDepth = DefaultDepth(theDisplay, theScreen);    
	      
	  /* use the default foreground and background colours */    
	  theForeground = BlackPixel(theDisplay, theScreen);    
	  theBackground = WhitePixel(theDisplay, theScreen);    
}    
    
/*    
** display_something    
**    
** write a string    
** and draw    
*/    
display_something()    
{	XEvent theEvent;
	XSelectInput(theDisplay, theWindow, ExposureMask);
	XNextEvent(theDisplay, &theEvent);    
	  /* the proverbial string */    
	  XDrawImageString(theDisplay, theWindow, theGC,    
	  	  10, 10, "Hello world",    
	  	  strlen("Hello world"));    
    
	  /* and a world (circle) to go with it */    
 	  XDrawArc(theDisplay, theWindow, theGC,    
	  	  30, 30,
	  	  100, 100, 
	  	  0, 360*64);
}    
    
main(argc, argv)    
int argc;    
char **argv;    
{
	  initX();    
    
	  theWindow = openWindow(10, 20, 500, 400, 5, argc, argv);    
    
	  getGC(&theGC);    
    
	  /* Display the window on the screen */    
	  XMapWindow(theDisplay, theWindow);    
    
	  display_something();    
	  XFlush(theDisplay);
	  XFlush(theDisplay);
	  XFlush(theDisplay);
	  sleep(30);    
    
	  quitX();    
}

Events

A non-exhaustive listing of X events is

A standard schema (with some minor additions) is in the program onewindow.c:

/*     
** Generic program schema for a one window program    
*/    
    
#include <stdio.h>    
#include <X11/Xlib.h>    
#include <X11/Xutil.h>    
    
/*    
** debug lists all events to an xterm window as they occur    
*/    
#define DEBUG    
    
char THE_WINDOW_NAME[] = "Window";    
char THE_ICON_NAME[] = "Icon";    
    
Display *theDisplay;  /* the display device */    
int	  theScreen;  /* the screen on the display */    
int	  theDepth;  /* number of color planes */    
Window  theWindow;    
GC	  theGC;    
unsigned long  theForeground, theBackground;    
    
/*    
** function openWindow    
*/    
    
Window    
openWindow(x, y, width, height, border_width, argc, argv)    
int x, y;  /* coords of the upper left corner in pixels */    
int width,    
    height;  /* size of the window in pixels */    
int border_width;  /* the border width is not included in the    
	  	  	     other dimensions */    
int argc;    
char **argv;    
{    
	  Window  theNewWindow;    
	  XSizeHints  theSizeHints;    
	      
	  /* now create the window */    
	  theNewWindow = XCreateSimpleWindow(theDisplay,     
	  	  	  DefaultRootWindow(theDisplay),    
	  	  	  x, y, width, height,    
	  	  	  border_width,    
	  	  	  theForeground, theBackground);    
    
	  /* set up the size hints for the window manager */    
	  theSizeHints.x = x;    
	  theSizeHints.y = y;    
	  theSizeHints.width = width;    
	  theSizeHints.height = height;    
	  /* and state what hints are included */    
	  theSizeHints.flags = PPosition | PSize;    
    
	  /* let the window manager know about the window */    
	  XSetStandardProperties(theDisplay, theNewWindow,    
	  	  THE_WINDOW_NAME, THE_ICON_NAME,    
	  	  None,	  /* no icon map */    
	  	  argv, argc, &theSizeHints);    
    
	  /* Decide what events the window will receive */    
	  XSelectInput(theDisplay, theNewWindow,    
	  	  (ButtonPressMask | KeyPressMask | ExposureMask));    
    
	  /* Return the window ID */    
	  return(theNewWindow);    
}    
    
/*    
** function getGC    
*/    
void    
getGC(theGC)    
GC *theGC;    
{/*	  unsigned long theBackground, theForeground;    */
	  XGCValues theGCValues;    
    
	  *theGC = XCreateGC(theDisplay, theWindow,     
	  	  	  (unsigned long) 0, &theGCValues);    
    
	  /* 
theForeground = BlackPixel(theDisplay, theScreen);    
	  theBackground = WhitePixel(theDisplay, theScreen);    
*/
	  XSetBackground(theDisplay, *theGC, theBackground);    
	  XSetForeground(theDisplay, *theGC, theForeground);    
}    
    
/*    
** function quit    
**    
** terminate the program gracefully    
*/    
quit()    
{    
	  XCloseDisplay(theDisplay);    
	  exit(0);    
}    
    
    
/* 
** function doExposeEvent 
**  
** An expose event occurs when the contents of a window are 
** invalidated and at least some of it needs to be redrawn 
*/ 
void    
doExposeEvent(pEvent)    
XExposeEvent *pEvent;    
{    
	  XDrawImageString(theDisplay, theWindow, theGC,    
	  	  10, 10, "Press q or any button to quit",    
	  	  strlen("Press q or any button to quit"));    
}    
    
/* 
** function doButtonPressEvent 
**
** A button has been pressed within the window 
*/ 
void doButtonPressEvent(pEvent)    
XButtonEvent *pEvent;    
{    
	  quit();    
}    
    
/* 
** function doKeyPressEvent 
** 
** a key has been pressed. It needs to be decoded and acted on 
*/ 
void    
doKeyPressEvent(pEvent)    
XKeyEvent *pEvent;    
{	  int theKeyBufferSize = 10;    
	  char theKeyBuffer[9];    
	  XComposeStatus theComposeStatus;    
	  KeySym theKeySym;    
    
	  XLookupString(pEvent, theKeyBuffer, theKeyBufferSize,    
	  	  &theKeySym, &theComposeStatus);    
	  if (theKeyBuffer[0] == 'q')    
	  	  quit();    
}    
    
initX()    
{    
	  /* set the display name from the environment vbl DISPLAY */    
	  theDisplay = XOpenDisplay(NULL);    
	  if (theDisplay == NULL)    
	  {	  fprintf(stderr, "Unable to open display %s\n",    
	  	  	  XDisplayName(NULL));    
	  	  exit(1);    
	  }    
	  theScreen = DefaultScreen(theDisplay);    
	  /* Find the depth of the colour map */    
	  theDepth = DefaultDepth(theDisplay, theScreen);    
	  /* use the default foreground and background colours */    
	  theForeground = BlackPixel(theDisplay, theScreen);    
	  theBackground = WhitePixel(theDisplay, theScreen);    
    
}    
    
main(argc, argv)    
int argc;    
char **argv;    
{	  XEvent theEvent;    
    
	  initX();    
    
	  theWindow = openWindow(10, 20, 200, 100, 5, argc, argv);    
	  getGC(&theGC);    
    
	  /* Display the window on the screen */    
	  XMapWindow(theDisplay, theWindow);    
	  XFlush(theDisplay);    
	  while (True)    
	  {    
	  	  XNextEvent(theDisplay, &theEvent);    
#ifdef DEBUG    
	  	  printf("Event number is %d\n", theEvent.type);    
#endif    
	  	  switch (theEvent.type)    
	  	  {    
	  	  case Expose:  doExposeEvent(&theEvent);    
	  	  	  	  break;    
    
	  	  case ButtonPress:    
	  	  	  	  doButtonPressEvent(&theEvent);    
	  	  	  	  break;    
    
	  	  case KeyPress:  doKeyPressEvent(&theEvent);    
	  	  	  	  break;    
    
	  	  case MappingNotify:    
	  	  	  	  XRefreshKeyboardMapping(&theEvent);    
	  	  	  	  break;    
	  	  }    
	  }    
}

Multiple windows


/*     
** Chase a box around the screen, attempting to click the    
** mouse in the box.    
** Scores are kept of your accuracy    
*/    
    
#include <stdio.h>    
#include <X11/Xlib.h>    
#include <X11/Xutil.h>    
    
#define DEBUG    
    
char THE_WINDOW_NAME[] = "chase";    
char THE_ICON_NAME[] = "chase";    
    
Display *theDisplay;  /* the display device */    
int	  theScreen;  /* the screen on the display */    
int	  theDepth;  /* number of color planes */    
GC theGC;  /* graphics context */    
    
Window theFrameWindow;  /* holds all the other windows */    
Window theHitWindow;  /* the count of hits */    
Window theMissWindow;  /* the count of misses */    
Window thePaneWindow;  /* the background window for the box to move in */    
Window theBoxWindow;  /* the box to hit with the cursor */    
unsigned long  theForeground, theBackground;    
int hits = 0;    
int misses = 0;    
    
int frame_x, frame_y, frame_width, frame_ht;  /* size of frame window */    
#define BOX_SIZE 4  /* in pixels */   
#define TEXT_HT 20   /* in pixels - and a kludge */ 
/*    
** function openWindow    
*/    
    
Window    
openWindow(x, y, width, height, border_width, parent, toplevel, argc, argv)    
int x, y;  /* coords of the upper left corner in pixels */    
int width,    
    height;  /* size of the window in pixels */    
int border_width;  /* the border width is not included in the    
	  	  	     other dimensions */    
Window parent;    
int toplevel;  /* a Boolean value */    
int argc;    
char **argv;    
{    
	  Window  theNewWindow;    
	  XSizeHints  theSizeHints;    
	      
	  /* now create the window */    
	  theNewWindow = XCreateSimpleWindow(theDisplay,     
	  	  	  parent,    
	  	  	  x, y, width, height,    
	  	  	  border_width,    
	  	  	  theForeground, theBackground);    
    
	  /* If the window is a toplevel window,    
	     set up the size hints for the window manager */    
	  if (toplevel)    
	  {    
	  	  theSizeHints.x = x;    
	  	  theSizeHints.y = y;    
	  	  theSizeHints.width = width;    
	  	  theSizeHints.height = height;    
	  	  /* and state what hints are included */    
	  	  theSizeHints.flags = PPosition | PSize;    
	      
	  	  /* let the window manager know about the window */    
	  	  XSetStandardProperties(theDisplay, theNewWindow,    
	  	  	  THE_WINDOW_NAME, THE_ICON_NAME,    
	  	  	  None,  /* no icon map */    
	  	  	  argv, argc, &theSizeHints);    
	  }    
	  /* Display the window on the screen */    
	  XMapWindow(theDisplay, theNewWindow);    
    
	  /* Return the window ID */    
	  return(theNewWindow);    
}    
    
/*    
** function getGC    
**    
** create a graphics context using default values, and    
** return it in the pointer theGC    
*/    
void    
getGC(theGC)    
GC *theGC;    
{	  unsigned long theBackground, theForeground;    
    
	  *theGC = XCreateGC(theDisplay, theFrameWindow, 0, NULL);    
	      
	  theBackground = WhitePixel(theDisplay, theScreen);    
	  theForeground = BlackPixel(theDisplay, theScreen);    
    
	  XSetBackground(theDisplay, *theGC, theBackground);    
	  XSetForeground(theDisplay, *theGC, theForeground);    
}    
    
/*    
** function quit    
**    
** terminate the program gracefully    
*/    
quit()    
{    
	  XCloseDisplay(theDisplay);    
	  exit(0);    
}    
    
    
void    
doExposeEvent(pEvent)    
XExposeEvent *pEvent;    
{    
	  if (pEvent->window == theHitWindow)    
	  {	  char hit_str[20];    
    
	  	  sprintf(hit_str, "Hits: %d", hits);    
	  	  XDrawImageString(theDisplay, theHitWindow, theGC,    
	  	  	  5, 10, hit_str, strlen(hit_str));    
	  }    
	  if (pEvent-> window == theMissWindow)    
	  {	  char miss_str[20];    
    
	  	  sprintf(miss_str, "Misses: %d", misses);    
	  	  XDrawImageString(theDisplay, theMissWindow, theGC,    
	  	  	  5, 10, miss_str, strlen(miss_str));    
	  }    
}    
    
void doButtonPressEvent(pEvent)    
XButtonEvent *pEvent;    
{	  int box_x, box_y;    
	  XEvent updateEvent;    
    
	  if (pEvent->window == thePaneWindow)    
	  {    
	  	  XClearArea(theDisplay, theMissWindow, 0, 0,     
	  	  	  frame_width / 2, TEXT_HT, True);    
	  	  misses++;    
	  }    
	  else /* pEvent->window == theBoxWindow */    
	  {    
	  	  XClearArea(theDisplay, theHitWindow, 0, 0,    
	  	  	  frame_width / 2, TEXT_HT, True);    
	  	  hits++;    
	  }    
	  box_x = rand() % (frame_width - BOX_SIZE);    
	  box_y = rand() % (frame_ht - TEXT_HT - BOX_SIZE);    
	  XMoveWindow(theDisplay, theBoxWindow, box_x, box_y);    
}    
    
void    
doKeyPressEvent(pEvent)    
XKeyEvent *pEvent;    
{	  int theKeyBufferSize = 10;    
	  char theKeyBuffer[64];    
	  XComposeStatus theComposeStatus;    
	  KeySym theKeySym;    
    
	  XLookupString(pEvent, theKeyBuffer, theKeyBufferSize,    
	  	  &theKeySym, &theComposeStatus);    
	  if (theKeyBuffer[0] == 'q')    
	  {	  printf("Hits: %d; Misses: %d\n", hits, misses);    
	  	  quit();    
	  }    
}    
    
initX() 
{    
	  theDisplay = XOpenDisplay(NULL);    
	  theScreen = DefaultScreen(theDisplay);    
	  /* use the default foreground and background colours */    
	  theForeground = BlackPixel(theDisplay, theScreen);    
	  theBackground = WhitePixel(theDisplay, theScreen);    
}    
main(argc, argv)    
int argc;    
char **argv;    
{	  XEvent theEvent;    
	  int box_x, box_y;    
    
	  initX();
    
	  /* create the frame window to occupy a large area of the screen,    
	     in the middle */    
	  frame_width = DisplayWidth(theDisplay, theScreen) / 2;    
	  frame_ht = (DisplayHeight(theDisplay, theScreen) * 2) / 3;    
	  frame_x = frame_width / 2;    
	  frame_y = frame_ht / 6;    
	  theFrameWindow = openWindow(frame_x, frame_y, frame_width, frame_ht, 5,    
	  	  	  	  DefaultRootWindow(theDisplay),    
	  	  	  	  True, argc, argv);    
	  theHitWindow = openWindow(0, 0, frame_width / 2, TEXT_HT,    
	  	  	  	  1, theFrameWindow, False, 0, NULL);    
	  theMissWindow = openWindow(frame_width / 2, 0,     
	  	  	  	  frame_width / 2, TEXT_HT,    
	  	  	  	  1, theFrameWindow, False, 0, NULL);    
	  thePaneWindow = openWindow(0, TEXT_HT,    
	  	  	  	  frame_width, frame_ht - TEXT_HT,    
	  	  	  	  1, theFrameWindow, False, 0, NULL);    
	  srand(1);    
	  box_x = rand() % (frame_width - BOX_SIZE);    
	  box_y = rand() % (frame_ht - TEXT_HT - BOX_SIZE);    
	  theBoxWindow = openWindow(box_x, box_y, BOX_SIZE, BOX_SIZE, 2,    
	  	  	  	  thePaneWindow, False, 0, (void *) 0);    
	  getGC(&theGC);    
	  XSelectInput(theDisplay, theFrameWindow,    
	  	  KeyPressMask);    
	  XSelectInput(theDisplay, thePaneWindow,    
	  	  ButtonPressMask);    
	  XSelectInput(theDisplay, theHitWindow,    
	  	  ExposureMask);    
	  XSelectInput(theDisplay, theMissWindow,    
	 	                ExposureMask);    
	  XSelectInput(theDisplay, theBoxWindow,    
	 	                ButtonPressMask);    
    
    
	  while (True)    
	  {    
	  	  XNextEvent(theDisplay, &theEvent);    
#ifdef DEBUG    
	  	  fprintf(stderr, "Event number is %d\n", theEvent.type);    
#endif    
	  	  switch (theEvent.type)    
	  	  {    
	  	  case Expose:  doExposeEvent(&theEvent);    
	  	  	  	  break;    
    
	  	  case ButtonPress:    
	  	  	  	  doButtonPressEvent(&theEvent);    
	  	  	  	  break;    
    
	  	  case KeyPress:  doKeyPressEvent(&theEvent);    
	  	  	  	  break;    
    
	  	  case MappingNotify:    
	  	  	  	  XRefreshKeyboardMapping(&theEvent);    
	  	  	  	  break;    
	  	  }    
	  }    
}

Fonts

A program that uses a different font is font.c. Here are some extracts from it---the bits that would need to be changed in any of catch.c, onewindow.c, etc.


#include <stdio.h>    
#include <X11/Xlib.h>    
#include <X11/Xutil.h>    
    
/*    
** Program wide constants    
*/    
char THE_WINDOW_NAME[] = "Window";    
char THE_ICON_NAME[] = "Icon";    
char FONT[] = "9x15";
 
/*    
** Program wide globals    
*/    
Display *display;  /* the display device */    
int	screen;  /* the screen on the display */    
Window  main_window;    
GC	gc;    
unsigned long  foreground, background;    
Font	font;

/*    
** Opens a window on the display device, and returns    
** the window ID.    
**    
** It takes (x,y) coords, the width and height of the window,    
** and the width of the border    
*/    
    
Window    
openWindow (x, y, width, height, border_width, argc, argv)    
	int x, y;  /* coords of the upper left corner in pixels */    
	int width,   
	    height;  /* size of the window in pixels */    
	int border_width;  /* the border width is not included in the    
			  	     other dimensions */    
	int argc;    
	char **argv;    
{    
	Window  new_window;    
	XSizeHints  size_hints;    
	    
	/* now create the window */    
	foreground = BlackPixel (display, screen);    
	background = WhitePixel (display, screen);    
	new_window = XCreateSimpleWindow (display,     
		  	  DefaultRootWindow (display),    
		  	  x, y, width, height,    
		  	  border_width,    
		  	  foreground, background);    
    
	/* set up the size hints for the window manager */    
	size_hints.x = x;    
	size_hints.y = y;    
	size_hints.width = width;    
	size_hints.height = height;    
	/* and state what hints are included */    
	size_hints.flags = PPosition | PSize;    
    
	/* let the window manager know about the window */    
	XSetStandardProperties (display, new_window,    
		  THE_WINDOW_NAME, THE_ICON_NAME,    
		  None,	  /* no icon map */    
		  argv, argc, &size_hints);    
    
	/* Return the window ID */    
	return (new_window);    
}    
    
/*    
** Create a graphics context using default values, and    
** return it.
*/    
GC   
getGC ()    
{    
	GC gc;    
	XGCValues gcValues;    
    
	gc = XCreateGC (display, main_window,     
		  	  (unsigned long) 0, &gcValues);    
    
	XSetBackground (display, gc, background);    
	XSetForeground (display, gc, foreground);    

	if (font != 0)
		XSetFont (display, gc, font);

	return (gc);
}    
    
/*    
** Terminate the program gracefully    
*/    
quitX ()    
{
	if (font != 0)
		XUnloadFont (display, font);    
	XCloseDisplay (display);    
	exit (0);    
}    
    
initX ()    
{	char **font_list;
	int count;
    
	/* set the display name from the environment vbl DISPLAY */    
	display = XOpenDisplay (NULL);    
	if (display == NULL)    
	 {	fprintf (stderr, "Unable to open display %s$backslash$n",    
		  	  XDisplayName (NULL));    
		  exit (1);    
	}    
	screen = DefaultScreen (display);    
	    
	/* use the default foreground and background colours */    
	foreground = BlackPixel (display, screen);    
	background = WhitePixel (display, screen);    

	font_list = XListFonts (display, FONT, 1, &count);
	if (count > 0)
	{	/* found the font we want, use the first match */
		font = XLoadFont (display, *font_list);
		XFreeFontNames (font_list);
	}
	else	
	{	/* this font not on the server. set it to
		** a non-existant value
		*/
		font = (Font) 0;
		fprintf (stderr, "couldn't find font %s\n", FONT);
	}
}    
    
/*    
** display_something    
**    
** write a string    
** and draw    
*/    
display_something ()    
{	XEvent theEvent;
	XSelectInput (display, main_window, ExposureMask);
	XNextEvent (display, &theEvent);    
	/* the proverbial string */    
	XDrawImageString (display, main_window, gc,    
		  10, 10, "Hello world",    
		  strlen ("Hello world"));    
    
	/* and a world (circle) to go with it */    
 	XDrawArc (display, main_window, gc,    
		  30, 30,
		  100, 100, 
		  0, 360*64);
}    
    
main (argc, argv)    
int argc;    
char **argv;    
{
	initX ();    
    
	main_window = openWindow (10, 20, 500, 400, 5, argc, argv);    
    
	gc = getGC ();    
    
	/* Display the window on the screen */    
	XMapWindow (display, main_window);    
    
	display_something ();    
	XFlush (display);
	sleep (30);    
    
	quitX ();    
}

Colour

For portable applications, remember these rules:

#include <stdio.h>    
#include <X11/Xlib.h>    
#include <X11/Xutil.h>    
    
/*    
** Program wide constants    
*/    
char THE_WINDOW_NAME[] = "Window";    
char THE_ICON_NAME[] = "Icon";    
char RED[] = "Red";
char BLUE[] = "Blue";
    
/*    
** Program wide globals    
*/    
Display *theDisplay;  /* the display device */    
int	  theScreen;  /* the screen on the display */    
int	  theDepth;  /* number of color planes */    
Window  theWindow;    
GC	  theGC;    
unsigned long  theForeground, theBackground;    
XColor	theRGBColor, theHardwareColor;
Colormap	theColormap;

/*    
** function openWindow    
**    
** This opens a window on the display device, and returns    
** the window ID.    
**    
** It takes (x,y) coords, the width and height of the window,    
** and the width of the border    
**    
** Require:     
**	  0 $<=$ x $<$ DisplayWidth(theDisplay, theScreen)    
**	  0 $<=$ y $<$ DisplayHeight(theDisplay, theScreen)    
**	  0 $<$ width    
**	  0 $<$ height    
**	  0 $<=$ border_width    
*/    
    
Window    
openWindow(x, y, width, height, border_width, argc, argv)    
int x, y;  /* coords of the upper left corner in pixels */    
int width,   
    height;  /* size of the window in pixels */    
int border_width;  /* the border width is not included in the    
	  	  	     other dimensions */    
int argc;    
char **argv;    
{    
	  Window  theNewWindow;    
	  XSizeHints  theSizeHints;    
	      
	  /* now create the window */    
	  theNewWindow = XCreateSimpleWindow(theDisplay,     
	  	  	  DefaultRootWindow(theDisplay),    
	  	  	  x, y, width, height,    
	  	  	  border_width,    
	  	  	  theForeground, theBackground);    
    
	  /* set up the size hints for the window manager */    
	  theSizeHints.x = x;    
	  theSizeHints.y = y;    
	  theSizeHints.width = width;    
	  theSizeHints.height = height;    
	  /* and state what hints are included */    
	  theSizeHints.flags = PPosition | PSize;    
    
	  /* let the window manager know about the window */    
	  XSetStandardProperties(theDisplay, theNewWindow,    
	  	  THE_WINDOW_NAME, THE_ICON_NAME,    
	  	  None,	  /* no icon map */    
	  	  argv, argc, &theSizeHints);    
    
	  /* Return the window ID */    
	  return(theNewWindow);    
}    
    
/*    
** function getGC    
**    
** create a graphics context using default values, and    
** return it in the pointer theGC    
*/    
void    
getGC(theGC)    
GC *theGC;    
{    
	  XGCValues theGCValues;    
    
	  *theGC = XCreateGC(theDisplay, theWindow,     
	  	  	  (unsigned long) 0, &theGCValues);    
	  XSetBackground(theDisplay, *theGC, theBackground);    
	  XSetForeground(theDisplay, *theGC, theForeground);    
}    
    
/*    
** function quit    
**    
** terminate the program gracefully    
*/    
quitX()    
{    
	  XCloseDisplay(theDisplay);    
	  exit(0);    
}    
    
initX()    
{    
	  /* set the display name from the environment vbl DISPLAY */    
	  theDisplay = XOpenDisplay(NULL);    
	  if (theDisplay == NULL)    
	 {	  fprintf(stderr, "Unable to open display %s$backslash$n",    
	  	  	  XDisplayName(NULL));    
	  	  exit(1);    
	  }    
	  theScreen = DefaultScreen(theDisplay);    
	  /* Find the depth of the colour map */    
	  theDepth = DefaultDepth(theDisplay, theScreen);    
	      
	  /* set the defaults in case we can't use colour */
	  theForeground = BlackPixel(theDisplay, theScreen);    
	  theBackground = WhitePixel(theDisplay, theScreen);    
	  
	  if (theDepth > 1)
	  {	/* not monochrome */
		theColormap = DefaultColormap(theDisplay, theScreen);
		if (XLookupColor(theDisplay, theColormap,
			RED, &theRGBColor, &theHardwareColor) != 0
		    &&
	       	    XAllocColor(theDisplay, theColormap,
				&theHardwareColor) != 0)
		theBackground = theHardwareColor.pixel;
		
		if (XLookupColor(theDisplay, theColormap,
			BLUE, &theRGBColor, &theHardwareColor) != 0
		    &&
	       	    XAllocColor(theDisplay, theColormap,
				&theHardwareColor) != 0)
		theForeground = theHardwareColor.pixel;
	}
}    
    
/*    
** display_something    
**    
** write a string    
** and draw    
*/    
display_something()    
{	XEvent theEvent;
	XSelectInput(theDisplay, theWindow, ExposureMask);
	XNextEvent(theDisplay, &theEvent);    
	  /* the proverbial string */    
	  XDrawImageString(theDisplay, theWindow, theGC,    
	  	  10, 10, "Hello world",    
	  	  strlen("Hello world"));    
    
	  /* and a world (circle) to go with it */    
 	  XDrawArc(theDisplay, theWindow, theGC,    
	  	  30, 30,
	  	  100, 100, 
	  	  0, 360*64);
}    
    
main(argc, argv)    
int argc;    
char **argv;    
{
	  initX();    
    
	  theWindow = openWindow(10, 20, 500, 400, 5, argc, argv);    
    
	  getGC(&theGC);    
    
	  /* Display the window on the screen */    
	  XMapWindow(theDisplay, theWindow);    
    
	  display_something();    
	  XFlush(theDisplay);
	  sleep(30);    
    
	  quitX();    
}

Widgets

Simple Motif program


#include <X11/Intrinsic.h>	
#include <Xm/Xm.h>	
#include <Xm/ArrowB.h>	
#include <Xm/MwmUtil.h>
	
char Class_name[] ="Arrow";	
	
main(argc, argv)	
int argc;
char **argv;
{	
	 Widget toplevel, arrow_widget;	
	 	
	 /* Initialise the intrinsics  with a toplevel widget */	
	 toplevel = XtInitialize(argv[0], /* application name */	
	 	 	 Class_name, 	/* class name */	
	 	 	 NULL, 		/* options (see below) */	
	 	 	 0,		/* number of options */	
	 	 	 &argc, argv);	
	 /*
	{ int int_val;
        XtVaGetValues(toplevel, XmNmwmFunctions, &int_val, NULL);
        int_val &= ~(MWM_FUNC_CLOSE | MWM_FUNC_ALL);
        XtVaSetValues(toplevel, XmNmwmFunctions, int_val, NULL);
	}
	 */
	 /* Create a widget, with the toplevel as manager;	
	    its class is ArrowButton.
	 */	
	 arrow_widget = XmCreateArrowButton(toplevel, /* parent */ 
	 	 	 	 	 "an_arrow",
					 NULL, 0
					 );

	/* sort out the geometry */
	XtManageChild(arrow_widget);
	 	
	 /* display all of the widgets */	
	 XtRealizeWidget(toplevel);	

	 /* enter the main processing loop */	
	 XtMainLoop();
}