foo
[gph-gfx] / test_x11.c
diff --git a/test_x11.c b/test_x11.c
new file mode 100644 (file)
index 0000000..1c9e143
--- /dev/null
@@ -0,0 +1,220 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include "gphgfx.h"
+
+static void redraw(void);
+static void reshape(int x, int y);
+static void keydown(int key, int x, int y);
+static void keyup(int key, int x, int y);
+static void button(int bn, int st, int x, int y);
+static void motion(int x, int y);
+
+static int create_window(const char *title, int width, int height);
+static void handle_event(XEvent *ev);
+static KeySym translate_keysym(KeySym sym);
+static void set_window_title(const char *title);
+
+static Display *dpy;
+static int scr;
+static Window win, root;
+static Atom xa_wm_proto, xa_wm_del_win;
+static int quit, mapped, win_width, win_height, modstate;
+static GC gc;
+
+int main(int argc, char **argv)
+{
+       if(!(dpy = XOpenDisplay(0))) {
+               fprintf(stderr, "failed to connect to the X server\n");
+               return 1;
+       }
+       xa_wm_proto = XInternAtom(dpy, "WM_PROTOCOLS", False);
+       xa_wm_del_win = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+
+       scr = DefaultScreen(dpy);
+       root = RootWindow(dpy, scr);
+
+       if(create_window("gph-gfx test", 800, 600) == -1) {
+               return 1;
+       }
+
+       if(ggfx_init("test", GGFX_INIT_DEBUG) == -1) {
+               return 1;
+       }
+
+       for(;;) {
+               while(XPending(dpy)) {
+                       XEvent ev;
+                       XNextEvent(dpy, &ev);
+                       handle_event(&ev);
+                       if(quit) goto end;
+               }
+               redraw();
+       }
+end:
+
+       ggfx_shutdown();
+       XFreeGC(dpy, gc);
+       XCloseDisplay(dpy);
+       return 0;
+}
+
+
+static void redraw(void)
+{
+       XSetForeground(dpy, gc, 0xff00);
+       XClearWindow(dpy, win);
+       usleep(10000);
+}
+
+static void reshape(int x, int y)
+{
+       printf("reshape %dx%d\n", x, y);
+}
+
+static void keydown(int key, int x, int y)
+{
+       switch(key) {
+       case 27:
+               quit = 1;
+               break;
+       }
+}
+
+static void keyup(int key, int x, int y)
+{
+}
+
+static void button(int bn, int st, int x, int y)
+{
+}
+
+static void motion(int x, int y)
+{
+}
+
+static int create_window(const char *title, int width, int height)
+{
+       XSetWindowAttributes xattr = {0};
+       XVisualInfo vinf;
+       unsigned int xattr_mask;
+
+       if(!XMatchVisualInfo(dpy, scr, 24, TrueColor, &vinf)) {
+               fprintf(stderr, "failed to find appropriate visual\n");
+               return -1;
+       }
+
+       xattr.background_pixel = BlackPixel(dpy, scr);
+       xattr.colormap = XCreateColormap(dpy, root, vinf.visual, AllocNone);
+       xattr_mask = CWBackPixel | CWColormap | CWBackPixmap | CWBorderPixel;
+       if(!(win = XCreateWindow(dpy, root, 0, 0, width, height, 0, vinf.depth,
+                                       InputOutput, vinf.visual, xattr_mask, &xattr))) {
+               fprintf(stderr, "Failed to create window\n");
+               return -1;
+       }
+
+       XSelectInput(dpy, win, ExposureMask | StructureNotifyMask | KeyPressMask |
+                       KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
+
+       set_window_title(title);
+       XSetWMProtocols(dpy, win, &xa_wm_del_win, 1);
+       XMapWindow(dpy, win);
+
+       gc = XCreateGC(dpy, win, 0, 0);
+       return 0;
+}
+
+
+static KeySym translate_keysym(KeySym sym)
+{
+       switch(sym) {
+       case XK_Escape:
+               return 27;
+       case XK_BackSpace:
+               return '\b';
+       case XK_Linefeed:
+               return '\r';
+       case XK_Return:
+               return '\n';
+       case XK_Delete:
+               return 127;
+       case XK_Tab:
+               return '\t';
+       default:
+               break;
+       }
+       return sym;
+}
+
+static void handle_event(XEvent *ev)
+{
+       KeySym sym;
+
+       switch(ev->type) {
+       case MapNotify:
+               mapped = 1;
+               break;
+       case UnmapNotify:
+               mapped = 0;
+               break;
+       case ConfigureNotify:
+               if(ev->xconfigure.width != win_width || ev->xconfigure.height != win_height) {
+                       win_width = ev->xconfigure.width;
+                       win_height = ev->xconfigure.height;
+                       reshape(ev->xconfigure.width, ev->xconfigure.height);
+               }
+               break;
+
+       case ClientMessage:
+               if(ev->xclient.message_type == xa_wm_proto) {
+                       if(ev->xclient.data.l[0] == xa_wm_del_win) {
+                               quit = 1;
+                       }
+               }
+               break;
+
+       case Expose:
+               /*upd_pending = 1;*/
+               break;
+
+       case KeyPress:
+       case KeyRelease:
+               modstate = ev->xkey.state & (ShiftMask | ControlMask | Mod1Mask);
+               if(!(sym = XLookupKeysym(&ev->xkey, 0))) {
+                       break;
+               }
+               sym = translate_keysym(sym);
+               if(ev->type == KeyPress) {
+                       keydown(sym, ev->xkey.x, ev->xkey.y);
+               } else {
+                       keyup(sym, ev->xkey.x, ev->xkey.y);
+               }
+               break;
+
+       case ButtonPress:
+       case ButtonRelease:
+               modstate = ev->xbutton.state & (ShiftMask | ControlMask | Mod1Mask);
+               button(ev->xbutton.button - Button1, ev->type == ButtonPress,
+                               ev->xbutton.x, ev->xbutton.y);
+               break;
+
+       case MotionNotify:
+               motion(ev->xmotion.x, ev->xmotion.y);
+               break;
+
+       default:
+               break;
+       }
+}
+
+static void set_window_title(const char *title)
+{
+       XTextProperty tprop;
+       if(!XStringListToTextProperty((char**)&title, 1, &tprop)) {
+               return;
+       }
+       XSetWMName(dpy, win, &tprop);
+       XFree(tprop.value);
+}