summaryrefslogtreecommitdiff
path: root/src/glut/fbdev/gamemode.c
diff options
context:
space:
mode:
authorSean D'Epagnier <geckosenator@freedesktop.org>2006-08-10 10:21:17 +0000
committerSean D'Epagnier <geckosenator@freedesktop.org>2006-08-10 10:21:17 +0000
commit7196cddb3a404292858101f9cd1a5061e422d2c1 (patch)
treeaa3f79e21b08d9f114c7b1984e6c86c114081cfe /src/glut/fbdev/gamemode.c
parent54e15d65858c1d1eeea7291059766686cf2e1671 (diff)
Added initial multisampling support to glfbdev driver.
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
Diffstat (limited to 'src/glut/fbdev/gamemode.c')
-rw-r--r--src/glut/fbdev/gamemode.c268
1 files changed, 248 insertions, 20 deletions
diff --git a/src/glut/fbdev/gamemode.c b/src/glut/fbdev/gamemode.c
index 3407c6e988..f6d6e4044e 100644
--- a/src/glut/fbdev/gamemode.c
+++ b/src/glut/fbdev/gamemode.c
@@ -24,10 +24,8 @@
* 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>
@@ -35,44 +33,274 @@
#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);
}
}