CtrlCore: X11 version of RegisterSystemHotKey

git-svn-id: svn://ultimatepp.org/upp/trunk@1590 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2009-09-24 20:36:45 +00:00
parent 5f258ee935
commit 15e13da48d
6 changed files with 84 additions and 12 deletions

View file

@ -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

View file

@ -35,8 +35,6 @@ bool (*&DisplayErrorFn())(const Value& v)
Ctrl *Ctrl::LoopCtrl;
int Ctrl::LoopLevel;
Vector<Callback> Ctrl::hotkey;
bool Ctrl::MemoryCheck;
void Ctrl::SetData(const Value&) {}

View file

@ -580,8 +580,6 @@ private:
static Callback CtrlCall;
static Vector<Callback> 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<Callback> 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<Callback> hotkey;
static Vector<dword> modhot;
static Vector<dword> 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;

View file

@ -675,6 +675,8 @@ bool PassWindowsKey(int wParam)
|| wParam >= 0x90; // OEM keys
}
Vector<Callback> 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)

View file

@ -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);
}

View file

@ -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<Callback> Ctrl::hotkey;
Vector<dword> Ctrl::keyhot;
Vector<dword> 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<Window, Ctrl::XWindow>& xmap = Xwindow();
for(int i = 0; i < xmap.GetCount(); i++)
if(xmap[i].ctrl && xmap[i].ctrl->HookProc(event))