diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 853a90a14b..9c7192f8ea 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -29,6 +29,11 @@ #include "MathUtil.h" #include "MemoryUtil.h" +#if defined(HAVE_X11) && HAVE_X11 +#include +#include +#endif + #include "Console.h" #include "Core.h" #include "CPUDetect.h" @@ -92,6 +97,9 @@ bool g_bStopping = false; bool g_bHwInit = false; bool g_bRealWiimote = false; HWND g_pWindowHandle = NULL; +#if defined(HAVE_X11) && HAVE_X11 +void *g_pXWindow = NULL; +#endif Common::Thread* g_EmuThread = NULL; SCoreStartupParameter g_CoreStartupParameter; @@ -234,7 +242,45 @@ void Stop() // - Hammertime! g_EmuThread = 0; } - +#if defined(HAVE_X11) && HAVE_X11 +void ProcessXEvents(void) +{ + if (GetState() == CORE_PAUSE) + { + Display *dpy = (Display *)g_pWindowHandle; + XEvent event; + KeySym key; + int num_events; + for (num_events = XPending(dpy);num_events > 0;num_events--) + { + XNextEvent(dpy, &event); + switch(event.type) { + case KeyRelease: + key = XLookupKeysym((XKeyEvent*)&event, 0); + if(key == XK_F4 && ((event.xkey.state & Mod1Mask) == Mod1Mask)) + Host_Message(WM_USER_STOP); + break; + case ClientMessage: + if ((ulong) event.xclient.data.l[0] == XInternAtom(dpy, "WM_DELETE_WINDOW", False)) + Host_Message(WM_USER_STOP); + break; + default: + break; + } + } + } +} + +THREAD_RETURN XEventThread(void *pArg) +{ + while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) + { + ProcessXEvents(); + Common::SleepCurrentThread(200); + } + return 0; +} +#endif // Create the CPU thread. which would be a CPU + Video thread in Single Core mode. @@ -330,6 +376,9 @@ THREAD_RETURN EmuThread(void *pArg) // Under linux, this is an X11 Display, not a HWND! g_pWindowHandle = (HWND)VideoInitialize.pWindowHandle; +#if defined(HAVE_X11) && HAVE_X11 + g_pXWindow = (Window *)VideoInitialize.pXWindow; +#endif Callback_PeekMessages = VideoInitialize.pPeekMessages; g_pUpdateFPSDisplay = VideoInitialize.pUpdateFPSDisplay; @@ -352,6 +401,7 @@ THREAD_RETURN EmuThread(void *pArg) Plugins.GetDSP()->Initialize((void *)&dspInit); + // Load and init GCPadPlugin SPADInitialize PADInitialize; PADInitialize.hWnd = g_pWindowHandle; PADInitialize.pLog = Callback_PADLog; @@ -364,6 +414,9 @@ THREAD_RETURN EmuThread(void *pArg) { SWiimoteInitialize WiimoteInitialize; WiimoteInitialize.hWnd = g_pWindowHandle; +#if defined(HAVE_X11) && HAVE_X11 + WiimoteInitialize.pXWindow = g_pXWindow; +#endif WiimoteInitialize.ISOId = Ascii2Hex(_CoreParameter.m_strUniqueID); WiimoteInitialize.pLog = Callback_WiimoteLog; WiimoteInitialize.pWiimoteInput = Callback_WiimoteInput; @@ -392,6 +445,9 @@ THREAD_RETURN EmuThread(void *pArg) // Spawn the CPU thread Common::Thread *cpuThread = NULL; +#if defined(HAVE_X11) && HAVE_X11 + Common::Thread *xEventThread = NULL; +#endif // ENTER THE VIDEO THREAD LOOP if (_CoreParameter.bCPUThread) @@ -401,6 +457,9 @@ THREAD_RETURN EmuThread(void *pArg) Plugins.GetVideo()->Video_Prepare(); // wglMakeCurrent cpuThread = new Common::Thread(CpuThread, pArg); +#if defined(HAVE_X11) && HAVE_X11 + xEventThread = new Common::Thread(XEventThread, pArg); +#endif Common::SetCurrentThreadName("Video thread"); if (g_pUpdateFPSDisplay != NULL) @@ -435,6 +494,9 @@ THREAD_RETURN EmuThread(void *pArg) { if (Callback_PeekMessages) Callback_PeekMessages(); +#if defined(HAVE_X11) && HAVE_X11 + ProcessXEvents(); +#endif Common::SleepCurrentThread(20); } diff --git a/Source/PluginSpecs/pluginspecs_video.h b/Source/PluginSpecs/pluginspecs_video.h index e7c08c423b..4b7e282758 100644 --- a/Source/PluginSpecs/pluginspecs_video.h +++ b/Source/PluginSpecs/pluginspecs_video.h @@ -70,6 +70,9 @@ typedef struct typedef struct { void *pWindowHandle; +#if defined(HAVE_X11) && HAVE_X11 + void *pXWindow; +#endif TSetInterrupt pSetInterrupt; TRegisterEvent pRegisterEvent; diff --git a/Source/PluginSpecs/pluginspecs_wiimote.h b/Source/PluginSpecs/pluginspecs_wiimote.h index fe173ae000..ad9e2255cd 100644 --- a/Source/PluginSpecs/pluginspecs_wiimote.h +++ b/Source/PluginSpecs/pluginspecs_wiimote.h @@ -19,6 +19,9 @@ typedef void (*TWiimoteInput)(int _number, u16 _channelID, const void* _pData, u typedef struct { HWND hWnd; +#ifdef __linux__ + void *pXWindow; +#endif u32 ISOId; TLogv pLog; TWiimoteInput pWiimoteInput; diff --git a/Source/Plugins/Plugin_GCPad/Src/GCPad.cpp b/Source/Plugins/Plugin_GCPad/Src/GCPad.cpp index 177d1129eb..77efbd905b 100644 --- a/Source/Plugins/Plugin_GCPad/Src/GCPad.cpp +++ b/Source/Plugins/Plugin_GCPad/Src/GCPad.cpp @@ -46,7 +46,6 @@ // Variables // --------- -bool KeyStatus[LAST_CONSTANT]; bool g_SearchDeviceDone = false; CONTROLLER_MAPPING_GC GCMapping[4]; std::vector joyinfo; @@ -55,7 +54,7 @@ int NumPads = 0, NumGoodPads = 0, g_ID = 0; HWND m_hWnd = NULL; // Handle to window #endif #if defined(HAVE_X11) && HAVE_X11 - Display* WMdisplay; + Display* GCdisplay; #endif SPADInitialize *g_PADInitialize = NULL; PLUGIN_GLOBALS* globals = NULL; @@ -194,7 +193,7 @@ void Initialize(void *init) m_hWnd = (HWND)g_PADInitialize->hWnd; #endif #if defined(HAVE_X11) && HAVE_X11 - WMdisplay = (Display*)g_PADInitialize->hWnd; + GCdisplay = (Display*)g_PADInitialize->hWnd; #endif if (!g_SearchDeviceDone) @@ -268,7 +267,6 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) g_ID = _numPAD; - ReadLinuxKeyboard(); if (NumGoodPads && NumPads > GCMapping[_numPAD].ID) UpdatePadState(GCMapping[_numPAD]); @@ -611,7 +609,11 @@ bool IsKey(int Key) #else if (MapKey < 256 || MapKey > 0xf000) { - Ret = KeyStatus[Key]; // Keyboard (Linux) + char keys[32]; + KeyCode keyCode; + XQueryKeymap(GCdisplay, keys); + keyCode = XKeysymToKeycode(GCdisplay, MapKey); + Ret = (keys[keyCode/8] & (1 << (keyCode%8))); // Keyboard (Linux) #endif } else if (MapKey < 0x1100) @@ -631,67 +633,6 @@ bool IsKey(int Key) return (Ret) ? true : false; } -void ReadLinuxKeyboard() -{ -#if defined(HAVE_X11) && HAVE_X11 - XEvent E; - KeySym key; - - // keyboard input - int num_events; - for (num_events = XPending(WMdisplay); num_events > 0; num_events--) - { - XNextEvent(WMdisplay, &E); - switch (E.type) - { - case KeyPress: - { - key = XLookupKeysym((XKeyEvent*)&E, 0); - - if ((key >= XK_F1 && key <= XK_F9) || - key == XK_Shift_L || key == XK_Shift_R || - key == XK_Control_L || key == XK_Control_R || key == XK_Escape) - { - XPutBackEvent(WMdisplay, &E); - break; - } - - for (int i = 0; i < LAST_CONSTANT; i++) - { - if (((int) key) == GCMapping[g_ID].Button[i]) - KeyStatus[i] = true; - } - break; - } - case KeyRelease: - { - key = XLookupKeysym((XKeyEvent*)&E, 0); - - if ((key >= XK_F1 && key <= XK_F9) || - key == XK_Shift_L || key == XK_Shift_R || - key == XK_Control_L || key == XK_Control_R || key == XK_Escape) { - XPutBackEvent(WMdisplay, &E); - break; - } - - for (int i = 0; i < LAST_CONSTANT; i++) - { - if (((int) key) == GCMapping[g_ID].Button[i]) - KeyStatus[i] = false; - } - break; - } - case ConfigureNotify: - case ClientMessage: - XPutBackEvent(WMdisplay, &E); - break; - default: - break; - } - } -#endif -} - // Check if Dolphin is in focus // ---------------- bool IsFocus() diff --git a/Source/Plugins/Plugin_GCPad/Src/GCPad.h b/Source/Plugins/Plugin_GCPad/Src/GCPad.h index da05c02c51..d56e5d4353 100644 --- a/Source/Plugins/Plugin_GCPad/Src/GCPad.h +++ b/Source/Plugins/Plugin_GCPad/Src/GCPad.h @@ -161,7 +161,6 @@ bool Search_Devices(std::vector &_joyinfo, int &_N void GetAxisState(CONTROLLER_MAPPING_GC &_GCMapping); void UpdatePadState(CONTROLLER_MAPPING_GC &_GCMapping); bool IsKey(int Key); -void ReadLinuxKeyboard(); bool IsFocus(); bool ReloadDLL(); void PAD_RumbleClose(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 4508debee7..504e4d0433 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -402,6 +402,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight "GPU", None, NULL, 0, NULL); XMapRaised(GLWin.dpy, GLWin.win); } + g_VideoInitialize.pXWindow = (Window *) &GLWin.win; if (g_Config.bHideCursor) { // make a blank cursor @@ -475,8 +476,8 @@ bool OpenGL_MakeCurrent() } // better for pad plugin key input (thc) - XSelectInput(GLWin.dpy, GLWin.win, ExposureMask | KeyPressMask | ButtonPressMask | KeyReleaseMask | ButtonReleaseMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask | - FocusChangeMask ); + XSelectInput(GLWin.dpy, GLWin.win, ExposureMask | KeyPressMask | KeyReleaseMask | + StructureNotifyMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask ); #endif return true; } @@ -529,7 +530,6 @@ void OpenGL_Update() // We just check all of our events here XEvent event; KeySym key; - static RECT rcWindow; static bool ShiftPressed = false; static bool ControlPressed = false; static int FKeyPressed = -1; @@ -539,7 +539,7 @@ void OpenGL_Update() switch(event.type) { case KeyRelease: key = XLookupKeysym((XKeyEvent*)&event, 0); - if((key >= XK_F1 && key <= XK_F9) || (key == XK_Escape)) { + if(key >= XK_F1 && key <= XK_F9) { g_VideoInitialize.pKeyPress(FKeyPressed, ShiftPressed, ControlPressed); FKeyPressed = -1; } else { @@ -547,8 +547,6 @@ void OpenGL_Update() ShiftPressed = false; else if(key == XK_Control_L || key == XK_Control_R) ControlPressed = false; - else - XPutBackEvent(GLWin.dpy, &event); } break; case KeyPress: @@ -576,13 +574,10 @@ void OpenGL_Update() ShiftPressed = true; else if(key == XK_Control_L || key == XK_Control_R) ControlPressed = true; - else - XPutBackEvent(GLWin.dpy, &event); } break; case ButtonPress: case ButtonRelease: - XPutBackEvent(GLWin.dpy, &event); break; case ConfigureNotify: Window winDummy; @@ -591,10 +586,6 @@ void OpenGL_Update() &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth); s_backbuffer_width = GLWin.width; s_backbuffer_height = GLWin.height; - rcWindow.left = 0; - rcWindow.top = 0; - rcWindow.right = GLWin.width; - rcWindow.bottom = GLWin.height; break; case ClientMessage: if ((ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", False)) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index ce900d9472..3c5417eb30 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -348,6 +348,9 @@ void Initialize(void *init) // Now the window handle is written _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle; +#if defined(HAVE_X11) && HAVE_X11 + _pVideoInitialize->pXWindow = g_VideoInitialize.pXWindow; +#endif OSD::AddMessage("Dolphin OpenGL Video Plugin" ,5000); } diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp index 615e691627..8792346ad4 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp @@ -61,9 +61,6 @@ int NumPads = 0, NumGoodPads = 0; // Number of goods pads std::vector joyinfo; CONTROLLER_MAPPING_WII WiiMapping[MAX_WIIMOTES]; -// Keyboard input -bool KeyStatus[LAST_CONSTANT]; - } // namespace #endif //_EMU_DECLARATIONS_ diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h index 64709be80e..d6758a8fe2 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h @@ -307,7 +307,6 @@ struct CONTROLLER_MAPPING_WII // WII PAD MAPPING extern int NumPads, NumGoodPads; // Number of goods pads extern std::vector joyinfo; extern CONTROLLER_MAPPING_WII WiiMapping[4]; -extern bool KeyStatus[64]; } // namespace diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index 82d915d8b1..3965edf715 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -196,10 +196,6 @@ void LoadRecordedMovements() } } -#if defined(HAVE_X11) && HAVE_X11 -Window GLWin; -#endif - /* Calibrate the mouse position to the emulation window. g_WiimoteInitialize.hWnd is the rendering window handle. */ void GetMousePos(float& x, float& y) { @@ -223,6 +219,7 @@ void GetMousePos(float& x, float& y) float WinWidth = 0, WinHeight = 0; float XOffset = 0, YOffset = 0; int root_x, root_y, win_x, win_y; + Window GLWin = *(Window *)g_WiimoteInitialize.pXWindow; if (GLWin != 0) { XWindowAttributes WinAttribs; @@ -643,8 +640,6 @@ void Update(int _number) // Read input or not if (WiiMapping[g_ID].Source == 1) { - ReadLinuxKeyboard(); - // Check if the pad state should be updated if (NumGoodPads > 0 && joyinfo.size() > (u32)WiiMapping[g_ID].ID) UpdatePadState(WiiMapping[g_ID]); @@ -672,89 +667,4 @@ void Update(int _number) } } - -void ReadLinuxKeyboard() -{ -#if defined(HAVE_X11) && HAVE_X11 - XEvent E; - KeySym key; - - // keyboard input - int num_events; - for (num_events = XPending(WMdisplay); num_events > 0; num_events--) - { - XNextEvent(WMdisplay, &E); - GLWin = E.xany.window; - switch (E.type) - { - case KeyPress: - { - key = XLookupKeysym((XKeyEvent*)&E, 0); - - if ((key >= XK_F1 && key <= XK_F9) || - key == XK_Shift_L || key == XK_Shift_R || - key == XK_Control_L || key == XK_Control_R || key == XK_Escape) - { - XPutBackEvent(WMdisplay, &E); - break; - } - - for (int i = 0; i < LAST_CONSTANT; i++) - { - if (((int) key) == WiiMapping[g_ID].Button[i]) - KeyStatus[i] = true; - } - break; - } - case KeyRelease: - { - key = XLookupKeysym((XKeyEvent*)&E, 0); - - if ((key >= XK_F1 && key <= XK_F9) || - key == XK_Shift_L || key == XK_Shift_R || - key == XK_Control_L || key == XK_Control_R || key == XK_Escape) { - XPutBackEvent(WMdisplay, &E); - break; - } - - for (int i = 0; i < LAST_CONSTANT; i++) - { - if (((int) key) == WiiMapping[g_ID].Button[i]) - KeyStatus[i] = false; - } - break; - } - case ButtonPress: - { - int button = ((XButtonEvent*)&E)->button; - if (button == 1) - KeyStatus[EWM_A] = true; - else if (button == 3) - KeyStatus[EWM_B] = true; - else - XPutBackEvent(WMdisplay, &E); - break; - } - case ButtonRelease: - { - int button = ((XButtonEvent*)&E)->button; - if (button == 1) - KeyStatus[EWM_A] = false; - else if (button == 3) - KeyStatus[EWM_B] = false; - else - XPutBackEvent(WMdisplay, &E); - break; - } - case ConfigureNotify: - case ClientMessage: - XPutBackEvent(WMdisplay, &E); - break; - default: - break; - } - } -#endif -} - } // end of namespace diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h index feb7542c43..1fa17bdbf2 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h @@ -42,7 +42,7 @@ void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) ; void Update(int _number); void DoState(PointerWrap &p); -void ReadLinuxKeyboard(); +//void ReadLinuxKeyboard(); bool IsKey(int Key); // Recordings diff --git a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp index 54759279cc..2249219686 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp @@ -297,7 +297,7 @@ int RecordingCheckKeys(int WmNuIr) // Multi System Input Status Check bool IsKey(int Key) { - int Ret = NULL; + int Ret = false; if (WiiMapping[g_ID].Source == 1) { @@ -310,7 +310,11 @@ bool IsKey(int Key) #else if (MapKey < 256 || MapKey >= 0xf000) { - Ret = KeyStatus[Key]; // Keyboard (Linux) + char keys[32]; + KeyCode keyCode; + XQueryKeymap(WMdisplay, keys); + keyCode = XKeysymToKeycode(WMdisplay, MapKey); + Ret = (keys[keyCode/8] & (1 << (keyCode%8))); // Keyboard (Linux) #endif } else if (MapKey < 0x1100) @@ -337,8 +341,28 @@ bool IsKey(int Key) Ret = !(x < 0 || x > 1 || y < 0 || y > 1); } #endif - - } +#if defined(HAVE_X11) && HAVE_X11 + if ((Key == EWM_SHAKE) || (Key == EWM_A) || (Key == EWM_B)) + { + Window GLWin = *(Window *)g_WiimoteInitialize.pXWindow; + if (GLWin != 0) + { + int root_x, root_y, win_x, win_y; + Window rootDummy, childWin; + unsigned int mask; + XQueryPointer(WMdisplay, GLWin, &rootDummy, &childWin, &root_x, &root_y, &win_x, &win_y, &mask); + if (((Key == EWM_A) && (mask & Button1Mask)) + || ((Key == EWM_B) && (mask & Button3Mask)) + || ((Key == EWM_SHAKE) && (mask & Button3Mask))) + { + float x, y; + GetMousePos(x, y); + Ret = !(x < 0 || x > 1 || y < 0 || y > 1); + } + } + } +#endif + } return (Ret) ? true : false; }