/*  w1.c    a very basic, yet complete X program */

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Display *dpy;
Window window1;
GC gc;
Screen *screen;

static void doInitialize(void);          /* function prototypes used below */
static void doCreateWindows(void);
static void doCreateGraphicsContext(void);
static void doExpose(XEvent *eventP);
static void doHandleEvents(void);

/********************** The main program *******************************/
int main(int argc, char *argv[])
{          
    doInitialize();
    doHandleEvents(); /* this never returns */
    return 0;
}                                        

/***************** doInitialize **************************/
static void doInitialize(void)
{
    dpy = XOpenDisplay(0); 
    if (!dpy){
        printf("Display not opened!\n");
        exit(1);
    }
    screen = XDefaultScreenOfDisplay(dpy);

    doCreateWindows();

    doCreateGraphicsContext();

    XStoreName(dpy, window1, "W1  click to exit");

    XMapWindow(dpy, window1);
} 

/******* doCreateWindows *********/
static void doCreateWindows(void)
{   
  int window1X = 300;
  int window1Y = 200;
  int window1W = 200;
  int window1H = 100;
  XSetWindowAttributes xswa;
                   
  /* Create the window1 window */
  xswa.event_mask = ExposureMask | ButtonPressMask;
  xswa.background_pixel = XWhitePixelOfScreen(screen);

  window1 = XCreateWindow(dpy,
                          XRootWindowOfScreen(screen),
                          window1X, 
                          window1Y,
                          window1W,
                          window1H,
                          0,
                          XDefaultDepthOfScreen(screen),
                          InputOutput,
                          XDefaultVisualOfScreen(screen),
                          CWEventMask | CWBackPixel,
                          &xswa);
}

/******** Create the graphics context *********/    
static void doCreateGraphicsContext(void)
{                                                
  XGCValues xgcv;
    
  /* Create graphics context. */
  xgcv.background = XWhitePixelOfScreen(screen);
  xgcv.foreground = XBlackPixelOfScreen(screen);
  gc = XCreateGC(dpy, window1, GCForeground | GCBackground, &xgcv);   
}


/****************** doHandleEvents ***********************/
static void doHandleEvents(void)
{
  XEvent event;         

  for ( ; ; )
  {
    XNextEvent(dpy, &event);
    switch (event.type)
    { 
      case Expose:
        doExpose(&event);
        break;
      case ButtonPress:
        exit(0); /* shut down */
    }
  }                                           
}

/***** draw and write the message in the window *****/
static void doExpose(XEvent *eventP)
{
  static char message[] = {"Click here to exit"}; 

  /* If this is an expose event on our window1 window,
     then write the text and rectangle. */

  if (eventP->xexpose.window != window1) return;
  XClearWindow(dpy, window1);
  XDrawImageString(dpy, window1, gc, 50, 25, message, strlen(message));
  XDrawRectangle(dpy, window1, gc, 50, 50, 100, 25);
}

