aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-04-08 13:37:16 +0800
committerPo Lu2022-04-08 13:37:16 +0800
commitac2708bf6f83dfb965694381c4e9d0c71f61bd0c (patch)
tree93c26be2946195cd3380eef81401d33a440a27e8 /src
parente9849939549010529e180ffb2509922f1bcc4843 (diff)
downloademacs-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.c256
-rw-r--r--src/pgtkterm.h77
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
99static Lisp_Object xg_default_icon_file; 99static Lisp_Object xg_default_icon_file;
100 100
101static void pgtk_delete_display (struct pgtk_display_info *dpyinfo); 101static void pgtk_delete_display (struct pgtk_display_info *);
102static void pgtk_clear_frame_area (struct frame *f, int x, int y, int width, 102static void pgtk_clear_frame_area (struct frame *, int, int, int, int);
103 int height); 103static void pgtk_fill_rectangle (struct frame *, unsigned long, int, int,
104static void pgtk_fill_rectangle (struct frame *f, unsigned long color, int x, 104 int, int, bool);
105 int y, int width, int height, 105static void pgtk_clip_to_row (struct window *, struct glyph_row *,
106 bool respect_alpha_background); 106 enum glyph_row_area, cairo_t *);
107static void pgtk_clip_to_row (struct window *w, struct glyph_row *row, 107static struct frame *pgtk_any_window_to_frame (GdkWindow *);
108 enum glyph_row_area area, cairo_t * cr); 108static void pgtk_regenerate_devices (struct pgtk_display_info *);
109static struct frame *pgtk_any_window_to_frame (GdkWindow *window); 109
110static void
111pgtk_device_added_or_removal_cb (GdkSeat *seat, GdkDevice *device,
112 gpointer user_data)
113{
114 pgtk_regenerate_devices (user_data);
115}
116
117static void
118pgtk_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
131static void
132pgtk_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
142static void
143pgtk_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
195static void
196pgtk_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
213static void
214pgtk_regenerate_devices (struct pgtk_display_info *dpyinfo)
215{
216 pgtk_free_devices (dpyinfo);
217 pgtk_enumerate_devices (dpyinfo, false);
218}
110 219
111static void 220static void
112pgtk_toolkit_position (struct frame *f, int x, int y, 221pgtk_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
248static Lisp_Object
249pgtk_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)
205void 335void
206mark_pgtkterm (void) 336mark_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
220char * 361char *
@@ -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
5229static gboolean 5381static gboolean
5230key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) 5382key_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
5861static bool 6025static bool
5862note_mouse_movement (struct frame *frame, const GdkEventMotion * event) 6026note_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
6038static Lisp_Object 6189static Lisp_Object
6039construct_mouse_click (struct input_event *result, 6190construct_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
6058static gboolean 6212static gboolean
6059button_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) 6213button_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
6177static gboolean 6333static gboolean
6178scroll_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) 6334scroll_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
6307static void 6469static void
6308drag_data_received (GtkWidget * widget, GdkDragContext * context, 6470drag_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" */
45struct pgtk_bitmap_record 43struct 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
52struct 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 () */
117struct pgtk_display_info 122struct 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
247struct pgtk_output 253struct 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. */
410struct x_output 412struct 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)