Skip to content

Commit

Permalink
Add reasonably complete support for slave devices.
Browse files Browse the repository at this point in the history
The current code doesn't see slave devices. I'm guessing it all worked
when you originally updated the code since most of the support was already
there, but it got broken by further shifts in the XI2 model.

1) I have a thinkpad tablet and the old gromit (which otherwise worked
rather poorly) let me configure the
trackpad/touchpoint/touchscreen/wacom pen and wacom eraser separately.
Gromit-mpx only sees 'Virtual Core Pointer'.  This patch adds
(updates?) slave visibility through XI2.

2) Proximity events are deprecated (they're still in the headers but
do nothing).  I've eliminated that code and gone to a strategy of
doing 'proximity' events through mouse motion.
  • Loading branch information
xiphmont authored and bk138 committed Sep 3, 2012
1 parent e5d460e commit 58bdef4
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 165 deletions.
201 changes: 100 additions & 101 deletions src/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,42 +229,49 @@ gboolean on_buttonpress (GtkWidget *win,
{
GromitData *data = (GromitData *) user_data;
gdouble pressure = 0.5;

/* get the data for this device */
GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, ev->device);
GdkDevice *master = ev->device;
GromitDeviceData *masterdata =
g_hash_table_lookup(data->devdatatable, master);
GdkDevice *slave =
gdk_event_get_source_device ((GdkEvent *) ev);
GromitDeviceData *slavedata =
g_hash_table_lookup(data->devdatatable, slave);

if(data->debug)
g_printerr("DEBUG: Device '%s': Button %i Down at (x,y)=(%.2f : %.2f)\n",
gdk_device_get_name(ev->device), ev->button, ev->x, ev->y);
gdk_device_get_name(slave), ev->button, ev->x, ev->y);

if (!devdata->is_grabbed)
if (!masterdata->is_grabbed)
return FALSE;


/* See GdkModifierType. Am I fixing a Gtk misbehaviour??? */
ev->state |= 1 << (ev->button + 7);

if (ev->state != masterdata->state ||
ev->state != slavedata->state ||
masterdata->lastslave != slave)
select_tool (data, master, slave, ev->state);

if (ev->state != devdata->state)
select_tool (data, ev->device, ev->state);

devdata->lastx = ev->x;
devdata->lasty = ev->y;
devdata->motion_time = ev->time;
slavedata->lastx = ev->x;
slavedata->lasty = ev->y;
slavedata->motion_time = ev->time;

if (gdk_device_get_source(ev->device) == GDK_SOURCE_MOUSE)
if (gdk_device_get_source(slave) == GDK_SOURCE_MOUSE)
{
data->maxwidth = devdata->cur_context->width;
data->maxwidth = slavedata->cur_context->width;
}
else
{
gdk_event_get_axis ((GdkEvent *) ev, GDK_AXIS_PRESSURE, &pressure);
data->maxwidth = (CLAMP (pressure * pressure,0,1) *
(double) devdata->cur_context->width);
(double) slavedata->cur_context->width);
}
if (ev->button <= 5)
draw_line (data, ev->device, ev->x, ev->y, ev->x, ev->y);
draw_line (data, slave, ev->x, ev->y, ev->x, ev->y);

coord_list_prepend (data, ev->device, ev->x, ev->y, data->maxwidth);
coord_list_prepend (data, slave, ev->x, ev->y, data->maxwidth);

return TRUE;
}
Expand All @@ -278,51 +285,67 @@ gboolean on_motion (GtkWidget *win,
GdkTimeCoord **coords = NULL;
gint nevents;
int i;
gboolean ret;
gdouble pressure = 0.5;

/* get the data for this device */
GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, ev->device);
GdkDevice *master = ev->device;
GromitDeviceData *masterdata =
g_hash_table_lookup(data->devdatatable, master);

if (!devdata->is_grabbed)
if (!masterdata->is_grabbed)
return FALSE;

