5.13. Your last Xlib Program   

You can now create an X Window System program which uses events(see later to retrieve it):

  #include <X11/Xlib.h>

#include <stdio.h>
#include <X11/Xutil.h>
#include <math.h>
#define LEFT_BUTTON 1 /* left button position */
#define MIDDLE_BUTTON 2 /* middle button position */
#define RIGHT_BUTTON 3 /* right button position */
/* This procedure accepts from the calling program the name of the colour which
they wish to set the current drawing colour to. */
void
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, colourname)
Display *myDisplay;
Window myWindow;
GC myGC; /* GC to set the colour for */
Colormap myColourmap; /* colour map */
int myDepth;
char *colourname; /* name of the colour to set */
{
XColor rgbcolour; /* exact rgb components of the colour */
XColor hwarecolour; /* closest rgb colour for the hardware */
int status; /* determines if function ok */
int myScreen;
myScreen = DefaultScreen (myDisplay);
/* if myDepth >1 then on a colour screen */
if (myDepth > 1)
{
status = XLookupColor(myDisplay, myColourmap,
colourname, &rgbcolour, &hwarecolour);
if (status != 0)
{
/* allocate colour to colour map */
status = XAllocColor (myDisplay, myColourmap, &hwarecolour);
if (status != 0)
{
/* set drawing colour */
XSetForeground (myDisplay, myGC, hwarecolour.pixel);
}
else
{
fprintf(stderr,"Cannot get a colour cell for :%s\n",colourname);
fprintf(stderr,"Using Black instead\n");
XSetForeground (myDisplay, myGC, BlackPixel (myDisplay, myScreen));
}
}
else
{
fprintf(stderr,"Cannot find colour :%s\n",colourname);
fprintf(stderr,"Using Black instead\n");
XSetForeground (myDisplay, myGC, BlackPixel (myDisplay, myScreen));
}
}
else
{
fprintf(stderr,"Cannot get a colour on this depth machine:%d\n",myDepth);
fprintf(stderr,"Using Black instead\n");
XSetForeground (myDisplay, myGC, BlackPixel (myDisplay, myScreen));
}
}

  /* This procedure calculates the square which is the closest to where the mouse

click was make */
void
CalculateObject(myDisplay, myWindow, myGC, myColourmap,myDepth, myEvent)
Display *myDisplay;
Window myWindow;
GC myGC; /* GC to set the colour for */
Colormap myColourmap; /* colour map */
int myDepth;
XEvent myEvent; /* event which has occured */
{
char objectstring[100];
char *object;
int x = myEvent.xmotion.x;
int y = myEvent.xmotion.y;
object = "unknown";
if (y < 100)
;
else if (y < 150)
{
if(x<100)
;
else if (x< 150)
object="rectangle";
else if ( (x<250) && (x>200) )
object="filled rectangle";
else if ( (x<350) && (x>300) )
object="circle";
else if ( (x<450) && (x>400) )
object="filled circle";
else if ( (x<560) && (x>500) )
object="oval";
else if ( (x<660) && (x>600) )
object="filled oval";
}
else if ( (y < 300) && (y>175) && (x>475) && (x<550) )
{
object="bignose";
}
else if ( (y < 350) && (y>300) )
{
if(x<100)
;
else if (x< 130)
object="arc";
else if ( (x<230) && (x>200) )
object="filled arc";
else if ( (x<350) && (x>300) )
object="star";
}
else if ( (y < 525) && (y>430) )
{
object="times font example";
}
else if (y < 675)
{
object="Symbol font example";
}
sprintf(objectstring,"Object is %s. ",
object);
XDrawImageString (myDisplay, myWindow, myGC,450,30,
objectstring,strlen(objectstring));
}

  void

