backported fixes from deeprunner
[miniglut] / miniglut.c
index 57abff9..16bb7b9 100644 (file)
@@ -66,6 +66,11 @@ static int cmap_size;
 #include <GL/gl.h>
 #include "miniglut.h"
 
+#ifdef _MSC_VER
+#pragma warning (disable: 4244 4305)
+#endif
+
+
 struct ctx_info {
        int rsize, gsize, bsize, asize;
        int zsize, ssize;
@@ -83,7 +88,6 @@ static void get_screen_size(int *scrw, int *scrh);
 
 static long get_msec(void);
 static void panic(const char *msg);
-static void warn(const char *msg);
 static void sys_exit(int status);
 static int sys_write(int fd, const void *buf, int count);
 
@@ -527,7 +531,7 @@ static KeySym translate_keysym(KeySym sym)
        case XK_Linefeed:
                return '\r';
        case XK_Return:
-               return '\n';
+               return '\r';
        case XK_Delete:
                return 127;
        case XK_Tab:
@@ -828,6 +832,11 @@ void glutSetCursor(int cidx)
        cur_cursor = cidx;
 }
 
+void glutWarpPointer(int x, int y)
+{
+       XWarpPointer(dpy, None, win, 0, 0, 0, 0, x, y);
+}
+
 void glutSetColor(int idx, float r, float g, float b)
 {
        XColor color;
@@ -1254,20 +1263,32 @@ void glutPositionWindow(int x, int y)
        SetWindowPos(win, HWND_NOTOPMOST, x, y, rect.right - rect.left, rect.bottom - rect.top, flags);
 }
 
+static void calc_win_rect(RECT *rect, int x, int y, int w, int h)
+{
+       rect->left = x;
+       rect->top = y;
+       rect->right = x + w;
+       rect->bottom = y + h;
+       AdjustWindowRect(rect, WS_OVERLAPPEDWINDOW, 0);
+}
+
 void glutReshapeWindow(int xsz, int ysz)
 {
        RECT rect;
        unsigned int flags = SWP_SHOWWINDOW;
 
        if(fullscreen) {
-               rect.left = prev_win_x;
-               rect.top = prev_win_y;
+               calc_win_rect(&rect, prev_win_x, prev_win_y, xsz, ysz);
                SetWindowLong(win, GWL_STYLE, WS_OVERLAPPEDWINDOW);
                fullscreen = 0;
                flags |= SWP_FRAMECHANGED;
        } else {
                GetWindowRect(win, &rect);
+               calc_win_rect(&rect, rect.left, rect.top, xsz, ysz);
        }
+
+       xsz = rect.right - rect.left;
+       ysz = rect.bottom - rect.top;
        SetWindowPos(win, HWND_NOTOPMOST, rect.left, rect.top, xsz, ysz, flags);
 }
 
@@ -1315,6 +1336,16 @@ void glutSetCursor(int cidx)
        }
 }
 
+void glutWarpPointer(int x, int y)
+{
+       POINT pt;
+       pt.x = x;
+       pt.y = y;
+
+       ClientToScreen(win, &pt);
+       SetCursorPos(pt.x, pt.y);
+}
+
 void glutSetColor(int idx, float r, float g, float b)
 {
        PALETTEENTRY col;
@@ -1466,9 +1497,7 @@ static int create_window_wglext(const char *title, int width, int height)
        HWND tmpwin = 0;
        HDC tmpdc = 0;
        HGLRC tmpctx = 0;
-       int i, pixfmt, curbpp;
-       char palbuf[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
-       LOGPALETTE *logpal;
+       int pixfmt;
 
        /* create a temporary window and GL context, just to query and retrieve
         * the wglChoosePixelFormatEXT function
@@ -1542,52 +1571,6 @@ static int create_window_wglext(const char *title, int width, int height)
        GETATTR(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, &ctx_info.srgb);
        GETATTR(WGL_SAMPLES_ARB, &ctx_info.samples);
 
-       if(init_mode & GLUT_INDEX) {
-               logpal = (LOGPALETTE*)palbuf;
-
-               GetSystemPaletteEntries(dc, 0, 256, logpal->palPalEntry);
-
-               logpal->palVersion = 0x300;
-               logpal->palNumEntries = 256;
-
-               if(!(cmap = CreatePalette(logpal))) {
-                       panic("Failed to create palette in indexed mode");
-               }
-               SelectPalette(dc, cmap, 0);
-               RealizePalette(dc);
-
-               cmap_size = 256;
-       } else {
-               if((curbpp = GetDeviceCaps(dc, BITSPIXEL) * GetDeviceCaps(dc, PLANES)) <= 8) {
-                       /* for RGB mode in 8bpp displays we also need to set up a palette
-                        * with RGB 332 colors
-                        */
-                       logpal = (LOGPALETTE*)palbuf;
-
-                       logpal->palVersion = 0x300;
-                       logpal->palNumEntries = 256;
-
-                       for(i=0; i<256; i++) {
-                               int r = i & 7;
-                               int g = (i >> 3) & 7;
-                               int b = (i >> 5) & 3;
-
-                               logpal->palPalEntry[i].peRed = (r << 5) | (r << 2) | (r >> 1);
-                               logpal->palPalEntry[i].peGreen = (g << 5) | (g << 2) | (g >> 1);
-                               logpal->palPalEntry[i].peBlue = (b << 6) | (b << 4) | (b << 2) | b;
-                               logpal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
-                       }
-
-                       if(!(cmap = CreatePalette(logpal))) {
-                               warn("Failed to create RGB 332 palette on palettized mode. Colors will be wrong\n");
-                       } else {
-                               SelectPalette(dc, cmap, 0);
-                               RealizePalette(dc);
-                       }
-                       cmap_size = 256;
-               }
-       }
-
        return 0;
 
 fail:
