summaryrefslogtreecommitdiffstats
path: root/src/glut/fbdev/gamemode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glut/fbdev/gamemode.c')
-rw-r--r--src/glut/fbdev/gamemode.c306
1 files changed, 306 insertions, 0 deletions
diff --git a/src/glut/fbdev/gamemode.c b/src/glut/fbdev/gamemode.c
new file mode 100644
index 00000000000..f6d6e4044ef
--- /dev/null
+++ b/src/glut/fbdev/gamemode.c
@@ -0,0 +1,306 @@
+/*
+ * 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
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <linux/fb.h>
+
+#include <GL/glut.h>
+
+#include "internal.h"
+
+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 GameMode;
+ case GLUT_GAME_MODE_POSSIBLE:
+ return ModePossible;
+ case GLUT_GAME_MODE_DISPLAY_CHANGED:
+ return DispChanged;
+ }
+
+ if(!ModePossible)
+ return -1;
+
+ switch(mode) {
+ case GLUT_GAME_MODE_WIDTH:
+ return GameVarInfo.xres;
+ case GLUT_GAME_MODE_HEIGHT:
+ return GameVarInfo.yres;
+ case GLUT_GAME_MODE_PIXEL_DEPTH:
+ return GameVarInfo.bits_per_pixel;
+ case GLUT_GAME_MODE_REFRESH_RATE:
+ 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);
+ }
+}