]> git.cworth.org Git - apitrace-tests/blob - apps/egl/eglut/eglut_x11.c
Add egl apps.
[apitrace-tests] / apps / egl / eglut / eglut_x11.c
1 /*
2  * Copyright (C) 2010 LunarG Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  *
22  * Authors:
23  *    Chia-I Wu <olv@lunarg.com>
24  */
25
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <X11/keysym.h>
29
30 #include "eglutint.h"
31
32 void
33 _eglutNativeInitDisplay(void)
34 {
35    _eglut->native_dpy = XOpenDisplay(_eglut->display_name);
36    if (!_eglut->native_dpy)
37       _eglutFatal("failed to initialize native display");
38
39    _eglut->surface_type = EGL_WINDOW_BIT;
40 }
41
42 void
43 _eglutNativeFiniDisplay(void)
44 {
45    XCloseDisplay(_eglut->native_dpy);
46 }
47
48 void
49 _eglutNativeInitWindow(struct eglut_window *win, const char *title,
50                        int x, int y, int w, int h)
51 {
52    XVisualInfo *visInfo, visTemplate;
53    int num_visuals;
54    Window root, xwin;
55    XSetWindowAttributes attr;
56    unsigned long mask;
57    EGLint vid;
58
59    if (!eglGetConfigAttrib(_eglut->dpy,
60             win->config, EGL_NATIVE_VISUAL_ID, &vid))
61       _eglutFatal("failed to get visual id");
62
63    /* The X window visual must match the EGL config */
64    visTemplate.visualid = vid;
65    visInfo = XGetVisualInfo(_eglut->native_dpy,
66          VisualIDMask, &visTemplate, &num_visuals);
67    if (!visInfo)
68       _eglutFatal("failed to get an visual of id 0x%x", vid);
69
70    root = RootWindow(_eglut->native_dpy, DefaultScreen(_eglut->native_dpy));
71
72    /* window attributes */
73    attr.background_pixel = 0;
74    attr.border_pixel = 0;
75    attr.colormap = XCreateColormap(_eglut->native_dpy,
76          root, visInfo->visual, AllocNone);
77    attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
78    mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
79
80    xwin = XCreateWindow(_eglut->native_dpy, root, x, y, w, h,
81          0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr);
82    if (!xwin)
83       _eglutFatal("failed to create a window");
84
85    XFree(visInfo);
86
87    /* set hints and properties */
88    {
89       XSizeHints sizehints;
90       sizehints.x = x;
91       sizehints.y = y;
92       sizehints.width  = w;
93       sizehints.height = h;
94       sizehints.flags = USSize | USPosition;
95       XSetNormalHints(_eglut->native_dpy, xwin, &sizehints);
96       XSetStandardProperties(_eglut->native_dpy, xwin,
97             title, title, None, (char **) NULL, 0, &sizehints);
98    }
99
100    XMapWindow(_eglut->native_dpy, xwin);
101
102    win->native.u.window = xwin;
103    win->native.width = w;
104    win->native.height = h;
105 }
106
107 void
108 _eglutNativeFiniWindow(struct eglut_window *win)
109 {
110    XDestroyWindow(_eglut->native_dpy, win->native.u.window);
111 }
112
113 static int
114 lookup_keysym(KeySym sym)
115 {
116    int special;
117
118    switch (sym) {
119    case XK_F1:
120       special = EGLUT_KEY_F1;
121       break;
122    case XK_F2:
123       special = EGLUT_KEY_F2;
124       break;
125    case XK_F3:
126       special = EGLUT_KEY_F3;
127       break;
128    case XK_F4:
129       special = EGLUT_KEY_F4;
130       break;
131    case XK_F5:
132       special = EGLUT_KEY_F5;
133       break;
134    case XK_F6:
135       special = EGLUT_KEY_F6;
136       break;
137    case XK_F7:
138       special = EGLUT_KEY_F7;
139       break;
140    case XK_F8:
141       special = EGLUT_KEY_F8;
142       break;
143    case XK_F9:
144       special = EGLUT_KEY_F9;
145       break;
146    case XK_F10:
147       special = EGLUT_KEY_F10;
148       break;
149    case XK_F11:
150       special = EGLUT_KEY_F11;
151       break;
152    case XK_F12:
153       special = EGLUT_KEY_F12;
154       break;
155    case XK_KP_Left:
156    case XK_Left:
157       special = EGLUT_KEY_LEFT;
158       break;
159    case XK_KP_Up:
160    case XK_Up:
161       special = EGLUT_KEY_UP;
162       break;
163    case XK_KP_Right:
164    case XK_Right:
165       special = EGLUT_KEY_RIGHT;
166       break;
167    case XK_KP_Down:
168    case XK_Down:
169       special = EGLUT_KEY_DOWN;
170       break;
171    default:
172       special = -1;
173       break;
174    }
175
176    return special;
177 }
178
179 static void
180 next_event(struct eglut_window *win)
181 {
182    int redraw = 0;
183    XEvent event;
184
185    if (!XPending(_eglut->native_dpy)) {
186       /* there is an idle callback */
187       if (_eglut->idle_cb) {
188          _eglut->idle_cb();
189          return;
190       }
191
192       /* the app requests re-display */
193       if (_eglut->redisplay)
194          return;
195    }
196
197    /* block for next event */
198    XNextEvent(_eglut->native_dpy, &event);
199
200    switch (event.type) {
201    case Expose:
202       redraw = 1;
203       break;
204    case ConfigureNotify:
205       win->native.width = event.xconfigure.width;
206       win->native.height = event.xconfigure.height;
207       if (win->reshape_cb)
208          win->reshape_cb(win->native.width, win->native.height);
209       break;
210    case KeyPress:
211       {
212          char buffer[1];
213          KeySym sym;
214          int r;
215
216          r = XLookupString(&event.xkey,
217                buffer, sizeof(buffer), &sym, NULL);
218          if (r && win->keyboard_cb) {
219             win->keyboard_cb(buffer[0]);
220          }
221          else if (!r && win->special_cb) {
222             r = lookup_keysym(sym);
223             if (r >= 0)
224                win->special_cb(r);
225          }
226       }
227       redraw = 1;
228       break;
229    default:
230       ; /*no-op*/
231    }
232
233    _eglut->redisplay = redraw;
234 }
235
236 void
237 _eglutNativeEventLoop(void)
238 {
239    while (1) {
240       struct eglut_window *win = _eglut->current;
241
242       next_event(win);
243
244       if (_eglut->redisplay) {
245          _eglut->redisplay = 0;
246
247          if (win->display_cb)
248             win->display_cb();
249          eglSwapBuffers(_eglut->dpy, win->surface);
250       }
251    }
252 }