Added initial multisampling support to glfbdev driver.
authorSean D'Epagnier <geckosenator@freedesktop.org>
Thu, 10 Aug 2006 10:21:17 +0000 (10:21 +0000)
committerSean D'Epagnier <geckosenator@freedesktop.org>
Thu, 10 Aug 2006 10:21:17 +0000 (10:21 +0000)
Fully implemented glutGameMode, and added vidresize stubs to make
Added support for glutReshapeDisplay to change video mode but not lose
current mesa context.
implementation glut 5 complient.
Fixed many minor bugs
Updated docs

14 files changed:
docs/glfbdev-driver.html
include/GL/glfbdev.h
src/glut/fbdev/Makefile
src/glut/fbdev/colormap.c
src/glut/fbdev/cursor.c
src/glut/fbdev/ext.c
src/glut/fbdev/fbdev.c
src/glut/fbdev/gamemode.c
src/glut/fbdev/input.c
src/glut/fbdev/internal.h
src/glut/fbdev/menu.c
src/glut/fbdev/state.c
src/glut/fbdev/vidresize.c [new file with mode: 0644]
src/mesa/drivers/fbdev/glfbdev.c

index f191b390fbe84c71cbc16c23d3d0947243bad6d9..981df7c088a09abb8528eb4a66e4a8fcc86b447d 100644 (file)
@@ -70,7 +70,7 @@ tty group as well
 
 <h1>4. Using fbdevglut</h1>
 Almost all of the programs in the progs directory use glut, and they compile with fbdevglut.
-Currently glBlendFunc is not working with glFBDev.
+
 <p>
 To compile the redbook sample programs:
 <pre>
index d2b12815c9f899f1572186c353a554437a94ee10..4e25e7b0566c70e1ddef0830f2c6d2a49c5f5013 100644 (file)
@@ -49,6 +49,7 @@ typedef struct GLFBDevContextRec *GLFBDevContextPtr;
 #define GLFBDEV_STENCIL_SIZE    103
 #define GLFBDEV_ACCUM_SIZE      104
 #define GLFBDEV_LEVEL           105
+#define GLFBDEV_MULTISAMPLE     106
 #define GLFBDEV_NONE              0
 
 /* For glFBDevGetString */
index 39a48f36343eb086eaf5958221e6e8af9e88a90a..4f70efe27946ddffed80efc66a1b69b550de0937 100644 (file)
@@ -6,8 +6,8 @@ include $(TOP)/configs/current
 GLX_SHARED = $(TOP)/src/glut/glx
 SHAPES = $(TOP)/src/glut/mini
 
-GLUT_MAJOR = 3
-GLUT_MINOR = 7
+GLUT_MAJOR = 5
+GLUT_MINOR = 0
 GLUT_TINY = 1
 
 INCLUDES = -I$(TOP)/include -I$(GLX_SHARED)
@@ -22,7 +22,8 @@ CORE_SOURCES = \
        state.c \
        input.c \
        callback.c \
-       gamemode.c
+       gamemode.c \
+       vidresize.c
 
 GLX_SHARED_SOURCES = \
        $(GLX_SHARED)/glut_8x13.c \
index 9a6dea20dc9f446caccd0bd9e027eae0cd8c2418..157296d15c1fadd4734b37c8f631f31cf76e58a3 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/fb.h>
 
 #include <GL/gl.h>
-#include <GL/glfbdev.h>
 #include <GL/glut.h>
 
 #include "internal.h"