if (ev->state != devdata->state)
select_tool (data, ev->device, ev->state);
GdkDevice *slave =
gdk_event_get_source_device ((GdkEvent *) ev);
GromitDeviceData *slavedata =
g_hash_table_lookup(data->devdatatable, slave);

if (ev->state != masterdata->state ||
ev->state != slavedata->state ||
masterdata->lastslave != slave)
select_tool (data, master, slave, ev->state);

ret = gdk_device_get_history (ev->device, ev->window,
devdata->motion_time, ev->time,
&coords, &nevents);
if(!(ev->state & (GDK_BUTTON1_MASK|
GDK_BUTTON2_MASK|
GDK_BUTTON3_MASK|
GDK_BUTTON4_MASK|
GDK_BUTTON5_MASK)))
return TRUE;

gdk_device_get_history (slave, ev->window,
slavedata->motion_time, ev->time,
&coords, &nevents);

if(!data->xinerama && nevents > 0)
{
for (i=0; i < nevents; i++)
{
gdouble x, y;

gdk_device_get_axis (ev->device, coords[i]->axes,
gdk_device_get_axis (slave, coords[i]->axes,
GDK_AXIS_PRESSURE, &pressure);
if (pressure > 0)
{
if (gdk_device_get_source(ev->device) == GDK_SOURCE_MOUSE)
data->maxwidth = devdata->cur_context->width;
if (gdk_device_get_source(slave) == GDK_SOURCE_MOUSE)
data->maxwidth = slavedata->cur_context->width;
else
data->maxwidth = (CLAMP (pressure * pressure, 0, 1) *
(double) devdata->cur_context->width);
(double) slavedata->cur_context->width);

gdk_device_get_axis(ev->device, coords[i]->axes,
gdk_device_get_axis(slave, coords[i]->axes,
GDK_AXIS_X, &x);
gdk_device_get_axis(ev->device, coords[i]->axes,
gdk_device_get_axis(slave, coords[i]->axes,
GDK_AXIS_Y, &y);

draw_line (data, ev->device, devdata->lastx, devdata->lasty, x, y);
draw_line (data, slave, slavedata->lastx, slavedata->lasty, x, y);

coord_list_prepend (data, ev->device, x, y, data->maxwidth);
devdata->lastx = x;
devdata->lasty = y;
coord_list_prepend (data, slave, x, y, data->maxwidth);
slavedata->lastx = x;
slavedata->lasty = y;
}
}

devdata->motion_time = coords[nevents-1]->time;
slavedata->motion_time = coords[nevents-1]->time;
g_free (coords);
}

Expand All @@ -331,22 +354,22 @@ gboolean on_motion (GtkWidget *win,

if (pressure > 0)
{
if (gdk_device_get_source(ev->device) == GDK_SOURCE_MOUSE)
data->maxwidth = devdata->cur_context->width;
if (gdk_device_get_source(slave) == GDK_SOURCE_MOUSE)
data->maxwidth = slavedata->cur_context->width;
else
data->maxwidth = (CLAMP (pressure * pressure,0,1) *
(double)devdata->cur_context->width);
data->maxwidth = (CLAMP (pressure * pressure,0,1) *
(double)slavedata->cur_context->width);

if(devdata->motion_time > 0)
if(slavedata->motion_time > 0)
{
draw_line (data, ev->device, devdata->lastx, devdata->lasty, ev->x, ev->y);
coord_list_prepend (data, ev->device, ev->x, ev->y, data->maxwidth);
draw_line (data, slave, slavedata->lastx, slavedata->lasty, ev->x, ev->y);
coord_list_prepend (data, slave, ev->x, ev->y, data->maxwidth);
}
}

devdata->lastx = ev->x;
devdata->lasty = ev->y;
devdata->motion_time = ev->time;
slavedata->lastx = ev->x;
slavedata->lasty = ev->y;
slavedata->motion_time = ev->time;

return TRUE;
}
Expand All @@ -357,71 +380,45 @@ gboolean on_buttonrelease (GtkWidget *win,
gpointer user_data)
{
GromitData *data = (GromitData *) user_data;
/* get the device data for this event */
GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, ev->device);

/* get the data for this device */
GdkDevice *master = ev->device;
GromitDeviceData *masterdata =
g_hash_table_lookup(data->devdatatable, master);
GdkDevice *slave =
gdk_event_get_source_device ((GdkEvent *) ev);
GromitDeviceData *slavedata =
g_hash_table_lookup(data->devdatatable, slave);

if(data->debug)
g_printerr("DEBUG: Device '%s': Button %i Up at (x,y)=(%.2f : %.2f)\n",
gdk_device_get_name(slave), ev->button, ev->x, ev->y);

gfloat direction = 0;
gint width = 0;
if(devdata->cur_context)
width = devdata->cur_context->arrowsize * devdata->cur_context->width / 2;

if(slavedata->cur_context)
width = slavedata->cur_context->arrowsize *
slavedata->cur_context->width / 2;

if ((ev->x != devdata->lastx) ||
(ev->y != devdata->lasty))
if ((ev->x != slavedata->lastx) ||
(ev->y != slavedata->lasty))
on_motion(win, (GdkEventMotion *) ev, user_data);

if (!devdata->is_grabbed)
return FALSE;

if (devdata->cur_context->arrowsize != 0 &&
coord_list_get_arrow_param (data, ev->device, width * 3,
&width, &direction))
draw_arrow (data, ev->device, ev->x, ev->y, width, direction);

coord_list_free (data, ev->device);

return TRUE;
}


if (!masterdata->is_grabbed)
return FALSE;

gboolean on_proximity_in (GtkWidget *win,
GdkEventProximity *ev,
gpointer user_data)
{
GromitData *data = (GromitData *) user_data;
gint x, y;
GdkModifierType state;
if (slavedata->cur_context->arrowsize != 0 &&
coord_list_get_arrow_param (data, slave, width * 3,
&width, &direction))
draw_arrow (data, slave, ev->x, ev->y, width, direction);

gdk_window_get_pointer (gtk_widget_get_window(data->win), &x, &y, &state);
select_tool (data, ev->device, state);
coord_list_free (data, slave);

if(data->debug)
g_printerr("DEBUG: prox in device %s: \n", gdk_device_get_name(ev->device));
return TRUE;
}


gboolean on_proximity_out (GtkWidget *win,
GdkEventProximity *ev,
gpointer user_data)
{
GromitData *data = (GromitData *) user_data;

/* get the data for this device */
GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, ev->device);

devdata->cur_context = data->default_pen;

devdata->state = 0;
devdata->device = NULL;

if(data->debug)
g_printerr("DEBUG: prox out device %s: \n", gdk_device_get_name(ev->device));
return FALSE;
}