@@ -1602,18 +1585,14 @@ fail:
        return -1;
 }
 
-
 static void create_window(const char *title)
 {
-       int pixfmt;
        RECT rect;
-       int width, height;
+       int i, pixfmt, width, height;
+       char palbuf[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
+       LOGPALETTE *logpal;
 
-       rect.left = init_x;
-       rect.top = init_y;
-       rect.right = init_x + init_width;
-       rect.bottom = init_y + init_height;
-       AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, 0);
+       calc_win_rect(&rect, init_x, init_y, init_width, init_height);
        width = rect.right - rect.left;
        height = rect.bottom - rect.top;
 
@@ -1625,10 +1604,10 @@ static void create_window(const char *title)
                pfd.dwFlags |= PFD_STEREO;
        }
        if(init_mode & GLUT_INDEX) {
-               pfd.iPixelType = PFD_TYPE_RGBA;
+               pfd.iPixelType = PFD_TYPE_COLORINDEX;
                pfd.cColorBits = 8;
        } else {
-               pfd.iPixelType = PFD_TYPE_COLORINDEX;
+               pfd.iPixelType = PFD_TYPE_RGBA;
                pfd.cColorBits = 24;
        }
        if(init_mode & GLUT_ALPHA) {
@@ -1645,41 +1624,92 @@ static void create_window(const char *title)
        }
        pfd.iLayerType = PFD_MAIN_PLANE;
 