DisplayWindowOfObjects(myDisplay, myWindow,myGC,myColourmap,myDepth,myfont)
Display *myDisplay;
Window myWindow;
GC myGC; /* GC to set the colour for */
Colormap myColourmap; /* colour map */
int myDepth;
XFontStruct **myfont;
{
char *fontname;
char character_string[200];
char *alphabet0="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *alphabet1="abcdefghijklmnopqrstuvwxyz";
char *alphabet2="0123456789";
int base_y;
int i;
double twopi= 8.0*atan(1.0);
char *heading="q to quit, Left button=red,Middle=blue,Right=select,Press any key";
/*--------------- Pre-assigned points for XDrawLines call below---------------*/
static XPoint points1[]=
{
499,214,489,224,484,229,479,239,474,254,479,274,489,279,499,279,
509,274,519,264
};
static XPoint points2[]=
{
499,284,504,289,509,289,514,289,519,284
};
static XPoint points3[]=
{
514,214,509,214,514,219,519,219,514,214
};
static XPoint points4[]=
{
484,209,479,214,479,214,484,214,489,209,484,209
};
static XPoint points5[]=
{
514,199,529,214,539,224,539,244,539,259,539,264,534,279,534,274
};
static XPoint points6[]=
{
519,194,529,204,544,219,544,239
};
static XPoint points7[]=
{
484,194,494,194,504,199,509,199
};
static XPoint points8[]=
{
489,189,494,189,509,189
};
static XPoint points9[]=
{
494,179,509,179,514,184,514,189
};
static XPoint points10[]=
{
524,189,534,199,549,209,554,229,549,249,549,259,549,279,549,284
};
/*--------End of Pre-assigned points for XDrawLines call below---------------*/

     setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "red");

