1#include "eglcommon.h" 2 3 4#include <assert.h> 5#include <math.h> 6#include <stdlib.h> 7#include <stdio.h> 8#include <string.h> 9#include <X11/Xlib.h> 10#include <X11/Xutil.h> 11#include <X11/keysym.h> 12#include <VG/openvg.h> /* using full OpenGL for now */ 13#include <EGL/egl.h> 14 15 16static init_func init = 0; 17static draw_func draw = 0; 18static reshape_func reshape = 0; 19static key_func keyPress = 0; 20static VGint width = 300, height = 300; 21static EGLint alpha_size = 0; 22 23 24void set_window_alpha_size(int size) 25{ 26 alpha_size = size; 27} 28 29void set_window_size(int w, int h) 30{ 31 width = w; 32 height = h; 33} 34 35/* 36 * Create an RGB, double-buffered X window. 37 * Return the window and context handles. 38 */ 39static void 40make_x_window(Display *x_dpy, EGLDisplay egl_dpy, 41 const char *name, 42 int x, int y, int width, int height, 43 Window *winRet, 44 EGLContext *ctxRet, 45 EGLSurface *surfRet) 46{ 47 EGLint attribs[] = { 48 EGL_RED_SIZE, 1, 49 EGL_GREEN_SIZE, 1, 50 EGL_BLUE_SIZE, 1, 51 EGL_ALPHA_SIZE, alpha_size, 52 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, 53 EGL_NONE 54 }; 55 56 int scrnum; 57 XSetWindowAttributes attr; 58 unsigned long mask; 59 Window root; 60 Window win; 61 XVisualInfo *visInfo, visTemplate; 62 int num_visuals; 63 EGLContext ctx; 64 EGLConfig config; 65 EGLint num_configs; 66 EGLint vid; 67 68 scrnum = DefaultScreen( x_dpy ); 69 root = RootWindow( x_dpy, scrnum ); 70 71 if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) || 72 !num_configs) { 73 printf("Error: couldn't get an EGL visual config\n"); 74 exit(1); 75 } 76 77 assert(config); 78 79 if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { 80 printf("Error: eglGetConfigAttrib() failed\n"); 81 exit(1); 82 } 83 84 /* The X window visual must match the EGL config */ 85 visTemplate.visualid = vid; 86 visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); 87 if (!visInfo) { 88 printf("Error: couldn't get X visual\n"); 89 exit(1); 90 } 91 92 /* window attributes */ 93 attr.background_pixel = 0; 94 attr.border_pixel = 0; 95 attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); 96 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; 97 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; 98 99 win = XCreateWindow( x_dpy, root, 0, 0, width, height, 100 0, visInfo->depth, InputOutput, 101 visInfo->visual, mask, &attr ); 102 103 /* set hints and properties */ 104 { 105 XSizeHints sizehints; 106 sizehints.x = x; 107 sizehints.y = y; 108 sizehints.width = width; 109 sizehints.height = height; 110 sizehints.flags = USSize | USPosition; 111 XSetNormalHints(x_dpy, win, &sizehints); 112 XSetStandardProperties(x_dpy, win, name, name, 113 None, (char **)NULL, 0, &sizehints); 114 } 115 116 eglBindAPI(EGL_OPENVG_API); 117 118 ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); 119 if (!ctx) { 120 printf("Error: eglCreateContext failed\n"); 121 exit(1); 122 } 123 124 *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); 125 126 if (!*surfRet) { 127 printf("Error: eglCreateWindowSurface failed\n"); 128 exit(1); 129 } 130 131 XFree(visInfo); 132 133 *winRet = win; 134 *ctxRet = ctx; 135} 136 137static void 138event_loop(Display *dpy, Window win, 139 EGLDisplay egl_dpy, EGLSurface egl_surf) 140{ 141 while (1) { 142 int redraw = 0; 143 XEvent event; 144 145 XNextEvent(dpy, &event); 146 147 switch (event.type) { 148 case Expose: 149 redraw = 1; 150 break; 151 case ConfigureNotify: 152 if (reshape) { 153 width = event.xconfigure.width; 154 height = event.xconfigure.height; 155 reshape(event.xconfigure.width, event.xconfigure.height); 156 } 157 break; 158 case KeyPress: 159 { 160 char buffer[10]; 161 int r, code; 162 code = XLookupKeysym(&event.xkey, 0); 163 if (!keyPress || !keyPress(code)) { 164 r = XLookupString(&event.xkey, buffer, sizeof(buffer), 165 NULL, NULL); 166 if (buffer[0] == 27) { 167 /* escape */ 168 return; 169 } 170 } 171 } 172 redraw = 1; 173 break; 174 default: 175 ; /*no-op*/ 176 } 177 178 if (redraw) { 179 draw(); 180 eglSwapBuffers(egl_dpy, egl_surf); 181 } 182 } 183} 184 185int window_width(void) 186{ 187 return width; 188} 189 190int window_height(void) 191{ 192 return height; 193} 194 195static void 196usage(void) 197{ 198 printf("Usage:\n"); 199 printf(" -display <displayname> set the display to run on\n"); 200 printf(" -info display OpenGL renderer info\n"); 201} 202 203int run(int argc, char **argv, 204 init_func init_f, 205 reshape_func resh_f, 206 draw_func draw_f, 207 key_func key_f) 208{ 209 const int winWidth = width, winHeight = height; 210 Display *x_dpy; 211 Window win; 212 EGLSurface egl_surf; 213 EGLContext egl_ctx; 214 EGLDisplay egl_dpy; 215 char *dpyName = NULL; 216 EGLBoolean printInfo = EGL_FALSE; 217 EGLint egl_major, egl_minor; 218 int i; 219 const char *s; 220 221 init = init_f; 222 draw = draw_f; 223 reshape = resh_f; 224 keyPress = key_f; 225 226 for (i = 1; i < argc; i++) { 227 if (strcmp(argv[i], "-display") == 0) { 228 dpyName = argv[i+1]; 229 i++; 230 } 231 else if (strcmp(argv[i], "-info") == 0) { 232 printInfo = EGL_TRUE; 233 } 234 } 235 236 x_dpy = XOpenDisplay(dpyName); 237 if (!x_dpy) { 238 printf("Error: couldn't open display %s\n", 239 dpyName ? dpyName : getenv("DISPLAY")); 240 return -1; 241 } 242 243 egl_dpy = eglGetDisplay(x_dpy); 244 if (!egl_dpy) { 245 printf("Error: eglGetDisplay() failed\n"); 246 return -1; 247 } 248 249 if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { 250 printf("Error: eglInitialize() failed\n"); 251 return -1; 252 } 253 254 s = eglQueryString(egl_dpy, EGL_VERSION); 255 printf("EGL_VERSION = %s\n", s); 256 257 make_x_window(x_dpy, egl_dpy, 258 "OpenVG Example", 0, 0, winWidth, winHeight, 259 &win, &egl_ctx, &egl_surf); 260 261 XMapWindow(x_dpy, win); 262 if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { 263 printf("Error: eglMakeCurrent() failed\n"); 264 return -1; 265 } 266 267 if (printInfo) { 268 printf("VG_RENDERER = %s\n", (char *) vgGetString(VG_RENDERER)); 269 printf("VG_VERSION = %s\n", (char *) vgGetString(VG_VERSION)); 270 printf("VG_VENDOR = %s\n", (char *) vgGetString(VG_VENDOR)); 271 } 272 273 if (init) 274 init(); 275 276 /* Set initial projection/viewing transformation. 277 * We can't be sure we'll get a ConfigureNotify event when the window 278 * first appears. 279 */ 280 if (reshape) 281 reshape(winWidth, winHeight); 282 283 event_loop(x_dpy, win, egl_dpy, egl_surf); 284 285 eglMakeCurrent(egl_dpy, 0, 0, 0); 286 eglDestroyContext(egl_dpy, egl_ctx); 287 eglDestroySurface(egl_dpy, egl_surf); 288 eglTerminate(egl_dpy); 289 290 291 XDestroyWindow(x_dpy, win); 292 XCloseDisplay(x_dpy); 293 294 return 0; 295} 296 297