From d972fb5979b447770e5be1d963ea570fb57c1cc1 Mon Sep 17 00:00:00 2001 From: Mark Cannon Date: Fri, 30 May 2008 02:58:50 +0000 Subject: [PATCH] Massive commit: revert X11, add input debounce code git-svn-id: https://openitg.svn.sourceforge.net/svnroot/openitg@360 83fadc84-e282-4d84-a09a-c4228d6ae7e5 --- ToDo.txt | 2 +- changelog.txt | 4 +- src/InputFilter.cpp | 7 - src/InputFilter.h | 2 - src/PrefsManager.cpp | 1 + src/PrefsManager.h | 1 + src/arch/InputHandler/InputHandler.cpp | 14 +- src/arch/InputHandler/InputHandler_X11.cpp | 233 +++++++++++++---------------- src/archutils/Unix/X11Helper.cpp | 146 ++++++++++++------ src/archutils/Unix/X11Helper.h | 36 +++-- 10 files changed, 254 insertions(+), 192 deletions(-) diff --git a/ToDo.txt b/ToDo.txt index 22440529..0072747a 100644 --- a/ToDo.txt +++ b/ToDo.txt @@ -1,7 +1,6 @@ /* More-or-less in order of priority. */ /* Major bug fixing */ --X11 full-screen causes scrolling brackets + desktop resize -Switching modes on the main menu causes OpenITG to hang -Figure out what the hell's up with saving USB stats @@ -13,6 +12,7 @@ -"Random" selections for non-existant BGVids always return the same video /* Minor feature additions */ +-Working full-screen on Linux -Re-implement "InputDebounceTime" -Include ThemeInfo.ini support (is this still needed?) -Add Windows code for network diagnostics diff --git a/changelog.txt b/changelog.txt index 711e7905..69c25dfb 100755 --- a/changelog.txt +++ b/changelog.txt @@ -2,11 +2,12 @@ OpenITG, alpha 6 (in development) --------------------------------- -Code structure changes: Reverted InputFilter - too little gain for too many problems - Backported/modified 4.0's X11 code (Linux window/input) -New metrics in ScreenGameplay: (Note: must be in Event Mode, Versus, and playing the same chart) "ScorePxAheadCommand" - played when player's score is higher "ScorePxBehindCommand" - played when player's score is lower +-New preferences: + "InputDebounceTime" - self-explanatory -New game commands: "clearcredits" - clears credits on the machine (useful for testing) "theme" - sets the theme, by name, when used (useful for theme switchers) @@ -15,6 +16,7 @@ OpenITG, alpha 6 (in development) -Win32 changes: Added code to reboot on crashes for arcade builds (#define ITG_ARCADE) -Misc. changes: + Enabled pad lighting on ScreenDemonstration Coins added by GameCommands are not counted toward bookkeeping totals Round text on ScreenSelectMusic updates for long/marathon songs Moved OpenITG-specific profile options to Extra.ini (caused ITG2 crashes) diff --git a/src/InputFilter.cpp b/src/InputFilter.cpp index d51d4132..61ff7b43 100755 --- a/src/InputFilter.cpp +++ b/src/InputFilter.cpp @@ -16,8 +16,6 @@ static const float FAST_REPEATS_PER_SEC = 8; static float g_fTimeBeforeSlow, g_fTimeBeforeFast, g_fTimeBetweenSlow, g_fTimeBetweenFast; -Preference g_fInputDebounceTime( "InputDebounceTime", 0 ); - InputFilter::InputFilter() { @@ -170,11 +168,6 @@ void InputFilter::Update(float fDeltaTime) } -void InputFilter::CheckButtonChange( DeviceInput di, ButtonState &bs, const RageTimer &now ) -{ - queue.push_back( InputEvent(di, bs.m_BeingHeld ? IET_FIRST_PRESS:IET_RELEASE) ); -} - bool InputFilter::IsBeingPressed( DeviceInput di ) { return m_ButtonState[di.device][di.button].m_BeingHeld; diff --git a/src/InputFilter.h b/src/InputFilter.h index 2e1789ac..7bd46727 100755 --- a/src/InputFilter.h +++ b/src/InputFilter.h @@ -72,8 +72,6 @@ public: CString GetButtonComment( DeviceInput di ) const; void GetInputEvents( InputEventArray &array ); -private: - void CheckButtonChange( DeviceInput di, ButtonState &bs, const RageTimer &now ); }; diff --git a/src/PrefsManager.cpp b/src/PrefsManager.cpp index aad4b1cc..9b81d0c5 100755 --- a/src/PrefsManager.cpp +++ b/src/PrefsManager.cpp @@ -211,6 +211,7 @@ PrefsManager::PrefsManager() : m_iCustomMaxStepsSizeKB ( "CustomMaxStepSizeKB", 100 ), m_bAllowExtraPlayerOptions ( "AllowExtraPlayerOptions", false ), + m_fInputDebounceTime ( "InputDebounceTime", 0 ), m_bComboContinuesBetweenSongs ( "ComboContinuesBetweenSongs", false ), m_fLongVerSongSeconds ( "LongVerSongSeconds", 60*2.5f ), // Dynamite Rave is 2:55 diff --git a/src/PrefsManager.h b/src/PrefsManager.h index 840751c2..1e00c90f 100755 --- a/src/PrefsManager.h +++ b/src/PrefsManager.h @@ -186,6 +186,7 @@ public: Preference m_iCustomMaxStepsSizeKB; Preference m_bAllowExtraPlayerOptions; + Preference m_fInputDebounceTime; Preference m_bComboContinuesBetweenSongs; Preference m_fLongVerSongSeconds; diff --git a/src/arch/InputHandler/InputHandler.cpp b/src/arch/InputHandler/InputHandler.cpp index ff6b3f67..747bf028 100755 --- a/src/arch/InputHandler/InputHandler.cpp +++ b/src/arch/InputHandler/InputHandler.cpp @@ -3,6 +3,11 @@ #include "RageUtil.h" #include "InputHandler.h" #include "RageLog.h" +#include "PrefsManager.h" // XXX +#include + +/* This code is taken from CNLohr's 3.9 AC build. */ +map< int, RageTimer > m_LastHit; void InputHandler::UpdateTimer() { @@ -20,7 +25,14 @@ void InputHandler::ButtonPressed( DeviceInput di, bool Down ) ++m_iInputsSinceUpdate; } - INPUTFILTER->ButtonPressed( di, Down ); + if( !Down ) + INPUTFILTER->ButtonPressed( di, Down ); + else + if( m_LastHit.find(di.button) == m_LastHit.end() || m_LastHit[di.button].PeekDeltaTime() > PREFSMAN->m_fInputDebounceTime ) + { + INPUTFILTER->ButtonPressed( di, Down ); + m_LastHit[di.button].Touch(); + } if( m_iInputsSinceUpdate >= 50 ) { diff --git a/src/arch/InputHandler/InputHandler_X11.cpp b/src/arch/InputHandler/InputHandler_X11.cpp index 3749ac17..dfc1f570 100755 --- a/src/arch/InputHandler/InputHandler_X11.cpp +++ b/src/arch/InputHandler/InputHandler_X11.cpp @@ -3,19 +3,15 @@ #include "RageUtil.h" #include "RageLog.h" #include "RageDisplay.h" -#include "InputFilter.h" -#include "EnumHelper.h" #include "archutils/Unix/X11Helper.h" #include #include -using namespace X11Helper; - -static DeviceButton XSymToDeviceButton( int key ) +static RageKeySym XSymToKeySym( int key ) { -#define KEY_INV DEVICE_BUTTON_INVALID - static const DeviceButton ASCIIKeySyms[] = +#define KEY_INV KEY_INVALID + const RageKeySym ASCIIKeySyms[] = { KEY_INV , KEY_INV , KEY_INV , KEY_INV , KEY_INV , /* 0 - 4 */ KEY_INV , KEY_INV , KEY_INV , KEY_BACK , KEY_TAB , /* 5 - 9 */ @@ -45,162 +41,145 @@ static DeviceButton XSymToDeviceButton( int key ) KEY_RBRACE , KEY_INV , KEY_DEL /* 125 - 127 */ }; - /* 0...31: */ - if( key >= 0xFF00 && key < 0xFF20 ) - return ASCIIKeySyms[key & 0xFF]; - /* 32...127: */ if( key < int(ARRAYSIZE(ASCIIKeySyms))) return ASCIIKeySyms[key]; /* XK_KP_0 ... XK_KP_9 to KEY_KP_C0 ... KEY_KP_C9 */ if( key >= XK_KP_0 && key <= XK_KP_9 ) - return enum_add2(KEY_KP_C0, key - XK_KP_0); + return (RageKeySym) (key - XK_KP_0 + KEY_KP_C0); switch( key ) { - /* These are needed because of the way X registers the keypad. */ - case XK_KP_Insert: return KEY_KP_C0; - case XK_KP_End: return KEY_KP_C1; - case XK_KP_Down: return KEY_KP_C2; - case XK_KP_Page_Down: return KEY_KP_C3; - case XK_KP_Left: return KEY_KP_C4; - case XK_KP_Begin: return KEY_KP_C5; - case XK_KP_Right: return KEY_KP_C6; - case XK_KP_Home: return KEY_KP_C7; - case XK_KP_Up: return KEY_KP_C8; - case XK_KP_Page_Up: return KEY_KP_C9; - case XK_KP_Decimal: return KEY_KP_PERIOD; - case XK_KP_Divide: return KEY_KP_SLASH; - case XK_KP_Multiply: return KEY_KP_ASTERISK; - case XK_KP_Subtract: return KEY_KP_HYPHEN; - case XK_KP_Add: return KEY_KP_PLUS; - case XK_KP_Equal: return KEY_KP_EQUAL; - case XK_KP_Enter: return KEY_KP_ENTER; - case XK_Up: return KEY_UP; - case XK_Down: return KEY_DOWN; - case XK_Right: return KEY_RIGHT; - case XK_Left: return KEY_LEFT; - case XK_Insert: return KEY_INSERT; - case XK_Home: return KEY_HOME; - case XK_Delete: return KEY_DEL; - case XK_End: return KEY_END; - case XK_Page_Up: return KEY_PGUP; - case XK_Page_Down: return KEY_PGDN; - case XK_F1: return KEY_F1; - case XK_F2: return KEY_F2; - case XK_F3: return KEY_F3; - case XK_F4: return KEY_F4; - case XK_F5: return KEY_F5; - case XK_F6: return KEY_F6; - case XK_F7: return KEY_F7; - case XK_F8: return KEY_F8; - case XK_F9: return KEY_F9; - case XK_F10: return KEY_F10; - case XK_F11: return KEY_F11; - case XK_F12: return KEY_F12; - case XK_F13: return KEY_F13; - case XK_F14: return KEY_F14; - case XK_F15: return KEY_F15; - - case XK_Num_Lock: return KEY_NUMLOCK; - case XK_Caps_Lock: return KEY_CAPSLOCK; - case XK_Scroll_Lock: return KEY_SCRLLOCK; - case XK_Return: return KEY_ENTER; - case XK_Sys_Req: return KEY_PRTSC; - case XK_Print: return KEY_PRTSC; - case XK_Shift_R: return KEY_RSHIFT; - case XK_Shift_L: return KEY_LSHIFT; - case XK_Control_R: return KEY_RCTRL; - case XK_Control_L: return KEY_LCTRL; - case XK_Alt_R: return KEY_RALT; - case XK_Alt_L: return KEY_LALT; - case XK_Meta_R: return KEY_RMETA; - case XK_Meta_L: return KEY_LMETA; - case XK_Super_L: return KEY_LSUPER; - case XK_Super_R: return KEY_RSUPER; - case XK_Menu: return KEY_MENU; + /* These are needed because of the way X registers + the keypad. */ + case XK_KP_Insert: return KEY_KP_C0; + case XK_KP_End: return KEY_KP_C1; + case XK_KP_Down: return KEY_KP_C2; + case XK_KP_Page_Down: return KEY_KP_C3; + case XK_KP_Left: return KEY_KP_C4; + case XK_KP_Begin: return KEY_KP_C5; + case XK_KP_Right: return KEY_KP_C6; + case XK_KP_Home: return KEY_KP_C7; + case XK_KP_Up: return KEY_KP_C8; + case XK_KP_Page_Up: return KEY_KP_C9; + case XK_KP_Decimal: return KEY_KP_PERIOD; + case XK_KP_Divide: return KEY_KP_SLASH; + case XK_KP_Multiply: return KEY_KP_ASTERISK; + case XK_KP_Subtract: return KEY_KP_HYPHEN; + case XK_KP_Add: return KEY_KP_PLUS; + case XK_KP_Equal: return KEY_KP_EQUAL; + case XK_KP_Enter: return KEY_KP_ENTER; + case XK_Up: return KEY_UP; + case XK_Down: return KEY_DOWN; + case XK_Right: return KEY_RIGHT; + case XK_Left: return KEY_LEFT; + case XK_Insert: return KEY_INSERT; + case XK_Home: return KEY_HOME; + case XK_Delete: return KEY_DEL; + case XK_End: return KEY_END; + case XK_Page_Up: return KEY_PGUP; + case XK_Page_Down: return KEY_PGDN; + case XK_F1: return KEY_F1; + case XK_F2: return KEY_F2; + case XK_F3: return KEY_F3; + case XK_F4: return KEY_F4; + case XK_F5: return KEY_F5; + case XK_F6: return KEY_F6; + case XK_F7: return KEY_F7; + case XK_F8: return KEY_F8; + case XK_F9: return KEY_F9; + case XK_F10: return KEY_F10; + case XK_F11: return KEY_F11; + case XK_F12: return KEY_F12; + case XK_F13: return KEY_F13; + case XK_F14: return KEY_F14; + case XK_F15: return KEY_F15; + + case XK_Num_Lock: return KEY_NUMLOCK; + case XK_Caps_Lock: return KEY_CAPSLOCK; + case XK_Scroll_Lock: return KEY_SCRLLOCK; + case XK_Return: return KEY_ENTER; + case XK_Sys_Req: return KEY_PRTSC; + case XK_Print: return KEY_PRTSC; + case XK_Shift_R: return KEY_RSHIFT; + case XK_Shift_L: return KEY_LSHIFT; + case XK_Control_R: return KEY_RCTRL; + case XK_Control_L: return KEY_LCTRL; + case XK_Alt_R: return KEY_RALT; + case XK_Alt_L: return KEY_LALT; + case XK_Meta_R: return KEY_RMETA; + case XK_Meta_L: return KEY_LMETA; + case XK_Super_L: return KEY_LSUPER; + case XK_Super_R: return KEY_RSUPER; + case XK_Menu: return KEY_MENU; } - return DEVICE_BUTTON_INVALID; + /* 0...31: */ + if( key - 0xFF00 < 0x20) + return ASCIIKeySyms[key - 0xFF00]; + + return KEY_INVALID; } InputHandler_X11::InputHandler_X11() { - if( Dpy == NULL || Win == None ) - return; - XWindowAttributes winAttrib; - - XGetWindowAttributes( Dpy, Win, &winAttrib ); - XSelectInput( Dpy, Win, winAttrib.your_event_mask | KeyPressMask | KeyReleaseMask ); + XKeyboardControl state; + state.auto_repeat_mode = AutoRepeatModeOff; + XChangeKeyboardControl(X11Helper::Dpy,KBAutoRepeatMode,&state); + X11Helper::Go(); + X11Helper::OpenMask(KeyPressMask); X11Helper::OpenMask(KeyReleaseMask); } InputHandler_X11::~InputHandler_X11() { - if( Dpy == NULL || Win == None ) - return; - XWindowAttributes winAttrib; - - XGetWindowAttributes( Dpy, Win, &winAttrib ); - XSelectInput( Dpy, Win, winAttrib.your_event_mask & ~(KeyPressMask|KeyReleaseMask) ); + XKeyboardControl state; + state.auto_repeat_mode = AutoRepeatModeDefault; + XChangeKeyboardControl(X11Helper::Dpy,KBAutoRepeatMode,&state); + X11Helper::CloseMask(KeyPressMask); X11Helper::CloseMask(KeyReleaseMask); + X11Helper::Stop(); } -void InputHandler_X11::Update( float fDeltaTime ) +void InputHandler_X11::Update(float fDeltaTime) { - if( Dpy == NULL || Win == None ) - { - InputHandler::UpdateTimer(); - return; - } + XEvent event; - XEvent event, lastEvent; - DeviceButton lastDB = DEVICE_BUTTON_INVALID; - lastEvent.type = 0; + if (X11Helper::Win) + while(XCheckTypedWindowEvent(X11Helper::Dpy, + X11Helper::Win, KeyPress, &event) ) + { + LOG->Trace("key: sym %i, key %i, state true", + XLookupKeysym(&event.xkey,0), XSymToKeySym(XLookupKeysym(&event.xkey,0))); - while( XCheckWindowEvent(Dpy, Win, KeyPressMask | KeyReleaseMask, &event) ) - { - const bool bPress = event.type == KeyPress; - if( lastEvent.type != 0 ) + DeviceInput di( DEVICE_KEYBOARD, + XSymToKeySym(XLookupKeysym(&event.xkey,0)) ); + ButtonPressed(di, true); + } + while(XCheckTypedWindowEvent(X11Helper::Dpy, + X11Helper::Win, KeyRelease, &event) ) { - if( bPress && event.xkey.time == lastEvent.xkey.time && - event.xkey.keycode == lastEvent.xkey.keycode ) - { - // This is a repeat event so ignore it. - lastEvent.type = 0; - continue; - } - // This is a new event so the last release was not a repeat. - ButtonPressed( DeviceInput(DEVICE_KEYBOARD, lastDB), false ); - lastEvent.type = 0; + LOG->Trace("key: sym %i, key %i, state false", + XLookupKeysym(&event.xkey,0), XSymToKeySym(XLookupKeysym(&event.xkey,0))); + + DeviceInput di( DEVICE_KEYBOARD, + XSymToKeySym(XLookupKeysym(&event.xkey,0)) ); + ButtonPressed(di, false); + } - // Why only the zero index? - lastDB = XSymToDeviceButton( XLookupKeysym(&event.xkey, 0) ); - if( lastDB == DEVICE_BUTTON_INVALID ) - continue; - - if( bPress ) - ButtonPressed( DeviceInput(DEVICE_KEYBOARD, lastDB), true ); - else - lastEvent = event; - } - // Handle any last releases. - if( lastEvent.type != 0 ) - ButtonPressed( DeviceInput(DEVICE_KEYBOARD, lastDB), false ); + InputHandler::UpdateTimer(); } -void InputHandler_X11::GetDevicesAndDescriptions( vector& vDevicesOut, vector& vDescriptionsOut ) +void InputHandler_X11::GetDevicesAndDescriptions( + vector& vDevicesOut, vector& vDescriptionsOut) { - if( !Dpy || !Win ) - return; - vDevicesOut.push_back( DEVICE_KEYBOARD ); vDescriptionsOut.push_back( "Keyboard" ); } /* - * (c) 2005, 2006 Sean Burke, Ben Anderson, Steve Checkoway + * (c) 2005 Sean Burke, Ben Anderson * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/archutils/Unix/X11Helper.cpp b/src/archutils/Unix/X11Helper.cpp index 321994f8..61dd575f 100755 --- a/src/archutils/Unix/X11Helper.cpp +++ b/src/archutils/Unix/X11Helper.cpp @@ -1,98 +1,160 @@ #include "global.h" #include "X11Helper.h" + +#include // Display, Window + #include "RageLog.h" +#include "RageDisplay.h" +#include "RageThreads.h" + +// Currently open masks: +static vector g_aiMasks; + +// Number of subsystems using the X connection: +static int g_iRefCount = 0; + +// Do we have a window? +static bool g_bHaveWin = false; Display *X11Helper::Dpy = NULL; -Window X11Helper::Win = None; +Window X11Helper::Win; -static int ErrorCallback( Display*, XErrorEvent* ); -static int FatalCallback( Display* ); +int protoErrorCallback( Display*, XErrorEvent* ); +int protoFatalCallback( Display* ); -bool X11Helper::OpenXConnection() +bool X11Helper::Go() { - DEBUG_ASSERT( Dpy == NULL && Win == None ); - Dpy = XOpenDisplay(0); - if( Dpy == NULL ) - return false; + if( g_iRefCount == 0 ) + { + Dpy = XOpenDisplay(0); + if( Dpy == NULL ) + return false; + + XSetIOErrorHandler( &protoFatalCallback ); + XSetErrorHandler( &protoErrorCallback ); + } + g_iRefCount++; - XSetIOErrorHandler( FatalCallback ); - XSetErrorHandler( ErrorCallback ); return true; } -void X11Helper::CloseXConnection() +void X11Helper::Stop() { - // The window should have been shut down - DEBUG_ASSERT( Dpy != NULL ); - DEBUG_ASSERT( Win == None ); - XCloseDisplay( Dpy ); - Dpy = NULL; + g_iRefCount--; + + if( g_iRefCount == 0 ) + { + XCloseDisplay( Dpy ); + Dpy = NULL; // For sanity's sake + g_aiMasks.clear(); + } +} + +static bool pApplyMasks(); + +bool X11Helper::OpenMask( long mask ) +{ + g_aiMasks.push_back(mask); + return pApplyMasks(); +} + +bool X11Helper::CloseMask( long mask ) +{ + vector::iterator i = find( g_aiMasks.begin(), g_aiMasks.end(), mask ); + if( i == g_aiMasks.end() ) + return true; + + g_aiMasks.erase( i ); + + return pApplyMasks(); } -bool X11Helper::MakeWindow( Window &win, int screenNum, int depth, Visual *visual, int width, int height, bool overrideRedirect ) +static bool pApplyMasks() { - if( !Dpy ) + if( X11Helper::Dpy == NULL | !g_bHaveWin ) + return true; + + LOG->Trace("X11Helper: Reapplying event masks."); + + long iMask = 0; + for( unsigned i = 0; i < g_aiMasks.size(); ++i ) + iMask |= g_aiMasks[i]; + + if( XSelectInput(X11Helper::Dpy, X11Helper::Win, iMask) == 0 ) + return false; + + return true; +} + +bool X11Helper::MakeWindow( int screenNum, int depth, Visual *visual, int width, int height ) +{ + vector::iterator i; + + if( g_iRefCount == 0 ) return false; + if( g_bHaveWin ) + { + XDestroyWindow( Dpy, Win ); + g_bHaveWin = false; + } + // pHaveWin will stay false if an error occurs once I do error + // checking here... + XSetWindowAttributes winAttribs; - winAttribs.border_pixel = 0; - winAttribs.event_mask = 0L; - if( win ) + winAttribs.border_pixel = 0; + winAttribs.event_mask = 0; + i = g_aiMasks.begin(); + while( i != g_aiMasks.end() ) { - // Preserve the event mask. - XWindowAttributes attribs; - XGetWindowAttributes( Dpy, win, &attribs ); - winAttribs.event_mask = attribs.your_event_mask; - XDestroyWindow( Dpy, win ); + winAttribs.event_mask |= *i; + i++; } + // XXX: Error catching/handling? + winAttribs.colormap = XCreateColormap( Dpy, RootWindow(Dpy, screenNum), visual, AllocNone ); - unsigned long mask = CWBorderPixel | CWColormap | CWEventMask; - if( overrideRedirect ) - { - winAttribs.override_redirect = True; - mask |= CWOverrideRedirect; - } - win = XCreateWindow( Dpy, RootWindow(Dpy, screenNum), 0, 0, width, height, 0, - depth, InputOutput, visual, mask, &winAttribs ); - if( win == None ) - return false; + Win = XCreateWindow( Dpy, RootWindow(Dpy, screenNum), 0, 0, width, + height, 0, depth, InputOutput, visual, + CWBorderPixel | CWColormap | CWEventMask, &winAttribs ); + + g_bHaveWin = true; /* Hide the mouse cursor. */ { const char pBlank[] = { 0,0,0,0,0,0,0,0 }; - Pixmap BlankBitmap = XCreateBitmapFromData( Dpy, win, pBlank, 8, 8 ); + Pixmap BlankBitmap = XCreateBitmapFromData( Dpy, Win, pBlank, 8, 8 ); XColor black = { 0, 0, 0, 0, 0, 0 }; Cursor pBlankPointer = XCreatePixmapCursor( Dpy, BlankBitmap, BlankBitmap, &black, &black, 0, 0 ); XFreePixmap( Dpy, BlankBitmap ); - XDefineCursor( Dpy, win, pBlankPointer ); + XDefineCursor( Dpy, Win, pBlankPointer ); XFreeCursor( Dpy, pBlankPointer ); } return true; } -int ErrorCallback( Display *d, XErrorEvent *err ) +int protoErrorCallback( Display *d, XErrorEvent *err ) { char errText[512]; XGetErrorText( d, err->error_code, errText, 512 ); LOG->Warn( "X11 Protocol error %s (%d) has occurred, caused by request %d,%d, resource ID %d", - errText, err->error_code, err->request_code, err->minor_code, (int) err->resourceid ); + errText, err->error_code, err->request_code, err->minor_code, err->resourceid ); return 0; // Xlib ignores our return value } -int FatalCallback( Display *d ) +int protoFatalCallback( Display *d ) { RageException::Throw( "Fatal I/O error communicating with X server." ); } /* - * (c) 2005, 2006 Ben Anderson, Steve Checkoway + * (c) 2005 Ben Anderson * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/archutils/Unix/X11Helper.h b/src/archutils/Unix/X11Helper.h index 255abbb7..0dd92762 100755 --- a/src/archutils/Unix/X11Helper.h +++ b/src/archutils/Unix/X11Helper.h @@ -3,6 +3,9 @@ #define X11_HELPER_H #include // Window + +#include "RageDisplay.h" // RageDisplay + namespace X11Helper { // All functions in here that return a bool return true on success, and @@ -10,28 +13,39 @@ namespace X11Helper // Create the connection, if necessary; otherwise do some important // internal session-tracking stuff (so you should call this anyway). - bool OpenXConnection(); - - // Destroy the connection, if appropriate; otherwise do some important - // internal session-tracking stuff (so you should call it anyway). - void CloseXConnection(); + bool Go(); // The current Display (connection). Initialized by the first call to - // OpenXConnection(). + // Go(). extern Display *Dpy; - // The Window used by LowLevelWindow_X11 as the main window. + // Get the current open window. Initialized by the first call to + // MakeWindow(). extern Window Win; - // (Re)create the Window win. - bool MakeWindow( Window &win, int screenNum, int depth, Visual *visual, - int width, int height, bool overrideRedirect ); + // (Re)create the window on the screen of this number with this depth, + // this visual type, this width (optional -- you can resize the window + // in your callback later), and this height (optional). + bool MakeWindow(int screenNum, int depth, Visual *visual, + int width=32, int height=32); + + // Unmask one X event type mask thingy (XSelectInput() arg 3) on the + // current window. Masked/unmasked events will carry between windows. + bool OpenMask(long mask); + + // (Re)mask one X event type mask thingy (XSelectInput() arg 3) on the + // current window. Masked/unmasked events will carry between windows. + bool CloseMask(long mask); + + // Destroy the connection, if appropriate; otherwise do some important + // internal session-tracking stuff (so you should call it anyway). + void Stop(); }; #endif /* - * (c) 2005, 2006 Ben Anderson, Steve Checkoway + * (c) 2005 Ben Anderson * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a -- 2.11.0