summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Zanoni <przanoni@src.gnome.org>2007-07-10 03:05:15 +0000
committerPaulo Zanoni <przanoni@src.gnome.org>2007-07-10 03:05:15 +0000
commit50e482c2509992074576f3f98b02604765cbb8fb (patch)
tree6fae9e351e15677f568ab85659556a87fede43d1
parentd8fd99eb79bdb002f5fd05b261c76b7b63c5e9fa (diff)
downloadmetacity-50e482c2509992074576f3f98b02604765cbb8fb.tar.gz
Corrected RadioButtons.
Adds option to enable/disable device access to windows. Corrects a few bugs. svn path=/branches/multiple_pointer_x/; revision=3265
-rw-r--r--src/common.h39
-rw-r--r--src/core.c6
-rw-r--r--src/display.c7
-rw-r--r--src/frames.c2
-rw-r--r--src/menu.c186
-rw-r--r--src/window.c64
-rw-r--r--src/window.h2
7 files changed, 247 insertions, 59 deletions
diff --git a/src/common.h b/src/common.h
index 8571c9f3..5501c781 100644
--- a/src/common.h
+++ b/src/common.h
@@ -52,28 +52,29 @@ typedef enum
typedef enum
{
- META_MENU_OP_DELETE = 1 << 0,
- META_MENU_OP_MINIMIZE = 1 << 1,
- META_MENU_OP_UNMAXIMIZE = 1 << 2,
- META_MENU_OP_MAXIMIZE = 1 << 3,
- META_MENU_OP_UNSHADE = 1 << 4,
- META_MENU_OP_SHADE = 1 << 5,
- META_MENU_OP_UNSTICK = 1 << 6,
- META_MENU_OP_STICK = 1 << 7,
- META_MENU_OP_WORKSPACES = 1 << 8,
- META_MENU_OP_MOVE = 1 << 9,
- META_MENU_OP_RESIZE = 1 << 10,
- META_MENU_OP_ABOVE = 1 << 11,
- META_MENU_OP_UNABOVE = 1 << 12,
- META_MENU_OP_MOVE_LEFT = 1 << 13,
- META_MENU_OP_MOVE_RIGHT = 1 << 14,
- META_MENU_OP_MOVE_UP = 1 << 15,
- META_MENU_OP_MOVE_DOWN = 1 << 16,
+ META_MENU_OP_DELETE = 1 << 0,
+ META_MENU_OP_MINIMIZE = 1 << 1,
+ META_MENU_OP_UNMAXIMIZE = 1 << 2,
+ META_MENU_OP_MAXIMIZE = 1 << 3,
+ META_MENU_OP_UNSHADE = 1 << 4,
+ META_MENU_OP_SHADE = 1 << 5,
+ META_MENU_OP_UNSTICK = 1 << 6,
+ META_MENU_OP_STICK = 1 << 7,
+ META_MENU_OP_WORKSPACES = 1 << 8,
+ META_MENU_OP_MOVE = 1 << 9,
+ META_MENU_OP_RESIZE = 1 << 10,
+ META_MENU_OP_ABOVE = 1 << 11,
+ META_MENU_OP_UNABOVE = 1 << 12,
+ META_MENU_OP_MOVE_LEFT = 1 << 13,
+ META_MENU_OP_MOVE_RIGHT = 1 << 14,
+ META_MENU_OP_MOVE_UP = 1 << 15,
+ META_MENU_OP_MOVE_DOWN = 1 << 16,
#ifdef MPX
- META_MENU_OP_RECOVER = 1 << 17,
+ META_MENU_OP_RECOVER = 1 << 17,
META_MENU_OP_CLIENT_POINTER = 1 << 18,
+ META_MENU_OP_ALLOW_ACCESS = 1 << 19
#else
- META_MENU_OP_RECOVER = 1 << 17
+ META_MENU_OP_RECOVER = 1 << 17
#endif
} MetaMenuOp;
diff --git a/src/core.c b/src/core.c
index 1454105e..4efe6798 100644
--- a/src/core.c
+++ b/src/core.c
@@ -481,6 +481,12 @@ meta_core_get_menu_accelerator (MetaMenuOp menu_op,
{
const char *name;
+ /* #ifdef MPX
+ * FIXME:
+ * warning: enumeration value 'META_MENU_OP_CLIENT_POINTER' not handled in
+ * switch. (the same for META_MENU_OP_ALLOW_DEVICES)
+ * #endif */
+
name = NULL;
switch (menu_op)
diff --git a/src/display.c b/src/display.c
index e27a3271..14ef5b0e 100644
--- a/src/display.c
+++ b/src/display.c
@@ -813,9 +813,8 @@ meta_display_open (void)
d = &display->devices;
- /* We should register ourselves as the pairing client here, and also as
- * the access control manager too.
- * XXX XRegisterPairingClient, XGrabAccessControl */
+ /* We should register ourselves as the pairing client here
+ * XXX XRegisterPairingClient */
d->mice = g_malloc(sizeof(XID) * DEFAULT_INPUT_ARRAY_SIZE);
d->keyboards = g_malloc(sizeof(XID) * DEFAULT_INPUT_ARRAY_SIZE);
@@ -850,7 +849,7 @@ meta_display_open (void)
d->keyboards[d->keybsUsed].name =
g_strdup_printf("%s", devInfo->name);
- XGetPairedPointer(display->xdisplay, kDev, (int *) &pDevId);
+ XGetPairedPointer(display->xdisplay, kDev, &pDevId);
meta_warning("opening device id %d\n",
(int)pDevId); /* XXX */
open = XOpenDevice(display->xdisplay, pDevId);
diff --git a/src/frames.c b/src/frames.c
index 76f80c2c..c14e73ba 100644
--- a/src/frames.c
+++ b/src/frames.c
@@ -594,7 +594,7 @@ meta_frames_manage_window (MetaFrames *frames,
*/
meta_core_grab_buttons (gdk_display, frame->xwindow);
-
+
g_hash_table_replace (frames->frames, &frame->xwindow, frame);
}
diff --git a/src/menu.c b/src/menu.c
index 73f40ff4..e7bc7f1c 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -513,18 +513,16 @@ meta_window_menu_new (MetaFrames *frames,
#ifdef MPX
{
- GtkWidget *submenu;
- GtkWidget *submenuitem;
-
+ GtkWidget *mi;
MenuItem sep = { 0, MENU_ITEM_SEPARATOR, NULL, FALSE, NULL };
- submenu = gtk_menu_new();
- submenuitem = menu_item_new (&sep, -1);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), submenuitem);
- gtk_widget_show (submenuitem);
+ mi = menu_item_new(&sep, -1);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), mi);
+ gtk_widget_show (mi);
}
{
/* SetClientPointer menu */
+
Display *display;
GtkWidget *submenu;
@@ -533,7 +531,7 @@ meta_window_menu_new (MetaFrames *frames,
MenuItem select_client_pointer = {
0, MENU_ITEM_NORMAL, NULL,
- FALSE, N_("Select Client Pointer")
+ FALSE, N_("Client pointer")
};
submenu = gtk_menu_new ();
@@ -545,40 +543,160 @@ meta_window_menu_new (MetaFrames *frames,
display = gdk_x11_drawable_get_xdisplay (GTK_WIDGET (frames)->window);
/* Someone might have changed the clientPointer! */
- XGetClientPointer(display, client_xwindow, (int *)&clientPtr);
- meta_warning("my mouse is %d\n", (int) clientPtr); /* XXX */
+ XGetClientPointer(display, client_xwindow, &clientPtr);
+
+ for (i = 0; i < devices->miceUsed; i++)
+ {
+
+ MenuItem setcpitem;
+ MenuData *md;
+ GtkWidget *mi;
+
+ setcpitem.type = MENU_ITEM_RADIOBUTTON;
+ setcpitem.op = META_MENU_OP_CLIENT_POINTER;
+ setcpitem.label = devices->mice[i].name;
+ mi = menu_item_new (&setcpitem, i+1);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
+ (clientPtr == devices->mice[i].xdev->device_id) ? 1 : 0);
+
+ md = g_new (MenuData, 1);
+ md->menu = menu;
+ md->op = META_MENU_OP_CLIENT_POINTER;
+ g_object_set_data (G_OBJECT(mi),
+ "device",
+ &devices->mice[i]);
+ gtk_signal_connect_full (GTK_OBJECT (mi),
+ "activate",
+ GTK_SIGNAL_FUNC (activate_cb),
+ NULL,
+ md,
+ g_free, FALSE, FALSE);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mi);
+ gtk_widget_show (mi);
+ }
+ }
- for (i = 0; i < devices->miceUsed; i++) {
+ {
+ /* Enable devices menu */
+ Display *display;
- MenuItem moveitem;
- MenuData *md;
- GtkWidget *mi;
+ GtkWidget *submenu;
+ GtkWidget *submenuitem;
+
+ int rule, nperm, ndeny, j;
+ XID *perm, *deny;
+
+ int allowed;
- moveitem.type = MENU_ITEM_RADIOBUTTON;
- moveitem.op = META_MENU_OP_CLIENT_POINTER;
- moveitem.label = devices->mice[i].name;
- meta_warning("name = %s\n", moveitem.label);
- /* XXX gotta make radiobuttons appear as checked!
- moveitem.checked = (clientPtr == `this guy`) ? 1 : 0; */
- mi = menu_item_new (&moveitem, i+1);
-
- md = g_new (MenuData, 1);
- md->menu = menu;
- md->op = META_MENU_OP_CLIENT_POINTER;
- g_object_set_data (G_OBJECT(mi),
- "device",
- &devices->mice[i]);
- gtk_signal_connect_full (GTK_OBJECT (mi),
- "activate",
- GTK_SIGNAL_FUNC (activate_cb),
- NULL,
- md,
- g_free, FALSE, FALSE);
+ MenuItem allowed_devices = {
+ 0, MENU_ITEM_NORMAL, NULL,
+ FALSE, N_("Allowed devices")
+ };
+
+ submenu = gtk_menu_new ();
+ submenuitem = menu_item_new (&allowed_devices, -1);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (submenuitem), submenu);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), submenuitem);
+ gtk_widget_show (submenuitem);
+ display = gdk_x11_drawable_get_xdisplay (GTK_WIDGET (frames)->window);
+
+ /* Gotta know which device has access to the window... Currently, we're
+ * doing this by calling XQueryWindowAccess everytime. But maybe we could
+ * store information on the windows. The problem is that if a client makes a
+ * change, we won't be able to discover (will we? do we have an xevent for
+ * it?) */
+ XQueryWindowAccess(display, client_xwindow, &rule, &perm, &nperm,
+ &deny, &ndeny);
+
+ for (i = 0; i < devices->miceUsed; i++)
+ {
+
+ /* Add the mice to the menu */
+ MenuItem alwdevitem;
+ MenuData *md;
+ GtkWidget *mi;
+
+ alwdevitem.type = MENU_ITEM_CHECKBOX;
+ alwdevitem.op = META_MENU_OP_ALLOW_ACCESS;
+ alwdevitem.label = devices->mice[i].name;
+ mi = menu_item_new (&alwdevitem, i+1);
+ allowed = 1;
+ for (j = 0; j < ndeny; j++)
+ if (devices->mice[i].xdev->device_id == deny[j] )
+ allowed = 0;
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), allowed);
+
+ md = g_new (MenuData, 1);
+ md->menu = menu;
+ md->op = META_MENU_OP_ALLOW_ACCESS;
+ g_object_set_data (G_OBJECT(mi),
+ "device",
+ &devices->mice[i]);
+ gtk_signal_connect_full (GTK_OBJECT (mi),
+ "activate",
+ GTK_SIGNAL_FUNC (activate_cb),
+ NULL,
+ md,
+ g_free, FALSE, FALSE);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mi);
+ gtk_widget_show (mi);
+
+ }
+
+
+ /* Add a separator */
+ {
+ GtkWidget *mi;
+ MenuItem sep = { 0, MENU_ITEM_SEPARATOR, NULL, FALSE, NULL };
+ mi = menu_item_new(&sep, -1);
gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mi);
gtk_widget_show (mi);
}
+
+ for (i = 0; i < devices->keybsUsed; i++)
+ {
+
+ /* Add the keyboards to the menu */
+ MenuItem alwdevitem;
+ MenuData *md;
+ GtkWidget *mi;
+
+ alwdevitem.type = MENU_ITEM_CHECKBOX;
+ alwdevitem.op = META_MENU_OP_ALLOW_ACCESS;
+ alwdevitem.label = devices->keyboards[i].name;
+ mi = menu_item_new (&alwdevitem, i+1);
+
+ allowed = 1;
+ for (j = 0; j < ndeny; j++)
+ if (devices->keyboards[i].xdev->device_id == deny[j] )
+ allowed = 0;
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), allowed);
+
+ md = g_new (MenuData, 1);
+ md->menu = menu;
+ md->op = META_MENU_OP_ALLOW_ACCESS;
+ g_object_set_data (G_OBJECT(mi),
+ "device",
+ &devices->keyboards[i]);
+ gtk_signal_connect_full (GTK_OBJECT (mi),
+ "activate",
+ GTK_SIGNAL_FUNC (activate_cb),
+ NULL,
+ md,
+ g_free, FALSE, FALSE);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mi);
+ gtk_widget_show (mi);
+
+ }
+ XFree(perm);
+ XFree(deny);
+
}
+
#endif
return menu;
diff --git a/src/window.c b/src/window.c
index 1d5dcc06..3cd013e3 100644
--- a/src/window.c
+++ b/src/window.c
@@ -49,6 +49,10 @@
#include <X11/Xatom.h>
#include <string.h>
+#ifdef MPX
+#include <stdlib.h>
+#endif
+
#ifdef HAVE_SHAPE
#include <X11/extensions/shape.h>
#endif
@@ -6264,11 +6268,65 @@ void
meta_window_set_client_pointer (Display *xdisplay, MetaWindow *window,
MetaDevInfo *dev)
{
- meta_warning("Changing client pointer to %s\n", dev->name); /* XXX */
XSetClientPointer(xdisplay, window->xwindow, dev->xdev);
return;
}
+
+void
+meta_window_change_access (Display *xdisplay, MetaWindow *window,
+ MetaDevInfo *dev)
+{
+
+ /* Metacity's behavior is: we always play with deny lists. According to
+ * xserver/dix/access.c:250, permit lists have priority over deny lists. So,
+ * if applications want to overwrite metacity's settings, they must use the
+ * "permit" lists. Metacity also sets NO default rule. */
+ int rule, nperm, ndeny, i, allowed;
+ XID *perm, *deny;
+
+ /* Read menu.c:~605 comments about calling XQueryWindowAccess evertytime */
+ XQueryWindowAccess(xdisplay, window->xwindow, &rule, &perm, &nperm, &deny,
+ &ndeny);
+
+ allowed = 1;
+ for (i = 0; i < ndeny; i++)
+ {
+ if (! allowed)
+ /* We already know that we are going to have to remove the device from
+ * the list, so let's do it now! */
+ deny[i-1] = deny[i];
+ if (dev->xdev->device_id == deny[i])
+ allowed = 0;
+ }
+
+ if (XGrabAccessControl(xdisplay))
+ {
+ if (allowed)
+ {
+ /* Put him into the deny list! */
+ /* XXX We're reallocating something allocated by xlib can't is be
+ * dangerous? Had no problem until now... */
+ deny = (XID *) realloc (deny, sizeof(XID) * ndeny +1);
+ deny[ndeny] = dev->xdev->device_id;
+ XDenyDevices(xdisplay, window->xwindow, deny, ndeny +1);
+ }
+ else
+ {
+ /* Remove him from the deny list! */
+ XDenyDevices(xdisplay, window->xwindow, deny, ndeny -1);
+ }
+ XUngrabAccessControl(xdisplay);
+ }
+ else
+ meta_warning("Couldn't grab access control!\n");
+
+ XFree(perm); /* This one can be XFree'd */
+ XFree(deny); /* This one was (probably) reallocated by realloc! */
+
+ return;
+}
+
#endif
#ifdef MPX
@@ -6399,6 +6457,10 @@ menu_callback (MetaWindowMenu *menu,
case META_MENU_OP_CLIENT_POINTER:
meta_window_set_client_pointer (xdisplay, window, device);
break;
+
+ case META_MENU_OP_ALLOW_ACCESS:
+ meta_window_change_access (xdisplay, window, device);
+ break;
#endif
case 0:
diff --git a/src/window.h b/src/window.h
index 8195a65b..2d2386e0 100644
--- a/src/window.h
+++ b/src/window.h
@@ -611,6 +611,8 @@ void meta_window_update_icon_now (MetaWindow *window);
#ifdef MPX
void meta_window_set_client_pointer (Display *xdisplay, MetaWindow *window,
MetaDevInfo *dev);
+void meta_window_change_access (Display *xdisplay, MetaWindow *window,
+ MetaDevInfo *dev);
#endif
#endif