#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#define FALSE 0
#define TRUE 1
Display *display;
GC gc;
Window window;
int firstDraw = 1;
void CreateWindow(void);
static Window CreateChildWindow(
Display *display,
Screen *screen,
Window parent_window);
static int find_best_visual(
Display *display,
int screen_number,
XVisualInfo *return_visual_info);
void DrawWindow(
int x,
int y);
void ProcessEvents(void);
main(
int argc,
char *argv[])
{
CreateWindow();
while (True)
{
ProcessEvents();
}
}
void CreateWindow(void)
{
unsigned long attributeMask;
XSetWindowAttributes attributes;
int depth;
Window parentWindow;
int screen;
XGCValues values;
Visual* visual;
XVisualInfo* visualList;
int numVisuals;
if ((display = XOpenDisplay (NULL)) == NULL)
{
printf("Cannot connect to server %s; quitting.\n",
XDisplayName (NULL));
exit(-1);
}
screen = DefaultScreen(display);
parentWindow = XCreateSimpleWindow(display,
RootWindow(display, screen),
0, 0, 800, 600, 4,
BlackPixel(display, screen),
BlackPixel(display, screen));
XSelectInput(display,
parentWindow,
ButtonPressMask |
PointerMotionMask);
XMapWindow(display, parentWindow);
XStoreName(display, parentWindow, "XOR Test Program");
window = CreateChildWindow(display,
ScreenOfDisplay(display, screen),
parentWindow);
gc = XCreateGC(display,
window,
(unsigned long)NULL,
(XGCValues *)&values);
XSetFunction(display, gc, GXxor);
XSetForeground(display, gc, AllPlanes);
XMapWindow(display, window);
XFlush (display);
}
void DrawWindow(
int x,
int y)
{
static int old_x;
if (firstDraw == 1)
{
firstDraw = 0;
}
else
{
XDrawLine(display, window, gc, old_x, 1000, old_x, 0);
}
old_x = x;
XDrawLine(display, window, gc, old_x, 1000, old_x, 0);
XSync (display, 0);
return;
}
void ProcessEvents (void)
{
XButtonEvent* buttonEvent;
XMotionEvent* motionEvent;
XEvent theEvent;
if (XPending (display)) {
XNextEvent (display, &theEvent);
switch (theEvent.type) {
case MotionNotify:
motionEvent = (XMotionEvent *)&theEvent;
DrawWindow(motionEvent->x, motionEvent->y);
break;
case ButtonPress:
buttonEvent = (XButtonEvent *) &theEvent;
switch (buttonEvent->button) {
case Button1:
XClearWindow(display, window);
firstDraw = 1;
break;
case Button2:
XClearWindow(display, window);
firstDraw = 1;
break;
case Button3:
exit (-1);
break;
default:
break;
}
break;
default:
break;
}
}
return;
}
static Window CreateChildWindow(
Display *display,
Screen *screen,
Window parent_window)
{
unsigned long attribute_mask;
Window child_window;
GLXContext context;
Colormap colormap;
Window root_window;
XWindowAttributes screen_attributes;
XVisualInfo visual_info;
XSetWindowAttributes window_attributes;
Window windows[2];
if (find_best_visual(display,
XScreenNumberOfScreen(screen),
&visual_info) == FALSE)
{
printf("Unable to find suitable visual.\n");
exit(-1);
}
colormap = XCreateColormap(display,
parent_window,
visual_info.visual,
AllocNone);
window_attributes.background_pixel = BlackPixelOfScreen(screen);
window_attributes.border_pixel = BlackPixelOfScreen(screen);
window_attributes.colormap = colormap;
window_attributes.event_mask = ExposureMask;
window_attributes.backing_store = NotUseful;
window_attributes.win_gravity = NorthWestGravity;
attribute_mask = CWBackPixel |
CWBorderPixel |
CWColormap |
CWEventMask |
CWBackingStore |
CWWinGravity;
root_window = RootWindowOfScreen(screen),
XGetWindowAttributes(display, root_window, &screen_attributes);
child_window = XCreateWindow(display,
root_window,
0,
0,
screen_attributes.width,
screen_attributes.height,
0,
visual_info.depth,
(unsigned int)CopyFromParent,
visual_info.visual,
attribute_mask,
&window_attributes);
windows[0] = child_window;
windows[1] = parent_window;
XSetWMColormapWindows(display, windows[1], windows, 2);
XReparentWindow(display, child_window, parent_window, 0,0);
XMapWindow(display, child_window);
context = glXCreateContext(display, &visual_info, NULL, GL_TRUE);
if (context == NULL)
{
printf("Unable to create OpenGL rendering context.\n");
exit(-1);
}
if (glXMakeCurrent(display, child_window, context) == FALSE)
{
printf("Unable to make OpenGL rendering context current.\n");
exit(-1);
}
return child_window;
}
static int find_best_visual(
Display *display,
int screen_number,
XVisualInfo *return_visual_info)
{
#define LAST_REQUIRED_ATTRIBUTE 9
int last_attribute;
int success;
XVisualInfo *visual_info;
static int visual_attributes[32] =
{
GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DEPTH_SIZE, 1,
};
success = FALSE;
last_attribute = LAST_REQUIRED_ATTRIBUTE;
visual_attributes[last_attribute++] = GLX_DOUBLEBUFFER;
visual_attributes[last_attribute] = None;
visual_info = glXChooseVisual(display,
screen_number,
visual_attributes);
if (visual_info == NULL)
last_attribute--;
visual_attributes[last_attribute++] = GLX_STENCIL_SIZE;
visual_attributes[last_attribute++] = 1;
visual_attributes[last_attribute] = None;
visual_info = glXChooseVisual(display,
screen_number,
visual_attributes);
if (visual_info == NULL)
{
last_attribute -= 2;
visual_attributes[last_attribute] = None;
visual_info = glXChooseVisual(display,
screen_number,
visual_attributes);
}
if (visual_info != NULL)
{
*return_visual_info = *visual_info;
XFree(visual_info);
success = TRUE;
}
return(success);
}