diff options
author | Paulo Zanoni <przanoni@src.gnome.org> | 2007-07-04 02:45:07 +0000 |
---|---|---|
committer | Paulo Zanoni <przanoni@src.gnome.org> | 2007-07-04 02:45:07 +0000 |
commit | d8fd99eb79bdb002f5fd05b261c76b7b63c5e9fa (patch) | |
tree | 4fa43cf5e90c434a8f9088079f2a4362e049375c | |
parent | 92c63dfdc51efbcc372ce6770bebe437d5c02dc9 (diff) | |
download | metacity-d8fd99eb79bdb002f5fd05b261c76b7b63c5e9fa.tar.gz |
Initial commit. Added the structures to enable compiling. Added an initial
Initial commit.
Added the structures to enable compiling.
Added an initial infrastructure to work with multiple devices.
Added the SetClientPointer option.
svn path=/branches/multiple_pointer_x/; revision=3263
-rw-r--r-- | configure.in | 30 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/common.h | 21 | ||||
-rw-r--r-- | src/devices.h | 61 | ||||
-rw-r--r-- | src/display.c | 93 | ||||
-rw-r--r-- | src/display.h | 8 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/menu.c | 104 | ||||
-rw-r--r-- | src/menu.h | 16 | ||||
-rw-r--r-- | src/ui.c | 25 | ||||
-rw-r--r-- | src/ui.h | 16 | ||||
-rw-r--r-- | src/window.c | 46 | ||||
-rw-r--r-- | src/window.h | 5 |
13 files changed, 427 insertions, 4 deletions
diff --git a/configure.in b/configure.in index 9d909b0b..d3cf72e3 100644 --- a/configure.in +++ b/configure.in @@ -158,6 +158,11 @@ AC_ARG_ENABLE(shape, [disable metacity's use of the shaped window extension]),, enable_shape=auto) +AC_ARG_ENABLE(mpx, + AC_HELP_STRING([--enable-mpx], + [enable multiple-pointer xserver features]),, + enable_mpx=no) + ## try definining HAVE_BACKTRACE AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)]) @@ -362,6 +367,28 @@ if test "x$found_shape" = "xyes"; then AC_DEFINE(HAVE_SHAPE, , [Have the shape extension library]) fi +XINPUT_LIBS= +found_xinput=no +AC_CHECK_LIB(Xi, XGetExtensionVersion, + [AC_CHECK_HEADER(X11/extensions/XInput.h, + XINPUT_LIBS=-lXi found_xinput=yes)], + , $ALL_X_LIBS) + +if test x$enable_mpx = xno; then + found_xinput=no +fi + +if test x$enable_mpx = xyes; then + if test "$found_xinput" = "no"; then + AC_MSG_ERROR([--enable-mpx forced and XInput not found]) + exit 1 + fi +fi + +if test "x$found_xinput" = "xyes"; then + AC_DEFINE(MPX, ,[Build with multiple-pointer xserver features]) +fi + found_xkb=no AC_CHECK_LIB(X11, XkbQueryExtension, [AC_CHECK_HEADER(X11/XKBlib.h, @@ -409,7 +436,7 @@ if test "x$found_xsync" = "xyes"; then AC_DEFINE(HAVE_XSYNC, , [Have the Xsync extension library]) fi -METACITY_LIBS="$METACITY_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" +METACITY_LIBS="$METACITY_LIBS $XSYNC_LIBS $RANDR_LIBS $XINPUT_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" METACITY_MESSAGE_LIBS="$METACITY_MESSAGE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" METACITY_WINDOW_DEMO_LIBS="$METACITY_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" METACITY_PROPS_LIBS="$METACITY_PROPS_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" @@ -521,6 +548,7 @@ metacity-$VERSION: Xsync: ${found_xsync} Render: ${have_xrender} Xcursor: ${have_xcursor} + Multiple-pointer xserver: ${enable_mpx} " METACITY_MINOR_VERSION=metacity_minor_version diff --git a/src/Makefile.am b/src/Makefile.am index 40b349ed..c800b390 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,7 @@ metacity_SOURCES= \ core.c \ core.h \ delete.c \ + devices.h \ display.c \ display.h \ draw-workspace.c \ @@ -111,7 +112,8 @@ libmetacity_private_la_SOURCES= \ theme-parser.h \ util.c \ util.h \ - common.h + common.h \ + devices.h libmetacity_private_la_LDFLAGS = -no-undefined libmetacity_private_la_LIBADD = @METACITY_LIBS@ diff --git a/src/common.h b/src/common.h index 8bdce9d3..8571c9f3 100644 --- a/src/common.h +++ b/src/common.h @@ -69,11 +69,31 @@ typedef enum 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_CLIENT_POINTER = 1 << 18, +#else META_MENU_OP_RECOVER = 1 << 17 +#endif } MetaMenuOp; typedef struct _MetaWindowMenu MetaWindowMenu; + +#ifdef MPX +/* This was defined here so I don't need to include devices.h on this file */ +typedef struct _MetaDevInfo MetaDevInfo; + +typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu, + Display *xdisplay, + Window client_xwindow, + guint32 timestamp, + MetaMenuOp op, + int workspace, + MetaDevInfo *pointer, + gpointer data); + +#else typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu, Display *xdisplay, Window client_xwindow, @@ -81,6 +101,7 @@ typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu, MetaMenuOp op, int workspace, gpointer data); +#endif /* when changing this enum, there are various switch statements * you have to update diff --git a/src/devices.h b/src/devices.h new file mode 100644 index 00000000..10be1456 --- /dev/null +++ b/src/devices.h @@ -0,0 +1,61 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* Metacity device structures */ + +/* + * Copyright (C) 2007 Paulo Ricardo Zanoni + * + * 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. + */ + +#ifndef META_DEVICES_H +#define META_DEVICES_H + +#ifdef MPX + +#include <X11/extensions/XInput.h> + +#include "common.h" + +/* By default, the MetaDevInfo lists have size 8. Almost no client has more + * than 8 mice or keyboards... */ +/* FIXME setting this define to 1 or 2 causes memory corruption!!!! */ +#define DEFAULT_INPUT_ARRAY_SIZE 8 + +typedef struct _MetaDevices MetaDevices; +/* typedef struct _MetaDevInfo MetaDevInfo; This guy was declared at common.h */ + +struct _MetaDevInfo +{ + XDevice *xdev; + gchar *name; +}; + +struct _MetaDevices +{ + MetaDevInfo *mice; + int miceUsed; + int miceSize; + + MetaDevInfo *keyboards; + int keybsUsed; + int keybsSize; + MetaDevInfo *pairedPointers; +}; + +#endif + +#endif diff --git a/src/display.c b/src/display.c index 9a4a6bd2..e27a3271 100644 --- a/src/display.c +++ b/src/display.c @@ -798,6 +798,99 @@ meta_display_open (void) if (meta_prefs_get_compositing_manager ()) enable_compositor (display); + +#ifdef MPX + { + /* Check to see the available input devices */ + + XDeviceInfo *devsInfo, *devInfo, *auxDevsInfo, *auxDevInfo; + int howManyDevices, i, j; + + XID pDevId; + XDevice *kDev; + XDevice *open; + MetaDevices *d; + + d = &display->devices; + + /* We should register ourselves as the pairing client here, and also as + * the access control manager too. + * XXX XRegisterPairingClient, XGrabAccessControl */ + + d->mice = g_malloc(sizeof(XID) * DEFAULT_INPUT_ARRAY_SIZE); + d->keyboards = g_malloc(sizeof(XID) * DEFAULT_INPUT_ARRAY_SIZE); + d->pairedPointers = g_malloc(sizeof(XID) * DEFAULT_INPUT_ARRAY_SIZE); + + d->miceUsed = 0; + d->miceSize = DEFAULT_INPUT_ARRAY_SIZE; + d->keybsUsed = 0; + d->keybsSize = DEFAULT_INPUT_ARRAY_SIZE; + + devsInfo = XListInputDevices(display->xdisplay, &howManyDevices); + for (i = 0; i < howManyDevices; i++) + { + devInfo = &devsInfo[i]; + + if (devInfo->use == IsXExtensionKeyboard) + { + if (d->keybsUsed == d->keybsSize) + { + /* FIXME This is broken! See comment in devices.h! */ + d->keyboards = g_realloc (d->keyboards, + sizeof(XID) * (d->keybsSize + DEFAULT_INPUT_ARRAY_SIZE)); + d->pairedPointers = g_realloc(d->pairedPointers, + sizeof(XID) * (d->keybsSize + DEFAULT_INPUT_ARRAY_SIZE)); + d->keybsSize += DEFAULT_INPUT_ARRAY_SIZE; + } + + meta_warning("opening deivce id %d, name %s\n", + (int)devInfo->id, devInfo->name); /* XXX */ + kDev = XOpenDevice(display->xdisplay, devInfo->id); + d->keyboards[d->keybsUsed].xdev = kDev; + d->keyboards[d->keybsUsed].name = + g_strdup_printf("%s", devInfo->name); + + XGetPairedPointer(display->xdisplay, kDev, (int *) &pDevId); + meta_warning("opening device id %d\n", + (int)pDevId); /* XXX */ + open = XOpenDevice(display->xdisplay, pDevId); + d->pairedPointers[d->keybsUsed].xdev = open; + + /* Look in the device list for a device with the id pDevId + * and then find its name */ + auxDevsInfo = devsInfo; + for (j = 0; j < howManyDevices; j++) + { + auxDevInfo = &auxDevsInfo[j]; + if (auxDevInfo->id == pDevId) + break; + + } + d->pairedPointers[d->keybsUsed].name = + g_strdup_printf("%s", auxDevInfo->name); + d->keybsUsed++; + meta_warning(" name = %s\n", auxDevInfo->name); /* XXX */ + } + else if (devInfo->use == IsXExtensionPointer) + { + if (d->miceUsed == d->miceSize) + { + d->mice = g_realloc(d->mice, + sizeof(XID) * (d->miceSize + DEFAULT_INPUT_ARRAY_SIZE)); + d->miceSize += DEFAULT_INPUT_ARRAY_SIZE; + } + meta_warning("opening device id %d, name %s\n", + (int)devInfo->id, devInfo->name); /* XXX */ + open = XOpenDevice(display->xdisplay, devInfo->id); + d->mice[d->miceUsed].xdev = open; + d->mice[d->miceUsed].name = g_strdup_printf("%s", devInfo->name); + d->miceUsed++; + } + } + XFreeDeviceList(devsInfo); + + } +#endif /* Done opening new display */ display->display_opening = FALSE; diff --git a/src/display.h b/src/display.h index 14bd4eee..5216afef 100644 --- a/src/display.h +++ b/src/display.h @@ -37,6 +37,10 @@ #include "common.h" #include "boxes.h" +#ifdef MPX +#include "devices.h" +#endif + #ifdef HAVE_STARTUP_NOTIFICATION #include <libsn/sn.h> #endif @@ -372,6 +376,10 @@ struct _MetaDisplay #else #define META_DISPLAY_HAS_RENDER(display) FALSE #endif + +#ifdef MPX + MetaDevices devices; +#endif }; /* Xserver time can wraparound, thus comparing two timestamps needs to take @@ -246,7 +246,7 @@ main (int argc, char **argv) if (setlocale (LC_ALL, "") == NULL) meta_warning ("Locale not understood by C library, internationalization will not work\n"); - + sigemptyset (&empty_mask); act.sa_handler = SIG_IGN; act.sa_mask = empty_mask; @@ -137,11 +137,20 @@ menu_closed (GtkMenu *widget, menu = data; meta_frames_notify_menu_hide (menu->frames); +#ifdef MPX + (* menu->func) (menu, gdk_display, + menu->client_xwindow, + gtk_get_current_event_time (), + 0, 0, 0, + menu->data); + +#else (* menu->func) (menu, gdk_display, menu->client_xwindow, gtk_get_current_event_time (), 0, 0, menu->data); +#endif /* menu may now be freed */ } @@ -156,14 +165,26 @@ activate_cb (GtkWidget *menuitem, gpointer data) md = data; meta_frames_notify_menu_hide (md->menu->frames); +#ifdef MPX (* md->menu->func) (md->menu, gdk_display, md->menu->client_xwindow, gtk_get_current_event_time (), md->op, GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), "workspace")), + g_object_get_data (G_OBJECT (menuitem), "device"), md->menu->data); +#else + (* md->menu->func) (md->menu, gdk_display, + md->menu->client_xwindow, + gtk_get_current_event_time (), + md->op, + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), + "workspace")), + md->menu->data); +#endif + /* menu may now be freed */ } @@ -311,14 +332,26 @@ menu_item_new (MenuItem *menuitem, int workspace_id) } MetaWindowMenu* +#ifdef MPX meta_window_menu_new (MetaFrames *frames, MetaMenuOp ops, MetaMenuOp insensitive, + MetaDevices *devices, Window client_xwindow, unsigned long active_workspace, int n_workspaces, MetaWindowMenuFunc func, gpointer data) +#else +meta_window_menu_new (MetaFrames *frames, + MetaMenuOp ops, + MetaMenuOp insensitive, + Window client_xwindow, + unsigned long active_workspace, + int n_workspaces, + MetaWindowMenuFunc func, + gpointer data) +#endif { int i; MetaWindowMenu *menu; @@ -477,6 +510,77 @@ meta_window_menu_new (MetaFrames *frames, g_signal_connect (menu->menu, "selection_done", G_CALLBACK (menu_closed), menu); +#ifdef MPX + + { + GtkWidget *submenu; + GtkWidget *submenuitem; + + 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); + } + + { + /* SetClientPointer menu */ + Display *display; + + GtkWidget *submenu; + GtkWidget *submenuitem; + XID clientPtr; + + MenuItem select_client_pointer = { + 0, MENU_ITEM_NORMAL, NULL, + FALSE, N_("Select Client Pointer") + }; + + submenu = gtk_menu_new (); + submenuitem = menu_item_new (&select_client_pointer, -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); + + /* Someone might have changed the clientPointer! */ + XGetClientPointer(display, client_xwindow, (int *)&clientPtr); + meta_warning("my mouse is %d\n", (int) clientPtr); /* XXX */ + + for (i = 0; i < devices->miceUsed; i++) { + + MenuItem moveitem; + MenuData *md; + GtkWidget *mi; + + 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); + + gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mi); + gtk_widget_show (mi); + } + } +#endif + return menu; } @@ -26,6 +26,9 @@ #include <gtk/gtk.h> #include "frames.h" +#ifdef MPX +#include "devices.h" +#endif /* Stock icons */ #define METACITY_STOCK_DELETE "metacity-delete" @@ -43,14 +46,27 @@ struct _MetaWindowMenu MetaMenuOp insensitive; }; +#ifdef MPX MetaWindowMenu* meta_window_menu_new (MetaFrames *frames, MetaMenuOp ops, MetaMenuOp insensitive, + MetaDevices *devices, Window client_xwindow, unsigned long active_workspace, int n_workspaces, MetaWindowMenuFunc func, gpointer data); + +#else +MetaWindowMenu* meta_window_menu_new (MetaFrames *frames, + MetaMenuOp ops, + MetaMenuOp insensitive, + Window client_xwindow, + unsigned long active_workspace, + int n_workspaces, + MetaWindowMenuFunc func, + gpointer data); +#endif void meta_window_menu_popup (MetaWindowMenu *menu, int root_x, int root_y, @@ -315,21 +315,46 @@ meta_ui_set_frame_title (MetaUI *ui, } MetaWindowMenu* +#ifdef MPX meta_ui_window_menu_new (MetaUI *ui, Window client_xwindow, MetaMenuOp ops, MetaMenuOp insensitive, + MetaDevices *devices, unsigned long active_workspace, int n_workspaces, MetaWindowMenuFunc func, gpointer data) + +#else +meta_ui_window_menu_new (MetaUI *ui, + Window client_xwindow, + MetaMenuOp ops, + MetaMenuOp insensitive, + unsigned long active_workspace, + int n_workspaces, + MetaWindowMenuFunc func, + gpointer data) +#endif { + +#ifdef MPX return meta_window_menu_new (ui->frames, ops, insensitive, + devices, client_xwindow, active_workspace, n_workspaces, func, data); + +#else + return meta_window_menu_new (ui->frames, + ops, insensitive, + client_xwindow, + active_workspace, + n_workspaces, + func, data); +#endif } void @@ -26,6 +26,9 @@ /* Don't include gtk.h or gdk.h here */ #include "common.h" +#ifdef MPX +#include "devices.h" +#endif #include <X11/Xlib.h> #include <X11/Xutil.h> #include <glib.h> @@ -118,14 +121,27 @@ void meta_ui_set_frame_title (MetaUI *ui, void meta_ui_repaint_frame (MetaUI *ui, Window xwindow); +#ifdef MPX MetaWindowMenu* meta_ui_window_menu_new (MetaUI *ui, Window client_xwindow, MetaMenuOp ops, MetaMenuOp insensitive, + MetaDevices *devices, unsigned long active_workspace, int n_workspaces, MetaWindowMenuFunc func, gpointer data); + +#else +MetaWindowMenu* meta_ui_window_menu_new (MetaUI *ui, + Window client_xwindow, + MetaMenuOp ops, + MetaMenuOp insensitive, + unsigned long active_workspace, + int n_workspaces, + MetaWindowMenuFunc func, + gpointer data); +#endif void meta_ui_window_menu_popup (MetaWindowMenu *menu, int root_x, int root_y, diff --git a/src/window.c b/src/window.c index fb26ae49..1d5dcc06 100644 --- a/src/window.c +++ b/src/window.c @@ -6259,6 +6259,19 @@ recalc_window_features (MetaWindow *window) */ } +#ifdef MPX +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; +} +#endif + +#ifdef MPX static void menu_callback (MetaWindowMenu *menu, Display *xdisplay, @@ -6266,7 +6279,19 @@ menu_callback (MetaWindowMenu *menu, guint32 timestamp, MetaMenuOp op, int workspace_index, + MetaDevInfo *device, gpointer data) + +#else +static void +menu_callback (MetaWindowMenu *menu, + Display *xdisplay, + Window client_xwindow, + guint32 timestamp, + MetaMenuOp op, + int workspace_index, + gpointer data) +#endif { MetaDisplay *display; MetaWindow *window; @@ -6369,6 +6394,12 @@ menu_callback (MetaWindowMenu *menu, case META_MENU_OP_RECOVER: meta_window_shove_titlebar_onscreen (window); break; + +#ifdef MPX + case META_MENU_OP_CLIENT_POINTER: + meta_window_set_client_pointer (xdisplay, window, device); + break; +#endif case 0: /* nothing */ @@ -6515,14 +6546,27 @@ meta_window_show_menu (MetaWindow *window, return; menu = +#ifdef MPX meta_ui_window_menu_new (window->screen->ui, window->xwindow, ops, insensitive, + &window->display->devices, meta_window_get_net_wm_desktop (window), meta_screen_get_n_workspaces (window->screen), menu_callback, - NULL); + NULL); + +#else + meta_ui_window_menu_new (window->screen->ui, + window->xwindow, + ops, + insensitive, + meta_window_get_net_wm_desktop (window), + meta_screen_get_n_workspaces (window->screen), + menu_callback, + NULL); +#endif window->display->window_menu = menu; window->display->window_with_menu = window; diff --git a/src/window.h b/src/window.h index ec3d05a8..8195a65b 100644 --- a/src/window.h +++ b/src/window.h @@ -608,4 +608,9 @@ void meta_window_unset_demands_attention (MetaWindow *window); void meta_window_update_icon_now (MetaWindow *window); +#ifdef MPX +void meta_window_set_client_pointer (Display *xdisplay, MetaWindow *window, + MetaDevInfo *dev); +#endif + #endif |