Flatland

Documentation

SourceForge.net Logo

osLinux.c

Go to the documentation of this file.
00001 // Summary: Defines methods for non-Windows functions.
00002 // Copyright: 2007  Philip Rideout.  All rights reserved.
00003 // License: see bsd-license.txt
00004 
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <memory.h>
00008 #include <sys/time.h>
00009 #include <GL/glx.h>
00010 #include <GL/glxext.h>
00011 #include "os.h"
00012 
00013 static Display *g_display;
00014 static Window g_window;
00015 static int g_screen;
00016 static GLXContext g_context;
00017 
00018 static OS_Event *g_eventHead = 0;
00019 static OS_Event **g_eventTail = &g_eventHead;
00020 static int g_keyboard[256];
00021 
00022 void osInit(int width, int height, unsigned int flags, int *attribs)
00023 {
00024     int attrib[] = {
00025         GLX_RGBA,
00026         GLX_DEPTH_SIZE, 0,
00027         GLX_RED_SIZE, 1,
00028         GLX_GREEN_SIZE, 1,
00029         GLX_BLUE_SIZE, 1,
00030         GLX_DOUBLEBUFFER, None,
00031     };
00032 
00033     XSetWindowAttributes attr;
00034     unsigned long mask;
00035     Window root;
00036     XVisualInfo *visinfo;
00037 
00038     atexit(osQuit);
00039     g_display = XOpenDisplay(NULL);
00040     g_screen = DefaultScreen(g_display);
00041     root = RootWindow(g_display, g_screen);
00042     visinfo = glXChooseVisual(g_display, g_screen, attrib);
00043 
00044     if (!visinfo)
00045     {
00046         printf("Error: couldn't create OpenGL window\n");
00047         exit(1);
00048     }
00049 
00050     attr.background_pixel = 0;
00051     attr.border_pixel = 0;
00052     attr.colormap = XCreateColormap(g_display, root, visinfo->visual, AllocNone);
00053     attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask;
00054     mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
00055 
00056     g_window = XCreateWindow(
00057         g_display,
00058         root,
00059         0, 0,
00060         width, height, 0,
00061         visinfo->depth,
00062         InputOutput,
00063         visinfo->visual,
00064         mask,
00065         &attr
00066     );
00067 
00068     XStoreName(g_display, g_window, "Flatland Demo");
00069 
00070     g_context = glXCreateContext(g_display, visinfo, NULL, True);
00071     glXMakeCurrent(g_display, g_window, g_context);
00072     XMapWindow(g_display, g_window);
00073 }
00074 
00075 void osQuit(void)
00076 {
00077     glXDestroyContext(g_display, g_context);
00078     XDestroyWindow(g_display, g_window);
00079 
00080     while (g_eventHead)
00081     {
00082         OS_Event *pending = g_eventHead;
00083         g_eventHead = pending->next;
00084         if (!g_eventHead)
00085             g_eventTail = &g_eventHead;
00086         free(pending);
00087     }
00088 
00089 }
00090 
00091 int osGetScreenWidth()
00092 {
00093     return DisplayWidth(g_display, g_screen);
00094 }
00095 
00096 int osGetScreenHeight()
00097 {
00098     return DisplayHeight(g_display, g_screen);
00099 }
00100 
00101 // http://opengl.org/registry/specs/SGI/swap_control.txt
00102 void osWaitVsync(int interval)
00103 {
00104     PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI;
00105     glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddress((const GLubyte*) "glXSwapIntervalSGI");
00106     if (glXSwapIntervalSGI)
00107         glXSwapIntervalSGI(interval);
00108 }
00109 
00110 unsigned int osGetMilliseconds()
00111 {
00112     struct timeval tp;
00113     gettimeofday(&tp, NULL);
00114     return tp.tv_sec * 1000 + tp.tv_usec / 1000;
00115 }
00116 
00117 int osPollEvent(struct OS_EventRec *e)
00118 {
00119     if (XPending(g_display))
00120     {
00121         OS_Event e;
00122         XEvent event;
00123         e.type = OS_NOEVENT;
00124 
00125         XNextEvent(g_display, &event);
00126         switch (event.type)
00127         {
00128           case Expose:
00129             //redraw(g_display, event.xany.window);
00130             break;
00131 
00132           case ConfigureNotify:
00133             //resize(event.xconfigure.width, event.xconfigure.height);
00134             break;
00135 
00136           case KeyRelease:
00137           case KeyPress:
00138           {
00139             XComposeStatus composeStatus;
00140             char asciiCode[32];
00141             KeySym keySym;
00142             int len;
00143 
00144             if (event.type == KeyPress)
00145             {     
00146                 e.type = OS_KEYDOWN;
00147                 e.key.state = OSKS_DOWN;
00148             }
00149             else
00150             {
00151                 e.type = OS_KEYUP;
00152                 e.key.state = OSKS_UP;
00153             }
00154 
00155             // Check for the ASCII/KeySym codes associated with the event:
00156             len = XLookupString(&event.xkey, asciiCode, sizeof(asciiCode), &keySym, &composeStatus);
00157 
00158             // ASCII Key
00159             if (len > 0)
00160             {
00161                 e.key.key = (unsigned char) asciiCode[0];
00162             }
00163             else // Special Key
00164             {
00165                 switch (keySym)
00166                 {
00167                   case XK_Left:   e.key.key = OSK_LEFT;   break;
00168                   case XK_Right:  e.key.key = OSK_RIGHT;  break;
00169                   case XK_Up:     e.key.key = OSK_UP;     break;
00170                   case XK_Down:   e.key.key = OSK_DOWN;   break;
00171                 }
00172             }
00173 
00174             // Update the keyboard state.
00175             g_keyboard[e.key.key] = e.key.state;
00176           }
00177           break;
00178         }
00179 
00180         if (e.type != OS_NOEVENT)
00181         {
00182             e.next = 0;
00183             *g_eventTail = (OS_Event*) malloc(sizeof(OS_Event));
00184             memcpy(*g_eventTail, &e, sizeof(OS_Event));
00185             g_eventTail = &((*g_eventTail)->next);
00186         }
00187     }
00188 
00189     if (g_eventHead)
00190     {
00191         OS_Event *pending = g_eventHead;
00192         memcpy(e, pending, sizeof(OS_Event));
00193         g_eventHead = pending->next;
00194         if (!g_eventHead)
00195             g_eventTail = &g_eventHead;
00196         free(pending);
00197         return 1;
00198     }
00199 }
00200 
00201 void osSwapBuffers()
00202 {
00203     glXSwapBuffers(g_display, g_window);
00204 }
00205 
00206 int osIsKeyDown(int key)
00207 {
00208     if (key < 0 || key > 0xff)
00209         return 0;
00210 
00211     return g_keyboard[key];
00212 }
00213 
00214 int osShowCursor(int) // TODO
00215 {
00216     return 0;
00217 }
00218 

Generated on Sat Jan 13 17:20:21 2007 for Flatland by doxygen 1.5.1