@@ -53,9 +52,9 @@ static void FindReverseMap(int r, int g, int b)
    unsigned int minv = -1, mini = 0;
    for(i=0; i<256; i++) {
       int val = 0;
-      val += abs(r-(ColorMap.red[i]>>shift));
-      val += abs(g-(ColorMap.green[i]>>shift));
-      val += abs(b-(ColorMap.blue[i]>>shift));
+      val += abs(r-(RedColorMap[i]>>shift));
+      val += abs(g-(GreenColorMap[i]>>shift));
+      val += abs(b-(BlueColorMap[i]>>shift));
       if(val < minv) {
         minv = val;
         mini = i;
index b753a5c9ff5c083b1281dd6abdb4bbf60c10868e..06ae2d6f54eb8998d9a2e4831afb69778db0e26e 100644 (file)
@@ -44,7 +44,7 @@ static unsigned char *MouseBuffer;
 
 void InitializeCursor(void)
 {
-   if((MouseBuffer = malloc(CURSOR_WIDTH * CURSOR_HEIGHT
+   if(!MouseBuffer && (MouseBuffer = malloc(CURSOR_WIDTH * CURSOR_HEIGHT
                            * VarInfo.bits_per_pixel / 8)) == NULL) {
       sprintf(exiterror, "malloc failure\n");
       exit(0);
@@ -216,10 +216,10 @@ void SwapCursor(void)
       if(miny < 0)
         miny = 0;
        
-      if(minx + sizex > VarInfo.xres)
-        sizex = VarInfo.xres - minx;
-      if(miny + sizey > VarInfo.yres)
-        sizey = VarInfo.yres - miny;
+      if(minx + sizex > VarInfo.xres - CURSOR_WIDTH)
+        sizex = VarInfo.xres - CURSOR_WIDTH - minx;
+      if(miny + sizey > VarInfo.yres - CURSOR_HEIGHT)
+        sizey = VarInfo.yres - CURSOR_HEIGHT - miny;
       off = FixedInfo.line_length * miny
         + minx * VarInfo.bits_per_pixel / 8;
       stride = (sizex + CURSOR_WIDTH) * VarInfo.bits_per_pixel / 8;
index 1746bf33e9c6128dab330b045a2e04fe82181d4e..4a3c185a16dc2b1d6ff569e817dcbede067529ca 100644 (file)
@@ -25,7 +25,6 @@
  */
 
 #include <GL/gl.h>
-#include <GL/glfbdev.h>
 #include <GL/glut.h>
 
 #include "internal.h"
index fcbd4f8da280233b345b5138352e1b46af2414ff..ce7d187b66dba9e5794ee1a62cb370c965e7dcfd 100644 (file)
@@ -22,6 +22,9 @@
  * Library for glut using mesa fbdev driver
  *
  * Written by Sean D'Epagnier (c) 2006
+ * 
+ * To improve on this library, maybe support subwindows or overlays,
+ * I (sean at depagnier dot com) will do my best to help.
  */
 
 #include <errno.h>
 #include <linux/vt.h>
 
 #include <GL/gl.h>
-#include <GL/glfbdev.h>
 #include <GL/glut.h>
 
 #include "internal.h"
 
 #define FBMODES "/etc/fb.modes"
 
-
 struct fb_fix_screeninfo FixedInfo;
-struct fb_var_screeninfo VarInfo, OrigVarInfo;
+struct fb_var_screeninfo VarInfo;
+static struct fb_var_screeninfo OrigVarInfo;
 
 static int DesiredDepth = 0;
 
@@ -64,9 +66,9 @@ struct GlutTimer *GlutTimers = NULL;
 struct timeval StartTime;
 
 /* per window data */
-static GLFBDevContextPtr Context;
-static GLFBDevBufferPtr Buffer;
-static GLFBDevVisualPtr Visual;
+GLFBDevContextPtr Context;
+GLFBDevBufferPtr Buffer;
+GLFBDevVisualPtr Visual;
 
 int Redisplay;
 int Visible;
@@ -75,13 +77,9 @@ int Active;
 /* we have to poll to see if we are visible
    on a framebuffer that is not active */
 int VisiblePoll;
+int Swapping, VTSwitch;
 static int FramebufferIndex;
 
-static int RequiredWidth;
-static int RequiredHeight;
-static int InitialWidthHint;
-static int InitialHeightHint;
-
 static int Initialized;
 
 char exiterror[256];
@@ -105,6 +103,9 @@ void TestVisible(void) {
 
 static void Cleanup(void)
 {
+   if(GameMode)
+      glutLeaveGameMode();
+
    if(ConsoleFD != -1)
       RestoreVT();
 
@@ -136,7 +137,7 @@ static void Cleanup(void)
 
    if(exiterror[0])
       fprintf(stderr, "[glfbdev glut] %s", exiterror);
-}
+ }
 
 static void CrashHandler(int sig)
 {
@@ -162,10 +163,9 @@ static void removeArgs(int *argcp, char **argv, int num)
 
 void glutInit (int *argcp, char **argv)
 {
-   int i;
-   int nomouse = 0;
-   int nokeyboard = 0;
-   int usestdin = 0;
+   int i, nomouse = 0, nokeyboard = 0, usestdin = 0;
+   int RequiredWidth = 0, RequiredHeight;
+   char *fbdev;
 
    /* parse out args */
    for (i = 1; i < *argcp;) {
@@ -242,6 +242,61 @@ void glutInit (int *argcp, char **argv)
    if(nokeyboard == 0)
       InitializeVT(usestdin);
 
+   fbdev = getenv("FRAMEBUFFER");
+   if(fbdev) {
+#ifdef MULTIHEAD
+      if(!sscanf(fbdev, "/dev/fb%d", &FramebufferIndex))
+        if(!sscanf(fbdev, "/dev/fb/%d", &FramebufferIndex))
+           sprintf(exiterror, "Could not determine Framebuffer index!\n");
+#endif
+   } else {
+      static char fb[128];
+      struct fb_con2fbmap confb;
+      int fd = open("/dev/fb0", O_RDWR);
+
+      FramebufferIndex = 0;
+
+      confb.console = CurrentVT;
+      if(ioctl(fd, FBIOGET_CON2FBMAP, &confb) != -1)
+        FramebufferIndex = confb.framebuffer;
+      sprintf(fb, "/dev/fb%d", FramebufferIndex);
+      fbdev = fb;
+      close(fd);
+   }
+
+   /* open the framebuffer device */
+   FrameBufferFD = open(fbdev, O_RDWR);
+   if (FrameBufferFD < 0) {
+      sprintf(exiterror, "Error opening %s: %s\n", fbdev, strerror(errno));
+      exit(0);
+   }
+
+   /* Get the fixed screen info */
+   if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) {
+      sprintf(exiterror, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n",
+             strerror(errno));
+      exit(0);
+   }
+
+   /* get the variable screen info */
+   if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &OrigVarInfo)) {
+      sprintf(exiterror, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n",
+             strerror(errno));
+      exit(0);
+   }
+
+   /* operate on a copy */
+   VarInfo = OrigVarInfo;
+
+   /* set the depth, resolution, etc */
+   if(RequiredWidth)
+      if(!ParseFBModes(RequiredWidth, RequiredWidth, RequiredHeight,
+                      RequiredHeight, 0, MAX_VSYNC)) {
+        sprintf(exiterror, "No mode (%dx%d) found in "FBMODES"\n",
+                RequiredWidth, RequiredHeight);
+        exit(0);
+      }
+
    Initialized = 1;
 }
 
@@ -250,17 +305,109 @@ void glutInitDisplayMode (unsigned int mode)
    DisplayMode = mode;
 }
 
+static const char *GetStrVal(const char *p, int *set, int min, int max)
+{
+   char *endptr;
+   int comp = *p, val;
+
+   if(p[1] == '=')
+      p++;
+
+   if(*p == '\0')
+      return p;
+
+   val = strtol(p+1, &endptr, 10);
+
+   if(endptr == p+1)
+      return p;
+
+   switch(comp) {
+   case '!':
+      if(val == min)
+        val = max;
+      else
+        val = min;
+      break;
+   case '<':
+      val = min;
+      break;
+   case '>':
+      val = max;
+      break;
+   }
+
+   if(val < min || val > max) {
+      sprintf(exiterror, "display string value out of range\n");
+      exit(0);
+   }
+
+   *set = val;
+
+   return endptr;
+}
+
+static void SetAttrib(int val, int attr)
+{
+   if(val)
+      DisplayMode |= attr;
+   else
+      DisplayMode &= ~attr;
+}
+
+void glutInitDisplayString(const char *string)
+{
+   const char *p = string;
+   int val;
+   while(*p) {
+      if(*p == ' ')
+        p++;
+      else
+      if(memcmp(p, "acca", 4) == 0) {
+        p = GetStrVal(p+4, &AccumSize, 1, 32);
+        SetAttrib(AccumSize, GLUT_ACCUM);
+      } else
+      if(memcmp(p, "acc", 3) == 0) {
+        p = GetStrVal(p+3, &AccumSize, 1, 32);
+        SetAttrib(AccumSize, GLUT_ACCUM);
+      } else
+      if(memcmp(p, "depth", 5) == 0) {
+        p = GetStrVal(p+5, &DepthSize, 12, 32);
+        SetAttrib(DepthSize, GLUT_DEPTH);
+      } else
+      if(memcmp(p, "double", 6) == 0) {
+        val = 1;
+        p = GetStrVal(p+6, &val, 0, 1);
+        SetAttrib(val, GLUT_DOUBLE);
+      } else
+      if(memcmp(p, "index", 5) == 0) {
+        val = 1;
+        p = GetStrVal(p+5, &val, 0, 1);
+        SetAttrib(val, GLUT_INDEX);
+      } else
+      if(memcmp(p, "stencil", 7) == 0) {
+        p = GetStrVal(p+7, &StencilSize, 0, 1);
+        SetAttrib(StencilSize, GLUT_STENCIL);
+      } else
+      if(memcmp(p, "samples", 7) == 0) {
+        NumSamples = 1;
+        p = GetStrVal(p+7, &NumSamples, 0, 16);
+        SetAttrib(NumSamples, GLUT_MULTISAMPLE);
+      } else
+      if(p = strchr(p, ' '))
+         p++;
+      else
+        break;
+   }
+}
+
 void glutInitWindowPosition (int x, int y)
 {
 }
 
 void glutInitWindowSize (int width, int height)
 {
-   InitialWidthHint = width;
-   InitialHeightHint = height;
 }
 
-
 static void ProcessTimers(void)
 {
    if(GlutTimers && GlutTimers->time < glutGet(GLUT_ELAPSED_TIME)) {
@@ -289,10 +436,12 @@ void glutMainLoop(void)
       else
         if(VisiblePoll)
            TestVisible();
+        else
+           usleep(1);
 
       if(IdleFunc)
         IdleFunc();
-
+      
       if(VisibleSwitch) {
         VisibleSwitch = 0;
         if(VisibilityFunc)
@@ -314,7 +463,7 @@ void glutMainLoop(void)
    }
 }
 
-static void ParseFBModes(void)
+int ParseFBModes(int minw, int maxw, int minh, int maxh, int minf, int maxf)
 {
    char buf[1024];
    struct fb_var_screeninfo vi = VarInfo;
@@ -322,44 +471,34 @@ static void ParseFBModes(void)
    FILE *fbmodes = fopen(FBMODES, "r");
 
    if(!fbmodes) {
-      sprintf(exiterror, "Warning: could not open "
-             FBMODES" using current mode\n");
-      return;
+      sprintf(exiterror, "Warning: could not open "FBMODES"\n");
+      return 0;
    }
 
-   if(InitialWidthHint == 0 && InitialHeightHint == 0
-      && RequiredWidth == 0)
-      return; /* use current mode */
-
    while(fgets(buf, sizeof buf, fbmodes)) {
       char *c;
-      int v;
+      int v, bpp, freq;
 
       if(!(c = strstr(buf, "geometry")))
         continue;
       v = sscanf(c, "geometry %d %d %d %d %d", &vi.xres, &vi.yres,
-                &vi.xres_virtual, &vi.yres_virtual, &vi.bits_per_pixel);
+                &vi.xres_virtual, &vi.yres_virtual, &bpp);
       if(v != 5)
         continue;
 
-      /* now we have to decide what is best */
-      if(RequiredWidth) {
-        if(RequiredWidth != vi.xres || RequiredHeight != vi.yres)
+      if(maxw < minw) {
+        if(maxw < vi.xres && minw > vi.xres)
            continue;
-      } else {
-        if(VarInfo.xres < vi.xres && VarInfo.xres < InitialWidthHint)
-           v++;
-        if(VarInfo.xres > vi.xres && vi.xres > InitialWidthHint)
-           v++;
-
-        if(VarInfo.yres < vi.yres && VarInfo.yres < InitialHeightHint)
-           v++;
-        if(VarInfo.yres > vi.yres && vi.yres > InitialHeightHint)
-           v++;
-
-        if(v < 7)
+      } else
+        if(maxw < vi.xres || minw > vi.xres)
+           continue;
+
+      if(maxh < minh) {
+        if(maxh < vi.yres && minh > vi.yres)
+           continue;
+      } else
+        if(maxh < vi.yres || minh > vi.yres)
            continue;
-      }
 
       fgets(buf, sizeof buf, fbmodes);
       if(!(c = strstr(buf, "timings")))
@@ -368,103 +507,34 @@ static void ParseFBModes(void)
       v = sscanf(c, "timings %d %d %d %d %d %d %d", &vi.pixclock,
                 &vi.left_margin, &vi.right_margin, &vi.upper_margin,
                 &vi.lower_margin, &vi.hsync_len, &vi.vsync_len);
+
       if(v != 7)
         continue;
 
-      VarInfo = vi; /* finally found a better mode */
-      if(RequiredWidth) {
-        fclose(fbmodes);
-        return;
-      }
+      freq = 1E12/vi.pixclock
+        /(vi.left_margin + vi.xres + vi.right_margin + vi.hsync_len)
+        /(vi.upper_margin + vi.yres + vi.lower_margin + vi.vsync_len);
+
+      if(maxf < minf) {
+        if(maxf < freq && minf > freq)
+           continue;
+      } else
+        if(maxf < freq || minf > freq)
+           continue;
+
+      VarInfo = vi;
+      fclose(fbmodes);
+      return 1;
    }
 
    fclose(fbmodes);
 
-   if(RequiredWidth) {
-      sprintf(exiterror, "No mode (%dx%d) found in "FBMODES"\n",
-             RequiredWidth, RequiredHeight);
-      exit(0);
-   }
+   return 0;
 }
 
 /* ---------- Window Management ----------*/
-int glutCreateWindow (const char *title)
+void SetVideoMode(void)
 {
-   char *fbdev;
-   int attribs[9], i, mask, size;
-
-   if(Initialized == 0) {
-      int argc = 0;
-      char *argv[] = {NULL};
-      glutInit(&argc, argv);
-   }
-
-   if(Context)
-      return 0;
-
-   fbdev = getenv("FRAMEBUFFER");
-   if(fbdev) {
-#ifdef MULTIHEAD
-      if(!sscanf(fbdev, "/dev/fb%d", &FramebufferIndex))
-        if(!sscanf(fbdev, "/dev/fb/%d", &FramebufferIndex))
-           sprintf(exiterror, "Could not determine Framebuffer index!\n");
-#endif
-   } else {
-      static char fb[128];
-      struct fb_con2fbmap confb;
-      int fd = open("/dev/fb0", O_RDWR);
-
-      FramebufferIndex = 0;
-
-      confb.console = CurrentVT;
-      if(ioctl(fd, FBIOGET_CON2FBMAP, &confb) != -1)
-        FramebufferIndex = confb.framebuffer;
-      sprintf(fb, "/dev/fb%d", FramebufferIndex);
-      fbdev = fb;
-      close(fd);
-   }
-
-   /* open the framebuffer device */
-   FrameBufferFD = open(fbdev, O_RDWR);
-   if (FrameBufferFD < 0) {
-      sprintf(exiterror, "Error opening %s: %s\n", fbdev, strerror(errno));
-      exit(0);
-   }
-
-   /* Get the fixed screen info */
-   if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) {
-      sprintf(exiterror, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n",
-             strerror(errno));
-      exit(0);
-   }
-
-   /* get the variable screen info */
-   if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &OrigVarInfo)) {
-      sprintf(exiterror, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n",
-             strerror(errno));
-      exit(0);
-   }
-
-   /* operate on a copy */
-   VarInfo = OrigVarInfo;
-
-   /* set the depth, resolution, etc */
-   ParseFBModes();
-
-   if(DisplayMode & GLUT_INDEX)
-      VarInfo.bits_per_pixel = 8;
-   else
-      if(VarInfo.bits_per_pixel == 8)
-        VarInfo.bits_per_pixel = 32;
-    
-   if (DesiredDepth)
-      VarInfo.bits_per_pixel = DesiredDepth;
-
-   VarInfo.xoffset = 0;
-   VarInfo.yoffset = 0;
-   VarInfo.nonstd = 0;
-   VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */
-
    /* set new variable screen info */
    if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo)) {
       sprintf(exiterror, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
@@ -498,8 +568,16 @@ int glutCreateWindow (const char *title)
 
    /* initialize colormap */
    LoadColorMap();
+}
+
+void CreateBuffer()
+{
+   int size = VarInfo.xres_virtual * VarInfo.yres_virtual
+                              * VarInfo.bits_per_pixel / 8;
 
    /* mmap the framebuffer into our address space */
+   if(FrameBuffer)
+      munmap(FrameBuffer, FixedInfo.smem_len);
    FrameBuffer = mmap(0, FixedInfo.smem_len, PROT_READ | PROT_WRITE, 
                      MAP_SHARED, FrameBufferFD, 0);
    if (FrameBuffer == MAP_FAILED) {
@@ -508,8 +586,30 @@ int glutCreateWindow (const char *title)
       exit(0);
    }
 
-   mask = DisplayMode;
-   for(i=0; i<8 && mask; i++) {
+   if(DisplayMode & GLUT_DOUBLE) {
+      free(BackBuffer);
+      if(!(BackBuffer = malloc(size))) {
+        sprintf(exiterror, "Failed to allocate double buffer\n");
+        exit(0);
+      }
+   } else
+      BackBuffer = FrameBuffer;
+
+   if(Buffer)
+      glFBDevDestroyBuffer(Buffer);
+
+   if(!(Buffer = glFBDevCreateBuffer( &FixedInfo, &VarInfo, Visual,
+                                     FrameBuffer, BackBuffer, size))) {
+      sprintf(exiterror, "Failure to create Buffer\n");
+      exit(0);
+   }
+}
+
+void CreateVisual(void)
+{
+   int i, mask = DisplayMode;
+   int attribs[20];
+   for(i=0; i<sizeof(attribs)/sizeof(*attribs) && mask; i++) {
       if(mask & GLUT_DOUBLE) {
         attribs[i] = GLFBDEV_DOUBLE_BUFFER;
         mask &= ~GLUT_DOUBLE;
@@ -549,6 +649,13 @@ int glutCreateWindow (const char *title)
            i--;
            continue;
         }
+
+      if(mask & GLUT_MULTISAMPLE) {
+        attribs[i] = GLFBDEV_MULTISAMPLE;
+        attribs[++i] = NumSamples;
+        mask &= ~GLUT_MULTISAMPLE;
+        continue;
+      }
        
       sprintf(exiterror, "Invalid mode from glutInitDisplayMode\n");
       exit(0);
@@ -560,23 +667,37 @@ int glutCreateWindow (const char *title)
       sprintf(exiterror, "Failure to create Visual\n");
       exit(0);
    }
+}
 
-   size = VarInfo.xres_virtual * VarInfo.yres_virtual
-      * VarInfo.bits_per_pixel / 8;
-   if(DisplayMode & GLUT_DOUBLE) {
-      if(!(BackBuffer = malloc(size))) {
-        sprintf(exiterror, "Failed to allocate double buffer\n");
-        exit(0);
-      }
-   } else
-      BackBuffer = FrameBuffer;
-
-   if(!(Buffer = glFBDevCreateBuffer( &FixedInfo, &VarInfo, Visual,
-                                     FrameBuffer, BackBuffer, size))) {
-      sprintf(exiterror, "Failure to create Buffer\n");
-      exit(0);
+int glutCreateWindow (const char *title)
+{
+   if(Initialized == 0) {
+      int argc = 0;
+      char *argv[] = {NULL};
+      glutInit(&argc, argv);
    }
 
+   if(Context)
+      return 0;
+
+   if(DisplayMode & GLUT_INDEX)
+      VarInfo.bits_per_pixel = 8;
+   else
+      if(VarInfo.bits_per_pixel == 8)
+        VarInfo.bits_per_pixel = 32;
+    
+   if (DesiredDepth)
+      VarInfo.bits_per_pixel = DesiredDepth;
+
+   VarInfo.xoffset = 0;
+   VarInfo.yoffset = 0;
+   VarInfo.nonstd = 0;
+   VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */
+
+   SetVideoMode();
+   CreateVisual();
+   CreateBuffer();
+
    if(!(Context = glFBDevCreateContext(Visual, NULL))) {
       sprintf(exiterror, "Failure to create Context\n");
       exit(0);
@@ -590,6 +711,8 @@ int glutCreateWindow (const char *title)
    InitializeCursor();
    InitializeMenus();
 
+   glutSetWindowTitle(title);
+
    Visible = 1;
    VisibleSwitch = 1;
    Redisplay = 1;
@@ -628,12 +751,21 @@ void glutSwapBuffers(void)
 {
    glFlush();
 
-   if(Visible && DisplayMode & GLUT_DOUBLE) {
-      if(ActiveMenu)
-        DrawMenus();
-      if(MouseEnabled)
-        DrawCursor();
+   if(ActiveMenu)
+      DrawMenus();
+   if(MouseEnabled)
+      DrawCursor();
+
+   if(DisplayMode & GLUT_DOUBLE && Visible) {
+      Swapping = 1;
       glFBDevSwapBuffers(Buffer);
+      Swapping = 0;
+   }
+
+   if(VTSwitch) {
+      if(ioctl(ConsoleFD, VT_ACTIVATE, VTSwitch) < 0)
+        sprintf(exiterror, "Error switching console\n");
+      VTSwitch = 0;
    }
 }
 
@@ -643,6 +775,25 @@ void glutPositionWindow(int x, int y)
 
 void glutReshapeWindow(int width, int height)
 {
+   if(GameMode)
+      return;
+
+   if(!ParseFBModes(width, width, height, height, 0, MAX_VSYNC))
+      return;
+
+   SetVideoMode();
+   CreateBuffer();
+   if(!glFBDevMakeCurrent( Context, Buffer, Buffer )) {
+      sprintf(exiterror, "Failure to Make Current\n");
+      exit(0);
+   }
+
+   InitializeMenus();
+
+   if(ReshapeFunc)
+      ReshapeFunc(VarInfo.xres, VarInfo.yres);
+   Redisplay = 1;
 }
 
 void glutFullScreen(void)
@@ -659,10 +810,12 @@ void glutPushWindow(void)
 
 void glutShowWindow(void)
 {
+   Visible = 1;
 }
 
 void glutHideWindow(void)
 {
+   Visible = 0;
 }
 
 static void UnIconifyWindow(int sig)
@@ -677,6 +830,9 @@ static void UnIconifyWindow(int sig)
              strerror(errno));
       exit(0);
    }
+   Redisplay = 1;
+   VisibleSwitch = 1;
+   Visible = 1;
 }
 
 void glutIconifyWindow(void)
@@ -691,6 +847,9 @@ void glutIconifyWindow(void)
 
 void glutSetWindowTitle(const char *name)
 {
+   /* escape code to set title in screen */
+   if(getenv("TERM") && memcmp(getenv("TERM"), "screen", 6) == 0)
+      printf("\033k%s\033\\", name);
 }
 
 void glutSetIconTitle(const char *name)
index 3407c6e98871019dc1734356926e253c54243df6..f6d6e4044efbb5602fd3ad748b6ef7c8effcf842 100644 (file)
  * Written by Sean D'Epagnier (c) 2006
  */
 
-/* NOTICE: game mode will not be fully implemented until
-   glutReshapeWindow is fully implemented */
-
 #include <stdlib.h>
+#include <string.h>
 
 #include <linux/fb.h>
 
 
 #include "internal.h"
 
-void glutGameModeString(const char *string)
+int GameMode;
+
+static int ModePossible, DispChanged;
+static struct fb_var_screeninfo NormVarInfo, GameVarInfo;
+
+static GLFBDevContextPtr GameContext;
+static GLFBDevVisualPtr NormVisual;
+
+/* storage for non-gamemode callbacks */
+void (*KeyFuncs[2])(unsigned char key, int x, int y);
+static void (*NormFuncs[8])();
+
+static const char*SetOpers(const char *p, unsigned int *min, unsigned int *max)
 {
-   
+   char *endptr;
+   int comp = *p, val, neq = 0;
+
+   if(p[1] == '=') {
+      neq = 0;
+      p++;
+   }
+
+   val = strtol(p+1, &endptr, 10);
+   if(endptr == p+1)
+      return p;
+
+   switch(comp) {
+   case '=':
+      *min = *max = val;
+      break;
+   case '!':
+      *min = val + 1;
+      *max = val - 1;
+      break;
+   case '<':
+      *max = val - neq;
+      break;
+   case '>':
+      *min = val + neq;
+      break;
+   }
+   return endptr;
 }
 
+void glutGameModeString(const char *string)
+{
+   const char *p = string;
+   unsigned int minb = 15, maxb = 32;
+   unsigned int minw = 0, maxw = -1;
+   unsigned int minh, maxh = -1;
+   unsigned int minf = 0, maxf = MAX_VSYNC;
+   char *endptr;
+   int count = -1, val;
+
+   ModePossible = 0;
+
+   if(DisplayMode & GLUT_INDEX)
+      minb = maxb = 8;
+
+ again:
+   count++;
+   if((val = strtol(p, &endptr, 10)) && *endptr=='x') {
+      maxw = minw = val;
+      p = endptr + 1;
+      maxh = minh = strtol(p, &endptr, 10);
+      p = endptr;
+      goto again;
+   }
+
+   if(*p == ':') {
+      minb = strtol(p+1, &endptr, 10);
+      p = endptr;
+      if(DisplayMode & GLUT_INDEX) {
+        if(minb != 8)
+           return;
+      } else
+        if(minb != 15 && minb != 16 && minb != 24 && minb != 32)
+           return;
+      maxb = minb;
+      goto again;
+   }
+
+   if(*p == '@') {
+      minf = strtol(p+1, &endptr, 10) - 5;
+      maxf = minf + 10;
+      p = endptr;
+      goto again;
+   }
+
+   if(count == 0)
+      while(*p) {
+        if(*p == ' ')
+           p++;
+        else
+        if(memcmp(p, "bpp", 3) == 0)
+           p = SetOpers(p+3, &minb, &maxb);
+        else
+        if(memcmp(p, "height", 6) == 0)
+           p = SetOpers(p+6, &minh, &maxh);
+        else
+        if(memcmp(p, "hertz", 5) == 0)
+           p = SetOpers(p+5, &minf, &maxf);
+        else
+        if(memcmp(p, "width", 5) == 0)
+           p = SetOpers(p+5, &minw, &maxw);
+        else
+        if(p = strchr(p, ' '))
+           p++;
+        else
+           break;
+   }
+
+   NormVarInfo = VarInfo;
+   if(!ParseFBModes(minw, maxw, minh, maxh, minf, maxf))
+      return;
+
+   GameVarInfo = VarInfo;
+   VarInfo = NormVarInfo;
+
+   /* determine optimal bitdepth, make sure we have enough video memory */
+   if(VarInfo.bits_per_pixel && VarInfo.bits_per_pixel <= maxb)
+      GameVarInfo.bits_per_pixel = VarInfo.bits_per_pixel;
+   else
+      GameVarInfo.bits_per_pixel = maxb;
+
+   while(FixedInfo.smem_len < GameVarInfo.xres * GameVarInfo.yres
+        * GameVarInfo.bits_per_pixel / 8) {
+      if(GameVarInfo.bits_per_pixel < minb)
+        return;
+      GameVarInfo.bits_per_pixel = ((GameVarInfo.bits_per_pixel+1)/8)*8-8;
+   }
+  
+   ModePossible = 1;
+}
+   
 int glutEnterGameMode(void)
 {
    if(ActiveMenu)
       return 0;
+
+   if(!ModePossible)
+      return 0;
+
+   if(GameMode) {
+      if(!memcmp(&GameVarInfo, &VarInfo, sizeof VarInfo)) {
+        DispChanged = 0;
+        return 1;
+      }
+      glutLeaveGameMode();
+   }
+
+   if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &GameVarInfo))
+      return 0;
+
+   NormVarInfo = VarInfo;
+   VarInfo = GameVarInfo;
+
+   NormVisual = Visual;
+   SetVideoMode();
+   CreateVisual();
+   CreateBuffer();
+
+   if(!(GameContext = glFBDevCreateContext(Visual, NULL))) {
+      sprintf(exiterror, "Failure to create Context\n");
+      exit(0);
+   }
+
+   if(!glFBDevMakeCurrent( GameContext, Buffer, Buffer )) {
+      sprintf(exiterror, "Failure to Make Game Current\n");
+      exit(0);
+   }
+
+   InitializeCursor();
+
+   KeyFuncs[0] = KeyboardFunc;
+   KeyFuncs[1] = KeyboardUpFunc;
+
+   NormFuncs[0] = DisplayFunc;
+   NormFuncs[1] = ReshapeFunc;
+   NormFuncs[2] = MouseFunc;
+   NormFuncs[3] = MotionFunc;
+   NormFuncs[4] = PassiveMotionFunc;
+   NormFuncs[5] = VisibilityFunc;
+   NormFuncs[6] = SpecialFunc;
+   NormFuncs[7] = SpecialUpFunc;
+
+   DisplayFunc = NULL;
+   ReshapeFunc = NULL;
+   KeyboardFunc = NULL;
+   KeyboardUpFunc = NULL;
+   MouseFunc = NULL;
+   MotionFunc = NULL;
+   PassiveMotionFunc = NULL;
+   VisibilityFunc = NULL;
+   SpecialFunc = SpecialUpFunc = NULL;
+
+   DispChanged = 1;
+   GameMode = 1;
+   Visible = 1;
+   VisibleSwitch = 1;
+   Redisplay = 1;
    return 1;
 }
 
 void glutLeaveGameMode(void)
 {
+   if(!GameMode)
+      return;
+
+   glFBDevDestroyContext(GameContext);
+   glFBDevDestroyVisual(Visual);
+
+   VarInfo = NormVarInfo;
+   Visual = NormVisual;
+   
+   if(Visual) {
+      SetVideoMode();
+      CreateBuffer();
+   
+      if(!glFBDevMakeCurrent( Context, Buffer, Buffer )) {
+        sprintf(exiterror, "Failure to Make Current\n");
+        exit(0);
+      }
+      
+      Redisplay = 1;
+   }
+
+   KeyboardFunc = KeyFuncs[0];
+   KeyboardUpFunc = KeyFuncs[1];
+
+
+   DisplayFunc = NormFuncs[0];
+   ReshapeFunc = NormFuncs[1];
+   MouseFunc = NormFuncs[2];
+   MotionFunc = NormFuncs[3];
+   PassiveMotionFunc = NormFuncs[4];
+   VisibilityFunc = NormFuncs[5];
+   SpecialFunc = NormFuncs[6];
+   SpecialUpFunc = NormFuncs[7];
+
+   GameMode = 0;
 }
 
 int glutGameModeGet(GLenum mode) {
    switch(mode) {
    case GLUT_GAME_MODE_ACTIVE:
-      return 1;
+      return GameMode;
    case GLUT_GAME_MODE_POSSIBLE:
-      return 1;
+      return ModePossible;
+   case GLUT_GAME_MODE_DISPLAY_CHANGED:
+      return DispChanged;
+   }
+
+   if(!ModePossible)
+      return -1;
+   
+   switch(mode) {
    case GLUT_GAME_MODE_WIDTH:
-      return VarInfo.xres;
+      return GameVarInfo.xres;
    case GLUT_GAME_MODE_HEIGHT:
-      return VarInfo.yres;
+      return GameVarInfo.yres;
    case GLUT_GAME_MODE_PIXEL_DEPTH:
-      return VarInfo.bits_per_pixel;
+      return GameVarInfo.bits_per_pixel;
    case GLUT_GAME_MODE_REFRESH_RATE:
-      if(VarInfo.pixclock) {
-        int htotal = VarInfo.left_margin + VarInfo.xres
-           + VarInfo.right_margin + VarInfo.hsync_len;
-        int vtotal = VarInfo.upper_margin + VarInfo.yres
-           + VarInfo.lower_margin + VarInfo.vsync_len;
-        return 1E12/VarInfo.pixclock/htotal/vtotal;
-      }
-      return 0;
-   case GLUT_GAME_MODE_DISPLAY_CHANGED:
-      return 0;
+      return 1E12/GameVarInfo.pixclock
+        / (GameVarInfo.left_margin + GameVarInfo.xres
+          + GameVarInfo.right_margin + GameVarInfo.hsync_len)
+        / (GameVarInfo.upper_margin + GameVarInfo.yres 
+          + GameVarInfo.lower_margin + GameVarInfo.vsync_len);
    }
 }
index 7daec8c9143d1a84dae74406edf8fdc7647bd34b..4fbd94d0701c18c30e5968eca19cf6e8910ebd75 100644 (file)
@@ -126,8 +126,11 @@ static void KeyboardHandler(int sig)
    if(!release && labelval >= K_F1 && labelval <= K_F12)
       if(KeyboardModifiers & GLUT_ACTIVE_ALT) {
         /* VT switch, we must do it */
-        if(ioctl(ConsoleFD, VT_ACTIVATE, labelval - K_F1 + 1) < 0)
-           sprintf(exiterror, "Error switching console\n");
+        if(Swapping)
+           VTSwitch = labelval - K_F1 + 1;
+        else
+           if(ioctl(ConsoleFD, VT_ACTIVATE, labelval - K_F1 + 1) < 0)
+              sprintf(exiterror, "Error switching console\n");
         return;
       }
    write(kbdpipe[1], &code, 1);
@@ -456,6 +459,7 @@ static int ReadMouse(void)
            PassiveMotionFunc(MouseX, MouseY);
 
       EraseCursor();
+
       if(ActiveMenu)
         Redisplay = 1;
       else
@@ -515,14 +519,17 @@ void InitializeVT(int usestdin)
    struct vt_mode vt;
    char console[128];
 
-   /* terminos settings for straight-through mode */
+   signal(SIGIO, SIG_IGN);
+
+   /* save old terminos settings */
    if (tcgetattr(0, &OldTermios) < 0) {
       sprintf(exiterror, "tcgetattr failed\n");
       exit(0);
    }
 
    tio = OldTermios;
-  
+
+   /* terminos settings for straight-through mode */  
    tio.c_lflag &= ~(ICANON | ECHO  | ISIG);
    tio.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
    tio.c_iflag |= IGNBRK;
@@ -607,8 +614,8 @@ void InitializeVT(int usestdin)
    }
 
    /* use SIGIO so VT switching can work if the program is locked */
-   if(ConsoleFD)
    signal(SIGIO, KeyboardHandler);
+
    pipe(kbdpipe);
 
    if(fcntl(kbdpipe[0], F_SETFL, O_NONBLOCK | O_ASYNC) < 0) {
@@ -642,64 +649,63 @@ void InitializeVT(int usestdin)
 
 void RestoreVT(void)
 {
-   if(ConsoleFD >= 0)
-      if (tcsetattr(0, TCSANOW, &OldTermios) < 0)
-        fprintf(stderr, "tcsetattr failed\n");
+   if(ConsoleFD < 0)
+      return;
 
-   if(ConsoleFD > 0) {
-      /* restore keyboard state */
-      if (ioctl(ConsoleFD, VT_SETMODE, &OldVTMode) < 0)
-        fprintf(stderr, "Failed to set vtmode\n");
+   if (tcsetattr(0, TCSANOW, &OldTermios) < 0)
+      fprintf(stderr, "tcsetattr failed\n");
 
-      if (ioctl(ConsoleFD, KDSKBMODE, OldKDMode) < 0)
-        fprintf(stderr, "ioctl KDSKBMODE failed!\n");
+   if(ConsoleFD == 0)
+       return;
 
-      /* if we were in text mode, switching to graphics and back restores
-        the colormap */
-      if(ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0)
-        fprintf(stderr, "ioctl KDSETMODE failed!\n");
+   /* restore keyboard state */
+   if (ioctl(ConsoleFD, VT_SETMODE, &OldVTMode) < 0)
+      fprintf(stderr, "Failed to set vtmode\n");
 
-      if(ioctl(ConsoleFD, KDSETMODE, OldMode) < 0)
-        fprintf(stderr, "ioctl KDSETMODE failed!\n");
+   if (ioctl(ConsoleFD, KDSKBMODE, OldKDMode) < 0)
+      fprintf(stderr, "ioctl KDSKBMODE failed!\n");
 
-      close(ConsoleFD);
-   }
+   if(ioctl(ConsoleFD, KDSETMODE, OldMode) < 0)
+      fprintf(stderr, "ioctl KDSETMODE failed!\n");
+   
+   close(ConsoleFD);
 }
 
 void InitializeMouse(void)
 {
 #ifdef HAVE_GPM
-   if(GpmMouse) {
+   if(!GpmMouse)
+#endif
+   {
+      const char *mousedev = getenv("MOUSE");
+      if(!mousedev)
+        mousedev = MOUSEDEV;
+      if((MouseFD = open(mousedev, O_RDONLY)) >= 0) {
+        if(!MouseSpeed)
+           MouseSpeed = 1;
+        NumMouseButtons = 3;
+        return;
+      }
+   }
+#ifdef HAVE_GPM
+   {
       Gpm_Connect conn;  
       int c;
       conn.eventMask  = ~0;   /* Want to know about all the events */
       conn.defaultMask = 0;   /* don't handle anything by default  */
       conn.minMod     = 0;    /* want everything                   */
       conn.maxMod     = ~0;   /* all modifiers included            */
-      if(Gpm_Open(&conn, 0) == -1) {
-        fprintf(stderr, "Cannot open gpmctl. Continuing without Mouse\n");
+      if(Gpm_Open(&conn, 0) != -1) {
+        if(!MouseSpeed)
+           MouseSpeed = 8;
+        NumMouseButtons = 3;
         return;
       }
-       
-      if(!MouseSpeed)
-        MouseSpeed = 5;
-   } else
+      fprintf(stderr, "Cannot open gpmctl.\n");
+   }
 #endif
-      {
-        const char *mousedev = getenv("MOUSE");
-        if(!mousedev)
-           mousedev = MOUSEDEV;
-        if((MouseFD = open(mousedev, O_RDONLY)) < 0) {
-           fprintf(stderr,"Cannot open %s.\n"
-                   "Continuing without Mouse\n", MOUSEDEV);
-           return;
-        }
-
-        if(!MouseSpeed)
-           MouseSpeed = 1;
-      }
-
-   NumMouseButtons = 3;
+   fprintf(stderr,"Cannot open %s.\n"
+          "Continuing without Mouse\n", MOUSEDEV);
 }
 
 void CloseMouse(void)
index ca5dc1a6397f3f4dc56e35e5fe7d53be40adb0bb..082cd4f6f3a1f40dc0223d19d05428437819415d 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <sys/time.h>
 #include <linux/fb.h>
+#include <GL/glfbdev.h>
 
 #define MULTIHEAD   /* enable multihead hacks,
                       it allows the program to continue drawing
                       screen corruption that requires C-l to fix */
 #define HAVE_GPM
 
+#define MAX_VSYNC 200
+
 /* this causes these symbols to not be exported */
 #pragma GCC visibility push(hidden)
 
+
+/* --------- fbdev ------------ */
 extern int Redisplay;
 extern int Visible;
 extern int VisibleSwitch;
 extern int Active;
 extern int VisiblePoll;
+extern int Swapping, VTSwitch;
 
 void TestVisible(void);
+int ParseFBModes(int, int, int, int, int, int);
+void CreateVisual(void);
 
 extern int FrameBufferFD;
 extern unsigned char *FrameBuffer;
@@ -53,7 +61,11 @@ extern int DisplayMode;
 extern char exiterror[256];
 
 extern struct fb_fix_screeninfo FixedInfo;
-extern struct fb_var_screeninfo VarInfo, OrigVarInfo;
+extern struct fb_var_screeninfo VarInfo;
+
+extern GLFBDevContextPtr Context;
+extern GLFBDevBufferPtr Buffer;
+extern GLFBDevVisualPtr Visual;
 
 /* --- colormap --- */
 #define REVERSECMAPSIZELOG 3
@@ -65,6 +77,7 @@ extern unsigned short RedColorMap[256],
 extern unsigned char ReverseColorMap[REVERSECMAPSIZE]
                                     [REVERSECMAPSIZE]
                                     [REVERSECMAPSIZE];
+void LoadOldColorMap(void);
 void LoadColorMap(void);
 void UnloadColorMap(void);
 void RestoreColorMap(void);
@@ -108,7 +121,7 @@ void OpenMenu(void);
 void CloseMenu(void);
 
 /* --- state --- */
-extern int AccumSize, DepthSize, StencilSize;
+extern int AccumSize, DepthSize, StencilSize, NumSamples;
 extern struct timeval StartTime;
 extern int KeyboardModifiers;
 
@@ -156,4 +169,7 @@ struct GlutTimer {
 
 extern struct GlutTimer *GlutTimers;
 
+/* ------- Game Mode -------- */
+extern int GameMode;
+
 #pragma GCC visibility pop
index 8ac0ed39879bf118c5341f7cac90d9a45c4791e7..f5a5ef754345db5ca8b9437d4160665bd715459e 100644 (file)
@@ -42,7 +42,6 @@ int ActiveMenu;
 int CurrentMenu;
 
 static double MenuProjection[16];
-static double MenuModelview[16];
 
 static int AttachedMenus[3];
 static int NumMenus = 1;
@@ -55,14 +54,8 @@ void InitializeMenus(void)
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0.0, VarInfo.xres, VarInfo.yres, 0.0);
-   glMatrixMode(GL_MODELVIEW);
-   glPushMatrix();
-   glLoadIdentity();
-   glViewport(0, 0, VarInfo.xres, VarInfo.yres);
    glGetDoublev(GL_PROJECTION_MATRIX, MenuProjection);
-   glGetDoublev(GL_MODELVIEW_MATRIX, MenuModelview);
-   glPopMatrix();
-   glMatrixMode(GL_PROJECTION);
+
    glPopMatrix();
    glPopAttrib();
 }
@@ -72,7 +65,7 @@ void FreeMenus(void)
    int i, j;
        
    for(i = 1; i<NumMenus; i++) {
-      for(j = 1; i<Menus[i].NumItems; j++)
+      for(j = 0; j<Menus[i].NumItems; j++)
         free(Menus[i].Items[j].name);
       free(Menus[i].Items);
    }
@@ -101,9 +94,10 @@ static int DrawMenu(int menu, int x, int *y)
 {
    int i;
    int ret = 1;
+
    for(i=0; i < Menus[menu].NumItems; i++) {
       char *s = Menus[menu].Items[i].name;
-      int a =0;
+      int a = 0;
       if(MouseY >= *y && MouseY < *y + MENU_FONT_HEIGHT &&
         MouseX >= x && MouseX < x + Menus[menu].width) {
         a = 1;
@@ -133,18 +127,26 @@ static int DrawMenu(int menu, int x, int *y)
 
 void DrawMenus(void)
 {
-   int x = Menus[ActiveMenu].x;
-   int y = Menus[ActiveMenu].y;
+   int x, y;
+
+   if(GameMode)
+      return;
+
+   x = Menus[ActiveMenu].x;
+   y = Menus[ActiveMenu].y;
 
    /* save old settings */
-   glPushAttrib(-1);
+   glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT
+               | GL_ENABLE_BIT | GL_VIEWPORT_BIT);
 
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
-   glLoadMatrixd(MenuModelview);
+   glLoadIdentity();
+
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadMatrixd(MenuProjection);
+   glViewport(0, 0, VarInfo.xres, VarInfo.yres);
 
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_ALPHA_TEST);
@@ -153,7 +155,7 @@ void DrawMenus(void)
    glDisable(GL_TEXTURE_2D);
    glEnable(GL_COLOR_LOGIC_OP);
    glLogicOp(GL_AND_REVERSE);
-    
+
    if(DrawMenu(ActiveMenu, x, &y))
       Menus[ActiveMenu].selected = -1;
     
@@ -171,8 +173,14 @@ void OpenMenu(void)
       MenuStatusFunc(GLUT_MENU_IN_USE, MouseX, MouseY);
    if(MenuStateFunc)
       MenuStateFunc(GLUT_MENU_IN_USE);
-   Menus[ActiveMenu].x = MouseX - Menus[ActiveMenu].width/2;
-   Menus[ActiveMenu].y = MouseY - Menus[ActiveMenu].NumItems*MENU_FONT_HEIGHT/2;
+   Menus[ActiveMenu].x = MouseX-Menus[ActiveMenu].width/2;
+
+   if(Menus[ActiveMenu].x < 0)
+      Menus[ActiveMenu].x = 0;
+   if(Menus[ActiveMenu].x + Menus[ActiveMenu].width >= VarInfo.xres)
+     Menus[ActiveMenu].x = VarInfo.xres - Menus[ActiveMenu].width - 1;
+
+   Menus[ActiveMenu].y = MouseY-Menus[ActiveMenu].NumItems*MENU_FONT_HEIGHT/2;
    Menus[ActiveMenu].selected = -1;
 }
 
index dadd2ad7200036dff9d701ea29de40ab53bf23b7..bca675c52c48acddb5b332c19ae01550771151d9 100644 (file)
@@ -37,6 +37,7 @@
 int AccumSize = 16; /* per channel size of accumulation buffer */
 int DepthSize = DEFAULT_SOFTWARE_DEPTH_BITS;
 int StencilSize = STENCIL_BITS;
+int NumSamples = 4;
 
 int glutGet(GLenum state)
 {
@@ -89,7 +90,7 @@ int glutGet(GLenum state)
         return 256;
       return 0;
    case GLUT_WINDOW_NUM_SAMPLES:
-      return 0;
+      return NumSamples;
    case GLUT_WINDOW_STEREO:
       return 0;
    case GLUT_WINDOW_CURSOR:
@@ -174,16 +175,6 @@ int glutDeviceGet(GLenum info)
    return -1;
 }
 
-int glutVideoResizeGet(GLenum param)
-{
-   switch(param) {
-   case GLUT_VIDEO_RESIZE_POSSIBLE:
-      return 0;
-      
-   }
-   return -1;
-}
-
 int glutGetModifiers(void){
    return KeyboardModifiers;
 }
diff --git a/src/glut/fbdev/vidresize.c b/src/glut/fbdev/vidresize.c
new file mode 100644 (file)
index 0000000..960b018
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ * Copyright (C) 1995-2006  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Library for glut using mesa fbdev driver
+ *
+ * Written by Sean D'Epagnier (c) 2006
+ */
+
+/* Notice, if you know how to implement these functions correctly
+   please proceed */
+
+#include <stdlib.h>
+
+#include <GL/glut.h>
+
+#include "internal.h"
+
+int glutVideoResizeGet(GLenum param)
+{
+   return 0;
+}
+
+void glutSetupVideoResizing(void)
+{
+}
+
+void glutStopVideoResizing(void)
+{
+}
+
+void glutVideoResize(int x, int y, int width, int height)
+{
+}
+
+void glutVideoPan(int x, int y, int width, int height)
+{
+}
index 412c09955f8f6effe950c184f7c277421c8b3df5..21b6165bb14e31dee6e8946599211799dcf01c86 100644 (file)
@@ -281,7 +281,7 @@ glFBDevGetString( int str )
    case GLFBDEV_VENDOR:
       return "Mesa Project";
    case GLFBDEV_VERSION:
-      return "1.0.0";
+      return "1.0.1";
    default:
       return NULL;
    }
@@ -372,6 +372,10 @@ glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
       case GLFBDEV_LEVEL:
          /* ignored for now */
          break;
+      case GLFBDEV_MULTISAMPLE:
+        numSamples = attrib[1];
+        attrib++;
+         break;
       default:
          /* unexpected token */
          _mesa_free(vis);
@@ -420,13 +424,6 @@ glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
       }
       else {
          _mesa_problem(NULL, "Unsupported fbdev RGB visual/bitdepth!\n");
-         /*
-         printf("fixInfo->visual = 0x%x\n", fixInfo->visual);
-         printf("varInfo->bits_per_pixel = %d\n", varInfo->bits_per_pixel);
-         printf("varInfo->red.offset = %d\n", varInfo->red.offset);
-         printf("varInfo->green.offset = %d\n", varInfo->green.offset);
-         printf("varInfo->blue.offset = %d\n", varInfo->blue.offset);
-         */
          _mesa_free(vis);
          return NULL;
       }
@@ -586,7 +583,6 @@ new_glfbdev_renderbuffer(void *bufferStart, const GLFBDevVisualPtr visual)
    return rb;
 }
 
