foo
[vktest3] / src / main_x11.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <X11/Xlib.h>
4 #include <X11/Xutil.h>
5 #include "app.h"
6 #include "vk.h"
7
8 static Window create_window(const char *title, int xsz, int ysz);
9 static void handle_event(XEvent *ev);
10 static int translate_keysym(KeySym sym);
11
12 static Display *dpy;
13 static Window win, root_win;
14 static int xscr;
15 static Atom xa_wm_proto, xa_wm_del_win;
16 static int reshape_pending, quit;
17 static int win_mapped;
18
19 int main(int argc, char **argv)
20 {
21         XEvent ev;
22
23         if(!(dpy = XOpenDisplay(0))) {
24                 fprintf(stderr, "failed to connect to the X server\n");
25                 return 1;
26         }
27         xscr = DefaultScreen(dpy);
28         root_win = RootWindow(dpy, xscr);
29         xa_wm_proto = XInternAtom(dpy, "WM_PROTOCOLS", False);
30         xa_wm_del_win = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
31
32         if(!(win = create_window("vkray", 1280, 800))) {
33                 return 1;
34         }
35         vk_init_xwin(dpy, win);
36
37         win_width = 1280;
38         win_height = 800;
39
40         if(app_init() == -1) {
41                 goto end;
42         }
43
44         for(;;) {
45                 while(XPending(dpy)) {
46                         XNextEvent(dpy, &ev);
47                         handle_event(&ev);
48                         if(quit) goto end;
49                 }
50
51                 if(reshape_pending) {
52                         app_reshape(win_width, win_height);
53                 }
54                 app_display();
55         }
56
57 end:
58         app_cleanup();
59         XDestroyWindow(dpy, win);
60         XCloseDisplay(dpy);
61         return 0;
62 }
63
64 void app_quit(void)
65 {
66         quit = 1;
67 }
68
69 void app_swap_buffers(void)
70 {
71 }
72
73 static Window create_window(const char *title, int xsz, int ysz)
74 {
75         Window win;
76         XVisualInfo vinf;
77         XTextProperty txprop;
78         XSetWindowAttributes xattr;
79
80         if(!XMatchVisualInfo(dpy, xscr, 24, TrueColor, &vinf)) {
81                 fprintf(stderr, "no suitable visual found\n");
82                 return 0;
83         }
84
85         xattr.background_pixel = BlackPixel(dpy, xscr);
86         xattr.colormap = XCreateColormap(dpy, root_win, vinf.visual, AllocNone);
87
88         if(!(win = XCreateWindow(dpy, root_win, 0, 0, xsz, ysz, 0, 24, InputOutput,
89                                         vinf.visual, CWBackPixel | CWColormap, &xattr))) {
90                 fprintf(stderr, "failed to create window\n");
91                 return 0;
92         }
93
94         XSelectInput(dpy, win, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
95                         ButtonMotionMask | ExposureMask | StructureNotifyMask);
96
97         XSetWMProtocols(dpy, win, &xa_wm_del_win, 1);
98
99         if(XStringListToTextProperty((char**)&title, 1, &txprop)) {
100                 XSetWMName(dpy, win, &txprop);
101                 XSetWMIconName(dpy, win, &txprop);
102                 XFree(txprop.value);
103         }
104
105         XMapWindow(dpy, win);
106
107         reshape_pending = 1;
108         return win;
109 }
110
111 static void handle_event(XEvent *ev)
112 {
113         KeySym sym;
114         int key;
115
116         switch(ev->type) {
117         case MapNotify:
118                 win_mapped = 1;
119                 break;
120         case UnmapNotify:
121                 win_mapped = 0;
122                 break;
123
124         case ConfigureNotify:
125                 if(ev->xconfigure.width != win_width || ev->xconfigure.height != win_height) {
126                         win_width = ev->xconfigure.width;
127                         win_height = ev->xconfigure.height;
128                         reshape_pending = 1;
129                 }
130                 break;
131
132         case KeyPress:
133         case KeyRelease:
134                 if((sym = XLookupKeysym(&ev->xkey, 0)) && (key = translate_keysym(sym))) {
135                         app_keyboard(key, ev->type == KeyPress);
136                 }
137                 break;
138
139         case ButtonPress:
140         case ButtonRelease:
141                 app_mouse(ev->xbutton.button - Button1, ev->type == ButtonPress, ev->xbutton.x, ev->xbutton.y);
142                 break;
143
144         case ClientMessage:
145                 if(ev->xclient.message_type == xa_wm_proto) {
146                         if(ev->xclient.data.l[0] == xa_wm_del_win) {
147                                 quit = 1;
148                         }
149                 }
150                 break;
151
152         default:
153                 break;
154         }
155 }
156
157 static int translate_keysym(KeySym sym)
158 {
159         if(sym < 128) return sym;
160
161         switch(sym) {
162         case XK_Escape: return 27;
163         case XK_Tab: return '\t';
164         case XK_Return: return '\n';
165         case XK_BackSpace: return '\b';
166         case XK_Delete: return KEY_DEL;
167         case XK_Home: return KEY_HOME;
168         case XK_End: return KEY_END;
169         case XK_Page_Up: return KEY_PGUP;
170         case XK_Page_Down: return KEY_PGDOWN;
171         default:
172                 break;
173         }
174
175         return 0;
176 }