source: project/gl-display-glx/glx_display.c @ 3309

Last change on this file since 3309 was 3309, checked in by thu, 14 years ago

initial commit

File size: 9.1 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <math.h>
4
5#include <GL/glx.h>
6#include <X11/keysym.h>
7#include <X11/extensions/shape.h>
8
9#include <sys/time.h>
10
11#include "glx_display.h"
12
13
14#ifdef GLX_DISPLAY_SINGLESTATE
15 static gl_window_t _gl_window;
16 static gl_window_t * gl_window;
17#endif
18
19/* TODO clean file organization */
20void shape_window( gl_window_t  * gl_window, int width, int height );
21
22#ifdef GLX_DISPLAY_SINGLESTATE
23unsigned int
24get_width()
25{
26  return gl_window->width;
27}
28unsigned int
29get_height()
30{
31  return gl_window->height;
32}
33unsigned int
34get_screen_width()
35{
36  return gl_window->screen_width;
37}
38unsigned int
39get_screen_height()
40{
41  return gl_window->screen_height;
42}
43#else
44unsigned int
45get_width( gl_window_t  * gl_window )
46{
47  return gl_window->width;
48}
49unsigned int
50get_height( gl_window_t  * gl_window )
51{
52  return gl_window->height;
53}
54unsigned int
55get_screen_width( gl_window_t  * gl_window )
56{
57  return gl_window->screen_width;
58}
59unsigned int
60get_screen_height( gl_window_t  * gl_window )
61{
62  return gl_window->screen_height;
63}
64#endif
65 
66void
67destroy_gl_window (
68#ifndef GLX_DISPLAY_SINGLESTATE
69  gl_window_t  * gl_window
70#endif
71  )
72{
73  if ( gl_window->glx_context )
74  {
75    glXMakeCurrent( gl_window->display, None, NULL );
76    glXDestroyContext( gl_window->display, gl_window->glx_context );
77    gl_window->glx_context = NULL;
78  }
79  /* TODO */
80  glXDestroyWindow(gl_window->display, gl_window->glx_window);
81  XDestroyWindow(gl_window->display, gl_window->window);
82   /* if (GLWin.fs)
83    {
84        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode);
85        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
86    }*/
87  XCloseDisplay(gl_window->display);
88}
89
90/* local routines */
91int query_extensions_glx (Display * display);
92void exit_on_err (char * s);
93Cursor CreateNullPointer (void);
94void SetNullPointer (void);
95
96/*
97**
98*/
99
100#ifndef GLX_DISPLAY_SINGLESTATE
101  gl_window_t  *
102#else
103  void
104#endif
105create_gl_window (
106/*              const char * title, */
107                unsigned int width,
108                unsigned int height,
109                int double_buffered,
110                int fullscreen,
111                int no_border,
112                int use_shape_extension)
113{
114  int nelements;
115  GLXFBConfig * fbconfigs;
116  XVisualInfo * vi;
117 
118  int attrlist[] = {
119  /*  GLX_RGBA, */
120    GLX_DOUBLEBUFFER, double_buffered ? True : False,
121    GLX_RED_SIZE, 4,
122    GLX_GREEN_SIZE, 4,
123    GLX_BLUE_SIZE, 4,
124    GLX_DEPTH_SIZE, 16,
125    None };
126
127  XWindowAttributes root_attributes;
128
129#ifdef GLX_DISPLAY_SINGLESTATE
130  gl_window = & _gl_window;
131#else
132  gl_window_t  * gl_window = (gl_window_t *)malloc( sizeof(gl_window_t) );
133#endif
134
135  gl_window->width                = width;
136  gl_window->height               = height;
137  gl_window->double_buffered_flag = double_buffered;
138  gl_window->fullscreen_flag      = fullscreen;
139
140  gl_window->display = XOpenDisplay( NULL );
141  if( !gl_window->display )
142    exit_on_err(" XOpenDisplay failed.");
143
144  gl_window->screen = DefaultScreen( gl_window->display );
145
146  /* TODO error handling */
147  XGetWindowAttributes( gl_window->display,
148                  RootWindow( gl_window->display,
149                              gl_window->screen ),
150                  &root_attributes);
151  gl_window->screen_width  = root_attributes.width;
152  gl_window->screen_height = root_attributes.height;
153
154  if ( fullscreen )
155  {
156    width  = gl_window->width  = gl_window->screen_width;
157    height = gl_window->height = gl_window->screen_height;
158  }
159
160  if( ! query_extensions_glx(gl_window->display) )
161    exit_on_err(" No supported glX extension.");
162
163  fbconfigs = glXChooseFBConfig( gl_window->display,
164                                 gl_window->screen,
165                                 attrlist,
166                                 &nelements );
167
168  vi = glXGetVisualFromFBConfig( gl_window->display, fbconfigs[0] );
169
170  gl_window->attributes.colormap = XCreateColormap( gl_window->display,
171                                   RootWindow( gl_window->display,
172                                               vi->screen ),
173                                   vi->visual, AllocNone);
174  gl_window->attributes.border_pixel = 0;
175  gl_window->attributes.background_pixel = 0;
176  gl_window->attributes.event_mask =
177    StructureNotifyMask | ExposureMask      |
178    KeyPressMask        | KeyReleaseMask    |
179    ButtonPressMask     | ButtonReleaseMask |
180    PointerMotionMask;
181  /* gl_window->attributes.override_redirect = 1; */
182
183  gl_window->window = XCreateWindow( gl_window->display,
184                       RootWindow( gl_window->display, vi->screen ),
185                      (1280-width)/2,(800-height)/2, width,height , 0,
186                      vi->depth, InputOutput, vi->visual,
187
188                      CWBorderPixel | CWBackPixel |
189                      CWColormap | CWEventMask /*| CWOverrideRedirect*/,
190
191                      &gl_window->attributes);
192  /* FIXME handle this ?*/
193  if ( !fullscreen && no_border )
194  {
195    shape_window( gl_window, width, height );
196  }
197
198  gl_window->glx_window = glXCreateWindow( gl_window->display, fbconfigs[0], gl_window->window, 0);
199
200  gl_window->glx_context = glXCreateNewContext( gl_window->display, fbconfigs[0],
201                           GLX_RGBA_TYPE, 0, GL_TRUE);
202
203  glXMakeContextCurrent( gl_window->display, gl_window->glx_window, gl_window->glx_window, gl_window->glx_context);
204
205  XMapWindow(gl_window->display, gl_window->window);
206  for (;;)
207  {
208    XEvent e;
209    XNextEvent( gl_window->display, &e);
210    if ( e.type == MapNotify ) break;
211  }
212
213  /* TODO provide the following to scheme side
214  if( glXIsDirect(gl_window->display, gl_window->glx_context) )
215    printf(" Direct Rendering.\n");
216  else
217    printf(" No Direct Rendering.\n");
218  */
219
220  XFree(fbconfigs);
221  XFree(vi);
222 
223#ifndef GLX_DISPLAY_SINGLESTATE
224  return gl_window;
225#endif
226}
227
228void
229grab_keyboard(
230#ifndef GLX_DISPLAY_SINGLESTATE
231  gl_window_t  * gl_window
232#endif
233  )
234{
235  XGrabKeyboard(gl_window->display, gl_window->window, True,
236                  GrabModeAsync, GrabModeAsync, CurrentTime); 
237}
238
239void
240grab_mouse(
241#ifndef GLX_DISPLAY_SINGLESTATE
242  gl_window_t  * gl_window
243#endif
244  )
245{
246  XGrabPointer(gl_window->display, gl_window->window, True, ButtonPressMask,
247                  GrabModeAsync, GrabModeAsync,
248                  gl_window->window, None, CurrentTime);
249}
250
251void
252warp_mouse(
253#ifndef GLX_DISPLAY_SINGLESTATE
254  gl_window_t  * gl_window,
255#endif
256  int x, int y
257  )
258{
259  XWarpPointer( gl_window->display, None, gl_window->window, 0,0,0,0,
260               /* gl_window->screen_width/2 , gl_window->screen_height/2 ); */
261                  x , y );
262}
263
264
265void
266swap_buffers (
267#ifndef GLX_DISPLAY_SINGLESTATE
268  gl_window_t  * gl_window
269#endif
270  )
271{
272  if ( gl_window->double_buffered_flag )
273  {
274    glXSwapBuffers( gl_window->display, gl_window->glx_window );
275  }
276  else
277  {
278    glFlush();
279  }
280}
281
282int event_type( XEvent * e ) { return e->type; }
283int event_x( XButtonEvent * e ) { return e->x; }
284int event_y( XButtonEvent * e ) { return e->y; }
285int event_button( XButtonEvent * e ) { return e->button; }
286int event_keycode( XEvent * e ) { return XLookupKeysym( &e->xkey, 0 ); }
287
288/*
289 * Returns a (pointer to a) XEvent.
290 * The type of the event could be LASTEvent + 1 if there's no actual event.
291 */
292XEvent *
293receive_event (
294#ifndef GLX_DISPLAY_SINGLESTATE
295  gl_window_t  * gl_window
296#endif
297  )
298{
299  static XEvent e;
300  static int pending = 0;
301
302  if (pending == 0) pending = XPending( gl_window->display );
303  if (pending > 0)
304  {
305    XNextEvent( gl_window->display, &e );
306    pending--;
307  }
308  else
309  {
310    e.type = LASTEvent + 1; /* means 'no event' */
311  }
312
313  return (void *) &e;
314}
315
316/*
317** local routines
318*/
319int query_extensions_glx(Display * dpy)
320{
321  int major, minor;
322
323
324  if(! glXQueryExtension(dpy, NULL, NULL))
325    return 0;
326
327  glXQueryVersion(dpy, &major, &minor);
328  if( (major == 1) && (minor < 3) )
329    {
330      printf(" glX version unsupported : less than 1.3\n");
331      return 0;
332    }
333
334  /* provide to scheme side
335  printf(" glX vendor     : %s\n",
336         glXGetClientString(dpy, GLX_VENDOR) );
337  printf(" glX version    : %s\n",
338         glXGetClientString(dpy, GLX_VERSION) );
339  printf(" glX extensions : %s\n",
340         glXGetClientString(dpy, GLX_EXTENSIONS) );
341  */
342
343  return 1;
344
345}
346
347void exit_on_err(char * s)
348{
349  fprintf(stderr, "%s\n", s);
350  exit(1);
351}
352
353
354void
355shape_window( gl_window_t  * gl_window, int width, int height )
356{
357  XRectangle rectangles[3];
358  int n_rectangles = 3;
359
360  rectangles[0].x = 1;
361  rectangles[0].y = 0;
362  rectangles[0].width = width - 2;
363  rectangles[0].height = 1;
364 
365  rectangles[1].x = 0;
366  rectangles[1].y = 1;
367  rectangles[1].width = width;
368  rectangles[1].height = height - 2;
369  rectangles[2].x = 1;
370  rectangles[2].y = height - 1;
371  rectangles[2].width = width - 2;
372  rectangles[2].height = 1;
373
374  XShapeCombineRectangles(gl_window->display, gl_window->window, ShapeBounding, 0, 0,
375                  rectangles, n_rectangles, ShapeSet, 0);
376}
377
378/*
379Cursor CreateNullPointer(void)
380{
381  Cursor cursor;
382  Pixmap pm;
383  GC ctx;
384  XGCValues val;
385  XColor color;
386
387  pm = XCreatePixmap(dpy, RootWindow(dpy, scrnum), 1, 1, 1);
388  val.function = GXclear;
389  ctx = XCreateGC(dpy, pm, GCFunction, &val);
390
391  color.pixel = 0;
392  color.red = 0;
393  color.flags = 04;
394  cursor = XCreatePixmapCursor(dpy, pm, pm, &color, &color, 0,0);
395
396  XFreePixmap(dpy, pm);
397  XFreeGC(dpy, ctx);
398
399  return cursor;
400}
401
402void SetNullPointer(void)
403{
404  XDefineCursor( dpy, win, CreateNullPointer() );
405}*/
406
407
408
409
410
411int time_milliseconds( void )
412{
413  static unsigned long time_base = 0;
414  struct timeval tp;
415 
416  gettimeofday (&tp, NULL);
417  if ( !time_base )
418  {
419    time_base = tp.tv_sec;
420    return tp.tv_usec / 1000;
421  }
422
423  int current = (tp.tv_sec - time_base)*1000 + tp.tv_usec/1000;
424  return current;
425}
426
427
Note: See TracBrowser for help on using the repository browser.