-
-       if(create_window_wglext(title, width, height) == -1) {
-
-               if(!(win = CreateWindow("MiniGLUT", title, WS_OVERLAPPEDWINDOW,
-                                       rect.left, rect.top, width, height, 0, 0, hinst, 0))) {
-                       panic("Failed to create window\n");
+       if(init_mode & (GLUT_SRGB | GLUT_MULTISAMPLE)) {
+               if(create_window_wglext(title, width, height) != -1) {
+                       goto ctxdone;
                }
-               dc = GetDC(win);
+       }
 
-               if(!(pixfmt = ChoosePixelFormat(dc, &pfd))) {
-                       panic("Failed to find suitable pixel format\n");
-               }
-               if(!SetPixelFormat(dc, pixfmt, &pfd)) {
-                       panic("Failed to set the selected pixel format\n");
-               }
-               if(!(ctx = wglCreateContext(dc))) {
-                       panic("Failed to create the OpenGL context\n");
-               }
-               wglMakeCurrent(dc, ctx);
+       /* if we don't need sRGB or multisample, or if the wglChoosePixelFormat method
+        * failed, just use the old-style ChoosePixelFormat method instead
+        */
+       if(!(win = CreateWindow("MiniGLUT", title, WS_OVERLAPPEDWINDOW,
+                               rect.left, rect.top, width, height, 0, 0, hinst, 0))) {
+               panic("Failed to create window\n");
+       }
+       dc = GetDC(win);
 
-               DescribePixelFormat(dc, pixfmt, sizeof pfd, &pfd);
-               ctx_info.rsize = pfd.cRedBits;
-               ctx_info.gsize = pfd.cGreenBits;
-               ctx_info.bsize = pfd.cBlueBits;
-               ctx_info.asize = pfd.cAlphaBits;
-               ctx_info.zsize = pfd.cDepthBits;
-               ctx_info.ssize = pfd.cStencilBits;
-               ctx_info.dblbuf = pfd.dwFlags & PFD_DOUBLEBUFFER ? 1 : 0;
-               ctx_info.samples = 0;
-               ctx_info.srgb = 0;
+       if(!(pixfmt = ChoosePixelFormat(dc, &pfd))) {
+               panic("Failed to find suitable pixel format\n");
+       }
+       if(!SetPixelFormat(dc, pixfmt, &pfd)) {
+               panic("Failed to set the selected pixel format\n");
+       }
+       if(!(ctx = wglCreateContext(dc))) {
+               panic("Failed to create the OpenGL context\n");
        }
+       wglMakeCurrent(dc, ctx);
 
+       DescribePixelFormat(dc, pixfmt, sizeof pfd, &pfd);
+       ctx_info.rsize = pfd.cRedBits;
+       ctx_info.gsize = pfd.cGreenBits;
+       ctx_info.bsize = pfd.cBlueBits;
+       ctx_info.asize = pfd.cAlphaBits;
+       ctx_info.zsize = pfd.cDepthBits;
+       ctx_info.ssize = pfd.cStencilBits;
+       ctx_info.dblbuf = pfd.dwFlags & PFD_DOUBLEBUFFER ? 1 : 0;
+       ctx_info.samples = 0;
+       ctx_info.srgb = 0;
+
+ctxdone:
        ShowWindow(win, 1);
        SetForegroundWindow(win);
        SetFocus(win);
+
+       if(init_mode & GLUT_INDEX) {
+               logpal = (LOGPALETTE*)palbuf;
+
+               GetSystemPaletteEntries(dc, 0, 256, logpal->palPalEntry);
+
+               logpal->palVersion = 0x300;
+               logpal->palNumEntries = 256;
+
+               if(!(cmap = CreatePalette(logpal))) {
+                       panic("Failed to create palette in indexed mode");
+               }
+               SelectPalette(dc, cmap, 0);
+               RealizePalette(dc);
+
+               cmap_size = 256;
+       } else {
+               if(GetDeviceCaps(dc, BITSPIXEL) * GetDeviceCaps(dc, PLANES) <= 8) {
+                       /* for RGB mode in 8bpp displays we also need to set up a palette
+                        * with RGB 332 colors
+                        */
+                       logpal = (LOGPALETTE*)palbuf;
+
+                       logpal->palVersion = 0x300;
+                       logpal->palNumEntries = 256;
+
+                       for(i=0; i<256; i++) {
+                               int r = i & 7;
+                               int g = (i >> 3) & 7;
+                               int b = (i >> 5) & 3;
+
+                               logpal->palPalEntry[i].peRed = (r << 5) | (r << 2) | (r >> 1);
+                               logpal->palPalEntry[i].peGreen = (g << 5) | (g << 2) | (g >> 1);
+                               logpal->palPalEntry[i].peBlue = (b << 6) | (b << 4) | (b << 2) | b;
+                               logpal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
+                       }
+
+                       if((cmap = CreatePalette(logpal))) {
+                               SelectPalette(dc, cmap, 0);
+                               RealizePalette(dc);
+                               cmap_size = 256;
+                       }
+               }
+       }
+
        upd_pending = 1;
        reshape_pending = 1;
 }
@@ -1811,6 +1841,16 @@ static void update_modkeys(void)
        }
 }
 
+#ifndef VK_OEM_1
+#define VK_OEM_1       0xba
+#define VK_OEM_2       0xbf
+#define VK_OEM_3       0xc0
+#define VK_OEM_4       0xdb
+#define VK_OEM_5       0xdc
+#define VK_OEM_6       0xdd
+#define VK_OEM_7       0xde
+#endif
+
 static int translate_vkey(int vkey)
 {
        switch(vkey) {
@@ -1927,13 +1967,6 @@ static void panic(const char *msg)
        sys_exit(1);
 }
 
-static void warn(const char *msg)
-{
-       const char *end = msg;
-       while(*end) end++;
-       sys_write(2, msg, end - msg);
-}
-
 
 #ifdef MINIGLUT_USE_LIBC
 #include <stdlib.h>