forked from AuroraMiddleware/gtk
Move files into x11 subdirectory.
Sun Oct 3 14:26:15 1999 Owen Taylor <otaylor@redhat.com> * gdk/gxid* gdk/x11/gxid*: Move files into x11 subdirectory.
This commit is contained in:
parent
9c2dea004f
commit
344e8000a2
@ -1,3 +1,7 @@
|
||||
Sun Oct 3 14:26:15 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gxid* gdk/x11/gxid*: Move files into x11 subdirectory.
|
||||
|
||||
Sun Oct 3 14:16:23 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.h: Include gdk/gdkdrawable.h with
|
||||
|
@ -1,3 +1,7 @@
|
||||
Sun Oct 3 14:26:15 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gxid* gdk/x11/gxid*: Move files into x11 subdirectory.
|
||||
|
||||
Sun Oct 3 14:16:23 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.h: Include gdk/gdkdrawable.h with
|
||||
|
@ -1,3 +1,7 @@
|
||||
Sun Oct 3 14:26:15 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gxid* gdk/x11/gxid*: Move files into x11 subdirectory.
|
||||
|
||||
Sun Oct 3 14:16:23 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.h: Include gdk/gdkdrawable.h with
|
||||
|
@ -1,3 +1,7 @@
|
||||
Sun Oct 3 14:26:15 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gxid* gdk/x11/gxid*: Move files into x11 subdirectory.
|
||||
|
||||
Sun Oct 3 14:16:23 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.h: Include gdk/gdkdrawable.h with
|
||||
|
@ -1,3 +1,7 @@
|
||||
Sun Oct 3 14:26:15 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gxid* gdk/x11/gxid*: Move files into x11 subdirectory.
|
||||
|
||||
Sun Oct 3 14:16:23 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.h: Include gdk/gdkdrawable.h with
|
||||
|
@ -1,3 +1,7 @@
|
||||
Sun Oct 3 14:26:15 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gxid* gdk/x11/gxid*: Move files into x11 subdirectory.
|
||||
|
||||
Sun Oct 3 14:16:23 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.h: Include gdk/gdkdrawable.h with
|
||||
|
@ -1,3 +1,7 @@
|
||||
Sun Oct 3 14:26:15 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gxid* gdk/x11/gxid*: Move files into x11 subdirectory.
|
||||
|
||||
Sun Oct 3 14:16:23 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.h: Include gdk/gdkdrawable.h with
|
||||
|
865
gdk/gxid.c
865
gdk/gxid.c
@ -1,865 +0,0 @@
|
||||
/*
|
||||
* gxid version 0.3
|
||||
*
|
||||
* Copyright 1997 Owen Taylor <owt1@cornell.edu>
|
||||
*/
|
||||
#undef G_LOG_DOMAIN
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XInput.h>
|
||||
|
||||
#include "gxid_proto.h"
|
||||
|
||||
/* #define DEBUG_CLIENTS */
|
||||
/* #define DEBUG_EVENTS */
|
||||
|
||||
char *program_name;
|
||||
Display *dpy;
|
||||
Window root_window; /* default root window of dpy */
|
||||
int port = 0; /* port to listen on */
|
||||
int socket_fd = 0; /* file descriptor of socket */
|
||||
typedef struct GxidWindow_ GxidWindow;
|
||||
|
||||
typedef struct GxidDevice_ GxidDevice;
|
||||
struct GxidDevice_ {
|
||||
XID id;
|
||||
int exclusive;
|
||||
int ispointer;
|
||||
|
||||
XDevice *xdevice;
|
||||
int motionnotify_type;
|
||||
int changenotify_type;
|
||||
};
|
||||
|
||||
struct GxidWindow_ {
|
||||
Window xwindow;
|
||||
/* Immediate child of root that is ancestor of window */
|
||||
Window root_child;
|
||||
int num_devices;
|
||||
GxidDevice **devices;
|
||||
};
|
||||
|
||||
GxidDevice **devices = NULL;
|
||||
int num_devices = 0;
|
||||
GxidWindow **windows = NULL;
|
||||
int num_windows = 0;
|
||||
|
||||
void
|
||||
handler(int signal)
|
||||
{
|
||||
fprintf(stderr,"%s: dying on signal %d\n",program_name,signal);
|
||||
if (socket_fd)
|
||||
close(socket_fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
init_socket(void)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
socket_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if (socket_fd < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: error getting socket\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (bind(socket_fd,(struct sockaddr *)(&sin),
|
||||
sizeof(struct sockaddr_in)) < 0)
|
||||
{
|
||||
fprintf (stderr,"%s: cannot bind to port %d\n",
|
||||
program_name,port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (listen(socket_fd,5) < 0)
|
||||
{
|
||||
fprintf (stderr,"%s: error listening on socket\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
};
|
||||
}
|
||||
|
||||
#define NUM_EVENTC 2
|
||||
static void
|
||||
enable_device(GxidDevice *dev)
|
||||
{
|
||||
XEventClass xevc[NUM_EVENTC];
|
||||
int num_eventc = NUM_EVENTC;
|
||||
int i,j;
|
||||
|
||||
if (!dev->xdevice)
|
||||
{
|
||||
if (dev->ispointer) return;
|
||||
|
||||
dev->xdevice = XOpenDevice(dpy, dev->id);
|
||||
if (!dev->xdevice) return;
|
||||
|
||||
DeviceMotionNotify (dev->xdevice, dev->motionnotify_type,
|
||||
xevc[0]);
|
||||
ChangeDeviceNotify (dev->xdevice, dev->changenotify_type,
|
||||
xevc[1]);
|
||||
|
||||
/* compress out zero event classes */
|
||||
for (i=0,j=0;i<NUM_EVENTC;i++)
|
||||
{
|
||||
if (xevc[i]) {
|
||||
xevc[j] = xevc[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
num_eventc = j;
|
||||
|
||||
XSelectExtensionEvent (dpy, root_window, xevc, num_eventc);
|
||||
}
|
||||
}
|
||||
|
||||
/* switch the core pointer from whatever it is now to something else,
|
||||
return true on success, false otherwise */
|
||||
static int
|
||||
switch_core_pointer(void)
|
||||
{
|
||||
GxidDevice *old_pointer = 0;
|
||||
GxidDevice *new_pointer = 0;
|
||||
int result;
|
||||
int i;
|
||||
|
||||
for (i=0;i<num_devices;i++)
|
||||
{
|
||||
if (devices[i]->ispointer)
|
||||
old_pointer = devices[i];
|
||||
else
|
||||
if (!new_pointer && !devices[i]->exclusive)
|
||||
new_pointer = devices[i];
|
||||
}
|
||||
|
||||
if (!old_pointer || !new_pointer)
|
||||
return 0;
|
||||
|
||||
#ifdef DEBUG_EVENTS
|
||||
fprintf(stderr,"gxid: Switching core from %ld to %ld\n",
|
||||
old_pointer->id,new_pointer->id);
|
||||
#endif
|
||||
result = XChangePointerDevice(dpy,new_pointer->xdevice, 0, 1);
|
||||
if (result != Success)
|
||||
{
|
||||
fprintf(stderr,"gxid: Error %d switching core from %ld to %ld\n",
|
||||
result, old_pointer->id, new_pointer->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_pointer->ispointer = 1;
|
||||
old_pointer->ispointer = 0;
|
||||
if (!old_pointer->xdevice)
|
||||
enable_device(old_pointer);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
disable_device(GxidDevice *dev)
|
||||
{
|
||||
if (dev->xdevice)
|
||||
{
|
||||
if (dev->ispointer)
|
||||
return;
|
||||
XCloseDevice(dpy,dev->xdevice);
|
||||
dev->xdevice = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GxidDevice *
|
||||
init_device(XDeviceInfo *xdevice)
|
||||
{
|
||||
GxidDevice *dev = (GxidDevice *)malloc(sizeof(GxidDevice));
|
||||
XAnyClassPtr class;
|
||||
int num_axes, i;
|
||||
|
||||
dev->id = xdevice->id;
|
||||
dev->exclusive = 0;
|
||||
dev->xdevice = NULL;
|
||||
|
||||
dev->ispointer = (xdevice->use == IsXPointer);
|
||||
|
||||
/* step through the classes */
|
||||
|
||||
num_axes = 0;
|
||||
class = xdevice->inputclassinfo;
|
||||
for (i=0;i<xdevice->num_classes;i++)
|
||||
{
|
||||
if (class->class == ValuatorClass)
|
||||
{
|
||||
XValuatorInfo *xvi = (XValuatorInfo *)class;
|
||||
num_axes = xvi->num_axes;
|
||||
}
|
||||
class = (XAnyClassPtr)(((char *)class) + class->length);
|
||||
}
|
||||
|
||||
/* return NULL if insufficient axes */
|
||||
if (num_axes < 2)
|
||||
{
|
||||
free((void *)dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dev->ispointer)
|
||||
enable_device(dev);
|
||||
return dev;
|
||||
}
|
||||
|
||||
void
|
||||
init_xinput(void)
|
||||
{
|
||||
char **extensions;
|
||||
XDeviceInfo *xdevices;
|
||||
int num_xdevices;
|
||||
int num_extensions;
|
||||
int i;
|
||||
|
||||
extensions = XListExtensions(dpy, &num_extensions);
|
||||
for (i = 0; i < num_extensions &&
|
||||
(strcmp(extensions[i], "XInputExtension") != 0); i++);
|
||||
XFreeExtensionList(extensions);
|
||||
if (i == num_extensions) /* XInput extension not found */
|
||||
{
|
||||
fprintf(stderr,"XInput extension not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
xdevices = XListInputDevices(dpy, &num_xdevices);
|
||||
devices = (GxidDevice **)malloc(num_xdevices * sizeof(GxidDevice *));
|
||||
|
||||
num_devices = 0;
|
||||
for(i=0; i<num_xdevices; i++)
|
||||
{
|
||||
GxidDevice *dev = init_device(&xdevices[i]);
|
||||
if (dev)
|
||||
devices[num_devices++] = dev;
|
||||
}
|
||||
XFreeDeviceList(xdevices);
|
||||
}
|
||||
|
||||
/* If this routine needs fixing, the corresponding routine
|
||||
in gdkinputgxi.h will need it too. */
|
||||
|
||||
Window
|
||||
gxi_find_root_child(Display *dpy, Window w)
|
||||
{
|
||||
Window root,parent;
|
||||
Window *children;
|
||||
int nchildren;
|
||||
|
||||
parent = w;
|
||||
do
|
||||
{
|
||||
w = parent;
|
||||
XQueryTree (dpy, w, &root, &parent, &children, &nchildren);
|
||||
if (children)
|
||||
XFree (children);
|
||||
}
|
||||
while (parent != root);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
int
|
||||
handle_claim_device(GxidClaimDevice *msg)
|
||||
{
|
||||
int i,j;
|
||||
XID devid;
|
||||
XID winid;
|
||||
int exclusive;
|
||||
GxidDevice *device = NULL;
|
||||
GxidWindow *window = NULL;
|
||||
|
||||
if (msg->length != sizeof(GxidClaimDevice))
|
||||
{
|
||||
fprintf(stderr,"Bad length for ClaimDevice message\n");
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
devid = ntohl(msg->device);
|
||||
winid = ntohl(msg->window);
|
||||
exclusive = ntohl(msg->exclusive);
|
||||
|
||||
#ifdef DEBUG_CLIENTS
|
||||
fprintf(stderr,"device %ld claimed (window 0x%lx)\n",devid,winid);
|
||||
#endif
|
||||
|
||||
for (i=0;i<num_devices;i++)
|
||||
{
|
||||
if (devices[i]->id == devid)
|
||||
{
|
||||
device = devices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!device)
|
||||
{
|
||||
fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
if (device->exclusive)
|
||||
{
|
||||
/* already in use */
|
||||
fprintf(stderr,
|
||||
"%s: Device %ld already claimed in exclusive mode\n",
|
||||
program_name,devid);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
if (exclusive)
|
||||
{
|
||||
for (i=0;i<num_windows;i++)
|
||||
{
|
||||
for (j=0;j<windows[i]->num_devices;j++)
|
||||
if (windows[i]->devices[j]->id == devid)
|
||||
{
|
||||
/* already in use */
|
||||
fprintf(stderr,
|
||||
"%s: Can't establish exclusive use of device %ld\n",
|
||||
program_name,devid);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
}
|
||||
if (device->ispointer)
|
||||
if (!switch_core_pointer())
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Can't free up core pointer %ld\n",
|
||||
program_name,devid);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
device->exclusive = 1;
|
||||
disable_device(device);
|
||||
XSelectInput(dpy,winid,StructureNotifyMask);
|
||||
}
|
||||
else /* !exclusive */
|
||||
{
|
||||
/* FIXME: this is a bit improper. We probably should do this only
|
||||
when a window is first claimed. But we might be fooled if
|
||||
an old client died without releasing it's windows. So until
|
||||
we look for client-window closings, do it here
|
||||
|
||||
(We do look for closings now...)
|
||||
*/
|
||||
|
||||
XSelectInput(dpy,winid,EnterWindowMask|StructureNotifyMask);
|
||||
}
|
||||
|
||||
for (i=0;i<num_windows;i++)
|
||||
{
|
||||
if (windows[i]->xwindow == winid)
|
||||
{
|
||||
window = windows[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create window structure if no devices have been previously
|
||||
claimed on it */
|
||||
if (!window)
|
||||
{
|
||||
num_windows++;
|
||||
windows = (GxidWindow **)realloc(windows,
|
||||
sizeof(GxidWindow*)*num_windows);
|
||||
window = (GxidWindow *)malloc(sizeof(GxidWindow));
|
||||
windows[num_windows-1] = window;
|
||||
|
||||
window->xwindow = winid;
|
||||
window->root_child = gxi_find_root_child(dpy,winid);
|
||||
window->num_devices = 0;
|
||||
window->devices = 0;
|
||||
}
|
||||
|
||||
|
||||
for (i=0;i<window->num_devices;i++)
|
||||
{
|
||||
if (window->devices[i] == device)
|
||||
return GXID_RETURN_OK;
|
||||
}
|
||||
|
||||
window->num_devices++;
|
||||
window->devices = (GxidDevice **)realloc(window->devices,
|
||||
sizeof(GxidDevice*)*num_devices);
|
||||
/* we need add the device to the window */
|
||||
window->devices[i] = device;
|
||||
|
||||
return GXID_RETURN_OK;
|
||||
}
|
||||
|
||||
int
|
||||
handle_release_device(GxidReleaseDevice *msg)
|
||||
{
|
||||
int i,j;
|
||||
XID devid;
|
||||
XID winid;
|
||||
|
||||
GxidDevice *device = NULL;
|
||||
|
||||
if (msg->length != sizeof(GxidReleaseDevice))
|
||||
{
|
||||
fprintf(stderr,"Bad length for ReleaseDevice message\n");
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
devid = ntohl(msg->device);
|
||||
winid = ntohl(msg->window);
|
||||
|
||||
#ifdef DEBUG_CLIENTS
|
||||
fprintf(stderr,"device %ld released (window 0x%lx)\n",devid,winid);
|
||||
#endif
|
||||
|
||||
for (i=0;i<num_devices;i++)
|
||||
{
|
||||
if (devices[i]->id == devid)
|
||||
{
|
||||
device = devices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!device)
|
||||
{
|
||||
fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
for (i=0;i<num_windows;i++)
|
||||
{
|
||||
GxidWindow *w = windows[i];
|
||||
|
||||
if (w->xwindow == winid)
|
||||
for (j=0;j<w->num_devices;j++)
|
||||
if (w->devices[j]->id == devid)
|
||||
{
|
||||
if (j<w->num_devices-1)
|
||||
w->devices[j] = w->devices[w->num_devices-1];
|
||||
w->num_devices--;
|
||||
|
||||
if (w->num_devices == 0)
|
||||
{
|
||||
if (i<num_windows-1)
|
||||
windows[i] = windows[num_windows-1];
|
||||
num_windows--;
|
||||
|
||||
free((void *)w);
|
||||
/* FIXME: should we deselect input? But what
|
||||
what if window is already destroyed */
|
||||
}
|
||||
|
||||
if (device->exclusive)
|
||||
{
|
||||
device->exclusive = 0;
|
||||
enable_device(device);
|
||||
}
|
||||
return GXID_RETURN_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* device/window combination not found */
|
||||
fprintf(stderr,
|
||||
"%s: Device %ld not claimed for window 0x%lx\n",
|
||||
program_name,devid,winid);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
void
|
||||
handle_connection (void)
|
||||
{
|
||||
GxidMessage msg;
|
||||
GxidU32 type;
|
||||
GxidU32 length;
|
||||
GxidI32 retval;
|
||||
|
||||
int conn_fd;
|
||||
struct sockaddr_in sin;
|
||||
int sin_length;
|
||||
int count;
|
||||
|
||||
sin_length = sizeof(struct sockaddr_in);
|
||||
conn_fd = accept(socket_fd,(struct sockaddr *)&sin,&sin_length);
|
||||
if (conn_fd < 0)
|
||||
{
|
||||
fprintf(stderr,"%s: Error accepting connection\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read type and length of message */
|
||||
|
||||
count = read(conn_fd,(char *)&msg,2*sizeof(GxidU32));
|
||||
if (count != 2*sizeof(GxidU32))
|
||||
{
|
||||
fprintf(stderr,"%s: Error reading message header\n",
|
||||
program_name);
|
||||
close(conn_fd);
|
||||
return;
|
||||
}
|
||||
type = ntohl(msg.any.type);
|
||||
length = ntohl(msg.any.length);
|
||||
|
||||
/* read rest of message */
|
||||
|
||||
if ((length > sizeof(GxidMessage)) || (length < 2*sizeof(GxidU32)))
|
||||
{
|
||||
fprintf(stderr,"%s: Bad message length\n",
|
||||
program_name);
|
||||
close(conn_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
count = read(conn_fd,2*sizeof(GxidU32) + (char *)&msg,
|
||||
length - 2*sizeof(GxidU32));
|
||||
if (count != length - 2*sizeof(GxidU32))
|
||||
{
|
||||
fprintf(stderr,"%s: Error reading message body\n",
|
||||
program_name);
|
||||
close(conn_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GXID_CLAIM_DEVICE:
|
||||
retval = handle_claim_device((GxidClaimDevice *)&msg);
|
||||
break;
|
||||
case GXID_RELEASE_DEVICE:
|
||||
retval = handle_release_device((GxidReleaseDevice *)&msg);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"%s: Unknown message type: %ld (ignoring)\n",
|
||||
program_name,type);
|
||||
close(conn_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
count = write(conn_fd,&retval,sizeof(GxidI32));
|
||||
if (count != sizeof(GxidI32))
|
||||
{
|
||||
fprintf(stderr,"%s: Error writing return code\n",
|
||||
program_name);
|
||||
}
|
||||
|
||||
close(conn_fd);
|
||||
}
|
||||
|
||||
void
|
||||
handle_motion_notify(XDeviceMotionEvent *event)
|
||||
{
|
||||
int i,j;
|
||||
GxidDevice *old_device = NULL;
|
||||
GxidDevice *new_device = NULL;
|
||||
Window w, root, child;
|
||||
int root_x, root_y, x, y, mask;
|
||||
|
||||
for (j=0;j<num_devices;j++)
|
||||
{
|
||||
if (devices[j]->ispointer)
|
||||
old_device = devices[j];
|
||||
if (devices[j]->id == event->deviceid)
|
||||
new_device = devices[j];
|
||||
}
|
||||
|
||||
if (new_device && !new_device->exclusive && !new_device->ispointer)
|
||||
{
|
||||
/* make sure we aren't stealing the pointer back from a slow
|
||||
client */
|
||||
child = root_window;
|
||||
do
|
||||
{
|
||||
w = child;
|
||||
/* FIXME: this fails disasterously if child vanishes between
|
||||
calls. (Which is prone to happening since we get events
|
||||
on root just as the client exits) */
|
||||
|
||||
XQueryPointer(dpy,w,&root,&child,&root_x,&root_y,
|
||||
&x,&y,&mask);
|
||||
}
|
||||
while (child != None);
|
||||
|
||||
for (i=0;i<num_windows;i++)
|
||||
if (windows[i]->xwindow == w)
|
||||
for (j=0;j<windows[i]->num_devices;j++)
|
||||
if (windows[i]->devices[j] == new_device)
|
||||
return;
|
||||
|
||||
/* FIXME: do something smarter with axes */
|
||||
XChangePointerDevice(dpy,new_device->xdevice, 0, 1);
|
||||
new_device->ispointer = 1;
|
||||
|
||||
old_device->ispointer = 0;
|
||||
if (!old_device->xdevice)
|
||||
enable_device(old_device);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handle_change_notify(XChangeDeviceNotifyEvent *event)
|
||||
{
|
||||
int j;
|
||||
GxidDevice *old_device = NULL;
|
||||
GxidDevice *new_device = NULL;
|
||||
|
||||
|
||||
for (j=0;j<num_devices;j++)
|
||||
{
|
||||
if (devices[j]->ispointer)
|
||||
old_device = devices[j];
|
||||
if (devices[j]->id == event->deviceid)
|
||||
new_device = devices[j];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_EVENTS
|
||||
fprintf(stderr,"gxid: ChangeNotify event; old = %ld; new = %ld\n",
|
||||
old_device->id, new_device->id);
|
||||
#endif
|
||||
|
||||
if (old_device != new_device)
|
||||
{
|
||||
new_device->ispointer = 1;
|
||||
|
||||
old_device->ispointer = 0;
|
||||
if (!old_device->xdevice)
|
||||
enable_device(old_device);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handle_enter_notify(XEnterWindowEvent *event, GxidWindow *window)
|
||||
{
|
||||
int i;
|
||||
GxidDevice *old_pointer = NULL;
|
||||
for (i=0;i<num_devices;i++)
|
||||
{
|
||||
if (devices[i]->ispointer)
|
||||
{
|
||||
old_pointer = devices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_EVENTS
|
||||
fprintf(stderr,"gxid: Enter event; oldpointer = %ld\n",
|
||||
old_pointer->id);
|
||||
#endif
|
||||
|
||||
if (old_pointer)
|
||||
for (i=0;i<window->num_devices;i++)
|
||||
{
|
||||
if (window->devices[i] == old_pointer)
|
||||
{
|
||||
switch_core_pointer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handle_destroy_notify(XDestroyWindowEvent *event)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
for (i=0;i<num_windows;i++)
|
||||
if (windows[i]->xwindow == event->window)
|
||||
{
|
||||
GxidWindow *w = windows[i];
|
||||
|
||||
for (j=0;j<w->num_devices;j++)
|
||||
{
|
||||
#ifdef DEBUG_CLIENTS
|
||||
fprintf(stderr,"device %ld released on destruction of window 0x%lx.\n",
|
||||
w->devices[j]->id,w->xwindow);
|
||||
#endif
|
||||
|
||||
if (w->devices[j]->exclusive)
|
||||
{
|
||||
w->devices[j]->exclusive = 0;
|
||||
enable_device(devices[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (i<num_windows-1)
|
||||
windows[i] = windows[num_windows-1];
|
||||
num_windows--;
|
||||
|
||||
if (w->devices)
|
||||
free((void *)w->devices);
|
||||
free((void *)w);
|
||||
/* FIXME: should we deselect input? But what
|
||||
what if window is already destroyed */
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handle_xevent(void)
|
||||
{
|
||||
int i;
|
||||
XEvent event;
|
||||
|
||||
XNextEvent (dpy, &event);
|
||||
|
||||
#ifdef DEBUG_EVENTS
|
||||
fprintf(stderr,"Event - type = %d; window = 0x%lx\n",
|
||||
event.type,event.xany.window);
|
||||
#endif
|
||||
|
||||
if (event.type == ConfigureNotify)
|
||||
{
|
||||
#ifdef DEBUG_EVENTS
|
||||
XConfigureEvent *xce = (XConfigureEvent *)&event;
|
||||
fprintf(stderr," configureNotify: window = 0x%lx\n",xce->window);
|
||||
#endif
|
||||
}
|
||||
else if (event.type == EnterNotify)
|
||||
{
|
||||
/* pointer entered a claimed window */
|
||||
for (i=0;i<num_windows;i++)
|
||||
{
|
||||
if (event.xany.window == windows[i]->xwindow)
|
||||
handle_enter_notify((XEnterWindowEvent *)&event,windows[i]);
|
||||
}
|
||||
}
|
||||
else if (event.type == DestroyNotify)
|
||||
{
|
||||
/* A claimed window was destroyed */
|
||||
for (i=0;i<num_windows;i++)
|
||||
{
|
||||
if (event.xany.window == windows[i]->xwindow)
|
||||
handle_destroy_notify((XDestroyWindowEvent *)&event);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (i=0;i<num_devices;i++)
|
||||
{
|
||||
if (event.type == devices[i]->motionnotify_type)
|
||||
{
|
||||
handle_motion_notify((XDeviceMotionEvent *)&event);
|
||||
break;
|
||||
}
|
||||
else if (event.type == devices[i]->changenotify_type)
|
||||
{
|
||||
handle_change_notify((XChangeDeviceNotifyEvent *)&event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s [-d display] [-p --gxid-port port]\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *display_name = NULL;
|
||||
fd_set readfds;
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
for (i=1;i<argc;i++)
|
||||
{
|
||||
if (!strcmp(argv[i],"-d"))
|
||||
{
|
||||
if (++i >= argc) usage();
|
||||
display_name = argv[i];
|
||||
}
|
||||
else if (!strcmp(argv[i],"--gxid-port") ||
|
||||
!strcmp(argv[i],"-p"))
|
||||
{
|
||||
if (++i >= argc) usage();
|
||||
port = atoi(argv[i]);
|
||||
break;
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
|
||||
if (!port)
|
||||
{
|
||||
char *t = getenv("GXID_PORT");
|
||||
if (t)
|
||||
port = atoi(t);
|
||||
else
|
||||
port = 6951;
|
||||
}
|
||||
/* set up a signal handler so we can clean up if killed */
|
||||
|
||||
signal(SIGTERM,handler);
|
||||
signal(SIGINT,handler);
|
||||
|
||||
/* initialize the X connection */
|
||||
|
||||
dpy = XOpenDisplay (display_name);
|
||||
if (!dpy)
|
||||
{
|
||||
fprintf (stderr, "%s: unable to open display '%s'\n",
|
||||
program_name, XDisplayName (display_name));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
root_window = DefaultRootWindow(dpy);
|
||||
|
||||
/* We'll want to do this in the future if we are to support
|
||||
gxid monitoring visibility information for clients */
|
||||
#if 0
|
||||
XSelectInput(dpy,root_window,SubstructureNotifyMask);
|
||||
#endif
|
||||
init_xinput();
|
||||
|
||||
/* set up our server connection */
|
||||
|
||||
init_socket();
|
||||
|
||||
/* main loop */
|
||||
|
||||
if (XPending(dpy)) /* this seems necessary to get things
|
||||
in sync */
|
||||
handle_xevent();
|
||||
while (1)
|
||||
{
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(ConnectionNumber(dpy),&readfds);
|
||||
FD_SET(socket_fd,&readfds);
|
||||
|
||||
if (select(8*sizeof(readfds),&readfds,
|
||||
(fd_set *)0,(fd_set *)0, (struct timeval *)0) < 0)
|
||||
{
|
||||
fprintf(stderr,"Error in select\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (FD_ISSET(socket_fd,&readfds))
|
||||
handle_connection();
|
||||
|
||||
while (XPending(dpy))
|
||||
handle_xevent();
|
||||
}
|
||||
|
||||
XCloseDisplay (dpy);
|
||||
exit (0);
|
||||
}
|
125
gdk/gxid_lib.c
125
gdk/gxid_lib.c
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* gxid version 0.3
|
||||
*
|
||||
* Copyright 1997 Owen Taylor <owt1@cornell.edu>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gxid_lib.h"
|
||||
|
||||
#ifdef XINPUT_GXI
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
/* handles mechanics of communicating with a client */
|
||||
static int
|
||||
gxid_send_message(char *host, int port, GxidMessage *msg)
|
||||
{
|
||||
int socket_fd;
|
||||
struct sockaddr_in sin;
|
||||
int count;
|
||||
GxidI32 retval;
|
||||
struct hostent *he;
|
||||
|
||||
if (!port) port = 6951;
|
||||
|
||||
if (!host || strcmp(host,"localhost") )
|
||||
{
|
||||
/* looking it up as localhost can be _SLOW_ on ppp systems */
|
||||
/* FIXME: Could localhost be anything other than loopback? */
|
||||
host = "127.0.0.1";
|
||||
}
|
||||
|
||||
he = gethostbyname(host);
|
||||
if (!he)
|
||||
{
|
||||
fprintf(stderr,"gxid_lib: error looking up %s\n",host);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
sin.sin_family = he->h_addrtype;
|
||||
sin.sin_port = htons(port);
|
||||
memcpy(&sin.sin_addr,he->h_addr_list[0],he->h_length);
|
||||
|
||||
socket_fd = socket(AF_INET,SOCK_STREAM,0);
|
||||
if (socket_fd < 0)
|
||||
{
|
||||
fprintf(stderr,"gxid_lib: can't get socket");
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
if (connect(socket_fd, (struct sockaddr *)&sin,
|
||||
sizeof sin) < 0)
|
||||
{
|
||||
fprintf(stderr,"gxid_lib: can't connect to %s:%d\n",host,port);
|
||||
close(socket_fd);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
count = write(socket_fd,(char *)msg,ntohl(msg->any.length));
|
||||
if (count != ntohl(msg->any.length))
|
||||
{
|
||||
fprintf(stderr,"gxid_lib: error writing");
|
||||
close(socket_fd);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
/* now read the return code */
|
||||
count = read(socket_fd,(char *)&retval,sizeof(GxidI32));
|
||||
if (count != sizeof(GxidI32))
|
||||
{
|
||||
fprintf(stderr,"gxid_lib: error reading return code");
|
||||
close(socket_fd);
|
||||
return GXID_RETURN_ERROR;
|
||||
}
|
||||
|
||||
close (socket_fd);
|
||||
return ntohl(retval);
|
||||
}
|
||||
|
||||
/* claim a device. If exclusive, device is claimed exclusively */
|
||||
int
|
||||
gxid_claim_device(char *host, int port, GxidU32 device, GxidU32 window,
|
||||
int exclusive)
|
||||
{
|
||||
GxidClaimDevice msg;
|
||||
msg.type = htonl(GXID_CLAIM_DEVICE);
|
||||
msg.length = htonl(sizeof(GxidClaimDevice));
|
||||
msg.device = htonl(device);
|
||||
msg.window = htonl(window);
|
||||
msg.exclusive = htonl(exclusive);
|
||||
|
||||
return gxid_send_message(host,port,(GxidMessage *)&msg);
|
||||
}
|
||||
|
||||
/* release a device/window pair */
|
||||
int
|
||||
gxid_release_device(char *host, int port, GxidU32 device, GxidU32 window)
|
||||
{
|
||||
GxidReleaseDevice msg;
|
||||
msg.type = htonl(GXID_RELEASE_DEVICE);
|
||||
msg.length = htonl(sizeof(GxidReleaseDevice));
|
||||
msg.device = htonl(device);
|
||||
msg.window = htonl(window);
|
||||
|
||||
return gxid_send_message(host,port,(GxidMessage *)&msg);
|
||||
}
|
||||
|
||||
#else /* !XINPUT_GXI */
|
||||
|
||||
/* Some compilers don't like empty source files */
|
||||
int
|
||||
gxid_claim_device(char *host, int port, GxidU32 device, GxidU32 window,
|
||||
int exclusive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* XINPUT_GXI */
|
||||
|
@ -1,6 +0,0 @@
|
||||
#include "gxid_proto.h"
|
||||
|
||||
int gxid_claim_device(char *host, int port,
|
||||
GxidU32 device, GxidU32 window, int exclusive);
|
||||
int gxid_release_device(char *host, int port, GxidU32 device,
|
||||
GxidU32 window);
|
@ -1,39 +0,0 @@
|
||||
#define GXID_CLAIM_DEVICE 1
|
||||
#define GXID_RELEASE_DEVICE 2
|
||||
|
||||
#define GXID_RETURN_OK 0
|
||||
#define GXID_RETURN_ERROR -1
|
||||
|
||||
typedef struct GxidClaimDevice_ GxidClaimDevice;
|
||||
typedef struct GxidReleaseDevice_ GxidReleaseDevice;
|
||||
typedef struct GxidMessageAny_ GxidMessageAny;
|
||||
typedef union GxidMessage_ GxidMessage;
|
||||
|
||||
typedef unsigned long GxidU32;
|
||||
typedef long GxidI32;
|
||||
|
||||
struct GxidClaimDevice_ {
|
||||
GxidU32 type;
|
||||
GxidU32 length;
|
||||
GxidU32 device;
|
||||
GxidU32 window;
|
||||
GxidU32 exclusive;
|
||||
};
|
||||
|
||||
struct GxidReleaseDevice_ {
|
||||
GxidU32 type;
|
||||
GxidU32 length;
|
||||
GxidU32 device;
|
||||
GxidU32 window;
|
||||
};
|
||||
|
||||
struct GxidMessageAny_ {
|
||||
GxidU32 type;
|
||||
GxidU32 length;
|
||||
};
|
||||
|
||||
union GxidMessage_ {
|
||||
GxidMessageAny any;
|
||||
GxidClaimDevice claim;
|
||||
GxidReleaseDevice release;
|
||||
};
|
Loading…
Reference in New Issue
Block a user