The goal of this document is to teach the reader about concepts which I found difficult to understand when I was learning about them. This document assumes that you are familiar with Makefiles and your development environment.
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xfuncproto.h>
#include <X11/Intrinsic.h>
Once that you have the header files included you can start by creating a name for the connection to the X server. In the beginning of your procedure or the beginning of the program after the header files you should add a line such as this:
Display *dis;Now you need to decide what to call your window. For example:
Window win;Now you can create a window in a procedure, such as main();
int main()A complete program would probably check to see that XOpenDisplay does not return 0. The argument given to XOpenDisplay is the display name, which can be NULL. XOpenDisplay returns the display connection, which is placed in the dis variable.
The call to XCreateSimpleWindow uses the connection to the X server which is called dis, as the first argument. The next argument is the parent window, which is in this case the root window. The root window is the background of your desktop, it takes the display connection name and the screen number as the arguments. Next you have the X and Y coordinates for placing the window, which in our case are (X) 1 and (Y) 1. The next series of numbers which are 500 represent the size of the window. The next number 0 is the border width of the window. Then the last two arguments are for the border color and background color. You can try replacing BlackPixel with WhitePixel.
Now you can map the window using XMapWindow; which displays the window on the screen. It takes two arguments. The first argument is the display connection. The next argument is the name of the window that was created with XCreateSimpleWindow.
The final request that you make will be to flush all requests to the X server. The X Window System has a queue for requests sent to the X server. By calling XFlush you cause all of the items in the queue to be executed.
Events in X are things like the mouse buttons being clicked, or the keys on the keyboard being pressed. The events can either be KeyPress or KeyRelease for control devices. When the window is resized the application is sent a ConfigureNotify event. When the window is below another window and is raised it is sent an Expose event, which would usually redraw the application.
The first step is to declare an X event.
XEvent report;The next step is to tell the X server what kind of input the program wants to process.
XSelectInput(dis, win, ExposureMask | KeyPressMask | ButtonPressMask);The first two arguments should be understood. The ExposureMask tells the X server that you want to process Expose events. The KeyPressMask tells the X server that you want to process KeyPress events. The ButtonPressMask tells the X server that you want to process mouse button events.
This is a simple event loop that outputs I have been exposed when the window first appears, and when the window is raised.
while (1) {This event loop is rather simple. It only checks for an expose event. XNextEvent waits for an event to occur. You can use other methods to get events, which are documented in the manual page for XNextEvent.
Now you will learn how to check if an event is a certain key being pressed. The first step is to put case KeyPress: in your switch for report.type. Place it in a similar manner as case Expose.
case KeyPress:XLookupKeysym checks if the key pressed was equal to XK_space, and if it was it outputs a message. The keyboard key names can be found in /usr/X11R6/include/X11/keysymdef.h. More keyboard events can be processed in a similar manner.
You will need to have a drawing procedure that is called by an Expose event for this next part to work. You could have a simple function called such as XDrawLine after the expose event instead of having it call a procedure.
The first step is to create a variable for the graphics context for drawing. The next step is to create a variable for the XColor structure. Now create a colormap for this window. Then create a character array with the color you wish to use in hexadecimal format.
GC green_gc;Now you need to assign a colormap to the colormap variable with DefaultColormap. DefaultColormap takes two arguments. The first argument is the display connection. The next argument is the screen number.
colormap = DefaultColormap(dis, 0);Now create the GC using XCreateGC and put the GC information in green_gc
green_gc = XCreateGC(dis, win, 0, 0);Now you can parse the color 00FF00 and allocate the color for later use.
XParseColor(dis, colormap, green, &green_col);Now that you have allocated a color you can set the foreground for the graphics context with XSetForeground. That last argument to XSetForeground is the pixel value of the color allocated.
XSetForeground(dis, green_gc, green_col.pixel);Now you can draw using the foreground color set for green_gc.
case Expose:This section uses the Independant JPEG Library version 6b.
The first step is to include the JPEG library header file.
This is under construction.