|
|
4d65c64 |
--- plib-1.8.4/src/pw/pw.h.fs 2004-04-07 01:45:19.000000000 +0200
|
|
|
4d65c64 |
+++ plib-1.8.4/src/pw/pw.h 2006-05-17 16:03:09.000000000 +0200
|
|
|
4d65c64 |
@@ -54,6 +54,11 @@
|
|
|
4d65c64 |
void pwSetCursor ( int c ) ;
|
|
|
4d65c64 |
void pwCleanup () ;
|
|
|
4d65c64 |
void pwSetAutoRepeatKey ( bool enable ) ;
|
|
|
4d65c64 |
+void pwSetResizable ( bool enable ) ;
|
|
|
4d65c64 |
+void pwSetCursorEx ( int wm, int fs ) ;
|
|
|
4d65c64 |
+void pwSetFullscreen () ;
|
|
|
4d65c64 |
+void pwSetWindowed () ;
|
|
|
4d65c64 |
+void pwToggleFullscreen () ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
#define PW_CURSOR_NONE 0
|
|
|
4d65c64 |
#define PW_CURSOR_RIGHT 1
|
|
|
4d65c64 |
--- plib-1.8.4/src/pw/pwX11.cxx.fs 2004-04-07 01:45:19.000000000 +0200
|
|
|
4d65c64 |
+++ plib-1.8.4/src/pw/pwX11.cxx 2006-05-17 16:06:07.000000000 +0200
|
|
|
4d65c64 |
@@ -74,14 +74,31 @@
|
|
|
4d65c64 |
|
|
|
4d65c64 |
#endif
|
|
|
4d65c64 |
|
|
|
4d65c64 |
-static bool initialised = false ;
|
|
|
4d65c64 |
+/* For XF86VIDMODE Support */
|
|
|
4d65c64 |
+#ifdef XF86VIDMODE
|
|
|
4d65c64 |
+#include <X11/extensions/xf86vmode.h>
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+static struct xf86vidmode_data {
|
|
|
4d65c64 |
+ int vidmode_available;
|
|
|
4d65c64 |
+ XF86VidModeModeInfo orig_mode;
|
|
|
4d65c64 |
+ int orig_viewport_x;
|
|
|
4d65c64 |
+ int orig_viewport_y;
|
|
|
4d65c64 |
+} XF86VidModeData = { 1, { 0 }, 0, 0 };
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+static void xf86_vidmode_init () ;
|
|
|
4d65c64 |
+#endif
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
static bool insideCallback = false ;
|
|
|
4d65c64 |
+static bool resizable = true;
|
|
|
4d65c64 |
+static bool mouse_grabbed = false;
|
|
|
4d65c64 |
+static bool keyb_grabbed = false;
|
|
|
4d65c64 |
static int modifiers = 0 ;
|
|
|
4d65c64 |
static int origin [2] = { 0, 0 } ;
|
|
|
4d65c64 |
static int size [2] = { 640, 480 } ;
|
|
|
4d65c64 |
static int currScreen = 0 ;
|
|
|
4d65c64 |
static int currConnect = 0 ;
|
|
|
4d65c64 |
-static int currCursor = PW_CURSOR_LEFT ;
|
|
|
4d65c64 |
+static int wmCursor = PW_CURSOR_LEFT ;
|
|
|
4d65c64 |
+static int fsCursor = PW_CURSOR_LEFT ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
static pwResizeCB *resizeCB = NULL ;
|
|
|
4d65c64 |
static pwExitCB *exitCB = NULL ;
|
|
|
4d65c64 |
@@ -92,12 +110,17 @@
|
|
|
4d65c64 |
static Display *currDisplay = NULL ;
|
|
|
4d65c64 |
static XVisualInfo *visualInfo = NULL ;
|
|
|
4d65c64 |
static Window currHandle ;
|
|
|
4d65c64 |
+static Window wmWindow ;
|
|
|
4d65c64 |
+static Window fsWindow = None ;
|
|
|
4d65c64 |
static GLXContext currContext ;
|
|
|
4d65c64 |
static Window rootWindow ;
|
|
|
4d65c64 |
static Atom delWinAtom ;
|
|
|
4d65c64 |
+static XTextProperty *titlePropertyPtr = NULL;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
static bool autoRepeat = false ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
+static void getEvents ();
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
void pwSetAutoRepeatKey ( bool enable )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
autoRepeat = enable ;
|
|
|
4d65c64 |
@@ -181,6 +204,41 @@
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|
|
|
4d65c64 |
+static void pwRealSetResizable ( bool enable, int width, int height )
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ XSizeHints sizeHints ;
|
|
|
4d65c64 |
+ XWMHints wmHints ;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ resizable = enable;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if (resizable)
|
|
|
4d65c64 |
+ sizeHints.flags = USSize;
|
|
|
4d65c64 |
+ else
|
|
|
4d65c64 |
+ sizeHints.flags = PSize | PMinSize | PMaxSize;;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if ( origin[0] >= 0 && origin[1] >= 0 )
|
|
|
4d65c64 |
+ sizeHints.flags |= USPosition ;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ sizeHints.x = origin[0] ;
|
|
|
4d65c64 |
+ sizeHints.y = origin[1] ;
|
|
|
4d65c64 |
+ sizeHints.width = width ;
|
|
|
4d65c64 |
+ sizeHints.height = height ;
|
|
|
4d65c64 |
+ sizeHints.min_width = width ;
|
|
|
4d65c64 |
+ sizeHints.min_height = height ;
|
|
|
4d65c64 |
+ sizeHints.base_width = width ;
|
|
|
4d65c64 |
+ sizeHints.base_height = height ;
|
|
|
4d65c64 |
+ sizeHints.max_width = width ;
|
|
|
4d65c64 |
+ sizeHints.max_height = height ;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ wmHints.flags = StateHint;
|
|
|
4d65c64 |
+ wmHints.initial_state = NormalState ;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ XSetWMProperties ( currDisplay, wmWindow,
|
|
|
4d65c64 |
+ titlePropertyPtr, titlePropertyPtr, 0, 0,
|
|
|
4d65c64 |
+ &sizeHints, &wmHints, NULL ) ;
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
void pwInit ( int multisample, int num_samples )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
pwInit ( 0, 0, -1, -1, multisample, "NoName", FALSE, num_samples ) ;
|
|
|
4d65c64 |
@@ -191,7 +249,7 @@
|
|
|
4d65c64 |
pwMousePosFunc *mp, pwResizeCB *rcb,
|
|
|
4d65c64 |
pwExitCB *ecb )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
- if ( ! initialised )
|
|
|
4d65c64 |
+ if ( ! currDisplay )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
fprintf ( stderr, "PW: You must not call pwSetCallbacks before pwInit.\n");
|
|
|
4d65c64 |
exit ( 1 ) ;
|
|
|
4d65c64 |
@@ -228,6 +286,7 @@
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
fprintf ( stderr, "PW: GLX extension not available on display '%s'?!?",
|
|
|
4d65c64 |
XDisplayName ( displayName ) ) ;
|
|
|
4d65c64 |
+ XCloseDisplay ( currDisplay ) ;
|
|
|
4d65c64 |
exit ( 1 ) ;
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
@@ -235,6 +294,11 @@
|
|
|
4d65c64 |
rootWindow = RootWindow ( currDisplay, currScreen ) ;
|
|
|
4d65c64 |
currConnect = ConnectionNumber ( currDisplay ) ;
|
|
|
4d65c64 |
delWinAtom = XInternAtom ( currDisplay, "WM_DELETE_WINDOW", 0 ) ;
|
|
|
4d65c64 |
+ fsWindow = None;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+#ifdef XF86VIDMODE
|
|
|
4d65c64 |
+ xf86_vidmode_init () ;
|
|
|
4d65c64 |
+#endif
|
|
|
4d65c64 |
|
|
|
4d65c64 |
if ( w == -1 ) w = DisplayWidth ( currDisplay, currScreen ) ;
|
|
|
4d65c64 |
if ( h == -1 ) h = DisplayHeight ( currDisplay, currScreen ) ;
|
|
|
4d65c64 |
@@ -244,10 +308,8 @@
|
|
|
4d65c64 |
size [ 0 ] = w ;
|
|
|
4d65c64 |
size [ 1 ] = h ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
+ static XTextProperty titleProperty ;
|
|
|
4d65c64 |
XSetWindowAttributes attribs ;
|
|
|
4d65c64 |
- XTextProperty textProperty ;
|
|
|
4d65c64 |
- XSizeHints sizeHints ;
|
|
|
4d65c64 |
- XWMHints wmHints ;
|
|
|
4d65c64 |
unsigned int mask ;
|
|
|
4d65c64 |
PixelFormat pf ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
@@ -280,6 +342,7 @@
|
|
|
4d65c64 |
if ( visualInfo == NULL )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
fprintf ( stderr, "PW: Unable to open a suitable graphics window,\n" ) ;
|
|
|
4d65c64 |
+ XCloseDisplay ( currDisplay ) ;
|
|
|
4d65c64 |
exit ( 1 ) ;
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
@@ -300,7 +363,12 @@
|
|
|
4d65c64 |
|
|
|
4d65c64 |
mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
- currHandle = XCreateWindow ( currDisplay, rootWindow,
|
|
|
4d65c64 |
+ wmWindow = XCreateWindow ( currDisplay, rootWindow,
|
|
|
4d65c64 |
+ x, y, w, h, 0, visualInfo->depth,
|
|
|
4d65c64 |
+ InputOutput, visualInfo->visual,
|
|
|
4d65c64 |
+ mask, &attribs ) ;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ currHandle = XCreateWindow ( currDisplay, wmWindow,
|
|
|
4d65c64 |
x, y, w, h, 0, visualInfo->depth,
|
|
|
4d65c64 |
InputOutput, visualInfo->visual,
|
|
|
4d65c64 |
mask, &attribs ) ;
|
|
|
4d65c64 |
@@ -315,19 +383,6 @@
|
|
|
4d65c64 |
fprintf ( stderr,"PW: That may be bad for performance." ) ;
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
- sizeHints.flags = 0 ;
|
|
|
4d65c64 |
-
|
|
|
4d65c64 |
- if ( x >= 0 && y >= 0 )
|
|
|
4d65c64 |
- sizeHints.flags |= USPosition ;
|
|
|
4d65c64 |
-
|
|
|
4d65c64 |
- sizeHints.flags |= USSize ;
|
|
|
4d65c64 |
-
|
|
|
4d65c64 |
- sizeHints.x = x ; sizeHints.y = y ;
|
|
|
4d65c64 |
- sizeHints.width = w ; sizeHints.height = h ;
|
|
|
4d65c64 |
-
|
|
|
4d65c64 |
- wmHints.flags = StateHint;
|
|
|
4d65c64 |
- wmHints.initial_state = NormalState ;
|
|
|
4d65c64 |
-
|
|
|
4d65c64 |
PropMotifWmHints hints ;
|
|
|
4d65c64 |
Atom prop_t ;
|
|
|
4d65c64 |
Atom prop ;
|
|
|
4d65c64 |
@@ -338,17 +393,17 @@
|
|
|
4d65c64 |
prop_t = prop = XInternAtom ( currDisplay, "_MOTIF_WM_HINTS", True ) ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
if ( prop != 0 )
|
|
|
4d65c64 |
- XChangeProperty ( currDisplay, currHandle, prop, prop_t, 32,
|
|
|
4d65c64 |
+ XChangeProperty ( currDisplay, wmWindow, prop, prop_t, 32,
|
|
|
4d65c64 |
PropModeReplace, (unsigned char *) &hints,
|
|
|
4d65c64 |
PROP_MOTIF_WM_HINTS_ELEMENTS) ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
- XStringListToTextProperty ( (char **) &title, 1, &textProperty ) ;
|
|
|
4d65c64 |
+ if (XStringListToTextProperty ( (char **) &title, 1, &titleProperty ) )
|
|
|
4d65c64 |
+ titlePropertyPtr = &titleProperty;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
- XSetWMProperties ( currDisplay, currHandle,
|
|
|
4d65c64 |
- &textProperty, &textProperty, 0, 0,
|
|
|
4d65c64 |
- &sizeHints, &wmHints, NULL ) ;
|
|
|
4d65c64 |
- XSetWMProtocols ( currDisplay, currHandle, &delWinAtom , 1 );
|
|
|
4d65c64 |
+ pwRealSetResizable ( true, w, h );
|
|
|
4d65c64 |
+ XSetWMProtocols ( currDisplay, wmWindow, &delWinAtom , 1 );
|
|
|
4d65c64 |
XMapWindow ( currDisplay, currHandle ) ;
|
|
|
4d65c64 |
+ XMapWindow ( currDisplay, wmWindow ) ;
|
|
|
4d65c64 |
glXMakeCurrent ( currDisplay, currHandle, currContext ) ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
pwSetCursor ( PW_CURSOR_LEFT ) ;
|
|
|
4d65c64 |
@@ -357,13 +412,14 @@
|
|
|
4d65c64 |
glHint ( GL_MULTISAMPLE_FILTER_HINT_NV, multisample ) ;
|
|
|
4d65c64 |
#endif
|
|
|
4d65c64 |
|
|
|
4d65c64 |
+ atexit( pwCleanup ) ;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
kbCB = NULL ;
|
|
|
4d65c64 |
msCB = NULL ;
|
|
|
4d65c64 |
mpCB = NULL ;
|
|
|
4d65c64 |
resizeCB = NULL ;
|
|
|
4d65c64 |
exitCB = defaultExitFunc ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
- initialised = true ;
|
|
|
4d65c64 |
insideCallback = false ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
glClear ( GL_COLOR_BUFFER_BIT ) ;
|
|
|
4d65c64 |
@@ -373,6 +429,14 @@
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|
|
|
4d65c64 |
+void pwSetResizable ( bool enable )
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ /* Make sure we get any last resize events before doing this */
|
|
|
4d65c64 |
+ getEvents();
|
|
|
4d65c64 |
+ pwRealSetResizable ( enable, size[0], size[1] ) ;
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
void pwGetSize ( int *w, int *h )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
if ( w ) *w = size[0] ;
|
|
|
4d65c64 |
@@ -380,17 +444,19 @@
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|
|
|
4d65c64 |
-void pwSetCursor ( int c )
|
|
|
4d65c64 |
+void pwRealSetCursor ( int c )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
+ int newCursor;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
switch ( c )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
- case PW_CURSOR_RIGHT : currCursor = XC_right_ptr ; break ;
|
|
|
4d65c64 |
- case PW_CURSOR_LEFT : currCursor = XC_left_ptr ; break ;
|
|
|
4d65c64 |
- case PW_CURSOR_QUERY : currCursor = XC_question_arrow ; break ;
|
|
|
4d65c64 |
- case PW_CURSOR_AIM : currCursor = XC_target ; break ;
|
|
|
4d65c64 |
- case PW_CURSOR_CIRCLE : currCursor = XC_circle ; break ;
|
|
|
4d65c64 |
- case PW_CURSOR_WAIT : currCursor = XC_watch ; break ;
|
|
|
4d65c64 |
- case PW_CURSOR_CROSS : currCursor = XC_crosshair ; break ;
|
|
|
4d65c64 |
+ case PW_CURSOR_RIGHT : newCursor = XC_right_ptr ; break ;
|
|
|
4d65c64 |
+ case PW_CURSOR_LEFT : newCursor = XC_left_ptr ; break ;
|
|
|
4d65c64 |
+ case PW_CURSOR_QUERY : newCursor = XC_question_arrow ; break ;
|
|
|
4d65c64 |
+ case PW_CURSOR_AIM : newCursor = XC_target ; break ;
|
|
|
4d65c64 |
+ case PW_CURSOR_CIRCLE : newCursor = XC_circle ; break ;
|
|
|
4d65c64 |
+ case PW_CURSOR_WAIT : newCursor = XC_watch ; break ;
|
|
|
4d65c64 |
+ case PW_CURSOR_CROSS : newCursor = XC_crosshair ; break ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
case PW_CURSOR_NONE :
|
|
|
4d65c64 |
default:
|
|
|
4d65c64 |
@@ -406,36 +472,231 @@
|
|
|
4d65c64 |
XCreatePixmapCursor ( currDisplay,
|
|
|
4d65c64 |
pix, pix, &bcol, &bcol, 0, 0 ) ) ;
|
|
|
4d65c64 |
XFreePixmap ( currDisplay, pix ) ;
|
|
|
4d65c64 |
-
|
|
|
4d65c64 |
- currCursor = 0 ;
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
return ;
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
XDefineCursor( currDisplay, currHandle,
|
|
|
4d65c64 |
- XCreateFontCursor ( currDisplay, currCursor ) ) ;
|
|
|
4d65c64 |
+ XCreateFontCursor ( currDisplay, newCursor ) ) ;
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|
|
|
4d65c64 |
-void pwSetSize ( int w, int h )
|
|
|
4d65c64 |
+void pwSetCursor ( int c )
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ pwRealSetCursor (c);
|
|
|
4d65c64 |
+ wmCursor = c;
|
|
|
4d65c64 |
+ fsCursor = c;
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+void pwSetCursorEx ( int wm, int fs )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
+ if (fsWindow == None)
|
|
|
4d65c64 |
+ pwRealSetCursor (wm);
|
|
|
4d65c64 |
+ else
|
|
|
4d65c64 |
+ pwRealSetCursor (fs);
|
|
|
4d65c64 |
+ wmCursor = wm;
|
|
|
4d65c64 |
+ fsCursor = fs;
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+#ifdef XF86VIDMODE
|
|
|
4d65c64 |
+static void
|
|
|
4d65c64 |
+xf86_vidmode_init ( void )
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ int i,j;
|
|
|
4d65c64 |
+ XF86VidModeModeLine *l = (XF86VidModeModeLine *)((char *)
|
|
|
4d65c64 |
+ &XF86VidModeData.orig_mode + sizeof XF86VidModeData.orig_mode.dotclock);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if (!XF86VidModeQueryVersion(currDisplay, &i, &j))
|
|
|
4d65c64 |
+ XF86VidModeData.vidmode_available = 0;
|
|
|
4d65c64 |
+ else if (!XF86VidModeQueryExtension(currDisplay, &i, &j))
|
|
|
4d65c64 |
+ XF86VidModeData.vidmode_available = 0;
|
|
|
4d65c64 |
+ else if (!XF86VidModeGetModeLine(currDisplay, currScreen,
|
|
|
4d65c64 |
+ (int *)&XF86VidModeData.orig_mode.dotclock, l))
|
|
|
4d65c64 |
+ XF86VidModeData.vidmode_available = 0;
|
|
|
4d65c64 |
+ else if (!XF86VidModeGetViewPort(currDisplay, currScreen,
|
|
|
4d65c64 |
+ &XF86VidModeData.orig_viewport_x,
|
|
|
4d65c64 |
+ &XF86VidModeData.orig_viewport_y))
|
|
|
4d65c64 |
+ XF86VidModeData.vidmode_available = 0;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if (!XF86VidModeData.vidmode_available)
|
|
|
4d65c64 |
+ fprintf(stderr, "Warning: XF86VidMode not available\n");
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+/* qsort comparison function for sorting the modes */
|
|
|
4d65c64 |
+static int cmpmodes(const void *va, const void *vb)
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ const XF86VidModeModeInfo *a = *(const XF86VidModeModeInfo **)va;
|
|
|
4d65c64 |
+ const XF86VidModeModeInfo *b = *(const XF86VidModeModeInfo **)vb;
|
|
|
4d65c64 |
+ if ( a->hdisplay == b->hdisplay )
|
|
|
4d65c64 |
+ return b->vdisplay - a->vdisplay;
|
|
|
4d65c64 |
+ else
|
|
|
4d65c64 |
+ return b->hdisplay - a->hdisplay;
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+static void pwXf86VmSetFullScreenResolution (int desired_width,
|
|
|
4d65c64 |
+ int desired_height, int &result_width, int &result_height)
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ int i;
|
|
|
4d65c64 |
+ XF86VidModeModeLine mode ; /* = { .hdisplay = 0, .privsize = 0 } ; */
|
|
|
4d65c64 |
+ XF86VidModeModeInfo **modes;
|
|
|
4d65c64 |
+ int mode_count;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* C++ can't do struct initialization by struct member name? */
|
|
|
4d65c64 |
+ mode.hdisplay = 0;
|
|
|
4d65c64 |
+ mode.privsize = 0;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if ( ! XF86VidModeData.vidmode_available )
|
|
|
4d65c64 |
+ return;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Try to switch video mode. This must be done after the pointer is
|
|
|
4d65c64 |
+ grabbed, because otherwise it can be outside the window negating the
|
|
|
4d65c64 |
+ XF86VidModeSetViewPort. */
|
|
|
4d65c64 |
+ if (XF86VidModeGetModeLine(currDisplay, currScreen, &i, &mode))
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ result_width = mode.hdisplay;
|
|
|
4d65c64 |
+ result_height = mode.vdisplay;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Get list of modelines. */
|
|
|
4d65c64 |
+ if (!XF86VidModeGetAllModeLines(currDisplay, currScreen, &mode_count, &modes))
|
|
|
4d65c64 |
+ mode_count = 0;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Search for an exact matching video mode. */
|
|
|
4d65c64 |
+ for (i = 0; i < mode_count; i++) {
|
|
|
4d65c64 |
+ if ((modes[i]->hdisplay == desired_width) &&
|
|
|
4d65c64 |
+ (modes[i]->vdisplay == desired_height))
|
|
|
4d65c64 |
+ break;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Search for a non exact match (smallest bigger res). */
|
|
|
4d65c64 |
+ if (i == mode_count) {
|
|
|
4d65c64 |
+ int best_width = 0, best_height = 0;
|
|
|
4d65c64 |
+ qsort(modes, mode_count, sizeof(void *), cmpmodes);
|
|
|
4d65c64 |
+ for (i = mode_count-1; i > 0; i--) {
|
|
|
4d65c64 |
+ if ( ! best_width ) {
|
|
|
4d65c64 |
+ if ( (modes[i]->hdisplay >= desired_width) &&
|
|
|
4d65c64 |
+ (modes[i]->vdisplay >= desired_height) ) {
|
|
|
4d65c64 |
+ best_width = modes[i]->hdisplay;
|
|
|
4d65c64 |
+ best_height = modes[i]->vdisplay;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+ } else {
|
|
|
4d65c64 |
+ if ( (modes[i]->hdisplay != best_width) ||
|
|
|
4d65c64 |
+ (modes[i]->vdisplay != best_height) ) {
|
|
|
4d65c64 |
+ i++;
|
|
|
4d65c64 |
+ break;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Switch video mode. */
|
|
|
4d65c64 |
+ if ((i >= 0) &&
|
|
|
4d65c64 |
+ ((modes[i]->hdisplay != mode.hdisplay) ||
|
|
|
4d65c64 |
+ (modes[i]->vdisplay != mode.vdisplay)) &&
|
|
|
4d65c64 |
+ XF86VidModeSwitchToMode(currDisplay, currScreen, modes[i]))
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ result_width = modes[i]->hdisplay;
|
|
|
4d65c64 |
+ result_height = modes[i]->vdisplay;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Lock mode switching. */
|
|
|
4d65c64 |
+ XF86VidModeLockModeSwitch(currDisplay, currScreen, True);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Set viewport. */
|
|
|
4d65c64 |
+ XF86VidModeSetViewPort(currDisplay, currScreen, 0, 0);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* clean up */
|
|
|
4d65c64 |
+ if (mode.privsize)
|
|
|
4d65c64 |
+ XFree(mode.c_private);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if (mode_count)
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ for (i = 0; i < mode_count; i++)
|
|
|
4d65c64 |
+ if (modes[i]->privsize)
|
|
|
4d65c64 |
+ XFree(modes[i]->c_private);
|
|
|
4d65c64 |
+ XFree(modes);
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+static void pwXf86VmRestoreOriginalResolution ( )
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ int i;
|
|
|
4d65c64 |
+ XF86VidModeModeLine mode;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if ( ! XF86VidModeData.vidmode_available )
|
|
|
4d65c64 |
+ return;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Unlock mode switching. */
|
|
|
4d65c64 |
+ XF86VidModeLockModeSwitch(currDisplay, currScreen, False);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if (!XF86VidModeGetModeLine(currDisplay, currScreen, &i, &mode) ||
|
|
|
4d65c64 |
+ (mode.hdisplay != XF86VidModeData.orig_mode.hdisplay) ||
|
|
|
4d65c64 |
+ (mode.vdisplay != XF86VidModeData.orig_mode.vdisplay))
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ if (!XF86VidModeSwitchToMode(currDisplay, currScreen,
|
|
|
4d65c64 |
+ &XF86VidModeData.orig_mode))
|
|
|
4d65c64 |
+ fprintf(stderr, "XF86VidMode couldnot restore original resolution\n");
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+ if (XF86VidModeData.orig_viewport_x || XF86VidModeData.orig_viewport_y)
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ if (!XF86VidModeSetViewPort(currDisplay, currScreen,
|
|
|
4d65c64 |
+ XF86VidModeData.orig_viewport_x,
|
|
|
4d65c64 |
+ XF86VidModeData.orig_viewport_y))
|
|
|
4d65c64 |
+ fprintf(stderr, "XF86VidMode couldnot restore original viewport\n");
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+#endif
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+void
|
|
|
4d65c64 |
+pwSetSize ( int w, int h )
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ bool notResizable = !resizable;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if (notResizable)
|
|
|
4d65c64 |
+ pwRealSetResizable ( true, w, h );
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
XResizeWindow ( currDisplay, currHandle, w, h ) ;
|
|
|
4d65c64 |
- XFlush ( currDisplay ) ;
|
|
|
4d65c64 |
+ XResizeWindow ( currDisplay, wmWindow, w, h ) ;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if (notResizable)
|
|
|
4d65c64 |
+ pwRealSetResizable ( false, w, h );
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+#ifdef XF86VIDMODE
|
|
|
4d65c64 |
+ if (fsWindow != None)
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ int screen_w = 0, screen_h ;
|
|
|
4d65c64 |
+ pwXf86VmSetFullScreenResolution ( w, h, screen_w, screen_h ) ;
|
|
|
4d65c64 |
+ /* check pwXf86VmSetFullScreenResolution didn't fail completly. */
|
|
|
4d65c64 |
+ if (screen_w)
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ /* Center the window */
|
|
|
4d65c64 |
+ XMoveWindow ( currDisplay, currHandle, ( screen_w - w ) / 2,
|
|
|
4d65c64 |
+ ( screen_h - h ) / 2 ) ;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+#endif
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ XFlush ( currDisplay );
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|
|
|
4d65c64 |
void pwSetOrigin ( int x, int y )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
- XMoveWindow ( currDisplay, currHandle, x, y ) ;
|
|
|
4d65c64 |
+ XMoveWindow ( currDisplay, wmWindow, x, y ) ;
|
|
|
4d65c64 |
XFlush ( currDisplay ) ;
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|
|
|
4d65c64 |
void pwSetSizeOrigin ( int x, int y, int w, int h )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
- XMoveWindow ( currDisplay, currHandle, x, y ) ;
|
|
|
4d65c64 |
- XResizeWindow ( currDisplay, currHandle, w, h ) ;
|
|
|
4d65c64 |
- XFlush ( currDisplay ) ;
|
|
|
4d65c64 |
+ XMoveWindow ( currDisplay, wmWindow, x, y ) ;
|
|
|
4d65c64 |
+ pwSetSize ( w, h );
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|
|
|
4d65c64 |
@@ -474,7 +735,11 @@
|
|
|
4d65c64 |
switch ( event.type )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
case ClientMessage : (*exitCB)() ; break ;
|
|
|
4d65c64 |
- case DestroyNotify : (*exitCB)() ; break ;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ case DestroyNotify :
|
|
|
4d65c64 |
+ if ( event.xdestroywindow.window == wmWindow )
|
|
|
4d65c64 |
+ (*exitCB)() ;
|
|
|
4d65c64 |
+ break ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
case ConfigureNotify :
|
|
|
4d65c64 |
if ( currHandle == event.xconfigure.window &&
|
|
|
4d65c64 |
@@ -605,7 +870,7 @@
|
|
|
4d65c64 |
|
|
|
4d65c64 |
void pwSwapBuffers ()
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
- if ( ! initialised )
|
|
|
4d65c64 |
+ if ( ! currDisplay )
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
fprintf ( stderr, "PLIB/PW: FATAL - Application called pwSwapBuffers"
|
|
|
4d65c64 |
" before pwInit.\n" ) ;
|
|
|
4d65c64 |
@@ -635,15 +900,133 @@
|
|
|
4d65c64 |
#endif
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|
|
|
4d65c64 |
+void pwSetFullscreen ()
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ XEvent event;
|
|
|
4d65c64 |
+ XSetWindowAttributes setattr;
|
|
|
4d65c64 |
+ /* local width and height vars used for fullscreen window size and for
|
|
|
4d65c64 |
+ storing the video_mode size which is then used to center the window */
|
|
|
4d65c64 |
+ int fs_width = DisplayWidth(currDisplay, currScreen);
|
|
|
4d65c64 |
+ int fs_height = DisplayHeight(currDisplay, currScreen);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Grab the keyboard */
|
|
|
4d65c64 |
+ if (XGrabKeyboard(currDisplay, rootWindow, False, GrabModeAsync,
|
|
|
4d65c64 |
+ GrabModeAsync, CurrentTime) != GrabSuccess)
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ fprintf(stderr, "Error can not grab keyboard, not going fullscreen\n");
|
|
|
4d65c64 |
+ return;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+ keyb_grabbed = true;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Create the fullscreen window */
|
|
|
4d65c64 |
+ setattr.override_redirect = True;
|
|
|
4d65c64 |
+ setattr.background_pixel = XBlackPixel(currDisplay, currScreen);
|
|
|
4d65c64 |
+ setattr.border_pixel = XBlackPixel(currDisplay, currScreen);
|
|
|
4d65c64 |
+ setattr.event_mask = StructureNotifyMask;
|
|
|
4d65c64 |
+ setattr.colormap = XCreateColormap ( currDisplay, rootWindow,
|
|
|
4d65c64 |
+ visualInfo->visual, AllocNone ) ;
|
|
|
4d65c64 |
+ fsWindow = XCreateWindow(currDisplay, rootWindow,
|
|
|
4d65c64 |
+ 0, 0, fs_width, fs_height, 0,
|
|
|
4d65c64 |
+ visualInfo->depth, InputOutput,
|
|
|
4d65c64 |
+ visualInfo->visual, CWOverrideRedirect |
|
|
|
4d65c64 |
+ CWBackPixel | CWColormap | CWBorderPixel |
|
|
|
4d65c64 |
+ CWEventMask, &setattr);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Map the fullscreen window */
|
|
|
4d65c64 |
+ XMapRaised(currDisplay, fsWindow);
|
|
|
4d65c64 |
+ /* wait until we are mapped. (shamelessly borrowed from SDL) */
|
|
|
4d65c64 |
+ do {
|
|
|
4d65c64 |
+ XMaskEvent(currDisplay, StructureNotifyMask, &event);
|
|
|
4d65c64 |
+ } while ( (event.type != MapNotify) ||
|
|
|
4d65c64 |
+ (event.xmap.event != fsWindow) );
|
|
|
4d65c64 |
+ /* Make sure we got to the top of the window stack */
|
|
|
4d65c64 |
+ XRaiseWindow(currDisplay, fsWindow);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Reparent the real window */
|
|
|
4d65c64 |
+ XReparentWindow(currDisplay, currHandle, fsWindow, 0, 0);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Grab the mouse. */
|
|
|
4d65c64 |
+ if (XGrabPointer(currDisplay, currHandle, False,
|
|
|
4d65c64 |
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
|
|
|
4d65c64 |
+ GrabModeAsync, GrabModeAsync, currHandle, None,
|
|
|
4d65c64 |
+ CurrentTime) == GrabSuccess)
|
|
|
4d65c64 |
+ mouse_grabbed = true;
|
|
|
4d65c64 |
+ else
|
|
|
4d65c64 |
+ fprintf(stderr, "Warning can not grab mouse\n");
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Make sure we get any last resize events before using size[] */
|
|
|
4d65c64 |
+ getEvents();
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+#ifdef XF86VIDMODE
|
|
|
4d65c64 |
+ /* Switch resolution */
|
|
|
4d65c64 |
+ pwXf86VmSetFullScreenResolution (size[0], size[1], fs_width, fs_height);
|
|
|
4d65c64 |
+#endif
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Center the window (if nescesarry) */
|
|
|
4d65c64 |
+ if ((fs_width != size[0]) || (fs_height != size[1]))
|
|
|
4d65c64 |
+ XMoveWindow(currDisplay, currHandle, (fs_width - size[0]) / 2,
|
|
|
4d65c64 |
+ (fs_height - size[1]) / 2);
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* And last set the cursor */
|
|
|
4d65c64 |
+ pwRealSetCursor (fsCursor);
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+void pwSetWindowed ()
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ if (mouse_grabbed) {
|
|
|
4d65c64 |
+ XUngrabPointer(currDisplay, CurrentTime);
|
|
|
4d65c64 |
+ mouse_grabbed = false;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+ if (keyb_grabbed) {
|
|
|
4d65c64 |
+ XUngrabKeyboard(currDisplay, CurrentTime);
|
|
|
4d65c64 |
+ keyb_grabbed = false;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+#ifdef XF86VIDMODE
|
|
|
4d65c64 |
+ /* Switch resolution */
|
|
|
4d65c64 |
+ pwXf86VmRestoreOriginalResolution ( ) ;
|
|
|
4d65c64 |
+#endif
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* Reparent the real window! */
|
|
|
4d65c64 |
+ XReparentWindow(currDisplay, currHandle, wmWindow, 0, 0);
|
|
|
4d65c64 |
+ XUnmapWindow(currDisplay, fsWindow);
|
|
|
4d65c64 |
+ XDestroyWindow(currDisplay, fsWindow);
|
|
|
4d65c64 |
+ fsWindow = None;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ /* And last set the cursor */
|
|
|
4d65c64 |
+ pwRealSetCursor (wmCursor);
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+void pwToggleFullscreen ()
|
|
|
4d65c64 |
+{
|
|
|
4d65c64 |
+ if (fsWindow == None)
|
|
|
4d65c64 |
+ pwSetFullscreen () ;
|
|
|
4d65c64 |
+ else
|
|
|
4d65c64 |
+ pwSetWindowed () ;
|
|
|
4d65c64 |
+}
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
void pwCleanup ()
|
|
|
4d65c64 |
{
|
|
|
4d65c64 |
- if ( ! initialised )
|
|
|
4d65c64 |
- fprintf ( stderr, "PLIB/PW: WARNING - Application called pwCleanup"
|
|
|
4d65c64 |
- " before pwInit.\n" ) ;
|
|
|
4d65c64 |
+ if ( ! currDisplay )
|
|
|
4d65c64 |
+ return;
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if ( titlePropertyPtr )
|
|
|
4d65c64 |
+ {
|
|
|
4d65c64 |
+ XFree ( titlePropertyPtr->value ) ;
|
|
|
4d65c64 |
+ titlePropertyPtr = NULL;
|
|
|
4d65c64 |
+ }
|
|
|
4d65c64 |
+
|
|
|
4d65c64 |
+ if ( fsWindow != None )
|
|
|
4d65c64 |
+ pwSetWindowed ( ) ;
|
|
|
4d65c64 |
|
|
|
4d65c64 |
glXDestroyContext ( currDisplay, currContext ) ;
|
|
|
4d65c64 |
XDestroyWindow ( currDisplay, currHandle ) ;
|
|
|
4d65c64 |
- XFlush ( currDisplay ) ;
|
|
|
4d65c64 |
+ XDestroyWindow ( currDisplay, wmWindow ) ;
|
|
|
4d65c64 |
+ XCloseDisplay ( currDisplay ) ;
|
|
|
4d65c64 |
+ currDisplay = NULL;
|
|
|
4d65c64 |
}
|
|
|
4d65c64 |
|
|
|
4d65c64 |
|