diff options
| author | Po Lu | 2022-04-08 13:37:16 +0800 |
|---|---|---|
| committer | Po Lu | 2022-04-08 13:37:16 +0800 |
| commit | ac2708bf6f83dfb965694381c4e9d0c71f61bd0c (patch) | |
| tree | 93c26be2946195cd3380eef81401d33a440a27e8 /src | |
| parent | e9849939549010529e180ffb2509922f1bcc4843 (diff) | |
| download | emacs-ac2708bf6f83dfb965694381c4e9d0c71f61bd0c.tar.gz emacs-ac2708bf6f83dfb965694381c4e9d0c71f61bd0c.zip | |
Implement support for reporting device names on PGTK
* lisp/frame.el (device-class): Add new function.
* lisp/term/pgtk-win.el (pgtk-device-class): New function.
* src/pgtkterm.c (pgtk_device_added_or_removal_cb)
(pgtk_seat_added_cb, pgtk_seat_removed_cb)
(pgtk_enumerate_devices)
(pgtk_free_devices, pgtk_regenerate_devices)
(pgtk_get_device_for_event): New functions.
(mark_pgtkterm): Mark device data.
(pgtk_delete_terminal): Delete device data.
(pgtk_handle_event, key_press_event, note_mouse_movement)
(construct_mouse_click, button_event, scroll_event)
(drag_data_received): Set device correctly.
(pgtk_term_init): Initialize device data and seat tracking.
(pgtk_delete_display): Delete device data.
* src/pgtkterm.h (struct pgtk_device_t): New struct.
(struct pgtk_display_info): New field `devices'. Delete lots of
unused macros and reformat comments.
Diffstat (limited to 'src')
| -rw-r--r-- | src/pgtkterm.c | 256 | ||||
| -rw-r--r-- | src/pgtkterm.h | 77 |
2 files changed, 226 insertions, 107 deletions
diff --git a/src/pgtkterm.c b/src/pgtkterm.c index b2816aa04af..d8c6dad2f9d 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c | |||
| @@ -98,15 +98,124 @@ static Time ignore_next_mouse_click_timeout; | |||
| 98 | 98 | ||
| 99 | static Lisp_Object xg_default_icon_file; | 99 | static Lisp_Object xg_default_icon_file; |
| 100 | 100 | ||
| 101 | static void pgtk_delete_display (struct pgtk_display_info *dpyinfo); | 101 | static void pgtk_delete_display (struct pgtk_display_info *); |
| 102 | static void pgtk_clear_frame_area (struct frame *f, int x, int y, int width, | 102 | static void pgtk_clear_frame_area (struct frame *, int, int, int, int); |
| 103 | int height); | 103 | static void pgtk_fill_rectangle (struct frame *, unsigned long, int, int, |
| 104 | static void pgtk_fill_rectangle (struct frame *f, unsigned long color, int x, | 104 | int, int, bool); |
| 105 | int y, int width, int height, | 105 | static void pgtk_clip_to_row (struct window *, struct glyph_row *, |
| 106 | bool respect_alpha_background); | 106 | enum glyph_row_area, cairo_t *); |
| 107 | static void pgtk_clip_to_row (struct window *w, struct glyph_row *row, | 107 | static struct frame *pgtk_any_window_to_frame (GdkWindow *); |
| 108 | enum glyph_row_area area, cairo_t * cr); | 108 | static void pgtk_regenerate_devices (struct pgtk_display_info *); |
| 109 | static struct frame *pgtk_any_window_to_frame (GdkWindow *window); | 109 | |
| 110 | static void | ||
| 111 | pgtk_device_added_or_removal_cb (GdkSeat *seat, GdkDevice *device, | ||
| 112 | gpointer user_data) | ||
| 113 | { | ||
| 114 | pgtk_regenerate_devices (user_data); | ||
| 115 | } | ||
| 116 | |||
| 117 | static void | ||
| 118 | pgtk_seat_added_cb (GdkDisplay *dpy, GdkSeat *seat, | ||
| 119 | gpointer user_data) | ||
| 120 | { | ||
| 121 | pgtk_regenerate_devices (user_data); | ||
| 122 | |||
| 123 | g_signal_connect (G_OBJECT (seat), "device-added", | ||
| 124 | G_CALLBACK (pgtk_device_added_or_removal_cb), | ||
| 125 | user_data); | ||
| 126 | g_signal_connect (G_OBJECT (seat), "device-removed", | ||
| 127 | G_CALLBACK (pgtk_device_added_or_removal_cb), | ||
| 128 | user_data); | ||
| 129 | } | ||
| 130 | |||
| 131 | static void | ||
| 132 | pgtk_seat_removed_cb (GdkDisplay *dpy, GdkSeat *seat, | ||
| 133 | gpointer user_data) | ||
| 134 | { | ||
| 135 | pgtk_regenerate_devices (user_data); | ||
| 136 | |||
| 137 | g_signal_handlers_disconnect_by_func (G_OBJECT (seat), | ||
| 138 | G_CALLBACK (pgtk_device_added_or_removal_cb), | ||
| 139 | user_data); | ||
| 140 | } | ||
| 141 | |||
| 142 | static void | ||
| 143 | pgtk_enumerate_devices (struct pgtk_display_info *dpyinfo, | ||
| 144 | bool initial_p) | ||
| 145 | { | ||
| 146 | struct pgtk_device_t *rec; | ||
| 147 | GList *all_seats, *devices_on_seat, *tem, *t1; | ||
| 148 | GdkSeat *seat; | ||
| 149 | char printbuf[1026]; /* Believe it or not, some device names are | ||
| 150 | actually almost this long. */ | ||
| 151 | |||
| 152 | block_input (); | ||
| 153 | all_seats = gdk_display_list_seats (dpyinfo->gdpy); | ||
| 154 | |||
| 155 | for (tem = all_seats; tem; tem = tem->next) | ||
| 156 | { | ||
| 157 | seat = GDK_SEAT (tem->data); | ||
| 158 | |||
| 159 | if (initial_p) | ||
| 160 | { | ||
| 161 | g_signal_connect (G_OBJECT (seat), "device-added", | ||
| 162 | G_CALLBACK (pgtk_device_added_or_removal_cb), | ||
| 163 | dpyinfo); | ||
| 164 | g_signal_connect (G_OBJECT (seat), "device-removed", | ||
| 165 | G_CALLBACK (pgtk_device_added_or_removal_cb), | ||
| 166 | dpyinfo); | ||
| 167 | } | ||
| 168 | |||
| 169 | /* We only want slaves, not master devices. */ | ||
| 170 | devices_on_seat = gdk_seat_get_slaves (seat, | ||
| 171 | GDK_SEAT_CAPABILITY_ALL); | ||
| 172 | |||
| 173 | for (t1 = devices_on_seat; t1; t1 = t1->next) | ||
| 174 | { | ||
| 175 | rec = xmalloc (sizeof *rec); | ||
| 176 | rec->seat = g_object_ref (seat); | ||
| 177 | rec->device = GDK_DEVICE (t1->data); | ||
| 178 | |||
| 179 | snprintf (printbuf, 1026, "%u:%s", | ||
| 180 | gdk_device_get_source (rec->device), | ||
| 181 | gdk_device_get_name (rec->device)); | ||
| 182 | |||
| 183 | rec->name = build_string (printbuf); | ||
| 184 | rec->next = dpyinfo->devices; | ||
| 185 | dpyinfo->devices = rec; | ||
| 186 | } | ||
| 187 | |||
| 188 | g_list_free (devices_on_seat); | ||
| 189 | } | ||
| 190 | |||
| 191 | g_list_free (all_seats); | ||
| 192 | unblock_input (); | ||
| 193 | } | ||
| 194 | |||
| 195 | static void | ||
| 196 | pgtk_free_devices (struct pgtk_display_info *dpyinfo) | ||
| 197 | { | ||
| 198 | struct pgtk_device_t *last, *tem; | ||
| 199 | |||
| 200 | tem = dpyinfo->devices; | ||
| 201 | while (tem) | ||
| 202 | { | ||
| 203 | last = tem; | ||
| 204 | tem = tem->next; | ||
| 205 | |||
| 206 | g_object_unref (last->seat); | ||
| 207 | xfree (last); | ||
| 208 | } | ||
| 209 | |||
| 210 | dpyinfo->devices = NULL; | ||
| 211 | } | ||
| 212 | |||
| 213 | static void | ||
| 214 | pgtk_regenerate_devices (struct pgtk_display_info *dpyinfo) | ||
| 215 | { | ||
| 216 | pgtk_free_devices (dpyinfo); | ||
| 217 | pgtk_enumerate_devices (dpyinfo, false); | ||
| 218 | } | ||
| 110 | 219 | ||
| 111 | static void | 220 | static void |
| 112 | pgtk_toolkit_position (struct frame *f, int x, int y, | 221 | pgtk_toolkit_position (struct frame *f, int x, int y, |
| @@ -136,6 +245,27 @@ pgtk_toolkit_position (struct frame *f, int x, int y, | |||
| 136 | } | 245 | } |
| 137 | } | 246 | } |
| 138 | 247 | ||
| 248 | static Lisp_Object | ||
| 249 | pgtk_get_device_for_event (struct pgtk_display_info *dpyinfo, | ||
| 250 | GdkEvent *event) | ||
| 251 | { | ||
| 252 | struct pgtk_device_t *tem; | ||
| 253 | GdkDevice *device; | ||
| 254 | |||
| 255 | device = gdk_event_get_source_device (event); | ||
| 256 | |||
| 257 | if (!device) | ||
| 258 | return Qt; | ||
| 259 | |||
| 260 | for (tem = dpyinfo->devices; tem; tem = tem->next) | ||
| 261 | { | ||
| 262 | if (tem->device == device) | ||
| 263 | return tem->name; | ||
| 264 | } | ||
| 265 | |||
| 266 | return Qt; | ||
| 267 | } | ||
| 268 | |||
| 139 | /* This is not a flip context in the same sense as gpu rendering | 269 | /* This is not a flip context in the same sense as gpu rendering |
| 140 | scenes, it only occurs when a new context was required due to a | 270 | scenes, it only occurs when a new context was required due to a |
| 141 | resize or other fundamental change. This is called when that | 271 | resize or other fundamental change. This is called when that |
| @@ -205,8 +335,11 @@ evq_flush (struct input_event *hold_quit) | |||
| 205 | void | 335 | void |
| 206 | mark_pgtkterm (void) | 336 | mark_pgtkterm (void) |
| 207 | { | 337 | { |
| 338 | struct pgtk_display_info *dpyinfo; | ||
| 339 | struct pgtk_device_t *device; | ||
| 208 | struct event_queue_t *evq = &event_q; | 340 | struct event_queue_t *evq = &event_q; |
| 209 | int i, n = evq->nr; | 341 | int i, n = evq->nr; |
| 342 | |||
| 210 | for (i = 0; i < n; i++) | 343 | for (i = 0; i < n; i++) |
| 211 | { | 344 | { |
| 212 | union buffered_input_event *ev = &evq->q[i]; | 345 | union buffered_input_event *ev = &evq->q[i]; |
| @@ -215,6 +348,14 @@ mark_pgtkterm (void) | |||
| 215 | mark_object (ev->ie.frame_or_window); | 348 | mark_object (ev->ie.frame_or_window); |
| 216 | mark_object (ev->ie.arg); | 349 | mark_object (ev->ie.arg); |
| 217 | } | 350 | } |
| 351 | |||
| 352 | for (dpyinfo = x_display_list; dpyinfo; | ||
| 353 | dpyinfo = dpyinfo->next) | ||
| 354 | { | ||
| 355 | for (device = dpyinfo->devices; device; | ||
| 356 | device = device->next) | ||
| 357 | mark_object (device->name); | ||
| 358 | } | ||
| 218 | } | 359 | } |
| 219 | 360 | ||
| 220 | char * | 361 | char * |
| @@ -4460,11 +4601,20 @@ pgtk_delete_terminal (struct terminal *terminal) | |||
| 4460 | g_clear_object (&dpyinfo->vertical_scroll_bar_cursor); | 4601 | g_clear_object (&dpyinfo->vertical_scroll_bar_cursor); |
| 4461 | g_clear_object (&dpyinfo->horizontal_scroll_bar_cursor); | 4602 | g_clear_object (&dpyinfo->horizontal_scroll_bar_cursor); |
| 4462 | g_clear_object (&dpyinfo->invisible_cursor); | 4603 | g_clear_object (&dpyinfo->invisible_cursor); |
| 4463 | if (dpyinfo->last_click_event != NULL) { | 4604 | if (dpyinfo->last_click_event != NULL) |
| 4464 | gdk_event_free (dpyinfo->last_click_event); | 4605 | { |
| 4465 | dpyinfo->last_click_event = NULL; | 4606 | gdk_event_free (dpyinfo->last_click_event); |
| 4466 | } | 4607 | dpyinfo->last_click_event = NULL; |
| 4608 | } | ||
| 4467 | 4609 | ||
| 4610 | /* Disconnect these handlers before the display closes so | ||
| 4611 | useless removal signals don't fire. */ | ||
| 4612 | g_signal_handlers_disconnect_by_func (G_OBJECT (dpyinfo->gdpy), | ||
| 4613 | G_CALLBACK (pgtk_seat_added_cb), | ||
| 4614 | dpyinfo); | ||
| 4615 | g_signal_handlers_disconnect_by_func (G_OBJECT (dpyinfo->gdpy), | ||
| 4616 | G_CALLBACK (pgtk_seat_removed_cb), | ||
| 4617 | dpyinfo); | ||
| 4468 | xg_display_close (dpyinfo->gdpy); | 4618 | xg_display_close (dpyinfo->gdpy); |
| 4469 | 4619 | ||
| 4470 | dpyinfo->gdpy = NULL; | 4620 | dpyinfo->gdpy = NULL; |
| @@ -4889,6 +5039,8 @@ pgtk_handle_event (GtkWidget *widget, GdkEvent *event, gpointer *data) | |||
| 4889 | make_float (event->touchpad_pinch.angle_delta)); | 5039 | make_float (event->touchpad_pinch.angle_delta)); |
| 4890 | inev.ie.modifiers = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), | 5040 | inev.ie.modifiers = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), |
| 4891 | event->touchpad_pinch.state); | 5041 | event->touchpad_pinch.state); |
| 5042 | inev.ie.device | ||
| 5043 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event); | ||
| 4892 | evq_enqueue (&inev); | 5044 | evq_enqueue (&inev); |
| 4893 | } | 5045 | } |
| 4894 | 5046 | ||
| @@ -5227,7 +5379,7 @@ pgtk_enqueue_preedit (struct frame *f, Lisp_Object preedit) | |||
| 5227 | } | 5379 | } |
| 5228 | 5380 | ||
| 5229 | static gboolean | 5381 | static gboolean |
| 5230 | key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | 5382 | key_press_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) |
| 5231 | { | 5383 | { |
| 5232 | struct coding_system coding; | 5384 | struct coding_system coding; |
| 5233 | union buffered_input_event inev; | 5385 | union buffered_input_event inev; |
| @@ -5237,8 +5389,6 @@ key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 5237 | USE_SAFE_ALLOCA; | 5389 | USE_SAFE_ALLOCA; |
| 5238 | 5390 | ||
| 5239 | EVENT_INIT (inev.ie); | 5391 | EVENT_INIT (inev.ie); |
| 5240 | inev.ie.kind = NO_EVENT; | ||
| 5241 | inev.ie.arg = Qnil; | ||
| 5242 | 5392 | ||
| 5243 | struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget)); | 5393 | struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget)); |
| 5244 | hlinfo = MOUSE_HL_INFO (f); | 5394 | hlinfo = MOUSE_HL_INFO (f); |
| @@ -5321,6 +5471,9 @@ key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 5321 | { | 5471 | { |
| 5322 | inev.ie.kind = ASCII_KEYSTROKE_EVENT; | 5472 | inev.ie.kind = ASCII_KEYSTROKE_EVENT; |
| 5323 | inev.ie.code = keysym; | 5473 | inev.ie.code = keysym; |
| 5474 | |||
| 5475 | inev.ie.device | ||
| 5476 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event); | ||
| 5324 | goto done; | 5477 | goto done; |
| 5325 | } | 5478 | } |
| 5326 | 5479 | ||
| @@ -5332,6 +5485,9 @@ key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 5332 | else | 5485 | else |
| 5333 | inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; | 5486 | inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; |
| 5334 | inev.ie.code = keysym & 0xFFFFFF; | 5487 | inev.ie.code = keysym & 0xFFFFFF; |
| 5488 | |||
| 5489 | inev.ie.device | ||
| 5490 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event); | ||
| 5335 | goto done; | 5491 | goto done; |
| 5336 | } | 5492 | } |
| 5337 | 5493 | ||
| @@ -5344,6 +5500,9 @@ key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 5344 | ? ASCII_KEYSTROKE_EVENT | 5500 | ? ASCII_KEYSTROKE_EVENT |
| 5345 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | 5501 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); |
| 5346 | inev.ie.code = XFIXNAT (c); | 5502 | inev.ie.code = XFIXNAT (c); |
| 5503 | |||
| 5504 | inev.ie.device | ||
| 5505 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event); | ||
| 5347 | goto done; | 5506 | goto done; |
| 5348 | } | 5507 | } |
| 5349 | 5508 | ||
| @@ -5427,6 +5586,9 @@ key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 5427 | key. */ | 5586 | key. */ |
| 5428 | inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT; | 5587 | inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT; |
| 5429 | inev.ie.code = keysym; | 5588 | inev.ie.code = keysym; |
| 5589 | |||
| 5590 | inev.ie.device | ||
| 5591 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event); | ||
| 5430 | goto done; | 5592 | goto done; |
| 5431 | } | 5593 | } |
| 5432 | 5594 | ||
| @@ -5478,6 +5640,8 @@ key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 5478 | ? ASCII_KEYSTROKE_EVENT | 5640 | ? ASCII_KEYSTROKE_EVENT |
| 5479 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | 5641 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); |
| 5480 | inev.ie.code = ch; | 5642 | inev.ie.code = ch; |
| 5643 | inev.ie.device | ||
| 5644 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event); | ||
| 5481 | evq_enqueue (&inev); | 5645 | evq_enqueue (&inev); |
| 5482 | } | 5646 | } |
| 5483 | 5647 | ||
| @@ -5859,7 +6023,8 @@ focus_out_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 5859 | another motion event, so we can check again the next time it moves. */ | 6023 | another motion event, so we can check again the next time it moves. */ |
| 5860 | 6024 | ||
| 5861 | static bool | 6025 | static bool |
| 5862 | note_mouse_movement (struct frame *frame, const GdkEventMotion * event) | 6026 | note_mouse_movement (struct frame *frame, |
| 6027 | const GdkEventMotion *event) | ||
| 5863 | { | 6028 | { |
| 5864 | XRectangle *r; | 6029 | XRectangle *r; |
| 5865 | struct pgtk_display_info *dpyinfo; | 6030 | struct pgtk_display_info *dpyinfo; |
| @@ -5879,6 +6044,9 @@ note_mouse_movement (struct frame *frame, const GdkEventMotion * event) | |||
| 5879 | dpyinfo->last_mouse_scroll_bar = NULL; | 6044 | dpyinfo->last_mouse_scroll_bar = NULL; |
| 5880 | note_mouse_highlight (frame, -1, -1); | 6045 | note_mouse_highlight (frame, -1, -1); |
| 5881 | dpyinfo->last_mouse_glyph_frame = NULL; | 6046 | dpyinfo->last_mouse_glyph_frame = NULL; |
| 6047 | frame->last_mouse_device | ||
| 6048 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (frame), | ||
| 6049 | (GdkEvent *) event); | ||
| 5882 | return true; | 6050 | return true; |
| 5883 | } | 6051 | } |
| 5884 | 6052 | ||
| @@ -5895,6 +6063,9 @@ note_mouse_movement (struct frame *frame, const GdkEventMotion * event) | |||
| 5895 | /* Remember which glyph we're now on. */ | 6063 | /* Remember which glyph we're now on. */ |
| 5896 | remember_mouse_glyph (frame, event->x, event->y, r); | 6064 | remember_mouse_glyph (frame, event->x, event->y, r); |
| 5897 | dpyinfo->last_mouse_glyph_frame = frame; | 6065 | dpyinfo->last_mouse_glyph_frame = frame; |
| 6066 | frame->last_mouse_device | ||
| 6067 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (frame), | ||
| 6068 | (GdkEvent *) event); | ||
| 5898 | return true; | 6069 | return true; |
| 5899 | } | 6070 | } |
| 5900 | 6071 | ||
| @@ -6010,26 +6181,6 @@ motion_notify_event (GtkWidget * widget, GdkEvent * event, | |||
| 6010 | return TRUE; | 6181 | return TRUE; |
| 6011 | } | 6182 | } |
| 6012 | 6183 | ||
| 6013 | /* Mouse clicks and mouse movement. Rah. | ||
| 6014 | |||
| 6015 | Formerly, we used PointerMotionHintMask (in standard_event_mask) | ||
| 6016 | so that we would have to call XQueryPointer after each MotionNotify | ||
| 6017 | event to ask for another such event. However, this made mouse tracking | ||
| 6018 | slow, and there was a bug that made it eventually stop. | ||
| 6019 | |||
| 6020 | Simply asking for MotionNotify all the time seems to work better. | ||
| 6021 | |||
| 6022 | In order to avoid asking for motion events and then throwing most | ||
| 6023 | of them away or busy-polling the server for mouse positions, we ask | ||
| 6024 | the server for pointer motion hints. This means that we get only | ||
| 6025 | one event per group of mouse movements. "Groups" are delimited by | ||
| 6026 | other kinds of events (focus changes and button clicks, for | ||
| 6027 | example), or by XQueryPointer calls; when one of these happens, we | ||
| 6028 | get another MotionNotify event the next time the mouse moves. This | ||
| 6029 | is at least as efficient as getting motion events when mouse | ||
| 6030 | tracking is on, and I suspect only negligibly worse when tracking | ||
| 6031 | is off. */ | ||
| 6032 | |||
| 6033 | /* Prepare a mouse-event in *RESULT for placement in the input queue. | 6184 | /* Prepare a mouse-event in *RESULT for placement in the input queue. |
| 6034 | 6185 | ||
| 6035 | If the event is a button press, then note that we have grabbed | 6186 | If the event is a button press, then note that we have grabbed |
| @@ -6037,7 +6188,8 @@ motion_notify_event (GtkWidget * widget, GdkEvent * event, | |||
| 6037 | 6188 | ||
| 6038 | static Lisp_Object | 6189 | static Lisp_Object |
| 6039 | construct_mouse_click (struct input_event *result, | 6190 | construct_mouse_click (struct input_event *result, |
| 6040 | const GdkEventButton * event, struct frame *f) | 6191 | const GdkEventButton *event, |
| 6192 | struct frame *f) | ||
| 6041 | { | 6193 | { |
| 6042 | /* Make the event type NO_EVENT; we'll change that when we decide | 6194 | /* Make the event type NO_EVENT; we'll change that when we decide |
| 6043 | otherwise. */ | 6195 | otherwise. */ |
| @@ -6052,11 +6204,15 @@ construct_mouse_click (struct input_event *result, | |||
| 6052 | XSETINT (result->y, event->y); | 6204 | XSETINT (result->y, event->y); |
| 6053 | XSETFRAME (result->frame_or_window, f); | 6205 | XSETFRAME (result->frame_or_window, f); |
| 6054 | result->arg = Qnil; | 6206 | result->arg = Qnil; |
| 6207 | result->device = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), | ||
| 6208 | (GdkEvent *) event); | ||
| 6055 | return Qnil; | 6209 | return Qnil; |
| 6056 | } | 6210 | } |
| 6057 | 6211 | ||
| 6058 | static gboolean | 6212 | static gboolean |
| 6059 | button_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | 6213 | button_event (GtkWidget *widget, |
| 6214 | GdkEvent *event, | ||
| 6215 | gpointer *user_data) | ||
| 6060 | { | 6216 | { |
| 6061 | union buffered_input_event inev; | 6217 | union buffered_input_event inev; |
| 6062 | struct frame *f, *frame; | 6218 | struct frame *f, *frame; |
| @@ -6175,7 +6331,7 @@ button_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 6175 | } | 6331 | } |
| 6176 | 6332 | ||
| 6177 | static gboolean | 6333 | static gboolean |
| 6178 | scroll_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | 6334 | scroll_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) |
| 6179 | { | 6335 | { |
| 6180 | union buffered_input_event inev; | 6336 | union buffered_input_event inev; |
| 6181 | struct frame *f, *frame; | 6337 | struct frame *f, *frame; |
| @@ -6207,6 +6363,8 @@ scroll_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 6207 | if (gdk_event_is_scroll_stop_event (event)) | 6363 | if (gdk_event_is_scroll_stop_event (event)) |
| 6208 | { | 6364 | { |
| 6209 | inev.ie.kind = TOUCH_END_EVENT; | 6365 | inev.ie.kind = TOUCH_END_EVENT; |
| 6366 | inev.ie.device | ||
| 6367 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event); | ||
| 6210 | evq_enqueue (&inev); | 6368 | evq_enqueue (&inev); |
| 6211 | return TRUE; | 6369 | return TRUE; |
| 6212 | } | 6370 | } |
| @@ -6300,14 +6458,17 @@ scroll_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) | |||
| 6300 | } | 6458 | } |
| 6301 | 6459 | ||
| 6302 | if (inev.ie.kind != NO_EVENT) | 6460 | if (inev.ie.kind != NO_EVENT) |
| 6303 | evq_enqueue (&inev); | 6461 | { |
| 6462 | inev.ie.device | ||
| 6463 | = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event); | ||
| 6464 | evq_enqueue (&inev); | ||
| 6465 | } | ||
| 6304 | return TRUE; | 6466 | return TRUE; |
| 6305 | } | 6467 | } |
| 6306 | 6468 | ||
| 6307 | static void | 6469 | static void |
| 6308 | drag_data_received (GtkWidget * widget, GdkDragContext * context, | 6470 | drag_data_received (GtkWidget *widget, GdkDragContext *context, |
| 6309 | gint x, gint y, | 6471 | gint x, gint y, GtkSelectionData *data, |
| 6310 | GtkSelectionData * data, | ||
| 6311 | guint info, guint time, gpointer user_data) | 6472 | guint info, guint time, gpointer user_data) |
| 6312 | { | 6473 | { |
| 6313 | struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget)); | 6474 | struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget)); |
| @@ -6716,6 +6877,12 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) | |||
| 6716 | 6877 | ||
| 6717 | pgtk_im_init (dpyinfo); | 6878 | pgtk_im_init (dpyinfo); |
| 6718 | 6879 | ||
| 6880 | g_signal_connect (G_OBJECT (dpyinfo->gdpy), "seat-added", | ||
| 6881 | G_CALLBACK (pgtk_seat_added_cb), dpyinfo); | ||
| 6882 | g_signal_connect (G_OBJECT (dpyinfo->gdpy), "seat-removed", | ||
| 6883 | G_CALLBACK (pgtk_seat_removed_cb), dpyinfo); | ||
| 6884 | pgtk_enumerate_devices (dpyinfo, true); | ||
| 6885 | |||
| 6719 | unblock_input (); | 6886 | unblock_input (); |
| 6720 | 6887 | ||
| 6721 | return dpyinfo; | 6888 | return dpyinfo; |
| @@ -6749,6 +6916,7 @@ pgtk_delete_display (struct pgtk_display_info *dpyinfo) | |||
| 6749 | tail->next = tail->next->next; | 6916 | tail->next = tail->next->next; |
| 6750 | } | 6917 | } |
| 6751 | 6918 | ||
| 6919 | pgtk_free_devices (dpyinfo); | ||
| 6752 | xfree (dpyinfo); | 6920 | xfree (dpyinfo); |
| 6753 | } | 6921 | } |
| 6754 | 6922 | ||
diff --git a/src/pgtkterm.h b/src/pgtkterm.h index b1165752aba..56c5d22e54e 100644 --- a/src/pgtkterm.h +++ b/src/pgtkterm.h | |||
| @@ -40,8 +40,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 40 | #include <cairo-svg.h> | 40 | #include <cairo-svg.h> |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | /* could use list to store these, but rest of emacs has a big infrastructure | ||
| 44 | for managing a table of bitmap "records" */ | ||
| 45 | struct pgtk_bitmap_record | 43 | struct pgtk_bitmap_record |
| 46 | { | 44 | { |
| 47 | void *img; | 45 | void *img; |
| @@ -51,6 +49,15 @@ struct pgtk_bitmap_record | |||
| 51 | cairo_pattern_t *pattern; | 49 | cairo_pattern_t *pattern; |
| 52 | }; | 50 | }; |
| 53 | 51 | ||
| 52 | struct pgtk_device_t | ||
| 53 | { | ||
| 54 | GdkSeat *seat; | ||
| 55 | GdkDevice *device; | ||
| 56 | |||
| 57 | Lisp_Object name; | ||
| 58 | struct pgtk_device_t *next; | ||
| 59 | }; | ||
| 60 | |||
| 54 | #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) | 61 | #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) |
| 55 | #define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) | 62 | #define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) |
| 56 | 63 | ||
| @@ -112,8 +119,6 @@ struct scroll_bar | |||
| 112 | bool horizontal; | 119 | bool horizontal; |
| 113 | }; | 120 | }; |
| 114 | 121 | ||
| 115 | |||
| 116 | /* init'd in pgtk_initialize_display_info () */ | ||
| 117 | struct pgtk_display_info | 122 | struct pgtk_display_info |
| 118 | { | 123 | { |
| 119 | /* Chain of all pgtk_display_info structures. */ | 124 | /* Chain of all pgtk_display_info structures. */ |
| @@ -208,13 +213,14 @@ struct pgtk_display_info | |||
| 208 | /* The scroll bar in which the last motion event occurred. */ | 213 | /* The scroll bar in which the last motion event occurred. */ |
| 209 | void *last_mouse_scroll_bar; | 214 | void *last_mouse_scroll_bar; |
| 210 | 215 | ||
| 211 | /* The invisible cursor used for pointer blanking. | 216 | /* The invisible cursor used for pointer blanking. */ |
| 212 | Unused if this display supports Xfixes extension. */ | ||
| 213 | Emacs_Cursor invisible_cursor; | 217 | Emacs_Cursor invisible_cursor; |
| 214 | 218 | ||
| 215 | /* The GDK cursor for scroll bars and popup menus. */ | 219 | /* The GDK cursor for scroll bars and popup menus. */ |
| 216 | GdkCursor *xg_cursor; | 220 | GdkCursor *xg_cursor; |
| 217 | 221 | ||
| 222 | /* List of all devices for all seats on this display. */ | ||
| 223 | struct pgtk_device_t *devices; | ||
| 218 | 224 | ||
| 219 | /* The frame where the mouse was last time we reported a mouse position. */ | 225 | /* The frame where the mouse was last time we reported a mouse position. */ |
| 220 | struct frame *last_mouse_glyph_frame; | 226 | struct frame *last_mouse_glyph_frame; |
| @@ -225,7 +231,7 @@ struct pgtk_display_info | |||
| 225 | /* The last click event. */ | 231 | /* The last click event. */ |
| 226 | GdkEvent *last_click_event; | 232 | GdkEvent *last_click_event; |
| 227 | 233 | ||
| 228 | /* input method */ | 234 | /* IM context data. */ |
| 229 | struct | 235 | struct |
| 230 | { | 236 | { |
| 231 | GtkIMContext *context; | 237 | GtkIMContext *context; |
| @@ -246,10 +252,6 @@ extern struct pgtk_display_info *x_display_list; | |||
| 246 | 252 | ||
| 247 | struct pgtk_output | 253 | struct pgtk_output |
| 248 | { | 254 | { |
| 249 | #if 0 | ||
| 250 | void *view; | ||
| 251 | void *miniimage; | ||
| 252 | #endif | ||
| 253 | unsigned long foreground_color; | 255 | unsigned long foreground_color; |
| 254 | unsigned long background_color; | 256 | unsigned long background_color; |
| 255 | void *toolbar; | 257 | void *toolbar; |
| @@ -406,7 +408,7 @@ struct pgtk_output | |||
| 406 | struct atimer *scale_factor_atimer; | 408 | struct atimer *scale_factor_atimer; |
| 407 | }; | 409 | }; |
| 408 | 410 | ||
| 409 | /* this dummy decl needed to support TTYs */ | 411 | /* Satisfy term.c. */ |
| 410 | struct x_output | 412 | struct x_output |
| 411 | { | 413 | { |
| 412 | int unused; | 414 | int unused; |
| @@ -452,59 +454,8 @@ enum | |||
| 452 | /* Turning a lisp vector value into a pointer to a struct scroll_bar. */ | 454 | /* Turning a lisp vector value into a pointer to a struct scroll_bar. */ |
| 453 | #define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec)) | 455 | #define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec)) |
| 454 | 456 | ||
| 455 | #define PGTK_FACE_FOREGROUND(f) ((f)->foreground) | ||
| 456 | #define PGTK_FACE_BACKGROUND(f) ((f)->background) | ||
| 457 | #define FRAME_DEFAULT_FACE(f) FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID) | 457 | #define FRAME_DEFAULT_FACE(f) FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID) |
| 458 | |||
| 459 | /* Compute pixel height of the frame's titlebar. */ | ||
| 460 | #define FRAME_PGTK_TITLEBAR_HEIGHT(f) 0 | ||
| 461 | |||
| 462 | /* Compute pixel size for vertical scroll bars */ | ||
| 463 | #define PGTK_SCROLL_BAR_WIDTH(f) \ | ||
| 464 | (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \ | ||
| 465 | ? rint (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0 \ | ||
| 466 | ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \ | ||
| 467 | : (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f))) \ | ||
| 468 | : 0) | ||
| 469 | |||
| 470 | /* Compute pixel size for horizontal scroll bars */ | ||
| 471 | #define PGTK_SCROLL_BAR_HEIGHT(f) \ | ||
| 472 | (FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) \ | ||
| 473 | ? rint (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0 \ | ||
| 474 | ? FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) \ | ||
| 475 | : (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f))) \ | ||
| 476 | : 0) | ||
| 477 | |||
| 478 | /* Difference btwn char-column-calculated and actual SB widths. | ||
| 479 | This is only a concern for rendering when SB on left. */ | ||
| 480 | #define PGTK_SCROLL_BAR_ADJUST(w, f) \ | ||
| 481 | (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) ? \ | ||
| 482 | (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f) \ | ||
| 483 | - PGTK_SCROLL_BAR_WIDTH (f)) : 0) | ||
| 484 | |||
| 485 | /* Difference btwn char-line-calculated and actual SB heights. | ||
| 486 | This is only a concern for rendering when SB on top. */ | ||
| 487 | #define PGTK_SCROLL_BAR_ADJUST_HORIZONTALLY(w, f) \ | ||
| 488 | (WINDOW_HAS_HORIZONTAL_SCROLL_BARS (w) ? \ | ||
| 489 | (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f) \ | ||
| 490 | - PGTK_SCROLL_BAR_HEIGHT (f)) : 0) | ||
| 491 | |||
| 492 | #define FRAME_MENUBAR_HEIGHT(f) (FRAME_X_OUTPUT (f)->menubar_height) | 458 | #define FRAME_MENUBAR_HEIGHT(f) (FRAME_X_OUTPUT (f)->menubar_height) |
| 493 | |||
| 494 | /* Calculate system coordinates of the left and top of the parent | ||
| 495 | window or, if there is no parent window, the screen. */ | ||
| 496 | #define PGTK_PARENT_WINDOW_LEFT_POS(f) \ | ||
| 497 | (FRAME_PARENT_FRAME (f) != NULL \ | ||
| 498 | ? [[FRAME_PGTK_VIEW (f) window] parentWindow].frame.origin.x : 0) | ||
| 499 | #define PGTK_PARENT_WINDOW_TOP_POS(f) \ | ||
| 500 | (FRAME_PARENT_FRAME (f) != NULL \ | ||
| 501 | ? ([[FRAME_PGTK_VIEW (f) window] parentWindow].frame.origin.y \ | ||
| 502 | + [[FRAME_PGTK_VIEW (f) window] parentWindow].frame.size.height \ | ||
| 503 | - FRAME_PGTK_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \ | ||
| 504 | : [[[PGTKScreen screepgtk] objectAtIndex: 0] frame].size.height) | ||
| 505 | |||
| 506 | #define FRAME_PGTK_FONT_TABLE(f) (FRAME_DISPLAY_INFO (f)->font_table) | ||
| 507 | |||
| 508 | #define FRAME_TOOLBAR_TOP_HEIGHT(f) ((f)->output_data.pgtk->toolbar_top_height) | 459 | #define FRAME_TOOLBAR_TOP_HEIGHT(f) ((f)->output_data.pgtk->toolbar_top_height) |
| 509 | #define FRAME_TOOLBAR_BOTTOM_HEIGHT(f) \ | 460 | #define FRAME_TOOLBAR_BOTTOM_HEIGHT(f) \ |
| 510 | ((f)->output_data.pgtk->toolbar_bottom_height) | 461 | ((f)->output_data.pgtk->toolbar_bottom_height) |