
/*** START MAIN.H ***/
/* http://www.geocities.com/jeff_louie/x11/helloworld.htm* */
/*
 *  main.h
 *  TestX
 *
 *  Created by Jeff Louie on Tue Feb 03 2004.
 *  Copyright (c) 2004 __MyCompanyName__. All rights reserved.
 *
 */

#ifndef MAIN_H
#  define MAIN_H 1

#  include <iostream>

#  include <stdlib.h>

/* include the X library headers */
#  include <X11/Xlib.h>
#  include <X11/Xos.h>
#  include <X11/Xutil.h>

class Main
{

public:
  // constructor
  Main(int argc, char* const argv[]);
  // virtual ~Main();

private:
  /* here are our X variables */
  Display* dis;
  int screen;
  Window win;
  GC gc;

  /* here are our X routines declared! */
  void init_x();
  void close_x();
  void redraw();
  int delay(int i);
};

#endif

/*** END MAIN.H ***/

/*** START MAIN.CPP ***/

// modified from Brian Hammond's Howdy program at
// http://www.insanityengine.com/doc/x11/xintro.html
// jeff louie 02.05.2004

int main(int argc, char* const argv[])
{
  Main m(argc, argv);
  return 0;
}

// Main::~Main() {;};
Main::Main(int argc, char* const argv[])
{
  XEvent event;   // XEvent declaration
  KeySym key;     // KeyPress Events
  char text[255]; // char buffer for KeyPress Events

  init_x();

  // event loop
  while (1) {
    // get the next event and stuff it into our event variable.
    // Note:  only events we set the mask for are detected!
    XNextEvent(dis, &event);

    switch (event.type) {
      int x;
      int y;
      case Expose:
        if (event.xexpose.count == 0) {
          redraw();
        }
        break;
      case KeyPress:
        if (XLookupString(&event.xkey, text, 255, &key, 0) == 1) {
          // use the XLookupString routine to convert the invent
          // KeyPress data into regular text.  Weird but necessary...
          if ((text[0] == 'q') || (text[0] == 'Q')) {
            close_x();
          } else {
            // echo key press
            printf("You pressed the %c key!\n", text[0]);
          }
        }
        break;
      case ButtonPress:
        // get cursor position
        x = event.xbutton.x;
        y = event.xbutton.y;
        strcpy(text, "X is FUN!");
        XSetForeground(dis, gc, rand() % event.xbutton.x % 255);
        // draw text at cursor
        XDrawString(dis, win, gc, x, y, text, strlen(text));
        break;
      default:
        printf("Unhandled event.\n");
    }
  }
}

void Main::init_x()
{
  unsigned long black, white;

  dis = XOpenDisplay(NULL);
  screen = DefaultScreen(dis);
  black = BlackPixel(dis, screen), white = WhitePixel(dis, screen);
  win = XCreateSimpleWindow(dis, DefaultRootWindow(dis), 0, 0, 300, 300, 5,
                            black, white);
  XSetStandardProperties(dis, win, "Hello World", "Hi", None, NULL, 0, NULL);
  XSelectInput(dis, win, ExposureMask | ButtonPressMask | KeyPressMask);
  // get Graphics Context
  gc = XCreateGC(dis, win, 0, 0);
  XSetBackground(dis, gc, white);
  XSetForeground(dis, gc, black);
  XClearWindow(dis, win);
  XMapRaised(dis, win);
};

void Main::close_x()
{
  XFreeGC(dis, gc);
  XDestroyWindow(dis, win);
  XCloseDisplay(dis);
  exit(1);
};

void Main::redraw()
{
  XClearWindow(dis, win);
};