XDrawRectangle (myDisplay, myWindow, myGC,
100, 100, 50, 50 );
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "yellow");
XFillRectangle (myDisplay, myWindow, myGC,
200, 100, 50, 50 );
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "blue");
/* draws a circle */
XDrawArc (myDisplay, myWindow, myGC,
300, 100, 50, 50 , 0, 360*64);
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "green");
XFillArc (myDisplay, myWindow, myGC,
400, 100, 50, 50 , 0, 360*64);
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "dodgerblue");
/* draws an oval */
XDrawArc (myDisplay, myWindow, myGC,
500,100, 60, 40 , 0, 360*64);
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "chocolate");
XFillArc (myDisplay, myWindow, myGC,
600,100, 60, 40 , 0, 360*64);
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "grey50");
/* draws an arc */
XDrawArc (myDisplay, myWindow, myGC,
100, 300, 60, 40 , 90*64, 180*64);
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "grey80");
XFillArc (myDisplay, myWindow, myGC,
200, 300, 60, 40 , 90*64, 180*64);
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "IndianRed");
#define RAYS 10
for(i=0;i<RAYS/2;i++)
XDrawLine(myDisplay, myWindow, myGC,
325+(int)25*cos(twopi/RAYS*i),
325+(int)25*sin(twopi/RAYS*i),
325+(int)25*cos(twopi/2.0+twopi/RAYS*i),
325+(int)25*sin(twopi/2.0+twopi/RAYS*i));
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "violet");
XDrawLines(myDisplay, myWindow, myGC,
points1,sizeof(points1)/sizeof(points1[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points2,sizeof(points2)/sizeof(points2[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points3,sizeof(points3)/sizeof(points3[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points4,sizeof(points4)/sizeof(points4[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points5,sizeof(points5)/sizeof(points5[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points6,sizeof(points6)/sizeof(points6[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points7,sizeof(points7)/sizeof(points7[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points8,sizeof(points8)/sizeof(points8[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points9,sizeof(points9)/sizeof(points9[0]),CoordModeOrigin);
XDrawLines(myDisplay, myWindow, myGC,
points10,sizeof(points10)/sizeof(points10[0]),CoordModeOrigin);
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "goldenrod");
fontname="-*-times-*-*-*-*-*-240-*-*-*-*-*-*";
sprintf(character_string,"This is font %s",fontname);
*myfont = XLoadQueryFont (myDisplay, fontname);
if (*myfont == (XFontStruct *)NULL)
{
fprintf(stderr,"Cannot get font:%s.\n",fontname);
exit();
}
XSetFont (myDisplay, myGC, (*myfont)->fid);

     base_y=450;

XDrawImageString (myDisplay, myWindow, myGC, 50, base_y,
character_string, strlen(character_string));
XDrawImageString (myDisplay, myWindow, myGC, 80, base_y+25,
alphabet0, strlen(alphabet0));
XDrawImageString (myDisplay, myWindow, myGC, 80, base_y+50,
alphabet1, strlen(alphabet1));
XDrawImageString (myDisplay, myWindow, myGC, 80, base_y+75,
alphabet2, strlen(alphabet2));
fontname="-*-symbol-*-*-*-*-24-400-*-*-*-*-*-*";
sprintf(character_string,"This is font %s",fontname);
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "aquamarine");
base_y=575;
XDrawImageString (myDisplay, myWindow, myGC, 50, base_y,
character_string, strlen(character_string));
(*myfont) = XLoadQueryFont (myDisplay, fontname);
if ((*myfont) == (XFontStruct *)NULL)
{
fprintf(stderr,"Cannot get font:%s.\n",fontname);
exit();
}
XSetFont (myDisplay, myGC, (*myfont)->fid);
base_y=600;
XDrawImageString (myDisplay, myWindow, myGC, 50, base_y,
character_string, strlen(character_string));
XDrawImageString (myDisplay, myWindow, myGC, 80, base_y+25,
alphabet0, strlen(alphabet0));
XDrawImageString (myDisplay, myWindow, myGC, 80, base_y+50,
alphabet1, strlen(alphabet1));
XDrawImageString (myDisplay, myWindow, myGC, 80, base_y+75,
alphabet2, strlen(alphabet2));
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "black");
fontname="8x13";
*myfont = XLoadQueryFont (myDisplay, fontname);
if (*myfont == (XFontStruct *)NULL)
{
fprintf(stderr,"Cannot get font:%s.\n",fontname);
exit();
}
XSetFont (myDisplay, myGC, (*myfont)->fid);
XDrawImageString (myDisplay, myWindow, myGC, 100, 10,
heading, strlen(heading));
}

  void

poll (myDisplay, myWindow,myGC,myColourmap,myDepth,myfont)
Display *myDisplay;
Window myWindow;
GC myGC; /* GC to set the colour for */
Colormap myColourmap; /* colour map */
int myDepth;
XFontStruct **myfont;
{
unsigned int width, height;
int newx, newy; /* top left corner of closest box */
XEvent myEvent; /* event which has occured */
KeySym mych; /* */
int ch; /* character received */
char text[10]; /* */
int finished; /* determines if user wishes to quit */
char *fontname;
/* set up which events you want for a particular window */
XSelectInput (myDisplay, myWindow,
PointerMotionMask | ButtonPressMask | KeyPressMask | ExposureMask);
finished = 0; /* initialize loop control */
while (!finished )
{
XNextEvent (myDisplay, &myEvent); /* read next event in the queue */
switch (myEvent.type)
{
case Expose : /* window manager now sends an Expose Event since override_redirect = False */
DisplayWindowOfObjects(myDisplay, myWindow,myGC,myColourmap,myDepth,&myfont);
break;
case MotionNotify :
{
char position[50];
sprintf(position,"(X,Y)=(%d,%d).",
myEvent.xmotion.x,myEvent.xmotion.y);
XDrawImageString (myDisplay, myWindow, myGC,30,30,
position,strlen(position));
}
break;
/* mouse button was pressed */
case ButtonPress:
switch (myEvent.xbutton.button)
{
case LEFT_BUTTON : setcolourvianame(myDisplay, myWindow, myGC,
myColourmap,myDepth,"red");
break;
case MIDDLE_BUTTON : setcolourvianame(myDisplay, myWindow, myGC,
myColourmap,myDepth,"blue");
break;
case RIGHT_BUTTON : CalculateObject(myDisplay, myWindow, myGC,
myColourmap,myDepth,
myEvent);
break;
}
break;
case KeyPress:
{
ch = XLookupString ((XKeyEvent *)&myEvent, text, 10, &mych, 0);
/* check if user wishes to quit */
if (ch == 1 && text[0] == 'q') finished = 1;
else
{
char keystring[50];
sprintf(keystring,"Key pressed is %s.",
text);
XDrawImageString (myDisplay, myWindow, myGC,200,30,
keystring,strlen(keystring));
}
}
break;
}
}
}

  main (argc, argv)

int argc;
char **argv;
{
Display *myDisplay;
int myScreen;
int myDepth;
Colormap myColourmap; /* colour map */
XSetWindowAttributes myWindowAttributes;
unsigned long myWindowMask;
Window myWindow;
XSizeHints theSizeHints;
GC myGC;
unsigned long myWhitePixel;
unsigned long myBlackPixel;
XGCValues myGCValues;
unsigned long myValueMask;
XFontStruct *myfont;
int i;
int x = 200; /* x top left corner of window */
int y = 150; /* y top left corner of window */
unsigned int width = 850; /* width of the window */
unsigned int height = 700; /* height of the window */
int border_width = 20; /* border width of the window */
myDisplay = XOpenDisplay ("");
if (myDisplay == NULL)
{
fprintf (stderr, "ERROR: Could not open a connection to X on display %s\n",
XDisplayName (NULL));
exit (0);
}
myScreen = DefaultScreen (myDisplay);
myDepth = DefaultDepth (myDisplay, myScreen);
myColourmap = DefaultColormap (myDisplay, myScreen);
myWhitePixel = WhitePixel (myDisplay, myScreen);
myBlackPixel = BlackPixel (myDisplay, myScreen);
myWindowAttributes.border_pixel = BlackPixel (myDisplay, myScreen);
myWindowAttributes.background_pixel = WhitePixel (myDisplay, myScreen);
myWindowAttributes.override_redirect = False;
myWindowMask = CWBackPixel | CWBorderPixel | CWOverrideRedirect;
myWindow = XCreateWindow (myDisplay, RootWindow (myDisplay, myScreen),
x, y, width, height, border_width,
myDepth, InputOutput, CopyFromParent,
myWindowMask, &myWindowAttributes);
theSizeHints.flags = PPosition | PSize; /* set mask for the hints */
theSizeHints.x = x; /* x position */
theSizeHints.y = y; /* y position */
theSizeHints.width = width; /* width of the window */
theSizeHints.height = height; /* height of the window */
XSetWMNormalHints (myDisplay, myWindow, &theSizeHints);
myGC = XCreateGC (myDisplay, myWindow, (unsigned long) 0, &myGCValues);
if (myGC == 0) /* error... cannot create gc */
{
XDestroyWindow(myDisplay, myScreen);
exit (0);
}
else /* set forground and background defaults */
{
XSetForeground (myDisplay, myGC, myBlackPixel);
XSetBackground (myDisplay, myGC, myWhitePixel);
}

     XMapWindow (myDisplay, myWindow);

DisplayWindowOfObjects(myDisplay, myWindow,myGC,myColourmap,myDepth,&myfont);
XFlush (myDisplay);
fprintf(stderr,"And now lets look at a mythical colour:\n");
setcolourvianame (myDisplay, myWindow, myGC, myColourmap,myDepth, "BabyShitGreen");
/*-----------------------------------------------------------------------------
Now Poll
-----------------------------------------------------------------------------*/
poll (myDisplay, myWindow,myGC,myColourmap,myDepth,&myfont);
/*-----------------------------------------------------------------------------
DESTROY ALL WINDOWS
-----------------------------------------------------------------------------*/
XFreeFont (myDisplay, myfont);
XDestroyWindow (myDisplay, myWindow);
XCloseDisplay (myDisplay);
exit (0);
}

You will also need to have an Imakefile (see later section on Imakefiles) :

LOCAL_LIBRARIES = $(XLIB) -lm

FILE = simplewindow
SRCS = $(FILE).c
OBJS = $(FILE).o
ComplexProgramTarget($(FILE))


The alternative would be for you to grab the source code (via ) and compile it on your machine.
Imakefile events.c

After retrieving and saving the code plus Imakefile, you should be able to type:
xmkmf -a ; make FILE=events
This will produce the executable called events.

It is possible to execute a (different) font program and display it on your screen. To run it, your system must be running X and the server control is set to xhost www.cs.curtin.edu.au/. Also it will not work if you are using a proxy server or you are running your browser on a machine different from the one you are displaying it on. Many example programs are available