diff --git a/uppsrc/Core/CharSet.h b/uppsrc/Core/CharSet.h index 7a84dd306..be9a29798 100644 --- a/uppsrc/Core/CharSet.h +++ b/uppsrc/Core/CharSet.h @@ -84,7 +84,7 @@ #define CHARSET_ISO_8859_8 81 #define CHARSET_ISO_8859_9 82 #define CHARSET_JIS_X0201 83 -#define CHARSET_KOI8_R 84 +// 84 #define CHARSET_KOI8_RU 85 #define CHARSET_KOI8_T 86 #define CHARSET_KOI8_U 87 diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index 2ca61b00d..a93214717 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -35,8 +35,6 @@ bool (*&DisplayErrorFn())(const Value& v) Ctrl *Ctrl::LoopCtrl; int Ctrl::LoopLevel; -Vector Ctrl::hotkey; - bool Ctrl::MemoryCheck; void Ctrl::SetData(const Value&) {} diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 7e8c61415..63b79e760 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -580,8 +580,6 @@ private: static Callback CtrlCall; - static Vector hotkey; - static bool DoCall(); #ifdef PLATFORM_WIN32 @@ -697,6 +695,8 @@ protected: Image DoMouse(int e, Point p, int zd = 0); static void sProcessMSG(MSG& msg); + static Vector hotkey; + friend void sSetCursor(Ctrl *ctrl, const Image& m); public: @@ -746,6 +746,9 @@ private: XWindow *GetXWindow(); static void SyncMousePos(); static void ReleaseGrab(); + static Vector hotkey; + static Vector modhot; + static Vector keyhot; void StartPopupGrab(); static void EndPopupGrab(); @@ -807,8 +810,8 @@ public: virtual bool HookProc(XEvent *event); Window GetWindow() const { return top ? top->window : None; } static Ctrl *CtrlFromWindow(Window w); - bool TrapX11Errors(); - void UntrapX11Errors(bool b); + static bool TrapX11Errors(); + static void UntrapX11Errors(bool b); Window GetParentWindow(void) const; Ctrl *GetParentWindowCtrl(void) const; diff --git a/uppsrc/CtrlCore/Win32Wnd.cpp b/uppsrc/CtrlCore/Win32Wnd.cpp index a7eefa425..1e4846313 100644 --- a/uppsrc/CtrlCore/Win32Wnd.cpp +++ b/uppsrc/CtrlCore/Win32Wnd.cpp @@ -675,6 +675,8 @@ bool PassWindowsKey(int wParam) || wParam >= 0x90; // OEM keys } +Vector Ctrl::hotkey; + int Ctrl::RegisterSystemHotKey(dword key, Callback cb) { ASSERT(key >= K_DELTA); @@ -693,15 +695,15 @@ int Ctrl::RegisterSystemHotKey(dword key, Callback cb) if(key & K_CTRL) mod |= MOD_CONTROL; - RegisterHotKey(NULL, q, mod, key & 0xffff); - return q; + return RegisterHotKey(NULL, q, mod, key & 0xffff) ? q : -1; } void Ctrl::UnregisterSystemHotKey(int id) { - ASSERT(id >= 0 && id < hotkey.GetCount()); - UnregisterHotKey(NULL, id); - hotkey[id].Clear(); + if(id >= 0 && id < hotkey.GetCount()) { + UnregisterHotKey(NULL, id); + hotkey[id].Clear(); + } } void Ctrl::sProcessMSG(MSG& msg) diff --git a/uppsrc/CtrlCore/X11App.cpp b/uppsrc/CtrlCore/X11App.cpp index 27d22eee3..0347925d7 100644 --- a/uppsrc/CtrlCore/X11App.cpp +++ b/uppsrc/CtrlCore/X11App.cpp @@ -430,6 +430,8 @@ void Ctrl::ExitX11() GuiLock __; // if(xic) // XDestroyIC(xic); + for(int i = 0; i < hotkey.GetCount(); i++) + UnregisterSystemHotKey(i); if(xim) XCloseIM(xim); } diff --git a/uppsrc/CtrlCore/X11Wnd.cpp b/uppsrc/CtrlCore/X11Wnd.cpp index 02cecdee8..c3d9a0c6b 100644 --- a/uppsrc/CtrlCore/X11Wnd.cpp +++ b/uppsrc/CtrlCore/X11Wnd.cpp @@ -161,11 +161,78 @@ bool Ctrl::HookProc(XEvent *event) { return false; } void DnDRequest(XSelectionRequestEvent *se); void DnDClear(); +dword X11mods(dword key) +{ + dword mod = 0; + if(key & K_ALT) + mod |= Mod1Mask; + if(key & K_SHIFT) + mod |= ShiftMask; + if(key & K_CTRL) + mod |= ControlMask; + return mod; +} + +Vector Ctrl::hotkey; +Vector Ctrl::keyhot; +Vector Ctrl::modhot; + +int Ctrl::RegisterSystemHotKey(dword key, Callback cb) +{ + GuiLock __; + ASSERT(key >= K_DELTA); + bool b = TrapX11Errors(); + KeyCode k = XKeysymToKeycode(Xdisplay, key & 0xffff); + dword mod = X11mods(key); + bool r = false; + for(dword nlock = 0; nlock < 2; nlock++) + for(dword clock = 0; clock < 2; clock++) + for(dword slock = 0; slock < 2; slock++) + r = XGrabKey(Xdisplay, k, + mod | (nlock * Mod2Mask) | (clock * LockMask) | (slock * Mod3Mask), + Xroot, true, GrabModeAsync, GrabModeAsync) || r; + UntrapX11Errors(b); + if(!r) return -1; + int q = hotkey.GetCount(); + for(int i = 0; i < hotkey.GetCount(); i++) + if(!hotkey[i]) { + q = i; + break; + } + hotkey.At(q) = cb; + keyhot.At(q) = k; + modhot.At(q) = mod; + return q; +} + +void Ctrl::UnregisterSystemHotKey(int id) +{ + GuiLock __; + if(id >= 0 && id < hotkey.GetCount() && hotkey[id]) { + bool b = TrapX11Errors(); + for(dword nlock = 0; nlock < 2; nlock++) + for(dword clock = 0; clock < 2; clock++) + for(dword slock = 0; slock < 2; slock++) + XUngrabKey(Xdisplay, keyhot[id], + modhot[id] | (nlock * Mod2Mask) | (clock * LockMask) | (slock * Mod3Mask), + Xroot); + UntrapX11Errors(b); + hotkey[id].Clear(); + } +} + void Ctrl::ProcessEvent(XEvent *event) { GuiLock __; if(xim && XFilterEvent(event, None)) return; + if(event->type == KeyPress) + for(int i = 0; i < hotkey.GetCount(); i++) + if(hotkey[i] && keyhot[i] == event->xkey.keycode + && modhot[i] == (event->xkey.state & (Mod1Mask|ShiftMask|ControlMask))) { + hotkey[i](); + return; + } ArrayMap& xmap = Xwindow(); for(int i = 0; i < xmap.GetCount(); i++) if(xmap[i].ctrl && xmap[i].ctrl->HookProc(event))