diff options
author | Perberos <[email protected]> | 2011-12-01 22:56:10 -0300 |
---|---|---|
committer | Perberos <[email protected]> | 2011-12-01 22:56:10 -0300 |
commit | c51ef797a707f4e2c6f9688d4378f2b0e9898a66 (patch) | |
tree | 019ae92bb53c19b30077545cb14743cbd1b57aef /mate-panel/panel-xutils.c | |
download | mate-panel-c51ef797a707f4e2c6f9688d4378f2b0e9898a66.tar.bz2 mate-panel-c51ef797a707f4e2c6f9688d4378f2b0e9898a66.tar.xz |
moving from https://github.com/perberos/mate-desktop-environment
Diffstat (limited to 'mate-panel/panel-xutils.c')
-rw-r--r-- | mate-panel/panel-xutils.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/mate-panel/panel-xutils.c b/mate-panel/panel-xutils.c new file mode 100644 index 00000000..4480f193 --- /dev/null +++ b/mate-panel/panel-xutils.c @@ -0,0 +1,258 @@ +/* + * panel-xutils.c: X related utility methods. + * + * Copyright (C) 2003 Sun Microsystems, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Authors: + * Mark McLoughlin <[email protected]> + */ + +#include "config.h" + +#include "panel-xutils.h" + +#include <glib.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> + +static Atom net_wm_window_type = None; +static Atom net_wm_window_type_dock = None; +static Atom net_wm_window_type_normal = None; +static Atom net_wm_strut = None; +static Atom net_wm_strut_partial = None; + +void +panel_xutils_set_window_type (GdkWindow *gdk_window, + PanelXUtilsWindowType type) +{ + Display *display; + Window window; + Atom atoms [2]; + int i = 0; + + g_return_if_fail (GDK_IS_WINDOW (gdk_window)); + + display = GDK_WINDOW_XDISPLAY (gdk_window); + window = GDK_WINDOW_XWINDOW (gdk_window); + + if (net_wm_window_type == None) + net_wm_window_type = XInternAtom (display, + "_NET_WM_WINDOW_TYPE", + False); + + switch (type) { + case PANEL_XUTILS_TYPE_DOCK: + if (net_wm_window_type_dock == None) + net_wm_window_type_dock = XInternAtom (display, + "_NET_WM_WINDOW_TYPE_DOCK", + False); + atoms [i++] = net_wm_window_type_dock; + break; + case PANEL_XUTILS_TYPE_NORMAL: + if (net_wm_window_type_normal == None) + net_wm_window_type_normal = XInternAtom (display, + "_NET_WM_WINDOW_TYPE_NORMAL", + False); + atoms [i++] = net_wm_window_type_normal; + break; + default: + g_assert_not_reached (); + break; + } + + gdk_error_trap_push (); + XChangeProperty (display, window, net_wm_window_type, + XA_ATOM, 32, PropModeReplace, + (guchar *) &atoms, i); + gdk_error_trap_pop (); +} + +enum { + STRUT_LEFT = 0, + STRUT_RIGHT = 1, + STRUT_TOP = 2, + STRUT_BOTTOM = 3, + STRUT_LEFT_START = 4, + STRUT_LEFT_END = 5, + STRUT_RIGHT_START = 6, + STRUT_RIGHT_END = 7, + STRUT_TOP_START = 8, + STRUT_TOP_END = 9, + STRUT_BOTTOM_START = 10, + STRUT_BOTTOM_END = 11 +}; + +void +panel_xutils_set_strut (GdkWindow *gdk_window, + PanelOrientation orientation, + guint32 strut, + guint32 strut_start, + guint32 strut_end) + { + Display *display; + Window window; + gulong struts [12] = { 0, }; + + g_return_if_fail (GDK_IS_WINDOW (gdk_window)); + + display = GDK_WINDOW_XDISPLAY (gdk_window); + window = GDK_WINDOW_XWINDOW (gdk_window); + + if (net_wm_strut == None) + net_wm_strut = XInternAtom (display, "_NET_WM_STRUT", False); + if (net_wm_strut_partial == None) + net_wm_strut_partial = XInternAtom (display, "_NET_WM_STRUT_PARTIAL", False); + + switch (orientation) { + case PANEL_ORIENTATION_LEFT: + struts [STRUT_LEFT] = strut; + struts [STRUT_LEFT_START] = strut_start; + struts [STRUT_LEFT_END] = strut_end; + break; + case PANEL_ORIENTATION_RIGHT: + struts [STRUT_RIGHT] = strut; + struts [STRUT_RIGHT_START] = strut_start; + struts [STRUT_RIGHT_END] = strut_end; + break; + case PANEL_ORIENTATION_TOP: + struts [STRUT_TOP] = strut; + struts [STRUT_TOP_START] = strut_start; + struts [STRUT_TOP_END] = strut_end; + break; + case PANEL_ORIENTATION_BOTTOM: + struts [STRUT_BOTTOM] = strut; + struts [STRUT_BOTTOM_START] = strut_start; + struts [STRUT_BOTTOM_END] = strut_end; + break; + } + + gdk_error_trap_push (); + XChangeProperty (display, window, net_wm_strut, + XA_CARDINAL, 32, PropModeReplace, + (guchar *) &struts, 4); + XChangeProperty (display, window, net_wm_strut_partial, + XA_CARDINAL, 32, PropModeReplace, + (guchar *) &struts, 12); + gdk_error_trap_pop (); +} + +void +panel_warp_pointer (GdkWindow *gdk_window, + int x, + int y) +{ + Display *display; + Window window; + + g_return_if_fail (GDK_IS_WINDOW (gdk_window)); + + display = GDK_WINDOW_XDISPLAY (gdk_window); + window = GDK_WINDOW_XWINDOW (gdk_window); + + gdk_error_trap_push (); + XWarpPointer (display, None, window, 0, 0, 0, 0, x, y); + gdk_error_trap_pop (); +} + +guint +panel_get_real_modifier_mask (guint mask) +{ + guint real_mask; + Display *display; + int i, min_keycode, max_keycode, keysyms_per_keycode; + int max_keycodes_per_modifier; + KeySym *keysyms_for_keycodes; + XModifierKeymap *modifier_keymap; + + real_mask = mask & ((Mod5Mask << 1) - 1); + + /* Already real */ + if (mask == real_mask) { + return mask; + } + + display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + + XDisplayKeycodes (display, &min_keycode, &max_keycode); + keysyms_for_keycodes = XGetKeyboardMapping (display, + min_keycode, + max_keycode - min_keycode + 1, + &keysyms_per_keycode); + + modifier_keymap = XGetModifierMapping (display); + max_keycodes_per_modifier = modifier_keymap->max_keypermod; + + /* Loop through all the modifiers and find out which "real" + * (Mod2..Mod5) modifiers Super, Hyper, and Meta are mapped to. + * Note, Mod1 is used by the Alt modifier */ + for (i = Mod2MapIndex * max_keycodes_per_modifier; + i < (Mod5MapIndex + 1) * max_keycodes_per_modifier; + i++) { + int keycode; + int j; + KeySym *keysyms_for_keycode; + int map_index; + int map_mask; + + keycode = modifier_keymap->modifiermap[i]; + + /* The array is sparse, there may be some + * empty entries. Filter those out + * (along with any invalid entries) */ + if (keycode < min_keycode || keycode > max_keycode) + continue; + + keysyms_for_keycode = keysyms_for_keycodes + + (keycode - min_keycode) * keysyms_per_keycode; + + map_index = i / max_keycodes_per_modifier; + + g_assert (map_index <= Mod5MapIndex); + + map_mask = 1 << map_index; + + for (j = 0; j < keysyms_per_keycode; j++) { + switch (keysyms_for_keycode[j]) { + case XK_Super_L: + case XK_Super_R: + if (mask & GDK_SUPER_MASK) + real_mask |= map_mask; + break; + case XK_Hyper_L: + case XK_Hyper_R: + if (mask & GDK_HYPER_MASK) + real_mask |= map_mask; + break; + case XK_Meta_L: + case XK_Meta_R: + if (mask & GDK_META_MASK) + real_mask |= map_mask; + break; + default: + break; + } + } + } + + XFreeModifiermap (modifier_keymap); + XFree (keysyms_for_keycodes); + + return real_mask; +} |