/* Remote control */
void on_mainapp_selection_get (GtkWidget *widget,
GtkSelectionData *selection_data,
Expand Down Expand Up @@ -514,11 +511,12 @@ void on_device_removed (GdkDeviceManager *device_manager,
gpointer user_data)
{
GromitData *data = (GromitData *) user_data;

if(!gdk_device_get_device_type(device) == GDK_DEVICE_TYPE_MASTER
|| gdk_device_get_n_axes(device) < 2)
GdkInputSource hardware_type = gdk_device_get_source(device);

if( hardware_type == GDK_SOURCE_KEYBOARD ||
gdk_device_get_n_axes(device) < 2)
return;

if(data->debug)
g_printerr("DEBUG: device '%s' removed\n", gdk_device_get_name(device));

Expand All @@ -530,9 +528,10 @@ void on_device_added (GdkDeviceManager *device_manager,
gpointer user_data)
{
GromitData *data = (GromitData *) user_data;
GdkInputSource hardware_type = gdk_device_get_source(device);

if(!gdk_device_get_device_type(device) == GDK_DEVICE_TYPE_MASTER
|| gdk_device_get_n_axes(device) < 2)
if( hardware_type == GDK_SOURCE_KEYBOARD ||
gdk_device_get_n_axes(device) < 2)
return;

if(data->debug)
Expand Down
Loading

0 comments on commit 58bdef4

Please sign in to comment.