It is now possible to buy quite inexpensive input devices such as drawing tablets, which allow drawing with a much greater ease of artistic expression than does a mouse. The simplest way to use such devices is simply as a replacement for the mouse, but that misses out many of the advantages of these devices, such as:
Pressure sensitivity
Tilt reporting
Sub-pixel positioning
Multiple inputs (for example, a stylus with a point and eraser)
For information about the XInput extension,
If we examine the full definition of, for example, the GdkEventMotion structure, we see that it has fields to support extended device information.
struct _GdkEventMotion
{
GdkEventType type;
GdkWindow *window;
guint32 time;
gdouble x;
gdouble y;
gdouble pressure;
gdouble xtilt;
gdouble ytilt;
guint state;
gint16 is_hint;
GdkInputSource source;
guint32 deviceid;
};pressure gives the pressure as a floating point number between 0 and 1. xtilt and ytilt can take on values between -1 and 1, corresponding to the degree of tilt in each direction. source and deviceid specify the device for which the event occurred in two different ways. source gives some simple information about the type of device. It can take the enumeration values:
GDK_SOURCE_MOUSE GDK_SOURCE_PEN GDK_SOURCE_ERASER GDK_SOURCE_CURSOR
deviceid specifies a unique numeric ID for the device. This can be used to find out further information about the device using the gdk_input_list_devices() call (see below). The special value GDK_CORE_POINTER is used for the core pointer device. (Usually the mouse.)
To let GTK know about our interest in the extended device information, we merely have to add a single line to our program:
gtk_widget_set_extension_events (drawing_area, GDK_EXTENSION_EVENTS_CURSOR);
By giving the value GDK_EXTENSION_EVENTS_CURSOR we say that we are interested in extension events, but only if we don't have to draw our own cursor information about drawing the cursor. We could also give the values GDK_EXTENSION_EVENTS_ALL if we were willing to draw our own cursor, or GDK_EXTENSION_EVENTS_NONE to revert back to the condition.
This is not completely the end of the story however. By , no extension devices are enabled. We need a mechanism to allow users to enable and configure their extension devices. GTK provides the InputDialog widget to automate this process. The following procedure manages an InputDialog widget. It creates the dialog if it isn't present, and raises it to the top otherwise.
void
input_dialog_destroy (GtkWidget *w, gpointer data)
{
*((GtkWidget **)data) = NULL;
}
void
create_input_dialog ()
{
static GtkWidget *inputd = NULL;
if (!inputd)
{
inputd = gtk_input_dialog_new();
gtk_signal_connect (GTK_OBJECT(inputd), "destroy,
(GtkSignalFunc)input_dialog_destroy, &inputd);
gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(inputd)-&62;close_button),
"clicked,
(GtkSignalFunc)gtk_widget_hide,
GTK_OBJECT(inputd));
gtk_widget_hide ( GTK_INPUT_DIALOG(inputd)-&62;save_button);
gtk_widget_show (inputd);
}
else
{
if (!GTK_WIDGET_MAPPED(inputd))
gtk_widget_show(inputd);
else
gdk_window_raise(inputd-&62;window);
}
}(You might want to take note of the way we handle this dialog. By connecting to the "destroysignal, we make sure that we don't keep a pointer to dialog around after it is destroyed - that could lead to a segfault.)
The InputDialog has two buttons "Closeand "Save, which by have no actions assigned to them. In the above function we make "Closehide the dialog, hide the "Savebutton, since we don't implement saving of XInput options in this program.
Once we've enabled the device, we can just use the extended device information in the extra fields of the event structures. In fact, it is always safe to use this information since these fields will have reasonable values even when extended events are not enabled.
Once change we do have to make is to call gdk_input_window_get_pointer() instead of gdk_window_get_pointer. This is necessary because gdk_window_get_pointer doesn't return the extended device information.
void gdk_input_window_get_pointer( GdkWindow *window,
guint32 deviceid,
gdouble *x,
gdouble *y,
gdouble *pressure,
gdouble *xtilt,
gdouble *ytilt,
GdkModifierType *mask);When calling this function, we need to specify the device ID as well as the window. Usually, we'll get the device ID from the deviceid field of an event structure. Again, this function will return reasonable values when extension events are not enabled. (In this case, event-&62;deviceid will have the value GDK_CORE_POINTER).
So the basic structure of our button-press and motion event handlers doesn't change much - we just need to add code to deal with the extended information.
static gboolean button_press_event( GtkWidget *widget, GdkEventButton *event ) { print_button_press (event-&62;deviceid); if (event-&62;button == 1 && pixmap != NULL) draw_brush (widget, event-&62;source, event-&62;x, event-&62;y, event-&62;pressure); return TRUE
Bhopal news
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100