-
 GLFBDevBufferPtr
 glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
                      const struct fb_var_screeninfo *varInfo,
@@ -600,6 +596,11 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
    ASSERT(frontBuffer);
    ASSERT(size > 0);
 
+   /* this is to update the visual if there was a resize and the
+      buffer is created again */
+   visual->var = *varInfo;
+   visual->fix = *fixInfo;
+
    if (visual->fix.visual != fixInfo->visual ||
        visual->fix.type != fixInfo->type ||
        visual->var.bits_per_pixel != varInfo->bits_per_pixel ||
@@ -624,7 +625,21 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
                           &frontrb->Base);
    /* add back renderbuffer */
    if (visual->glvisual.doubleBufferMode) {
+      int malloced = !backBuffer;
+      if (malloced) {
+         /* malloc a back buffer */
+         backBuffer = _mesa_malloc(size);
+         if (!backBuffer) {
+            _mesa_free_framebuffer_data(&buf->glframebuffer);
+            _mesa_free(buf);
+            return NULL;
+         }
+      }
+
       backrb = new_glfbdev_renderbuffer(backBuffer, visual);
+      if(malloced)
+        backrb->mallocedBuffer = GL_TRUE;
+
       _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT,
                              &backrb->Base);
    }
@@ -637,32 +652,12 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
                                 GL_FALSE, /* alpha */
                                 GL_FALSE /* aux bufs */);
 
-
-
    buf->fix = *fixInfo;   /* struct assignment */
    buf->var = *varInfo;   /* struct assignment */
    buf->visual = visual;  /* ptr assignment */
    buf->size = size;
    buf->bytesPerPixel = visual->var.bits_per_pixel / 8;
 
-   if (visual->glvisual.doubleBufferMode) {
-      if (!backBuffer) {
-         /* malloc a back buffer */
-         backrb->Base.Data = _mesa_malloc(size);
-         if (!backrb->Base.Data) {
-            _mesa_free_framebuffer_data(&buf->glframebuffer);
-            _mesa_free(buf);
-            return NULL;
-         }
-         backrb->mallocedBuffer = GL_TRUE;
-      }
-   }
-   /* this causes segfault:
-   else {
-      backrb->bottom = NULL;
-      backrb->rowStride = 0;
-      }*/
-
    return buf;
 }