1 #include <stdlib.h>
2 #include <gmodule.h>
3 #include <clutter/clutter.h>
4 
5 #include "test-utils.h"
6 #include "tests/clutter-test-utils.h"
7 
8 typedef struct {
9   ClutterActor *stage;
10 
11   GHashTable *devices;
12 } TestDevicesApp;
13 
14 int
15 test_devices_main (int argc, char **argv);
16 
17 static const gchar *
device_type_name(ClutterInputDevice * device)18 device_type_name (ClutterInputDevice *device)
19 {
20   ClutterInputDeviceType d_type;
21 
22   d_type = clutter_input_device_get_device_type (device);
23   switch (d_type)
24     {
25     case CLUTTER_POINTER_DEVICE:
26       return "Pointer";
27 
28     case CLUTTER_KEYBOARD_DEVICE:
29       return "Keyboard";
30 
31     case CLUTTER_EXTENSION_DEVICE:
32       return "Extension";
33 
34     case CLUTTER_PEN_DEVICE:
35       return "Pen";
36 
37     case CLUTTER_ERASER_DEVICE:
38       return "Eraser";
39 
40     case CLUTTER_CURSOR_DEVICE:
41       return "Cursor";
42 
43     default:
44       return "Unknown";
45     }
46 }
47 
48 static gboolean
stage_button_event_cb(ClutterActor * actor,ClutterEvent * event,TestDevicesApp * app)49 stage_button_event_cb (ClutterActor   *actor,
50                        ClutterEvent   *event,
51                        TestDevicesApp *app)
52 {
53   ClutterInputDevice *device;
54   ClutterInputDevice *source_device;
55   ClutterActor *hand = NULL;
56 
57   device = clutter_event_get_device (event);
58   source_device = clutter_event_get_source_device (event);
59 
60   hand = g_hash_table_lookup (app->devices, device);
61 
62   g_print ("Device: '%s' (type: %s, source: '%s')\n",
63            clutter_input_device_get_device_name (device),
64            device_type_name (device),
65            source_device != device
66              ? clutter_input_device_get_device_name (source_device)
67              : "<same>");
68 
69   if (hand != NULL)
70     {
71       gfloat event_x, event_y;
72 
73       clutter_event_get_coords (event, &event_x, &event_y);
74       clutter_actor_set_position (hand, event_x, event_y);
75     }
76 
77   return FALSE;
78 }
79 
80 static gboolean
stage_motion_event_cb(ClutterActor * actor,ClutterEvent * event,TestDevicesApp * app)81 stage_motion_event_cb (ClutterActor   *actor,
82                        ClutterEvent   *event,
83                        TestDevicesApp *app)
84 {
85   ClutterInputDevice *device;
86   ClutterActor *hand = NULL;
87 
88   device = clutter_event_get_device (event);
89 
90   hand = g_hash_table_lookup (app->devices, device);
91   if (hand != NULL)
92     {
93       gfloat event_x, event_y;
94 
95       clutter_event_get_coords (event, &event_x, &event_y);
96       clutter_actor_set_position (hand, event_x, event_y);
97 
98       return TRUE;
99     }
100 
101   return FALSE;
102 }
103 
104 static void
seat_device_added_cb(ClutterSeat * seat,ClutterInputDevice * device,TestDevicesApp * app)105 seat_device_added_cb (ClutterSeat        *seat,
106                       ClutterInputDevice *device,
107                       TestDevicesApp     *app)
108 {
109   ClutterInputDeviceType device_type;
110   ClutterActor *hand = NULL;
111 
112   g_print ("got a %s device '%s'\n",
113            device_type_name (device),
114            clutter_input_device_get_device_name (device));
115 
116   device_type = clutter_input_device_get_device_type (device);
117   if (device_type == CLUTTER_POINTER_DEVICE ||
118       device_type == CLUTTER_PEN_DEVICE ||
119       device_type == CLUTTER_POINTER_DEVICE)
120     {
121       g_print ("*** enabling device '%s' ***\n",
122                clutter_input_device_get_device_name (device));
123 
124       hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR
125                                                           G_DIR_SEPARATOR_S
126                                                           "redhand.png",
127                                                           NULL);
128       g_hash_table_insert (app->devices, device, hand);
129 
130       clutter_container_add_actor (CLUTTER_CONTAINER (app->stage), hand);
131     }
132 }
133 
134 static void
seat_device_removed_cb(ClutterSeat * seat,ClutterInputDevice * device,TestDevicesApp * app)135 seat_device_removed_cb (ClutterSeat        *seat,
136                         ClutterInputDevice *device,
137                         TestDevicesApp     *app)
138 {
139   ClutterInputDeviceType device_type;
140   ClutterActor *hand = NULL;
141 
142   g_print ("removed a %s device '%s'\n",
143            device_type_name (device),
144            clutter_input_device_get_device_name (device));
145 
146   device_type = clutter_input_device_get_device_type (device);
147   if (device_type == CLUTTER_POINTER_DEVICE ||
148       device_type == CLUTTER_PEN_DEVICE ||
149       device_type == CLUTTER_POINTER_DEVICE)
150     {
151       hand = g_hash_table_lookup (app->devices, device);
152       if (hand != NULL)
153         clutter_container_add_actor (CLUTTER_CONTAINER (app->stage), hand);
154 
155       g_hash_table_remove (app->devices, device);
156     }
157 }
158 
159 G_MODULE_EXPORT int
test_devices_main(int argc,char ** argv)160 test_devices_main (int argc, char **argv)
161 {
162   ClutterActor *stage;
163   TestDevicesApp *app;
164   ClutterSeat *seat;
165   GList *stage_devices, *l;
166 
167   clutter_test_init (&argc, &argv);
168 
169   app = g_new0 (TestDevicesApp, 1);
170   app->devices = g_hash_table_new (g_direct_hash, g_direct_equal) ;
171 
172   stage = clutter_test_get_stage ();
173   clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue);
174   clutter_stage_set_title (CLUTTER_STAGE (stage), "Devices");
175   g_signal_connect (stage,
176                     "destroy", G_CALLBACK (clutter_test_quit),
177                     NULL);
178   g_signal_connect (stage,
179                     "motion-event", G_CALLBACK (stage_motion_event_cb),
180                     app);
181   g_signal_connect (stage,
182                     "button-press-event", G_CALLBACK (stage_button_event_cb),
183                     app);
184   app->stage = stage;
185 
186   clutter_actor_show (stage);
187 
188   seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
189   g_signal_connect (seat,
190                     "device-added", G_CALLBACK (seat_device_added_cb),
191                     app);
192   g_signal_connect (seat,
193                     "device-removed", G_CALLBACK (seat_device_removed_cb),
194                     app);
195 
196   stage_devices = clutter_seat_list_devices (seat);
197 
198   if (stage_devices == NULL)
199     g_error ("No input devices found.");
200 
201   for (l = stage_devices; l != NULL; l = l->next)
202     {
203       ClutterInputDevice *device = l->data;
204       ClutterInputDeviceType device_type;
205       ClutterActor *hand = NULL;
206 
207       g_print ("got a %s device '%s'\n",
208                device_type_name (device),
209                clutter_input_device_get_device_name (device));
210 
211       device_type = clutter_input_device_get_device_type (device);
212       if (device_type == CLUTTER_POINTER_DEVICE ||
213           device_type == CLUTTER_PEN_DEVICE ||
214           device_type == CLUTTER_POINTER_DEVICE)
215         {
216           g_print ("*** enabling device '%s' ***\n",
217                    clutter_input_device_get_device_name (device));
218 
219           hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR
220                                                               G_DIR_SEPARATOR_S
221                                                               "redhand.png",
222                                                               NULL);
223           g_hash_table_insert (app->devices, device, hand);
224 
225           clutter_container_add_actor (CLUTTER_CONTAINER (stage), hand);
226         }
227     }
228 
229   g_list_free (stage_devices);
230 
231   clutter_test_main ();
232 
233   return EXIT_SUCCESS;
234 }
235