This source file includes following definitions.
- pgtk_get_monitor_scale_factor
- check_pgtk_display_info
- is_wayland_display
- pgtk_display_info_for_name
- pgtk_set_foreground_color
- pgtk_set_background_color
- pgtk_set_alpha_background
- pgtk_set_border_color
- pgtk_set_cursor_color
- pgtk_set_name_internal
- pgtk_set_name
- pgtk_explicitly_set_name
- pgtk_implicitly_set_name
- pgtk_set_title
- pgtk_set_menu_bar_lines
- pgtk_set_tab_bar_lines
- pgtk_change_tab_bar_height
- x_change_tool_bar_height
- pgtk_set_tool_bar_lines
- pgtk_set_child_frame_border_width
- pgtk_set_internal_border_width
- pgtk_set_icon_type
- pgtk_set_icon_name
- pgtk_set_cursor_type
- pgtk_set_mouse_color
- pgtk_set_undecorated
- pgtk_set_skip_taskbar
- pgtk_set_override_redirect
- xg_set_icon
- xg_set_icon_from_xpm_data
- pgtk_set_sticky
- pgtk_set_tool_bar_position
- pgtk_set_scroll_bar_foreground
- pgtk_set_scroll_bar_background
- unwind_create_frame
- do_unwind_create_frame
- x_decode_color
- pgtk_default_font_parameter
- update_watched_scale_factor
- DEFUN
- pgtk_frame_restack
- pgtk_is_lower_char
- pgtk_is_upper_char
- pgtk_is_numeric_char
- parse_resource_key
- pgtk_get_defaults_value
- pgtk_set_defaults_value
- pgtk_get_defaults_value
- pgtk_set_defaults_value
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- check_x_display_info
- pgtk_set_scroll_bar_default_width
- pgtk_set_scroll_bar_default_height
- pgtk_get_string_resource
- pgtk_get_focus_frame
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- pgtk_frame_scale_factor
- DEFUN
- DEFUN
- unwind_create_tip_frame
- x_create_tip_frame
- compute_tip_xy
- pgtk_hide_tip
- DEFUN
- frame_geometry
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- clean_up_dialog
- DEFUN
- DEFUN
- syms_of_pgtkfns
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <config.h>
24
25 #include <math.h>
26 #include <c-strcase.h>
27
28 #include "lisp.h"
29 #include "blockinput.h"
30 #include "gtkutil.h"
31 #include "window.h"
32 #include "character.h"
33 #include "buffer.h"
34 #include "keyboard.h"
35 #include "termhooks.h"
36 #include "fontset.h"
37 #include "font.h"
38 #include "xsettings.h"
39 #include "atimer.h"
40
41 static ptrdiff_t image_cache_refcount;
42
43 static int x_decode_color (struct frame *f, Lisp_Object color_name,
44 int mono_color);
45 static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object);
46
47 static const char *pgtk_app_name = "Emacs";
48
49
50 static Lisp_Object monitor_scale_factor_alist;
51
52
53
54
55
56
57
58 static double
59 pgtk_get_monitor_scale_factor (const char *model)
60 {
61 if (model == NULL)
62 return 0.0;
63
64 Lisp_Object mdl = build_string (model);
65 Lisp_Object tem = Fassoc (mdl, monitor_scale_factor_alist, Qnil);
66 if (NILP (tem))
67 return 0;
68 Lisp_Object cdr = Fcdr (tem);
69 if (NILP (cdr))
70 return 0;
71 if (FIXNUMP (cdr))
72 return XFIXNUM (cdr);
73 else if (FLOATP (cdr))
74 return XFLOAT_DATA (cdr);
75 else
76 error ("unknown type of scale-factor");
77 }
78
79 struct pgtk_display_info *
80 check_pgtk_display_info (Lisp_Object object)
81 {
82 struct pgtk_display_info *dpyinfo = NULL;
83
84 if (NILP (object))
85 {
86 struct frame *sf = XFRAME (selected_frame);
87
88 if (FRAME_PGTK_P (sf) && FRAME_LIVE_P (sf))
89 dpyinfo = FRAME_DISPLAY_INFO (sf);
90 else if (x_display_list != 0)
91 dpyinfo = x_display_list;
92 else
93 error ("Frames are not in use or not initialized");
94 }
95 else if (TERMINALP (object))
96 {
97 struct terminal *t = decode_live_terminal (object);
98
99 if (t->type != output_pgtk)
100 error ("Terminal %d is not a display", t->id);
101
102 dpyinfo = t->display_info.pgtk;
103 }
104 else if (STRINGP (object))
105 dpyinfo = pgtk_display_info_for_name (object);
106 else
107 {
108 struct frame *f = decode_window_system_frame (object);
109 dpyinfo = FRAME_DISPLAY_INFO (f);
110 }
111
112 return dpyinfo;
113 }
114
115
116
117
118
119
120
121 static Lisp_Object
122 is_wayland_display (Lisp_Object dpyname)
123 {
124 const char *p = SSDATA (dpyname);
125 if (strncmp (p, "wayland-", 8) != 0)
126 return Qnil;
127 p += 8;
128 do {
129 if (*p < '0' || *p > '9')
130 return Qnil;
131 } while (*++p != '\0');
132 return Qt;
133 }
134
135
136
137 static struct pgtk_display_info *
138 pgtk_display_info_for_name (Lisp_Object name)
139 {
140 struct pgtk_display_info *dpyinfo;
141
142 CHECK_STRING (name);
143
144 if (!NILP (is_wayland_display (name)))
145 {
146 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
147 if (!NILP (is_wayland_display (XCAR (dpyinfo->name_list_element))))
148 return dpyinfo;
149 }
150 else
151 {
152 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
153 if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
154 return dpyinfo;
155 }
156
157
158 Vx_resource_name = Vinvocation_name;
159
160 validate_x_resource_name ();
161
162 dpyinfo = pgtk_term_init (name, SSDATA (Vx_resource_name));
163
164 if (dpyinfo == 0)
165 error ("Cannot connect to display server %s", SDATA (name));
166
167 return dpyinfo;
168 }
169
170
171
172
173
174
175
176
177 static void
178 pgtk_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
179 {
180 unsigned long fg, old_fg;
181
182 block_input ();
183 old_fg = FRAME_FOREGROUND_COLOR (f);
184 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
185 FRAME_FOREGROUND_PIXEL (f) = fg;
186 FRAME_X_OUTPUT (f)->foreground_color = fg;
187
188 if (FRAME_GTK_WIDGET (f))
189 {
190 if (FRAME_X_OUTPUT (f)->cursor_color == old_fg)
191 {
192 FRAME_X_OUTPUT (f)->cursor_color = fg;
193 FRAME_X_OUTPUT (f)->cursor_xgcv.background = fg;
194 }
195
196 update_face_from_frame_parameter (f, Qforeground_color, arg);
197 if (FRAME_VISIBLE_P (f))
198 SET_FRAME_GARBAGED (f);
199 }
200 unblock_input ();
201 }
202
203
204 static void
205 pgtk_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
206 {
207 unsigned long bg;
208
209 block_input ();
210 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
211 FRAME_BACKGROUND_PIXEL (f) = bg;
212
213
214 if (FRAME_VISIBLE_P (f))
215 pgtk_clear_frame (f);
216
217 FRAME_X_OUTPUT (f)->background_color = bg;
218 FRAME_X_OUTPUT (f)->cursor_xgcv.foreground = bg;
219
220 xg_set_background_color (f, bg);
221 update_face_from_frame_parameter (f, Qbackground_color, arg);
222
223 if (FRAME_VISIBLE_P (f))
224 SET_FRAME_GARBAGED (f);
225 unblock_input ();
226 }
227
228 static void
229 pgtk_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
230 {
231 gui_set_alpha_background (f, arg, oldval);
232
233
234
235
236 gtk_widget_set_app_paintable (FRAME_GTK_OUTER_WIDGET (f),
237 f->alpha_background != 1.0);
238
239 if (FRAME_GTK_OUTER_WIDGET (f)
240 && gtk_widget_get_realized (FRAME_GTK_OUTER_WIDGET (f))
241 && f->alpha_background != 1.0)
242 gdk_window_set_opaque_region (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)),
243 NULL);
244 }
245
246 static void
247 pgtk_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
248 {
249 int pix;
250
251 CHECK_STRING (arg);
252 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
253 FRAME_X_OUTPUT (f)->border_pixel = pix;
254 pgtk_frame_rehighlight (FRAME_DISPLAY_INFO (f));
255 }
256
257 static void
258 pgtk_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
259 {
260 unsigned long fore_pixel, pixel;
261 struct pgtk_output *x = f->output_data.pgtk;
262
263 if (!NILP (Vx_cursor_fore_pixel))
264 {
265 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
266 WHITE_PIX_DEFAULT (f));
267 }
268 else
269 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
270
271 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
272
273
274 if (pixel == FRAME_BACKGROUND_PIXEL (f))
275 {
276 pixel = x->mouse_color;
277 if (pixel == fore_pixel)
278 {
279 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
280 }
281 }
282
283 x->cursor_foreground_color = fore_pixel;
284 x->cursor_color = pixel;
285
286 if (FRAME_X_WINDOW (f) != 0)
287 {
288 x->cursor_xgcv.background = x->cursor_color;
289 x->cursor_xgcv.foreground = fore_pixel;
290
291 if (FRAME_VISIBLE_P (f))
292 {
293 gui_update_cursor (f, false);
294 gui_update_cursor (f, true);
295 }
296 }
297
298 update_face_from_frame_parameter (f, Qcursor_color, arg);
299 }
300
301 static void
302 pgtk_set_name_internal (struct frame *f, Lisp_Object name)
303 {
304 if (FRAME_GTK_OUTER_WIDGET (f))
305 {
306 block_input ();
307 {
308 Lisp_Object encoded_name;
309
310
311
312 encoded_name = ENCODE_UTF_8 (name);
313
314 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
315 SSDATA (encoded_name));
316 }
317 unblock_input ();
318 }
319 }
320
321 static void
322 pgtk_set_name (struct frame *f, Lisp_Object name, int explicit)
323 {
324
325
326 if (explicit)
327 {
328
329
330 if (f->explicit_name && NILP (name))
331 update_mode_lines = 12;
332
333 f->explicit_name = !NILP (name);
334 }
335 else if (f->explicit_name)
336 return;
337
338 if (NILP (name))
339 name = build_string (pgtk_app_name);
340 else
341 CHECK_STRING (name);
342
343
344 if (!NILP (Fstring_equal (name, f->name)))
345 return;
346
347 fset_name (f, name);
348
349
350 if (!NILP (f->title))
351 name = f->title;
352
353 pgtk_set_name_internal (f, name);
354 }
355
356
357
358
359
360 static void
361 pgtk_explicitly_set_name (struct frame *f, Lisp_Object arg,
362 Lisp_Object oldval)
363 {
364 pgtk_set_name (f, arg, true);
365 }
366
367
368
369
370
371 void
372 pgtk_implicitly_set_name (struct frame *f, Lisp_Object arg,
373 Lisp_Object oldval)
374 {
375 pgtk_set_name (f, arg, false);
376 }
377
378
379
380
381
382 static void
383 pgtk_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
384 {
385
386 if (EQ (name, f->title))
387 return;
388
389 update_mode_lines = 22;
390
391 fset_title (f, name);
392
393 if (NILP (name))
394 name = f->name;
395 else
396 CHECK_STRING (name);
397
398 pgtk_set_name_internal (f, name);
399 }
400
401 static void
402 pgtk_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
403 {
404 int nlines;
405
406
407
408
409 if (FRAME_MINIBUF_ONLY_P (f) || FRAME_PARENT_FRAME (f))
410 return;
411
412 if (TYPE_RANGED_FIXNUMP (int, value))
413 nlines = XFIXNUM (value);
414 else
415 nlines = 0;
416
417
418 fset_redisplay (f);
419
420 FRAME_MENU_BAR_LINES (f) = 0;
421 FRAME_MENU_BAR_HEIGHT (f) = 0;
422 if (nlines)
423 {
424 FRAME_EXTERNAL_MENU_BAR (f) = 1;
425 if (FRAME_PGTK_P (f) && f->output_data.pgtk->menubar_widget == 0)
426
427 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
428 }
429 else
430 {
431 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
432 free_frame_menubar (f);
433 FRAME_EXTERNAL_MENU_BAR (f) = 0;
434 if (FRAME_X_P (f))
435 f->output_data.pgtk->menubar_widget = 0;
436 }
437
438 adjust_frame_glyphs (f);
439 }
440
441
442
443
444
445
446
447 static void
448 pgtk_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
449 {
450 int nlines;
451
452
453 if (FRAME_MINIBUF_ONLY_P (f))
454 return;
455
456
457 if (RANGED_FIXNUMP (0, value, INT_MAX))
458 nlines = XFIXNAT (value);
459 else
460 nlines = 0;
461
462 pgtk_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
463 }
464
465
466 void
467 pgtk_change_tab_bar_height (struct frame *f, int height)
468 {
469 int unit = FRAME_LINE_HEIGHT (f);
470 int old_height = FRAME_TAB_BAR_HEIGHT (f);
471
472
473
474
475
476
477 int lines = height / unit;
478 if (lines == 0 && height != 0)
479 lines = 1;
480
481
482 fset_redisplay (f);
483
484
485 FRAME_TAB_BAR_HEIGHT (f) = height;
486 FRAME_TAB_BAR_LINES (f) = lines;
487 store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
488
489 if (FRAME_X_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
490 {
491 clear_frame (f);
492 clear_current_matrices (f);
493 }
494
495 if ((height < old_height) && WINDOWP (f->tab_bar_window))
496 clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
497
498 if (!f->tab_bar_resized)
499 {
500 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
501
502
503
504 if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
505 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
506 1, false, Qtab_bar_lines);
507 else
508 adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
509
510 f->tab_bar_resized = f->tab_bar_redisplayed;
511 }
512 else
513
514 adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
515
516
517
518 adjust_frame_glyphs (f);
519 SET_FRAME_GARBAGED (f);
520 if (FRAME_X_WINDOW (f))
521 pgtk_clear_under_internal_border (f);
522 }
523
524
525 static void
526 x_change_tool_bar_height (struct frame *f, int height)
527 {
528 FRAME_TOOL_BAR_LINES (f) = 0;
529 FRAME_TOOL_BAR_HEIGHT (f) = 0;
530 if (height)
531 {
532 FRAME_EXTERNAL_TOOL_BAR (f) = true;
533 if (FRAME_X_P (f) && f->output_data.pgtk->toolbar_widget == 0)
534
535 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
536 update_frame_tool_bar (f);
537 }
538 else
539 {
540 if (FRAME_EXTERNAL_TOOL_BAR (f))
541 free_frame_tool_bar (f);
542 FRAME_EXTERNAL_TOOL_BAR (f) = false;
543 }
544 }
545
546
547 static void
548 pgtk_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
549 {
550 int nlines;
551
552
553 if (FRAME_MINIBUF_ONLY_P (f))
554 return;
555
556
557 if (RANGED_FIXNUMP (0, value, INT_MAX))
558 nlines = XFIXNAT (value);
559 else
560 nlines = 0;
561
562 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
563
564 }
565
566 static void
567 pgtk_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
568 {
569 int border;
570
571 if (NILP (arg))
572 border = -1;
573 else if (RANGED_FIXNUMP (0, arg, INT_MAX))
574 border = XFIXNAT (arg);
575 else
576 signal_error ("Invalid child frame border width", arg);
577
578 if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
579 {
580 f->child_frame_border_width = border;
581
582 if (FRAME_GTK_WIDGET (f))
583 {
584 adjust_frame_size (f, -1, -1, 3,
585 false, Qchild_frame_border_width);
586 pgtk_clear_under_internal_border (f);
587 }
588 }
589 }
590
591 static void
592 pgtk_set_internal_border_width (struct frame *f, Lisp_Object arg,
593 Lisp_Object oldval)
594 {
595 int border = check_int_nonnegative (arg);
596
597 if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
598 {
599 f->internal_border_width = border;
600
601 if (FRAME_X_WINDOW (f))
602 {
603 adjust_frame_size (f, -1, -1, 3, false, Qinternal_border_width);
604 pgtk_clear_under_internal_border (f);
605 }
606 }
607 }
608
609 static void
610 pgtk_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
611 {
612 bool result;
613
614 if (STRINGP (arg))
615 {
616 if (STRINGP (oldval) && BASE_EQ (Fstring_equal (oldval, arg), Qt))
617 return;
618 }
619 else if (!STRINGP (oldval) && NILP (oldval) == NILP (arg))
620 return;
621
622 block_input ();
623 if (NILP (arg))
624 result = pgtk_text_icon (f,
625 SSDATA ((!NILP (f->icon_name)
626 ? f->icon_name : f->name)));
627 else
628 result = FRAME_TERMINAL (f)->set_bitmap_icon_hook (f, arg);
629
630 if (result)
631 {
632 unblock_input ();
633 error ("No icon window available");
634 }
635
636 unblock_input ();
637 }
638
639 static void
640 pgtk_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
641 {
642 bool result;
643
644 if (STRINGP (arg))
645 {
646 if (STRINGP (oldval) && BASE_EQ (Fstring_equal (oldval, arg), Qt))
647 return;
648 }
649 else if (!NILP (arg) || NILP (oldval))
650 return;
651
652 fset_icon_name (f, arg);
653
654 block_input ();
655
656 result = pgtk_text_icon (f,
657 SSDATA ((!NILP (f->icon_name)
658 ? f->icon_name
659 : !NILP (f->title)
660 ? f->title : f->name)));
661
662 if (result)
663 {
664 unblock_input ();
665 error ("No icon window available");
666 }
667
668 unblock_input ();
669 }
670
671 static void
672 pgtk_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
673 {
674 set_frame_cursor_types (f, arg);
675 }
676
677 static void
678 pgtk_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
679 {
680 }
681
682 static void
683 pgtk_set_undecorated (struct frame *f, Lisp_Object new_value,
684 Lisp_Object old_value)
685 {
686 if (!EQ (new_value, old_value))
687 {
688 FRAME_UNDECORATED (f) = NILP (new_value) ? false : true;
689 xg_set_undecorated (f, new_value);
690 }
691 }
692
693 static void
694 pgtk_set_skip_taskbar (struct frame *f, Lisp_Object new_value,
695 Lisp_Object old_value)
696 {
697 if (!EQ (new_value, old_value))
698 {
699 xg_set_skip_taskbar (f, new_value);
700 FRAME_SKIP_TASKBAR (f) = !NILP (new_value);
701 }
702 }
703
704 static void
705 pgtk_set_override_redirect (struct frame *f, Lisp_Object new_value,
706 Lisp_Object old_value)
707 {
708 if (!EQ (new_value, old_value))
709 {
710
711
712 pgtk_make_frame_invisible (f);
713
714 xg_set_override_redirect (f, new_value);
715
716 pgtk_make_frame_visible (f);
717 FRAME_OVERRIDE_REDIRECT (f) = !NILP (new_value);
718 }
719 }
720
721
722 bool
723 xg_set_icon (struct frame *f, Lisp_Object file)
724 {
725 bool result = false;
726 Lisp_Object found;
727
728 if (!FRAME_GTK_OUTER_WIDGET (f))
729 return false;
730
731 found = image_find_image_file (file);
732
733 if (!NILP (found))
734 {
735 GdkPixbuf *pixbuf;
736 GError *err = NULL;
737 char *filename = SSDATA (ENCODE_FILE (found));
738 block_input ();
739
740 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
741
742 if (pixbuf)
743 {
744 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
745 pixbuf);
746 g_object_unref (pixbuf);
747
748 result = true;
749 }
750 else
751 g_error_free (err);
752
753 unblock_input ();
754 }
755
756 return result;
757 }
758
759 bool
760 xg_set_icon_from_xpm_data (struct frame *f, const char **data)
761 {
762 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
763
764 if (!pixbuf)
765 return false;
766
767 if (!FRAME_GTK_OUTER_WIDGET (f))
768 return false;
769
770 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
771 g_object_unref (pixbuf);
772 return true;
773 }
774
775 static void
776 pgtk_set_sticky (struct frame *f, Lisp_Object new_value,
777 Lisp_Object old_value)
778 {
779 if (!FRAME_GTK_OUTER_WIDGET (f))
780 return;
781
782 if (!NILP (new_value))
783 gtk_window_stick (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
784 else
785 gtk_window_unstick (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
786 }
787
788 static void
789 pgtk_set_tool_bar_position (struct frame *f,
790 Lisp_Object new_value, Lisp_Object old_value)
791 {
792 Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
793
794 if (!NILP (Fmemq (new_value, choice)))
795 {
796 if (!EQ (new_value, old_value))
797 {
798 xg_change_toolbar_position (f, new_value);
799 fset_tool_bar_position (f, new_value);
800 }
801 }
802 else
803 wrong_choice (choice, new_value);
804 }
805
806 static void
807 pgtk_set_scroll_bar_foreground (struct frame *f, Lisp_Object new_value,
808 Lisp_Object old_value)
809 {
810 GtkCssProvider *css_provider =
811 FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider;
812
813 if (FRAME_TOOLTIP_P (f))
814 return;
815
816 if (NILP (new_value))
817 {
818 gtk_css_provider_load_from_data (css_provider, "", -1, NULL);
819 update_face_from_frame_parameter (f, Qscroll_bar_foreground, new_value);
820 }
821 else if (STRINGP (new_value))
822 {
823 Emacs_Color rgb;
824
825 if (!pgtk_parse_color (f, SSDATA (new_value), &rgb))
826 error ("Unknown color.");
827
828 char css[64];
829 sprintf (css, "scrollbar slider { background-color: #%06x; }",
830 (unsigned int) rgb.pixel & 0xffffff);
831 gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
832 update_face_from_frame_parameter (f, Qscroll_bar_foreground, new_value);
833
834 }
835 else
836 error ("Invalid scroll-bar-foreground.");
837 }
838
839 static void
840 pgtk_set_scroll_bar_background (struct frame *f, Lisp_Object new_value,
841 Lisp_Object old_value)
842 {
843 GtkCssProvider *css_provider =
844 FRAME_X_OUTPUT (f)->scrollbar_background_css_provider;
845
846 if (NILP (new_value))
847 {
848 gtk_css_provider_load_from_data (css_provider, "", -1, NULL);
849 update_face_from_frame_parameter (f, Qscroll_bar_background, new_value);
850 }
851 else if (STRINGP (new_value))
852 {
853 Emacs_Color rgb;
854
855 if (!pgtk_parse_color (f, SSDATA (new_value), &rgb))
856 error ("Unknown color.");
857
858
859
860
861 char css[64];
862 sprintf (css, "scrollbar trough { background-color: #%06x; }",
863 (unsigned int) rgb.pixel & 0xffffff);
864 gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
865 update_face_from_frame_parameter (f, Qscroll_bar_background, new_value);
866
867 }
868 else
869 error ("Invalid scroll-bar-background.");
870 }
871
872
873
874
875
876
877
878 DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0,
879 doc:
880
881
882
883
884
885
886
887 )
888 (Lisp_Object frames, Lisp_Object type)
889 {
890 Lisp_Object rest, tmp;
891 cairo_surface_type_t surface_type;
892
893 if (!CONSP (frames))
894 frames = list1 (frames);
895
896 tmp = Qnil;
897 for (rest = frames; CONSP (rest); rest = XCDR (rest))
898 {
899 struct frame *f = decode_window_system_frame (XCAR (rest));
900 Lisp_Object frame;
901
902 XSETFRAME (frame, f);
903 if (!FRAME_VISIBLE_P (f))
904 error ("Frames to be exported must be visible.");
905 tmp = Fcons (frame, tmp);
906 }
907 frames = Fnreverse (tmp);
908
909 #ifdef CAIRO_HAS_PDF_SURFACE
910 if (NILP (type) || EQ (type, Qpdf))
911 surface_type = CAIRO_SURFACE_TYPE_PDF;
912 else
913 #endif
914 #ifdef CAIRO_HAS_PNG_FUNCTIONS
915 if (EQ (type, Qpng))
916 {
917 if (!NILP (XCDR (frames)))
918 error ("PNG export cannot handle multiple frames.");
919 surface_type = CAIRO_SURFACE_TYPE_IMAGE;
920 }
921 else
922 #endif
923 #ifdef CAIRO_HAS_PS_SURFACE
924 if (EQ (type, Qpostscript))
925 surface_type = CAIRO_SURFACE_TYPE_PS;
926 else
927 #endif
928 #ifdef CAIRO_HAS_SVG_SURFACE
929 if (EQ (type, Qsvg))
930 {
931
932 if (!NILP (XCDR (frames)))
933 error ("SVG export cannot handle multiple frames.");
934 surface_type = CAIRO_SURFACE_TYPE_SVG;
935 }
936 else
937 #endif
938 error ("Unsupported export type");
939
940 return pgtk_cr_export_frames (frames, surface_type);
941 }
942
943 frame_parm_handler pgtk_frame_parm_handlers[] =
944 {
945 gui_set_autoraise,
946 gui_set_autolower,
947 pgtk_set_background_color,
948 pgtk_set_border_color,
949 gui_set_border_width,
950 pgtk_set_cursor_color,
951 pgtk_set_cursor_type,
952 gui_set_font,
953 pgtk_set_foreground_color,
954 pgtk_set_icon_name,
955 pgtk_set_icon_type,
956 pgtk_set_child_frame_border_width,
957 pgtk_set_internal_border_width,
958 gui_set_right_divider_width,
959 gui_set_bottom_divider_width,
960 pgtk_set_menu_bar_lines,
961 pgtk_set_mouse_color,
962 pgtk_explicitly_set_name,
963 gui_set_scroll_bar_width,
964 gui_set_scroll_bar_height,
965 pgtk_set_title,
966 gui_set_unsplittable,
967 gui_set_vertical_scroll_bars,
968 gui_set_horizontal_scroll_bars,
969 gui_set_visibility,
970 pgtk_set_tab_bar_lines,
971 pgtk_set_tool_bar_lines,
972 pgtk_set_scroll_bar_foreground,
973 pgtk_set_scroll_bar_background,
974 gui_set_screen_gamma,
975 gui_set_line_spacing,
976 gui_set_left_fringe,
977 gui_set_right_fringe,
978 0,
979 gui_set_fullscreen,
980 gui_set_font_backend,
981 gui_set_alpha,
982 pgtk_set_sticky,
983 pgtk_set_tool_bar_position,
984 0,
985 pgtk_set_undecorated,
986 pgtk_set_parent_frame,
987 pgtk_set_skip_taskbar,
988 pgtk_set_no_focus_on_map,
989 pgtk_set_no_accept_focus,
990 pgtk_set_z_group,
991 pgtk_set_override_redirect,
992 gui_set_no_special_glyphs,
993 pgtk_set_alpha_background,
994 NULL,
995 };
996
997
998
999
1000
1001
1002 static Lisp_Object
1003 unwind_create_frame (Lisp_Object frame)
1004 {
1005 struct frame *f = XFRAME (frame);
1006
1007
1008
1009
1010 if (!FRAME_LIVE_P (f))
1011 return Qnil;
1012
1013
1014 if (NILP (Fmemq (frame, Vframe_list)))
1015 {
1016
1017
1018
1019
1020
1021
1022
1023 if (FRAME_IMAGE_CACHE (f) != NULL
1024 && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
1025 FRAME_IMAGE_CACHE (f)->refcount++;
1026
1027 pgtk_free_frame_resources (f);
1028 free_glyphs (f);
1029 return Qt;
1030 }
1031
1032 return Qnil;
1033 }
1034
1035 static void
1036 do_unwind_create_frame (Lisp_Object frame)
1037 {
1038 unwind_create_frame (frame);
1039 }
1040
1041
1042
1043
1044
1045 static int
1046 x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
1047 {
1048 Emacs_Color cdef;
1049
1050 CHECK_STRING (color_name);
1051
1052
1053 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
1054 return mono_color;
1055
1056
1057
1058 if (pgtk_defined_color (f, SSDATA (color_name), &cdef, true, 0))
1059 return cdef.pixel;
1060
1061 signal_error ("Undefined color", color_name);
1062 }
1063
1064 void
1065 pgtk_default_font_parameter (struct frame *f, Lisp_Object parms)
1066 {
1067 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1068 Lisp_Object font_param =
1069 gui_display_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
1070 RES_TYPE_STRING);
1071 Lisp_Object font = Qnil;
1072 if (BASE_EQ (font_param, Qunbound))
1073 font_param = Qnil;
1074
1075 if (NILP (font_param))
1076 {
1077
1078
1079
1080 const char *system_font = xsettings_get_system_font ();
1081 if (system_font)
1082 font = font_open_by_name (f, build_unibyte_string (system_font));
1083 }
1084
1085 if (NILP (font))
1086 font = !NILP (font_param) ? font_param
1087 : gui_display_get_arg (dpyinfo, parms, Qfont, "font", "Font",
1088 RES_TYPE_STRING);
1089
1090 if (!FONTP (font) && !STRINGP (font))
1091 {
1092 const char *names[] = {
1093 "monospace-10",
1094 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
1095 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
1096 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
1097
1098
1099 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
1100
1101
1102 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
1103 "fixed",
1104 NULL
1105 };
1106 int i;
1107
1108 for (i = 0; names[i]; i++)
1109 {
1110 font = font_open_by_name (f, build_unibyte_string (names[i]));
1111 if (!NILP (font))
1112 break;
1113 }
1114 if (NILP (font))
1115 error ("No suitable font was found");
1116 }
1117
1118
1119 gui_default_parameter (f, parms, Qfont, font, "font", "Font",
1120 RES_TYPE_STRING);
1121 }
1122
1123 static void
1124 update_watched_scale_factor (struct atimer *timer)
1125 {
1126 struct frame *f = timer->client_data;
1127 double scale_factor = FRAME_SCALE_FACTOR (f);
1128
1129 if (scale_factor != FRAME_X_OUTPUT (f)->watched_scale_factor)
1130 {
1131 FRAME_X_OUTPUT (f)->watched_scale_factor = scale_factor;
1132 pgtk_cr_update_surface_desired_size (f,
1133 FRAME_CR_SURFACE_DESIRED_WIDTH (f),
1134 FRAME_CR_SURFACE_DESIRED_HEIGHT (f),
1135 true);
1136 }
1137 }
1138
1139
1140
1141
1142
1143
1144
1145 DEFUN ("pgtk-set-monitor-scale-factor", Fpgtk_set_monitor_scale_factor,
1146 Spgtk_set_monitor_scale_factor, 2, 2, 0,
1147 doc:
1148
1149
1150
1151
1152
1153 )
1154 (Lisp_Object monitor_model, Lisp_Object scale_factor)
1155 {
1156 CHECK_STRING (monitor_model);
1157 if (!NILP (scale_factor))
1158 {
1159 CHECK_NUMBER (scale_factor);
1160 if (FIXNUMP (scale_factor))
1161 {
1162 if (XFIXNUM (scale_factor) <= 0)
1163 error ("scale factor must be > 0.");
1164 }
1165 else if (FLOATP (scale_factor))
1166 {
1167 if (XFLOAT_DATA (scale_factor) <= 0.0)
1168 error ("scale factor must be > 0.");
1169 }
1170 else
1171 error ("unknown type of scale-factor");
1172 }
1173
1174 Lisp_Object tem = Fassoc (monitor_model, monitor_scale_factor_alist, Qnil);
1175 if (NILP (tem))
1176 {
1177 if (!NILP (scale_factor))
1178 monitor_scale_factor_alist = Fcons (Fcons (monitor_model, scale_factor),
1179 monitor_scale_factor_alist);
1180 }
1181 else
1182 Fsetcdr (tem, scale_factor);
1183
1184 return scale_factor;
1185 }
1186
1187 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0,
1188 doc:
1189
1190
1191
1192
1193
1194
1195 )
1196 (Lisp_Object parms)
1197 {
1198 struct frame *f;
1199 Lisp_Object frame, tem;
1200 Lisp_Object name;
1201 bool minibuffer_only = false;
1202 bool undecorated = false, override_redirect = false;
1203 long window_prompting = 0;
1204 specpdl_ref count = SPECPDL_INDEX ();
1205 Lisp_Object display;
1206 struct pgtk_display_info *dpyinfo = NULL;
1207 Lisp_Object parent, parent_frame;
1208 struct kboard *kb;
1209
1210 parms = Fcopy_alist (parms);
1211
1212
1213
1214 Vx_resource_name = Vinvocation_name;
1215
1216 display =
1217 gui_display_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
1218 if (BASE_EQ (display, Qunbound))
1219 display =
1220 gui_display_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
1221 if (BASE_EQ (display, Qunbound))
1222 display = Qnil;
1223 dpyinfo = check_pgtk_display_info (display);
1224 kb = dpyinfo->terminal->kboard;
1225
1226 if (!dpyinfo->terminal->name)
1227 error ("Terminal is not live, can't create new frames on it");
1228
1229 name =
1230 gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
1231 RES_TYPE_STRING);
1232 if (!STRINGP (name) && !BASE_EQ (name, Qunbound) && !NILP (name))
1233 error ("Invalid frame name--not a string or nil");
1234
1235 if (STRINGP (name))
1236 Vx_resource_name = name;
1237
1238
1239 parent =
1240 gui_display_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL,
1241 RES_TYPE_NUMBER);
1242 if (BASE_EQ (parent, Qunbound))
1243 parent = Qnil;
1244 if (!NILP (parent))
1245 CHECK_NUMBER (parent);
1246
1247 frame = Qnil;
1248 tem =
1249 gui_display_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer",
1250 "Minibuffer", RES_TYPE_SYMBOL);
1251 if (EQ (tem, Qnone) || NILP (tem))
1252 f = make_frame_without_minibuffer (Qnil, kb, display);
1253 else if (EQ (tem, Qonly))
1254 {
1255 f = make_minibuffer_frame ();
1256 minibuffer_only = true;
1257 }
1258 else if (WINDOWP (tem))
1259 f = make_frame_without_minibuffer (tem, kb, display);
1260 else
1261 f = make_frame (true);
1262
1263 parent_frame =
1264 gui_display_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
1265 RES_TYPE_SYMBOL);
1266
1267 if (!NILP (parent)
1268 || BASE_EQ (parent_frame, Qunbound)
1269 || NILP (parent_frame)
1270 || !FRAMEP (parent_frame)
1271 || !FRAME_LIVE_P (XFRAME (parent_frame))
1272 || !FRAME_PGTK_P (XFRAME (parent_frame)))
1273 parent_frame = Qnil;
1274
1275 fset_parent_frame (f, parent_frame);
1276 store_frame_param (f, Qparent_frame, parent_frame);
1277
1278 if (!NILP
1279 (tem =
1280 (gui_display_get_arg
1281 (dpyinfo, parms, Qundecorated, NULL, NULL, RES_TYPE_BOOLEAN)))
1282 && !(BASE_EQ (tem, Qunbound)))
1283 undecorated = true;
1284
1285 FRAME_UNDECORATED (f) = undecorated;
1286 store_frame_param (f, Qundecorated, undecorated ? Qt : Qnil);
1287
1288 if (!NILP
1289 (tem =
1290 (gui_display_get_arg
1291 (dpyinfo, parms, Qoverride_redirect, NULL, NULL, RES_TYPE_BOOLEAN)))
1292 && !(BASE_EQ (tem, Qunbound)))
1293 override_redirect = true;
1294
1295 FRAME_OVERRIDE_REDIRECT (f) = override_redirect;
1296 store_frame_param (f, Qoverride_redirect, override_redirect ? Qt : Qnil);
1297
1298 XSETFRAME (frame, f);
1299
1300 f->terminal = dpyinfo->terminal;
1301
1302 f->output_method = output_pgtk;
1303 FRAME_X_OUTPUT (f) = xzalloc (sizeof *FRAME_X_OUTPUT (f));
1304 FRAME_FONTSET (f) = -1;
1305 FRAME_X_OUTPUT (f)->white_relief.pixel = -1;
1306 FRAME_X_OUTPUT (f)->black_relief.pixel = -1;
1307
1308 FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider =
1309 gtk_css_provider_new ();
1310 FRAME_X_OUTPUT (f)->scrollbar_background_css_provider =
1311 gtk_css_provider_new ();
1312
1313 fset_icon_name (f,
1314 gui_display_get_arg (dpyinfo, parms, Qicon_name, "iconName",
1315 "Title", RES_TYPE_STRING));
1316 if (!STRINGP (f->icon_name))
1317 fset_icon_name (f, Qnil);
1318
1319 FRAME_DISPLAY_INFO (f) = dpyinfo;
1320
1321
1322 record_unwind_protect (do_unwind_create_frame, frame);
1323
1324
1325
1326 {
1327 Lisp_Object black;
1328
1329
1330
1331
1332 FRAME_FOREGROUND_PIXEL (f) = -1;
1333 FRAME_BACKGROUND_PIXEL (f) = -1;
1334 FRAME_X_OUTPUT (f)->cursor_color = -1;
1335 FRAME_X_OUTPUT (f)->cursor_foreground_color = -1;
1336 FRAME_X_OUTPUT (f)->border_pixel = -1;
1337 FRAME_X_OUTPUT (f)->mouse_color = -1;
1338
1339 black = build_string ("black");
1340 FRAME_FOREGROUND_PIXEL (f)
1341 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1342 FRAME_BACKGROUND_PIXEL (f)
1343 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1344 FRAME_X_OUTPUT (f)->cursor_color
1345 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1346 FRAME_X_OUTPUT (f)->cursor_foreground_color
1347 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1348 FRAME_X_OUTPUT (f)->border_pixel
1349 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1350 FRAME_X_OUTPUT (f)->mouse_color
1351 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1352 }
1353
1354
1355 if (!NILP (parent))
1356 {
1357 FRAME_X_OUTPUT (f)->parent_desc = (Window) XFIXNAT (parent);
1358 FRAME_X_OUTPUT (f)->explicit_parent = true;
1359 }
1360 else
1361 {
1362 FRAME_X_OUTPUT (f)->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
1363 FRAME_X_OUTPUT (f)->explicit_parent = false;
1364 }
1365
1366
1367
1368 if (BASE_EQ (name, Qunbound) || NILP (name))
1369 {
1370 fset_name (f, build_string (dpyinfo->x_id_name));
1371 f->explicit_name = false;
1372 }
1373 else
1374 {
1375 fset_name (f, name);
1376 f->explicit_name = true;
1377
1378 specbind (Qx_resource_name, name);
1379 }
1380
1381 register_font_driver (&ftcrfont_driver, f);
1382 #ifdef HAVE_HARFBUZZ
1383 register_font_driver (&ftcrhbfont_driver, f);
1384 #endif
1385
1386 image_cache_refcount =
1387 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
1388
1389 gui_default_parameter (f, parms, Qfont_backend, Qnil,
1390 "fontBackend", "FontBackend", RES_TYPE_STRING);
1391
1392
1393
1394 pgtk_default_font_parameter (f, parms);
1395 if (!FRAME_FONT (f))
1396 {
1397 delete_frame (frame, Qnoelisp);
1398 error ("Invalid frame font");
1399 }
1400
1401 gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
1402 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
1403
1404 if (NILP (Fassq (Qinternal_border_width, parms)))
1405 {
1406 Lisp_Object value;
1407
1408 value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
1409 "internalBorder", "internalBorder",
1410 RES_TYPE_NUMBER);
1411 if (!BASE_EQ (value, Qunbound))
1412 parms = Fcons (Fcons (Qinternal_border_width, value), parms);
1413 }
1414
1415 gui_default_parameter (f, parms, Qinternal_border_width,
1416 make_fixnum (0),
1417 "internalBorderWidth", "internalBorderWidth",
1418 RES_TYPE_NUMBER);
1419
1420
1421 if (NILP (Fassq (Qchild_frame_border_width, parms)))
1422 {
1423 Lisp_Object value;
1424
1425 value = gui_display_get_arg (dpyinfo, parms, Qchild_frame_border_width,
1426 "childFrameBorder", "childFrameBorder",
1427 RES_TYPE_NUMBER);
1428 if (! BASE_EQ (value, Qunbound))
1429 parms = Fcons (Fcons (Qchild_frame_border_width, value),
1430 parms);
1431
1432 }
1433
1434 gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil,
1435 "childFrameBorderWidth", "childFrameBorderWidth",
1436 RES_TYPE_NUMBER);
1437 gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
1438 NULL, NULL, RES_TYPE_NUMBER);
1439 gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
1440 NULL, NULL, RES_TYPE_NUMBER);
1441 gui_default_parameter (f, parms, Qvertical_scroll_bars,
1442 Qright,
1443 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
1444 gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
1445 "horizontalScrollBars", "ScrollBars",
1446 RES_TYPE_SYMBOL);
1447
1448 gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
1449 "foreground", "Foreground", RES_TYPE_STRING);
1450 gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
1451 "background", "Background", RES_TYPE_STRING);
1452 gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
1453 "pointerColor", "Foreground", RES_TYPE_STRING);
1454 gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
1455 "borderColor", "BorderColor", RES_TYPE_STRING);
1456 gui_default_parameter (f, parms, Qscreen_gamma, Qnil,
1457 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
1458 gui_default_parameter (f, parms, Qline_spacing, Qnil,
1459 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
1460 gui_default_parameter (f, parms, Qleft_fringe, Qnil,
1461 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
1462 gui_default_parameter (f, parms, Qright_fringe, Qnil,
1463 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
1464 gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
1465 NULL, NULL, RES_TYPE_BOOLEAN);
1466
1467 gui_default_parameter (f, parms, Qscroll_bar_foreground, Qnil,
1468 "scrollBarForeground", "ScrollBarForeground",
1469 RES_TYPE_STRING);
1470 gui_default_parameter (f, parms, Qscroll_bar_background, Qnil,
1471 "scrollBarBackground", "ScrollBarBackground",
1472 RES_TYPE_STRING);
1473
1474
1475
1476
1477 init_frame_faces (f);
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492 tem = gui_display_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL,
1493 RES_TYPE_NUMBER);
1494 if (NUMBERP (tem))
1495 store_frame_param (f, Qmin_width, tem);
1496 tem = gui_display_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL,
1497 RES_TYPE_NUMBER);
1498 if (NUMBERP (tem))
1499 store_frame_param (f, Qmin_height, tem);
1500 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
1501 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true,
1502 Qx_create_frame_1);
1503
1504
1505
1506
1507
1508
1509 gui_default_parameter (f, parms, Qmenu_bar_lines,
1510 NILP (Vmenu_bar_mode)
1511 ? make_fixnum (0) : make_fixnum (1),
1512 NULL, NULL, RES_TYPE_NUMBER);
1513 gui_default_parameter (f, parms, Qtab_bar_lines,
1514 NILP (Vtab_bar_mode)
1515 ? make_fixnum (0) : make_fixnum (1),
1516 NULL, NULL, RES_TYPE_NUMBER);
1517 gui_default_parameter (f, parms, Qtool_bar_lines,
1518 NILP (Vtool_bar_mode)
1519 ? make_fixnum (0) : make_fixnum (1),
1520 NULL, NULL, RES_TYPE_NUMBER);
1521
1522 gui_default_parameter (f, parms, Qbuffer_predicate, Qnil,
1523 "bufferPredicate", "BufferPredicate",
1524 RES_TYPE_SYMBOL);
1525 gui_default_parameter (f, parms, Qtitle, Qnil,
1526 "title", "Title", RES_TYPE_STRING);
1527 gui_default_parameter (f, parms, Qwait_for_wm, Qt,
1528 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
1529 gui_default_parameter (f, parms, Qtool_bar_position,
1530 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
1531 gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
1532 "inhibitDoubleBuffering", "InhibitDoubleBuffering",
1533 RES_TYPE_BOOLEAN);
1534
1535
1536 window_prompting =
1537 gui_figure_window_size (f, parms, true, true);
1538
1539 tem =
1540 gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
1541 RES_TYPE_BOOLEAN);
1542 f->no_split = minibuffer_only || EQ (tem, Qt);
1543
1544 xg_create_frame_widgets (f);
1545 pgtk_set_event_handler (f);
1546
1547 if (FRAME_GTK_OUTER_WIDGET (f))
1548 gtk_widget_realize (FRAME_GTK_OUTER_WIDGET (f));
1549
1550
1551
1552 if (FRAME_GTK_WIDGET (f))
1553 gtk_widget_realize (FRAME_GTK_WIDGET (f));
1554
1555 #define INSTALL_CURSOR(FIELD, NAME) \
1556 FRAME_X_OUTPUT (f)->FIELD = gdk_cursor_new_for_display (FRAME_X_DISPLAY (f), GDK_ ## NAME)
1557
1558 INSTALL_CURSOR (text_cursor, XTERM);
1559 INSTALL_CURSOR (nontext_cursor, LEFT_PTR);
1560 INSTALL_CURSOR (modeline_cursor, XTERM);
1561 INSTALL_CURSOR (hand_cursor, HAND2);
1562 INSTALL_CURSOR (hourglass_cursor, WATCH);
1563 INSTALL_CURSOR (horizontal_drag_cursor, SB_H_DOUBLE_ARROW);
1564 INSTALL_CURSOR (vertical_drag_cursor, SB_V_DOUBLE_ARROW);
1565 INSTALL_CURSOR (left_edge_cursor, LEFT_SIDE);
1566 INSTALL_CURSOR (right_edge_cursor, RIGHT_SIDE);
1567 INSTALL_CURSOR (top_edge_cursor, TOP_SIDE);
1568 INSTALL_CURSOR (bottom_edge_cursor, BOTTOM_SIDE);
1569 INSTALL_CURSOR (top_left_corner_cursor, TOP_LEFT_CORNER);
1570 INSTALL_CURSOR (top_right_corner_cursor, TOP_RIGHT_CORNER);
1571 INSTALL_CURSOR (bottom_right_corner_cursor, BOTTOM_RIGHT_CORNER);
1572 INSTALL_CURSOR (bottom_left_corner_cursor, BOTTOM_LEFT_CORNER);
1573
1574 #undef INSTALL_CURSOR
1575
1576
1577 f->terminal->reference_count++;
1578 FRAME_DISPLAY_INFO (f)->reference_count++;
1579 Vframe_list = Fcons (frame, Vframe_list);
1580
1581
1582
1583 gui_default_parameter (f, parms, Qicon_type, Qt,
1584 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
1585
1586 gui_default_parameter (f, parms, Qauto_raise, Qnil,
1587 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
1588 gui_default_parameter (f, parms, Qauto_lower, Qnil,
1589 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
1590 gui_default_parameter (f, parms, Qcursor_type, Qbox,
1591 "cursorType", "CursorType", RES_TYPE_SYMBOL);
1592 gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
1593 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
1594 gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
1595 "scrollBarHeight", "ScrollBarHeight",
1596 RES_TYPE_NUMBER);
1597 gui_default_parameter (f, parms, Qalpha, Qnil,
1598 "alpha", "Alpha", RES_TYPE_NUMBER);
1599 gui_default_parameter (f, parms, Qalpha_background, Qnil,
1600 "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
1601
1602 if (!NILP (parent_frame))
1603 {
1604 struct frame *p = XFRAME (parent_frame);
1605
1606 block_input ();
1607
1608 GtkWidget *fixed = FRAME_GTK_WIDGET (f);
1609 GtkWidget *fixed_of_p = FRAME_GTK_WIDGET (p);
1610 GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed);
1611 g_object_ref (fixed);
1612 gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed);
1613 gtk_fixed_put (GTK_FIXED (fixed_of_p), fixed, f->left_pos, f->top_pos);
1614 gtk_widget_show_all (fixed);
1615 g_object_unref (fixed);
1616
1617 gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
1618 FRAME_GTK_OUTER_WIDGET (f) = NULL;
1619 FRAME_OUTPUT_DATA (f)->vbox_widget = NULL;
1620 FRAME_OUTPUT_DATA (f)->hbox_widget = NULL;
1621 FRAME_OUTPUT_DATA (f)->menubar_widget = NULL;
1622 FRAME_OUTPUT_DATA (f)->toolbar_widget = NULL;
1623 FRAME_OUTPUT_DATA (f)->ttip_widget = NULL;
1624 FRAME_OUTPUT_DATA (f)->ttip_lbl = NULL;
1625 FRAME_OUTPUT_DATA (f)->ttip_window = NULL;
1626
1627 unblock_input ();
1628 }
1629
1630 if (FRAME_GTK_OUTER_WIDGET (f))
1631 {
1632 GList *w = gtk_container_get_children (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)));
1633 for (; w != NULL; w = w->next)
1634 gtk_widget_show_all (GTK_WIDGET (w->data));
1635 }
1636
1637 gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
1638 NULL, NULL, RES_TYPE_BOOLEAN);
1639 gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
1640 NULL, NULL, RES_TYPE_BOOLEAN);
1641
1642
1643 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
1644 {
1645
1646
1647 initialize_frame_menubar (f);
1648
1649 }
1650
1651
1652 f->can_set_window_size = true;
1653
1654
1655
1656
1657 block_input ();
1658 xg_wm_set_size_hint (f, window_prompting, false);
1659 unblock_input ();
1660
1661 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
1662 0, true, Qx_create_frame_2);
1663
1664
1665
1666
1667 gui_default_parameter (f, parms, Qfullscreen, Qnil,
1668 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
1669
1670
1671
1672
1673 if (!FRAME_X_OUTPUT (f)->explicit_parent)
1674 {
1675
1676
1677 Lisp_Object visibility
1678 = gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
1679 RES_TYPE_SYMBOL);
1680 Lisp_Object height
1681 = gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
1682 Lisp_Object width
1683 = gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
1684
1685 if (EQ (visibility, Qicon))
1686 {
1687 f->was_invisible = true;
1688 pgtk_iconify_frame (f);
1689 }
1690 else
1691 {
1692 if (BASE_EQ (visibility, Qunbound))
1693 visibility = Qt;
1694
1695 if (!NILP (visibility))
1696 pgtk_make_frame_visible (f);
1697 else
1698 f->was_invisible = true;
1699 }
1700
1701
1702
1703
1704 f->was_invisible
1705 = (f->was_invisible
1706 && (!BASE_EQ (height, Qunbound) || !BASE_EQ (width, Qunbound)));
1707
1708 store_frame_param (f, Qvisibility, visibility);
1709 }
1710
1711
1712 gui_default_parameter (f, parms, Qskip_taskbar, Qnil,
1713 NULL, NULL, RES_TYPE_BOOLEAN);
1714
1715 gui_default_parameter (f, parms, Qz_group, Qnil,
1716 NULL, NULL, RES_TYPE_SYMBOL);
1717
1718
1719
1720 if (FRAME_HAS_MINIBUF_P (f)
1721 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
1722 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
1723 kset_default_minibuffer_frame (kb, frame);
1724
1725
1726
1727 for (tem = parms; CONSP (tem); tem = XCDR (tem))
1728 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
1729 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
1730
1731 FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
1732
1733 FRAME_X_OUTPUT (f)->cr_surface_visible_bell = NULL;
1734 FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
1735 FRAME_X_OUTPUT (f)->watched_scale_factor = 1.0;
1736 struct timespec ts = make_timespec (1, 0);
1737 FRAME_X_OUTPUT (f)->scale_factor_atimer = start_atimer(ATIMER_CONTINUOUS,
1738 ts,
1739 update_watched_scale_factor,
1740 f);
1741
1742
1743
1744 Vwindow_list = Qnil;
1745
1746 return unbind_to (count, frame);
1747 }
1748
1749
1750
1751
1752
1753 static void
1754 pgtk_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
1755 {
1756 block_input ();
1757 xg_frame_restack (f1, f2, above_flag);
1758 unblock_input ();
1759 }
1760
1761 DEFUN ("pgtk-frame-restack", Fpgtk_frame_restack, Spgtk_frame_restack, 2, 3, 0,
1762 doc:
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776 )
1777 (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
1778 {
1779 struct frame *f1 = decode_live_frame (frame1);
1780 struct frame *f2 = decode_live_frame (frame2);
1781
1782 if (!(FRAME_GTK_OUTER_WIDGET (f1) && FRAME_GTK_OUTER_WIDGET (f2)))
1783 error ("Cannot restack frames");
1784 pgtk_frame_restack (f1, f2, !NILP (above));
1785 return Qt;
1786 }
1787
1788 #ifdef HAVE_GSETTINGS
1789
1790 #define RESOURCE_KEY_MAX_LEN 128
1791 #define SCHEMA_ID "org.gnu.emacs.defaults"
1792 #define PATH_FOR_CLASS_TYPE "/org/gnu/emacs/defaults-by-class/"
1793 #define PATH_PREFIX_FOR_NAME_TYPE "/org/gnu/emacs/defaults-by-name/"
1794
1795 static inline int
1796 pgtk_is_lower_char (int c)
1797 {
1798 return c >= 'a' && c <= 'z';
1799 }
1800
1801 static inline int
1802 pgtk_is_upper_char (int c)
1803 {
1804 return c >= 'A' && c <= 'Z';
1805 }
1806
1807 static inline int
1808 pgtk_is_numeric_char (int c)
1809 {
1810 return c >= '0' && c <= '9';
1811 }
1812
1813 static GSettings *
1814 parse_resource_key (const char *res_key, char *setting_key)
1815 {
1816 char path[32 + RESOURCE_KEY_MAX_LEN];
1817 const char *sp = res_key;
1818 char *dp;
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833 if (pgtk_is_upper_char (*sp))
1834 {
1835
1836
1837
1838 strcpy (path, PATH_FOR_CLASS_TYPE);
1839 while (*sp != '\0')
1840 {
1841 if (*sp == '.')
1842 break;
1843 sp++;
1844 }
1845 }
1846 else
1847 {
1848 strcpy (path, PATH_PREFIX_FOR_NAME_TYPE);
1849 dp = path + strlen (path);
1850 while (*sp != '\0')
1851 {
1852 int c = *sp;
1853 if (c == '.')
1854 break;
1855 if (pgtk_is_lower_char (c))
1856 (void) 0;
1857 else if (pgtk_is_upper_char (c))
1858 c = c - 'A' + 'a';
1859 else if (pgtk_is_numeric_char (c))
1860 (void) 0;
1861 else
1862 return NULL;
1863 *dp++ = c;
1864 sp++;
1865 }
1866 *dp++ = '/';
1867 *dp = '\0';
1868 }
1869
1870 if (*sp++ != '.')
1871 return NULL;
1872
1873
1874 dp = setting_key;
1875 while (*sp != '\0')
1876 {
1877 int c = *sp;
1878 if (pgtk_is_lower_char (c))
1879 (void) 0;
1880 else if (pgtk_is_upper_char (c))
1881 {
1882 c = c - 'A' + 'a';
1883 if (dp != setting_key)
1884 *dp++ = '-';
1885 }
1886 else if (pgtk_is_numeric_char (c))
1887 (void) 0;
1888 else
1889 return NULL;
1890
1891 *dp++ = c;
1892 sp++;
1893 }
1894 *dp = '\0';
1895
1896
1897 GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default ();
1898 GSettingsSchema *scm = g_settings_schema_source_lookup (ssrc, SCHEMA_ID, TRUE);
1899 if (!scm)
1900 return NULL;
1901 if (!g_settings_schema_has_key (scm, setting_key))
1902 {
1903 g_settings_schema_unref (scm);
1904 return NULL;
1905 }
1906
1907
1908 GSettings *gs = g_settings_new_full (scm, NULL, path);
1909
1910 g_settings_schema_unref (scm);
1911 return gs;
1912 }
1913
1914 const char *
1915 pgtk_get_defaults_value (const char *key)
1916 {
1917 char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2];
1918
1919 if (strlen (key) >= RESOURCE_KEY_MAX_LEN)
1920 error ("resource key too long.");
1921
1922 GSettings *gs = parse_resource_key (key, skey);
1923 if (gs == NULL)
1924 {
1925 return NULL;
1926 }
1927
1928 gchar *str = g_settings_get_string (gs, skey);
1929
1930
1931
1932
1933
1934
1935 static char holder[128];
1936 strncpy (holder, str, 128);
1937 holder[127] = '\0';
1938
1939 g_object_unref (gs);
1940 g_free (str);
1941 return holder[0] != '\0' ? holder : NULL;
1942 }
1943
1944 static void
1945 pgtk_set_defaults_value (const char *key, const char *value)
1946 {
1947 char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2];
1948
1949 if (strlen (key) >= RESOURCE_KEY_MAX_LEN)
1950 error ("resource key too long.");
1951
1952 GSettings *gs = parse_resource_key (key, skey);
1953 if (gs == NULL)
1954 error ("unknown resource key.");
1955
1956 if (value != NULL)
1957 {
1958 g_settings_set_string (gs, skey, value);
1959 }
1960 else
1961 {
1962 g_settings_reset (gs, skey);
1963 }
1964
1965 g_object_unref (gs);
1966 }
1967
1968 #undef RESOURCE_KEY_MAX_LEN
1969 #undef SCHEMA_ID
1970 #undef PATH_FOR_CLASS_TYPE
1971 #undef PATH_PREFIX_FOR_NAME_TYPE
1972
1973 #else
1974
1975 const char *
1976 pgtk_get_defaults_value (const char *key)
1977 {
1978 return NULL;
1979 }
1980
1981 static void
1982 pgtk_set_defaults_value (const char *key, const char *value)
1983 {
1984 error ("gsettings not supported.");
1985 }
1986
1987 #endif
1988
1989
1990 DEFUN ("pgtk-set-resource", Fpgtk_set_resource, Spgtk_set_resource, 2, 2, 0,
1991 doc: )
1992 (Lisp_Object attribute, Lisp_Object value)
1993 {
1994 check_window_system (NULL);
1995
1996 CHECK_STRING (attribute);
1997 if (!NILP (value))
1998 CHECK_STRING (value);
1999
2000 char *res = SSDATA (Vx_resource_name);
2001 char *attr = SSDATA (attribute);
2002 if (attr[0] >= 'A' && attr[0] <= 'Z')
2003 res = SSDATA (Vx_resource_class);
2004
2005 char *key = g_strdup_printf ("%s.%s", res, attr);
2006
2007 pgtk_set_defaults_value (key, NILP (value) ? NULL : SSDATA (value));
2008
2009 return Qnil;
2010 }
2011
2012
2013 DEFUN ("x-server-max-request-size", Fx_server_max_request_size, Sx_server_max_request_size, 0, 1, 0,
2014 doc: )
2015 (Lisp_Object terminal)
2016 {
2017 check_pgtk_display_info (terminal);
2018
2019
2020 return Qnil;
2021 }
2022
2023
2024 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2025 doc:
2026
2027
2028
2029
2030
2031 )
2032 (Lisp_Object terminal)
2033 {
2034 check_pgtk_display_info (terminal);
2035 return make_fixnum (1);
2036 }
2037
2038
2039 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
2040 doc:
2041
2042
2043
2044
2045
2046
2047 )
2048 (Lisp_Object terminal)
2049 {
2050 struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
2051 GdkDisplay *gdpy;
2052 gint n_monitors, i;
2053 int height_mm_at_0 = 0, height_mm_at_other = 0;
2054
2055 block_input ();
2056 gdpy = dpyinfo->gdpy;
2057 n_monitors = gdk_display_get_n_monitors (gdpy);
2058
2059 for (i = 0; i < n_monitors; ++i)
2060 {
2061 GdkRectangle rec;
2062
2063 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
2064 gdk_monitor_get_geometry (monitor, &rec);
2065
2066 int mm = gdk_monitor_get_height_mm (monitor);
2067
2068 if (rec.y == 0)
2069 height_mm_at_0 = max (height_mm_at_0, mm);
2070 else
2071 height_mm_at_other += mm;
2072 }
2073
2074 unblock_input ();
2075
2076 return make_fixnum (height_mm_at_0 + height_mm_at_other);
2077 }
2078
2079
2080 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
2081 doc:
2082
2083
2084
2085
2086
2087
2088 )
2089 (Lisp_Object terminal)
2090 {
2091 struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
2092 GdkDisplay *gdpy;
2093 gint n_monitors, i;
2094 int width_mm_at_0 = 0, width_mm_at_other = 0;
2095
2096 block_input ();
2097 gdpy = dpyinfo->gdpy;
2098 n_monitors = gdk_display_get_n_monitors (gdpy);
2099
2100 for (i = 0; i < n_monitors; ++i)
2101 {
2102 GdkRectangle rec;
2103
2104 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
2105 gdk_monitor_get_geometry (monitor, &rec);
2106
2107 int mm = gdk_monitor_get_width_mm (monitor);
2108
2109 if (rec.x == 0)
2110 width_mm_at_0 = max (width_mm_at_0, mm);
2111 else
2112 width_mm_at_other += mm;
2113 }
2114
2115 unblock_input ();
2116
2117 return make_fixnum (width_mm_at_0 + width_mm_at_other);
2118 }
2119
2120
2121 DEFUN ("x-display-backing-store", Fx_display_backing_store, Sx_display_backing_store, 0, 1, 0,
2122 doc:
2123
2124
2125
2126 )
2127 (Lisp_Object terminal)
2128 {
2129 check_pgtk_display_info (terminal);
2130 return Qnil;
2131 }
2132
2133
2134 DEFUN ("x-display-visual-class", Fx_display_visual_class, Sx_display_visual_class, 0, 1, 0,
2135 doc:
2136
2137
2138
2139
2140
2141
2142
2143 )
2144 (Lisp_Object terminal)
2145 {
2146 return intern ("true-color");
2147 }
2148
2149
2150 DEFUN ("x-display-save-under", Fx_display_save_under, Sx_display_save_under, 0, 1, 0,
2151 doc:
2152
2153
2154 )
2155 (Lisp_Object terminal)
2156 {
2157 check_pgtk_display_info (terminal);
2158 return Qnil;
2159 }
2160
2161
2162 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection, 1, 3, 0,
2163 doc:
2164
2165
2166
2167 )
2168 (Lisp_Object display, Lisp_Object resource_string, Lisp_Object must_succeed)
2169 {
2170 struct pgtk_display_info *dpyinfo;
2171
2172 if (NILP (display))
2173 display = build_string ("");
2174
2175 CHECK_STRING (display);
2176
2177 dpyinfo = pgtk_term_init (display, SSDATA (Vx_resource_name));
2178 if (dpyinfo == 0)
2179 {
2180 if (!NILP (must_succeed))
2181 fatal ("Display on %s not responding.\n", SSDATA (display));
2182 else
2183 error ("Display on %s not responding.\n", SSDATA (display));
2184 }
2185
2186 return Qnil;
2187 }
2188
2189
2190 DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection, 1, 1, 0,
2191 doc:
2192
2193
2194 )
2195 (Lisp_Object terminal)
2196 {
2197 struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
2198
2199 if (dpyinfo->reference_count > 0)
2200 error ("Display still has frames on it");
2201
2202 pgtk_delete_terminal (dpyinfo->terminal);
2203
2204 return Qnil;
2205 }
2206
2207
2208 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
2209 doc: )
2210 (void)
2211 {
2212 Lisp_Object result = Qnil;
2213 struct pgtk_display_info *ndi;
2214
2215 for (ndi = x_display_list; ndi; ndi = ndi->next)
2216 result = Fcons (XCAR (ndi->name_list_element), result);
2217
2218 return result;
2219 }
2220
2221 DEFUN ("pgtk-font-name", Fpgtk_font_name, Spgtk_font_name, 1, 1, 0,
2222 doc:
2223
2224
2225 )
2226 (Lisp_Object name)
2227 {
2228 char *nm;
2229 CHECK_STRING (name);
2230 nm = SSDATA (name);
2231
2232 if (nm[0] != '-')
2233 return name;
2234 if (strstr (nm, "fontset") && !strstr (nm, "fontset-startup"))
2235 return name;
2236
2237 char *str = pgtk_xlfd_to_fontname (SSDATA (name));
2238 name = build_string (str);
2239 xfree (str);
2240 return name;
2241 }
2242
2243
2244
2245
2246
2247
2248
2249
2250 struct pgtk_display_info *
2251 check_x_display_info (Lisp_Object frame)
2252 {
2253 return check_pgtk_display_info (frame);
2254 }
2255
2256 void
2257 pgtk_set_scroll_bar_default_width (struct frame *f)
2258 {
2259 int unit = FRAME_COLUMN_WIDTH (f);
2260 int minw = xg_get_default_scrollbar_width (f);
2261
2262 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
2263 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
2264 }
2265
2266 void
2267 pgtk_set_scroll_bar_default_height (struct frame *f)
2268 {
2269 int height = FRAME_LINE_HEIGHT (f);
2270 int min_height = xg_get_default_scrollbar_height (f);
2271
2272 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height;
2273 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height;
2274 }
2275
2276
2277 const char *
2278 pgtk_get_string_resource (XrmDatabase rdb, const char *name,
2279 const char *class)
2280 {
2281 check_window_system (NULL);
2282
2283 if (inhibit_x_resources)
2284
2285 return NULL;
2286
2287 const char *res = pgtk_get_defaults_value (name);
2288 if (res == NULL)
2289 res = pgtk_get_defaults_value (class);
2290
2291 if (res == NULL)
2292 return NULL;
2293
2294 if (c_strncasecmp (res, "YES", 3) == 0)
2295 return "true";
2296
2297 if (c_strncasecmp (res, "NO", 2) == 0)
2298 return "false";
2299
2300 return res;
2301 }
2302
2303 Lisp_Object
2304 pgtk_get_focus_frame (struct frame *frame)
2305 {
2306 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
2307 Lisp_Object focus;
2308
2309 if (!dpyinfo->x_focus_frame)
2310 return Qnil;
2311
2312 XSETFRAME (focus, dpyinfo->x_focus_frame);
2313 return focus;
2314 }
2315
2316 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2317 doc: )
2318 (Lisp_Object color, Lisp_Object frame)
2319 {
2320 Emacs_Color col;
2321 struct frame *f = decode_window_system_frame (frame);
2322
2323 CHECK_STRING (color);
2324
2325 if (pgtk_defined_color (f, SSDATA (color), &col, false, false))
2326 return Qt;
2327 else
2328 return Qnil;
2329 }
2330
2331
2332 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2333 doc: )
2334 (Lisp_Object color, Lisp_Object frame)
2335 {
2336 Emacs_Color col;
2337 struct frame *f = decode_window_system_frame (frame);
2338
2339 CHECK_STRING (color);
2340
2341 if (pgtk_defined_color (f, SSDATA (color), &col, false, false))
2342 return list3i (col.red, col.green, col.blue);
2343 else
2344 return Qnil;
2345 }
2346
2347 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2348 doc: )
2349 (Lisp_Object terminal)
2350 {
2351 check_pgtk_display_info (terminal);
2352 return Qt;
2353 }
2354
2355 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p, 0, 1, 0,
2356 doc:
2357
2358
2359
2360 )
2361 (Lisp_Object terminal)
2362 {
2363 return Qnil;
2364 }
2365
2366 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 0, 1, 0,
2367 doc:
2368
2369
2370
2371
2372
2373
2374 )
2375 (Lisp_Object terminal)
2376 {
2377 struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
2378 GdkDisplay *gdpy;
2379 gint n_monitors, i;
2380 int width = 0;
2381
2382 block_input ();
2383 gdpy = dpyinfo->gdpy;
2384 n_monitors = gdk_display_get_n_monitors (gdpy);
2385
2386 for (i = 0; i < n_monitors; ++i)
2387 {
2388 GdkRectangle rec;
2389 double scale = 1;
2390
2391 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
2392 gdk_monitor_get_geometry (monitor, &rec);
2393
2394
2395 scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
2396 if (scale == 0.0)
2397 scale = gdk_monitor_get_scale_factor (monitor);
2398 rec.x = rec.x * scale + 0.5;
2399 rec.y = rec.y * scale + 0.5;
2400 rec.width = rec.width * scale + 0.5;
2401 rec.height = rec.height * scale + 0.5;
2402
2403 width = max (width, rec.x + rec.width);
2404 }
2405
2406 unblock_input ();
2407
2408 return make_fixnum (width);
2409 }
2410
2411 DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height, 0, 1, 0,
2412 doc:
2413
2414
2415
2416
2417
2418
2419 )
2420 (Lisp_Object terminal)
2421 {
2422 struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
2423 GdkDisplay *gdpy;
2424 gint n_monitors, i;
2425 int height = 0;
2426
2427 block_input ();
2428 gdpy = dpyinfo->gdpy;
2429 n_monitors = gdk_display_get_n_monitors (gdpy);
2430
2431 for (i = 0; i < n_monitors; ++i)
2432 {
2433 GdkRectangle rec;
2434 double scale = 1;
2435
2436 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
2437 gdk_monitor_get_geometry (monitor, &rec);
2438
2439
2440 scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
2441 if (scale == 0.0)
2442 scale = gdk_monitor_get_scale_factor (monitor);
2443 rec.x = rec.x * scale + 0.5;
2444 rec.y = rec.y * scale + 0.5;
2445 rec.width = rec.width * scale + 0.5;
2446 rec.height = rec.height * scale + 0.5;
2447
2448 height = max (height, rec.y + rec.height);
2449 }
2450
2451 unblock_input ();
2452
2453 return make_fixnum (height);
2454 }
2455
2456 DEFUN ("pgtk-display-monitor-attributes-list", Fpgtk_display_monitor_attributes_list,
2457 Spgtk_display_monitor_attributes_list,
2458 0, 1, 0,
2459 doc:
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472 )
2473 (Lisp_Object terminal)
2474 {
2475 struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
2476 Lisp_Object attributes_list = Qnil;
2477
2478 GdkDisplay *gdpy;
2479 gint primary_monitor = 0, n_monitors, i;
2480 Lisp_Object monitor_frames, rest, frame;
2481 static const char *source = "Gdk";
2482 struct MonitorInfo *monitors;
2483
2484 block_input ();
2485 gdpy = dpyinfo->gdpy;
2486 n_monitors = gdk_display_get_n_monitors (gdpy);
2487 monitor_frames = make_nil_vector (n_monitors);
2488 monitors = xzalloc (n_monitors * sizeof *monitors);
2489
2490 FOR_EACH_FRAME (rest, frame)
2491 {
2492 struct frame *f = XFRAME (frame);
2493
2494 if (FRAME_PGTK_P (f)
2495 && FRAME_DISPLAY_INFO (f) == dpyinfo
2496 && !FRAME_TOOLTIP_P (f))
2497 {
2498 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
2499
2500 for (i = 0; i < n_monitors; i++)
2501 if (gdk_display_get_monitor_at_window (gdpy, gwin)
2502 == gdk_display_get_monitor (gdpy, i))
2503 break;
2504 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
2505 }
2506 }
2507
2508 for (i = 0; i < n_monitors; ++i)
2509 {
2510 gint width_mm, height_mm;
2511 GdkRectangle rec, work;
2512 struct MonitorInfo *mi = &monitors[i];
2513 double scale = 1;
2514
2515 GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
2516 if (gdk_monitor_is_primary (monitor))
2517 primary_monitor = i;
2518 gdk_monitor_get_geometry (monitor, &rec);
2519
2520 width_mm = gdk_monitor_get_width_mm (monitor);
2521 height_mm = gdk_monitor_get_height_mm (monitor);
2522 gdk_monitor_get_workarea (monitor, &work);
2523
2524
2525 scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
2526 if (scale == 0.0)
2527 scale = gdk_monitor_get_scale_factor (monitor);
2528 rec.x = rec.x * scale + 0.5;
2529 rec.y = rec.y * scale + 0.5;
2530 rec.width = rec.width * scale + 0.5;
2531 rec.height = rec.height * scale + 0.5;
2532 work.x = work.x * scale + 0.5;
2533 work.y = work.y * scale + 0.5;
2534 work.width = work.width * scale + 0.5;
2535 work.height = work.height * scale + 0.5;
2536
2537 mi->geom.x = rec.x;
2538 mi->geom.y = rec.y;
2539 mi->geom.width = rec.width;
2540 mi->geom.height = rec.height;
2541 mi->work.x = work.x;
2542 mi->work.y = work.y;
2543 mi->work.width = work.width;
2544 mi->work.height = work.height;
2545 mi->mm_width = width_mm;
2546 mi->mm_height = height_mm;
2547 mi->scale_factor = scale;
2548
2549 dupstring (&mi->name, (gdk_monitor_get_model (monitor)));
2550 }
2551
2552 attributes_list = make_monitor_attribute_list (monitors,
2553 n_monitors,
2554 primary_monitor,
2555 monitor_frames,
2556 source);
2557 free_monitors (monitors, n_monitors);
2558 unblock_input ();
2559
2560 return attributes_list;
2561 }
2562
2563 double
2564 pgtk_frame_scale_factor (struct frame *f)
2565 {
2566 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2567 GdkDisplay *gdpy = dpyinfo->gdpy;
2568
2569 block_input ();
2570
2571 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
2572 GdkMonitor *gmon = gdk_display_get_monitor_at_window (gdpy, gwin);
2573
2574
2575 double scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (gmon));
2576 if (scale == 0.0)
2577 scale = gdk_monitor_get_scale_factor (gmon);
2578
2579 unblock_input ();
2580
2581 return scale;
2582 }
2583
2584 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, 0, 1, 0,
2585 doc:
2586
2587
2588 )
2589 (Lisp_Object terminal)
2590 {
2591 check_pgtk_display_info (terminal);
2592 return make_fixnum (32);
2593 }
2594
2595
2596 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, 0, 1, 0,
2597 doc:
2598
2599
2600 )
2601 (Lisp_Object terminal)
2602 {
2603 struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
2604
2605 return make_fixnum (1 << min (dpyinfo->n_planes, 24));
2606 }
2607
2608
2609
2610
2611
2612
2613 static Lisp_Object tip_frame;
2614
2615
2616
2617 GtkWidget *tip_window;
2618
2619
2620
2621 static Lisp_Object tip_timer;
2622
2623
2624 static Lisp_Object tip_last_string;
2625
2626
2627 static Lisp_Object tip_last_frame;
2628
2629
2630 static Lisp_Object tip_last_parms;
2631
2632
2633 static void
2634 unwind_create_tip_frame (Lisp_Object frame)
2635 {
2636 Lisp_Object deleted;
2637
2638 deleted = unwind_create_frame (frame);
2639 if (EQ (deleted, Qt))
2640 {
2641 tip_window = NULL;
2642 tip_frame = Qnil;
2643 }
2644 }
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656 static Lisp_Object
2657 x_create_tip_frame (struct pgtk_display_info *dpyinfo, Lisp_Object parms, struct frame *p)
2658 {
2659 struct frame *f;
2660 Lisp_Object frame;
2661 Lisp_Object name;
2662 specpdl_ref count = SPECPDL_INDEX ();
2663 bool face_change_before = face_change;
2664
2665 if (!dpyinfo->terminal->name)
2666 error ("Terminal is not live, can't create new frames on it");
2667
2668 parms = Fcopy_alist (parms);
2669
2670
2671 name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
2672 RES_TYPE_STRING);
2673 if (!STRINGP (name)
2674 && !BASE_EQ (name, Qunbound)
2675 && !NILP (name))
2676 error ("Invalid frame name--not a string or nil");
2677
2678 frame = Qnil;
2679 f = make_frame (false);
2680 f->wants_modeline = false;
2681 XSETFRAME (frame, f);
2682 record_unwind_protect (unwind_create_tip_frame, frame);
2683
2684 f->terminal = dpyinfo->terminal;
2685
2686
2687
2688
2689
2690 f->output_method = output_pgtk;
2691 f->output_data.pgtk = xzalloc (sizeof *f->output_data.pgtk);
2692 FRAME_FONTSET (f) = -1;
2693 f->output_data.pgtk->white_relief.pixel = -1;
2694 f->output_data.pgtk->black_relief.pixel = -1;
2695
2696 f->tooltip = true;
2697 fset_icon_name (f, Qnil);
2698 FRAME_DISPLAY_INFO (f) = dpyinfo;
2699 f->output_data.pgtk->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
2700 f->output_data.pgtk->explicit_parent = false;
2701
2702
2703
2704 {
2705 Lisp_Object black;
2706
2707
2708
2709
2710 FRAME_FOREGROUND_PIXEL (f) = -1;
2711 FRAME_BACKGROUND_PIXEL (f) = -1;
2712 f->output_data.pgtk->border_pixel = -1;
2713
2714 black = build_string ("black");
2715 FRAME_FOREGROUND_PIXEL (f)
2716 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2717 FRAME_BACKGROUND_PIXEL (f)
2718 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2719 f->output_data.pgtk->border_pixel
2720 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2721 }
2722
2723
2724
2725 if (BASE_EQ (name, Qunbound) || NILP (name))
2726 {
2727 fset_name (f, build_string (dpyinfo->x_id_name));
2728 f->explicit_name = false;
2729 }
2730 else
2731 {
2732 fset_name (f, name);
2733 f->explicit_name = true;
2734
2735 specbind (Qx_resource_name, name);
2736 }
2737
2738 register_font_driver (&ftcrfont_driver, f);
2739 #ifdef HAVE_HARFBUZZ
2740 register_font_driver (&ftcrhbfont_driver, f);
2741 #endif
2742
2743 image_cache_refcount =
2744 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
2745
2746 gui_default_parameter (f, parms, Qfont_backend, Qnil,
2747 "fontBackend", "FontBackend", RES_TYPE_STRING);
2748
2749
2750
2751 pgtk_default_font_parameter (f, parms);
2752
2753 gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
2754 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
2755
2756
2757
2758
2759 if (NILP (Fassq (Qinternal_border_width, parms)))
2760 {
2761 Lisp_Object value;
2762
2763 value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
2764 "internalBorder", "internalBorder",
2765 RES_TYPE_NUMBER);
2766 if (! BASE_EQ (value, Qunbound))
2767 parms = Fcons (Fcons (Qinternal_border_width, value),
2768 parms);
2769 }
2770
2771 gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1),
2772 "internalBorderWidth", "internalBorderWidth",
2773 RES_TYPE_NUMBER);
2774 gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
2775 NULL, NULL, RES_TYPE_NUMBER);
2776 gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
2777 NULL, NULL, RES_TYPE_NUMBER);
2778
2779
2780 gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
2781 "foreground", "Foreground", RES_TYPE_STRING);
2782 gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
2783 "background", "Background", RES_TYPE_STRING);
2784 gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
2785 "pointerColor", "Foreground", RES_TYPE_STRING);
2786 gui_default_parameter (f, parms, Qcursor_color, build_string ("black"),
2787 "cursorColor", "Foreground", RES_TYPE_STRING);
2788 gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
2789 "borderColor", "BorderColor", RES_TYPE_STRING);
2790 gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
2791 NULL, NULL, RES_TYPE_BOOLEAN);
2792
2793
2794
2795
2796 init_frame_faces (f);
2797
2798 f->output_data.pgtk->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
2799
2800 gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
2801 "inhibitDoubleBuffering", "InhibitDoubleBuffering",
2802 RES_TYPE_BOOLEAN);
2803
2804 gui_figure_window_size (f, parms, false, false);
2805
2806 xg_create_frame_widgets (f);
2807 pgtk_set_event_handler (f);
2808 tip_window = FRAME_GTK_OUTER_WIDGET (f);
2809 gtk_window_set_transient_for (GTK_WINDOW (tip_window),
2810 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (p)));
2811 gtk_window_set_attached_to (GTK_WINDOW (tip_window), FRAME_GTK_WIDGET (p));
2812 gtk_window_set_destroy_with_parent (GTK_WINDOW (tip_window), TRUE);
2813 gtk_window_set_decorated (GTK_WINDOW (tip_window), FALSE);
2814 gtk_window_set_type_hint (GTK_WINDOW (tip_window), GDK_WINDOW_TYPE_HINT_TOOLTIP);
2815 f->output_data.pgtk->current_cursor = f->output_data.pgtk->text_cursor;
2816
2817 gui_default_parameter (f, parms, Qauto_raise, Qnil,
2818 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2819 gui_default_parameter (f, parms, Qauto_lower, Qnil,
2820 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2821 gui_default_parameter (f, parms, Qcursor_type, Qbox,
2822 "cursorType", "CursorType", RES_TYPE_SYMBOL);
2823 gui_default_parameter (f, parms, Qalpha, Qnil,
2824 "alpha", "Alpha", RES_TYPE_NUMBER);
2825 gui_default_parameter (f, parms, Qalpha_background, Qnil,
2826 "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
2827
2828
2829 if (NILP (Fframe_parameter (frame, Qtooltip)))
2830 {
2831 AUTO_FRAME_ARG (arg, Qtooltip, Qt);
2832 Fmodify_frame_parameters (frame, arg);
2833 }
2834
2835
2836
2837
2838
2839 {
2840 Lisp_Object disptype;
2841
2842 disptype = intern ("color");
2843
2844 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
2845 {
2846 AUTO_FRAME_ARG (arg, Qdisplay_type, disptype);
2847 Fmodify_frame_parameters (frame, arg);
2848 }
2849 }
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859 {
2860 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
2861
2862 call2 (Qface_set_after_frame_default, frame, Qnil);
2863
2864 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
2865 {
2866 AUTO_FRAME_ARG (arg, Qbackground_color, bg);
2867 Fmodify_frame_parameters (frame, arg);
2868 }
2869 }
2870
2871 f->no_split = true;
2872
2873
2874
2875 FRAME_DISPLAY_INFO (f)->reference_count++;
2876 f->terminal->reference_count++;
2877
2878
2879
2880
2881 Vframe_list = Fcons (frame, Vframe_list);
2882 f->can_set_window_size = true;
2883 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
2884 0, true, Qtip_frame);
2885
2886
2887
2888
2889
2890
2891 face_change = face_change_before;
2892
2893
2894 return unbind_to (count, frame);
2895 }
2896
2897
2898
2899
2900
2901
2902
2903 static void
2904 compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx,
2905 Lisp_Object dy, int width, int height, int *root_x,
2906 int *root_y)
2907 {
2908 Lisp_Object left, top, right, bottom;
2909 int min_x, min_y, max_x, max_y = -1;
2910
2911
2912 left = Fcdr (Fassq (Qleft, parms));
2913 top = Fcdr (Fassq (Qtop, parms));
2914 right = Fcdr (Fassq (Qright, parms));
2915 bottom = Fcdr (Fassq (Qbottom, parms));
2916
2917
2918
2919 if ((!INTEGERP (left) && !INTEGERP (right))
2920 || (!INTEGERP (top) && !INTEGERP (bottom)))
2921 {
2922 Lisp_Object frame, attributes, monitor, geometry;
2923 GdkSeat *seat =
2924 gdk_display_get_default_seat (FRAME_DISPLAY_INFO (f)->gdpy);
2925 GdkDevice *dev = gdk_seat_get_pointer (seat);
2926 GdkScreen *scr;
2927
2928 block_input ();
2929 gdk_device_get_position (dev, &scr, root_x, root_y);
2930 unblock_input ();
2931
2932 XSETFRAME (frame, f);
2933 attributes = Fpgtk_display_monitor_attributes_list (frame);
2934
2935
2936
2937 while (CONSP (attributes))
2938 {
2939 monitor = XCAR (attributes);
2940 geometry = Fassq (Qgeometry, monitor);
2941 if (CONSP (geometry))
2942 {
2943 min_x = XFIXNUM (Fnth (make_fixnum (1), geometry));
2944 min_y = XFIXNUM (Fnth (make_fixnum (2), geometry));
2945 max_x = min_x + XFIXNUM (Fnth (make_fixnum (3), geometry));
2946 max_y = min_y + XFIXNUM (Fnth (make_fixnum (4), geometry));
2947 if (min_x <= *root_x && *root_x < max_x
2948 && min_y <= *root_y && *root_y < max_y)
2949 {
2950 break;
2951 }
2952 max_y = -1;
2953 }
2954
2955 attributes = XCDR (attributes);
2956 }
2957 }
2958
2959
2960
2961 if (max_y < 0)
2962 {
2963 min_x = 0;
2964 min_y = 0;
2965 max_x = pgtk_display_pixel_width (FRAME_DISPLAY_INFO (f));
2966 max_y = pgtk_display_pixel_height (FRAME_DISPLAY_INFO (f));
2967 }
2968
2969 if (INTEGERP (top))
2970 *root_y = XFIXNUM (top);
2971 else if (INTEGERP (bottom))
2972 *root_y = XFIXNUM (bottom) - height;
2973 else if (*root_y + XFIXNUM (dy) <= min_y)
2974 *root_y = min_y;
2975 else if (*root_y + XFIXNUM (dy) + height <= max_y)
2976
2977 *root_y += XFIXNUM (dy);
2978 else if (height + XFIXNUM (dy) + min_y <= *root_y)
2979
2980 *root_y -= height + XFIXNUM (dy);
2981 else
2982
2983 *root_y = min_y;
2984
2985 if (INTEGERP (left))
2986 *root_x = XFIXNUM (left);
2987 else if (INTEGERP (right))
2988 *root_x = XFIXNUM (right) - width;
2989 else if (*root_x + XFIXNUM (dx) <= min_x)
2990 *root_x = 0;
2991 else if (*root_x + XFIXNUM (dx) + width <= max_x)
2992
2993 *root_x += XFIXNUM (dx);
2994 else if (width + XFIXNUM (dx) + min_x <= *root_x)
2995
2996 *root_x -= width + XFIXNUM (dx);
2997 else
2998
2999 *root_x = min_x;
3000 }
3001
3002
3003
3004 static Lisp_Object
3005 pgtk_hide_tip (bool delete)
3006 {
3007 if (!NILP (tip_timer))
3008 {
3009 call1 (Qcancel_timer, tip_timer);
3010 tip_timer = Qnil;
3011 }
3012
3013
3014
3015
3016
3017
3018 if ((NILP (tip_last_frame) && NILP (tip_frame))
3019 || (!use_system_tooltips
3020 && !delete
3021 && FRAMEP (tip_frame)
3022 && FRAME_LIVE_P (XFRAME (tip_frame))
3023 && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
3024
3025
3026
3027 return Qnil;
3028 else
3029 {
3030 Lisp_Object was_open = Qnil;
3031
3032 specpdl_ref count = SPECPDL_INDEX ();
3033 specbind (Qinhibit_redisplay, Qt);
3034 specbind (Qinhibit_quit, Qt);
3035
3036
3037 if (FRAMEP (tip_last_frame))
3038 {
3039 struct frame *f = XFRAME (tip_last_frame);
3040
3041 if (FRAME_LIVE_P (f))
3042 {
3043 if (xg_hide_tooltip (f))
3044 was_open = Qt;
3045 }
3046 }
3047
3048
3049
3050
3051 if (use_system_tooltips)
3052 tip_last_frame = Qnil;
3053
3054
3055 if (FRAMEP (tip_frame))
3056 {
3057 struct frame *f = XFRAME (tip_frame);
3058
3059 if (FRAME_LIVE_P (f))
3060 {
3061 if (delete || use_system_tooltips)
3062 {
3063
3064
3065
3066 delete_frame (tip_frame, Qnil);
3067 tip_frame = Qnil;
3068 }
3069 else
3070 pgtk_make_frame_invisible (f);
3071
3072 was_open = Qt;
3073 }
3074 else
3075 tip_frame = Qnil;
3076 }
3077 else
3078 tip_frame = Qnil;
3079
3080 return unbind_to (count, was_open);
3081 }
3082 }
3083
3084 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
3085 doc:
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114 )
3115 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
3116 Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
3117 {
3118 struct frame *f, *tip_f;
3119 struct window *w;
3120 int root_x, root_y;
3121 struct buffer *old_buffer;
3122 struct text_pos pos;
3123 int width, height;
3124 int old_windows_or_buffers_changed = windows_or_buffers_changed;
3125 specpdl_ref count = SPECPDL_INDEX ();
3126 Lisp_Object window, size, tip_buf;
3127 bool displayed;
3128 #ifdef ENABLE_CHECKING
3129 struct glyph_row *row, *end;
3130 #endif
3131 AUTO_STRING (tip, " *tip*");
3132
3133 specbind (Qinhibit_redisplay, Qt);
3134
3135 CHECK_STRING (string);
3136 if (SCHARS (string) == 0)
3137 string = make_unibyte_string (" ", 1);
3138
3139 if (NILP (frame))
3140 frame = selected_frame;
3141 f = decode_window_system_frame (frame);
3142
3143 if (!FRAME_GTK_OUTER_WIDGET (f))
3144 return unbind_to (count, Qnil);
3145
3146 if (NILP (timeout))
3147 timeout = Vx_show_tooltip_timeout;
3148 CHECK_FIXNAT (timeout);
3149
3150 if (NILP (dx))
3151 dx = make_fixnum (5);
3152 else
3153 CHECK_FIXNUM (dx);
3154
3155 if (NILP (dy))
3156 dy = make_fixnum (-10);
3157 else
3158 CHECK_FIXNUM (dy);
3159
3160 if (use_system_tooltips)
3161 {
3162 bool ok;
3163
3164
3165 Fx_hide_tip ();
3166
3167 block_input ();
3168
3169 ok = true;
3170 xg_show_tooltip (f, string);
3171 tip_last_frame = frame;
3172
3173 unblock_input ();
3174 if (ok) goto start_timer;
3175 }
3176
3177 if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
3178 {
3179 if (FRAME_VISIBLE_P (XFRAME (tip_frame))
3180 && EQ (frame, tip_last_frame)
3181 && !NILP (Fequal_including_properties (tip_last_string, string))
3182 && !NILP (Fequal (tip_last_parms, parms)))
3183 {
3184
3185 tip_f = XFRAME (tip_frame);
3186 if (!NILP (tip_timer))
3187 {
3188 call1 (Qcancel_timer, tip_timer);
3189 tip_timer = Qnil;
3190 }
3191
3192 block_input ();
3193 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
3194 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
3195 gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y);
3196 unblock_input ();
3197
3198 goto start_timer;
3199 }
3200 else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
3201 {
3202 bool delete = false;
3203 Lisp_Object tail, elt, parm, last;
3204
3205
3206
3207
3208 for (tail = parms; CONSP (tail); tail = XCDR (tail))
3209 {
3210 elt = XCAR (tail);
3211 parm = Fcar (elt);
3212
3213
3214 if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
3215 && !EQ (parm, Qright) && !EQ (parm, Qbottom))
3216 {
3217 last = Fassq (parm, tip_last_parms);
3218 if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
3219 {
3220
3221 delete = true;
3222 break;
3223 }
3224 else
3225 tip_last_parms =
3226 call2 (Qassq_delete_all, parm, tip_last_parms);
3227 }
3228 else
3229 tip_last_parms =
3230 call2 (Qassq_delete_all, parm, tip_last_parms);
3231 }
3232
3233
3234
3235
3236 for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
3237 {
3238 elt = XCAR (tail);
3239 parm = Fcar (elt);
3240 if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright)
3241 && !EQ (parm, Qbottom) && !NILP (Fcdr (elt)))
3242 {
3243
3244 delete = true;
3245 break;
3246 }
3247 }
3248
3249 pgtk_hide_tip (delete);
3250 }
3251 else
3252 pgtk_hide_tip (true);
3253 }
3254 else
3255 pgtk_hide_tip (true);
3256
3257 tip_last_frame = frame;
3258 tip_last_string = string;
3259 tip_last_parms = parms;
3260
3261 if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
3262 {
3263
3264 if (NILP (Fassq (Qname, parms)))
3265 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
3266 if (NILP (Fassq (Qinternal_border_width, parms)))
3267 parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), parms);
3268 if (NILP (Fassq (Qborder_width, parms)))
3269 parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
3270 if (NILP (Fassq (Qborder_color, parms)))
3271 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
3272 if (NILP (Fassq (Qbackground_color, parms)))
3273 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
3274 parms);
3275
3276
3277
3278 if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, f)))
3279
3280 return unbind_to (count, Qnil);
3281 }
3282
3283 tip_f = XFRAME (tip_frame);
3284 window = FRAME_ROOT_WINDOW (tip_f);
3285 tip_buf = Fget_buffer_create (tip, Qnil);
3286
3287
3288 bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
3289 bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
3290 set_window_buffer (window, tip_buf, false, false);
3291 w = XWINDOW (window);
3292 w->pseudo_window_p = true;
3293
3294
3295
3296
3297
3298 w->left_col = 0;
3299 w->top_line = 0;
3300 w->pixel_left = 0;
3301 w->pixel_top = 0;
3302
3303 if (CONSP (Vx_max_tooltip_size)
3304 && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
3305 && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
3306 {
3307 w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size));
3308 w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size));
3309 }
3310 else
3311 {
3312 w->total_cols = 80;
3313 w->total_lines = 40;
3314 }
3315
3316 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
3317 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
3318 FRAME_TOTAL_COLS (tip_f) = w->total_cols;
3319 adjust_frame_glyphs (tip_f);
3320
3321
3322
3323 specpdl_ref count_1 = SPECPDL_INDEX ();
3324 old_buffer = current_buffer;
3325 set_buffer_internal_1 (XBUFFER (w->contents));
3326 bset_truncate_lines (current_buffer, Qnil);
3327 specbind (Qinhibit_read_only, Qt);
3328 specbind (Qinhibit_modification_hooks, Qt);
3329 specbind (Qinhibit_point_motion_hooks, Qt);
3330 Ferase_buffer ();
3331 Finsert (1, &string);
3332 clear_glyph_matrix (w->desired_matrix);
3333 clear_glyph_matrix (w->current_matrix);
3334 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
3335 displayed = try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
3336
3337 if (!displayed && NILP (Vx_max_tooltip_size))
3338 {
3339 #ifdef ENABLE_CHECKING
3340 row = w->desired_matrix->rows;
3341 end = w->desired_matrix->rows + w->desired_matrix->nrows;
3342
3343 while (row < end)
3344 {
3345 if (!row->displays_text_p
3346 || row->ends_at_zv_p)
3347 break;
3348 ++row;
3349 }
3350
3351 eassert (row < end && row->ends_at_zv_p);
3352 #endif
3353 }
3354
3355
3356 size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
3357 make_fixnum (w->pixel_height), Qnil,
3358 Qnil);
3359
3360 width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
3361 height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
3362 width += FRAME_COLUMN_WIDTH (tip_f);
3363
3364
3365 compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
3366
3367
3368 block_input ();
3369 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), width, height);
3370 gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y);
3371 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (tip_f));
3372 SET_FRAME_VISIBLE (tip_f, 1);
3373 gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (tip_f)),
3374 f->output_data.pgtk->current_cursor);
3375
3376 unblock_input ();
3377
3378 pgtk_cr_update_surface_desired_size (tip_f, width, height, false);
3379
3380 w->must_be_updated_p = true;
3381 update_single_window (w);
3382 flush_frame (tip_f);
3383 set_buffer_internal_1 (old_buffer);
3384 unbind_to (count_1, Qnil);
3385 windows_or_buffers_changed = old_windows_or_buffers_changed;
3386
3387 start_timer:
3388
3389 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
3390 intern ("x-hide-tip"));
3391
3392 return unbind_to (count, Qnil);
3393 }
3394
3395
3396 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
3397 doc:
3398 )
3399 (void)
3400 {
3401 return pgtk_hide_tip (!tooltip_reuse_hidden_frame);
3402 }
3403
3404
3405
3406
3407
3408
3409 static Lisp_Object
3410 frame_geometry (Lisp_Object frame, Lisp_Object attribute)
3411 {
3412 struct frame *f = decode_live_frame (frame);
3413 Lisp_Object fullscreen_symbol = Fframe_parameter (frame, Qfullscreen);
3414 bool fullscreen = (EQ (fullscreen_symbol, Qfullboth)
3415 || EQ (fullscreen_symbol, Qfullscreen));
3416 int border = fullscreen ? 0 : f->border_width;
3417 int title_height = 0;
3418 int native_width = FRAME_PIXEL_WIDTH (f);
3419 int native_height = FRAME_PIXEL_HEIGHT (f);
3420 int outer_width = native_width + 2 * border;
3421 int outer_height = native_height + 2 * border + title_height;
3422
3423
3424 int left_pos, top_pos;
3425
3426 if (FRAME_GTK_OUTER_WIDGET (f))
3427 gtk_window_get_position (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
3428 &left_pos, &top_pos);
3429 else
3430 {
3431 GtkAllocation alloc;
3432
3433 if (FRAME_GTK_WIDGET (f) == NULL)
3434 return Qnil;
3435
3436 gtk_widget_get_allocation (FRAME_GTK_WIDGET (f), &alloc);
3437 left_pos = alloc.x;
3438 top_pos = alloc.y;
3439 }
3440
3441 int native_left = left_pos + border;
3442 int native_top = top_pos + border + title_height;
3443 int native_right = left_pos + outer_width - border;
3444 int native_bottom = top_pos + outer_height - border;
3445 int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
3446 int tab_bar_height = 0, tab_bar_width = 0;
3447 int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f);
3448 int tool_bar_width = (tool_bar_height
3449 ? outer_width - 2 * internal_border_width : 0);
3450
3451 tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
3452 tab_bar_width = (tab_bar_height
3453 ? native_width - 2 * internal_border_width : 0);
3454
3455
3456 if (EQ (attribute, Qouter_edges))
3457 return list4 (make_fixnum (left_pos), make_fixnum (top_pos),
3458 make_fixnum (left_pos + outer_width),
3459 make_fixnum (top_pos + outer_height));
3460 else if (EQ (attribute, Qnative_edges))
3461 return list4 (make_fixnum (native_left), make_fixnum (native_top),
3462 make_fixnum (native_right), make_fixnum (native_bottom));
3463 else if (EQ (attribute, Qinner_edges))
3464 return list4 (make_fixnum (native_left + internal_border_width),
3465 make_fixnum (native_top
3466 + tab_bar_height
3467 + FRAME_TOOL_BAR_TOP_HEIGHT (f)
3468 + internal_border_width),
3469 make_fixnum (native_right - internal_border_width),
3470 make_fixnum (native_bottom - internal_border_width
3471 - FRAME_TOOL_BAR_BOTTOM_HEIGHT (f)));
3472 else
3473 return
3474 list (Fcons (Qouter_position,
3475 Fcons (make_fixnum (left_pos),
3476 make_fixnum (top_pos))),
3477 Fcons (Qouter_size,
3478 Fcons (make_fixnum (outer_width),
3479 make_fixnum (outer_height))),
3480 Fcons (Qexternal_border_size,
3481 (fullscreen
3482 ? Fcons (make_fixnum (0), make_fixnum (0))
3483 : Fcons (make_fixnum (border), make_fixnum (border)))),
3484 Fcons (Qtitle_bar_size,
3485 Fcons (make_fixnum (0), make_fixnum (title_height))),
3486 Fcons (Qmenu_bar_external, Qnil),
3487 Fcons (Qmenu_bar_size, Fcons (make_fixnum (0), make_fixnum (0))),
3488 Fcons (Qtab_bar_size,
3489 Fcons (make_fixnum (tab_bar_width),
3490 make_fixnum (tab_bar_height))),
3491 Fcons (Qtool_bar_external,
3492 FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
3493 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
3494 Fcons (Qtool_bar_size,
3495 Fcons (make_fixnum (tool_bar_width),
3496 make_fixnum (tool_bar_height))),
3497 Fcons (Qinternal_border_width,
3498 make_fixnum (internal_border_width)));
3499 }
3500
3501 DEFUN ("pgtk-frame-geometry", Fpgtk_frame_geometry, Spgtk_frame_geometry, 0, 1, 0,
3502 doc:
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539 )
3540 (Lisp_Object frame)
3541 {
3542 return frame_geometry (frame, Qnil);
3543 }
3544
3545 DEFUN ("pgtk-frame-edges", Fpgtk_frame_edges, Spgtk_frame_edges, 0, 2, 0,
3546 doc:
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560 )
3561 (Lisp_Object frame, Lisp_Object type)
3562 {
3563 return frame_geometry (frame, ((EQ (type, Qouter_edges)
3564 || EQ (type, Qinner_edges))
3565 ? type : Qnative_edges));
3566 }
3567
3568 DEFUN ("pgtk-set-mouse-absolute-pixel-position",
3569 Fpgtk_set_mouse_absolute_pixel_position,
3570 Spgtk_set_mouse_absolute_pixel_position, 2, 2, 0,
3571 doc:
3572
3573 )
3574 (Lisp_Object x, Lisp_Object y)
3575 {
3576 struct frame *f = SELECTED_FRAME ();
3577 GtkWidget *widget = gtk_widget_get_toplevel (FRAME_WIDGET (f));
3578 GdkWindow *window = gtk_widget_get_window (widget);
3579 GdkDisplay *gdpy = gdk_window_get_display (window);
3580 GdkScreen *gscr = gdk_window_get_screen (window);
3581 GdkSeat *seat = gdk_display_get_default_seat (gdpy);
3582 GdkDevice *device = gdk_seat_get_pointer (seat);
3583
3584 gdk_device_warp (device, gscr, XFIXNUM (x), XFIXNUM (y));
3585
3586 return Qnil;
3587 }
3588
3589 DEFUN ("pgtk-mouse-absolute-pixel-position",
3590 Fpgtk_mouse_absolute_pixel_position,
3591 Spgtk_mouse_absolute_pixel_position, 0, 0, 0,
3592 doc:
3593
3594
3595 )
3596 (void)
3597 {
3598 struct frame *f = SELECTED_FRAME ();
3599 GtkWidget *widget = gtk_widget_get_toplevel (FRAME_WIDGET (f));
3600 GdkWindow *window = gtk_widget_get_window (widget);
3601 GdkDisplay *gdpy = gdk_window_get_display (window);
3602 GdkScreen *gscr;
3603 GdkSeat *seat = gdk_display_get_default_seat (gdpy);
3604 GdkDevice *device = gdk_seat_get_pointer (seat);
3605 int x = 0, y = 0;
3606
3607 gdk_device_get_position (device, &gscr, &x, &y);
3608
3609 return Fcons (make_fixnum (x), make_fixnum (y));
3610 }
3611
3612
3613 DEFUN ("pgtk-page-setup-dialog", Fpgtk_page_setup_dialog,
3614 Spgtk_page_setup_dialog, 0, 0, 0,
3615 doc:
3616 )
3617 (void)
3618 {
3619 block_input ();
3620 xg_page_setup_dialog ();
3621 unblock_input ();
3622
3623 return Qnil;
3624 }
3625
3626 DEFUN ("pgtk-get-page-setup", Fpgtk_get_page_setup,
3627 Spgtk_get_page_setup, 0, 0, 0,
3628 doc:
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644 )
3645 (void)
3646 {
3647 Lisp_Object result;
3648
3649 block_input ();
3650 result = xg_get_page_setup ();
3651 unblock_input ();
3652
3653 return result;
3654 }
3655
3656 DEFUN ("pgtk-print-frames-dialog", Fpgtk_print_frames_dialog, Spgtk_print_frames_dialog, 0, 1, "",
3657 doc:
3658
3659
3660 )
3661 (Lisp_Object frames)
3662 {
3663 Lisp_Object rest, tmp;
3664
3665 if (!CONSP (frames))
3666 frames = list1 (frames);
3667
3668 tmp = Qnil;
3669 for (rest = frames; CONSP (rest); rest = XCDR (rest))
3670 {
3671 struct frame *f = decode_window_system_frame (XCAR (rest));
3672 Lisp_Object frame;
3673
3674 XSETFRAME (frame, f);
3675 if (!FRAME_VISIBLE_P (f))
3676 error ("Frames to be printed must be visible.");
3677 tmp = Fcons (frame, tmp);
3678 }
3679 frames = Fnreverse (tmp);
3680
3681
3682 specpdl_ref count = SPECPDL_INDEX ();
3683 specbind (Qredisplay_dont_pause, Qt);
3684 redisplay_preserve_echo_area (32);
3685 unbind_to (count, Qnil);
3686
3687 block_input ();
3688 xg_print_frames_dialog (frames);
3689 unblock_input ();
3690
3691 return Qnil;
3692 }
3693
3694 static void
3695 clean_up_dialog (void)
3696 {
3697 pgtk_menu_set_in_use (false);
3698 }
3699
3700 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
3701 doc:
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712 )
3713 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
3714 Lisp_Object mustmatch, Lisp_Object only_dir_p)
3715 {
3716 struct frame *f = SELECTED_FRAME ();
3717 char *fn;
3718 Lisp_Object file = Qnil;
3719 Lisp_Object decoded_file;
3720 specpdl_ref count = SPECPDL_INDEX ();
3721 char *cdef_file;
3722
3723 check_window_system (f);
3724
3725 if (popup_activated ())
3726 error ("Trying to use a menu from within a menu-entry");
3727 else
3728 pgtk_menu_set_in_use (true);
3729
3730 CHECK_STRING (prompt);
3731 CHECK_STRING (dir);
3732
3733
3734 specbind (Qinhibit_redisplay, Qt);
3735 record_unwind_protect_void (clean_up_dialog);
3736
3737 block_input ();
3738
3739 if (STRINGP (default_filename))
3740 cdef_file = SSDATA (default_filename);
3741 else
3742 cdef_file = SSDATA (dir);
3743
3744 fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
3745 !NILP (mustmatch), !NILP (only_dir_p));
3746
3747 if (fn)
3748 {
3749 file = build_string (fn);
3750 xfree (fn);
3751 }
3752
3753 unblock_input ();
3754
3755
3756 if (NILP (file))
3757 quit ();
3758
3759 decoded_file = DECODE_FILE (file);
3760
3761 return unbind_to (count, decoded_file);
3762 }
3763
3764 DEFUN ("pgtk-backend-display-class", Fpgtk_backend_display_class, Spgtk_backend_display_class, 0, 1, "",
3765 doc:
3766
3767
3768 )
3769 (Lisp_Object terminal)
3770 {
3771 struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
3772 GdkDisplay *gdpy = dpyinfo->gdpy;
3773 const gchar *type_name = G_OBJECT_TYPE_NAME (G_OBJECT (gdpy));
3774 return build_string (type_name);
3775 }
3776
3777 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
3778 doc:
3779
3780
3781 )
3782 (Lisp_Object frame, Lisp_Object ignored)
3783 {
3784 struct frame *f = decode_window_system_frame (frame);
3785 Lisp_Object font;
3786 Lisp_Object font_param;
3787 char *default_name = NULL;
3788 specpdl_ref count = SPECPDL_INDEX ();
3789
3790 if (popup_activated ())
3791 error ("Trying to use a menu from within a menu-entry");
3792 else
3793 pgtk_menu_set_in_use (true);
3794
3795
3796 specbind (Qinhibit_redisplay, Qt);
3797 record_unwind_protect_void (clean_up_dialog);
3798
3799 block_input ();
3800
3801 XSETFONT (font, FRAME_FONT (f));
3802 font_param = Ffont_get (font, QCname);
3803 if (STRINGP (font_param))
3804 default_name = xlispstrdup (font_param);
3805 else
3806 {
3807 font_param = Fframe_parameter (frame, Qfont_parameter);
3808 if (STRINGP (font_param))
3809 default_name = xlispstrdup (font_param);
3810 }
3811
3812 font = xg_get_font (f, default_name);
3813 xfree (default_name);
3814
3815 unblock_input ();
3816
3817 if (NILP (font))
3818 quit ();
3819
3820 return unbind_to (count, font);
3821 }
3822
3823 DEFUN ("x-gtk-debug", Fx_gtk_debug, Sx_gtk_debug, 1, 1, 0,
3824 doc: )
3825 (Lisp_Object enable)
3826 {
3827 gboolean enable_debug = !NILP (enable);
3828
3829 block_input ();
3830 gtk_window_set_interactive_debugging (enable_debug);
3831 unblock_input ();
3832
3833 return NILP (enable) ? Qnil : Qt;
3834 }
3835
3836 void
3837 syms_of_pgtkfns (void)
3838 {
3839 DEFSYM (Qfont_parameter, "font-parameter");
3840 DEFSYM (Qfontsize, "fontsize");
3841 DEFSYM (Qcancel_timer, "cancel-timer");
3842 DEFSYM (Qframe_title_format, "frame-title-format");
3843 DEFSYM (Qicon_title_format, "icon-title-format");
3844 DEFSYM (Qdark, "dark");
3845 DEFSYM (Qhide, "hide");
3846 DEFSYM (Qresize_mode, "resize-mode");
3847
3848 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
3849 doc: );
3850 Vx_cursor_fore_pixel = Qnil;
3851
3852 Fprovide (intern_c_string ("gtk"), Qnil);
3853
3854 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
3855 doc: );
3856 {
3857 char *ver = g_strdup_printf ("%d.%d.%d",
3858 GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
3859 GTK_MICRO_VERSION);
3860 int len = strlen (ver);
3861 Vgtk_version_string = make_pure_string (ver, len, len, false);
3862 g_free (ver);
3863 }
3864
3865
3866 Fprovide (intern_c_string ("cairo"), Qnil);
3867
3868 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
3869 doc: );
3870 {
3871 char *ver = g_strdup_printf ("%d.%d.%d",
3872 CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
3873 CAIRO_VERSION_MICRO);
3874 int len = strlen (ver);
3875 Vcairo_version_string = make_pure_string (ver, len, len, false);
3876 g_free (ver);
3877 }
3878
3879 defsubr (&Spgtk_set_resource);
3880 defsubr (&Sxw_display_color_p);
3881 defsubr (&Sx_display_grayscale_p);
3882 defsubr (&Spgtk_font_name);
3883 defsubr (&Sxw_color_defined_p);
3884 defsubr (&Sxw_color_values);
3885 defsubr (&Sx_server_max_request_size);
3886 defsubr (&Sx_display_pixel_width);
3887 defsubr (&Sx_display_pixel_height);
3888 defsubr (&Spgtk_display_monitor_attributes_list);
3889 defsubr (&Spgtk_frame_geometry);
3890 defsubr (&Spgtk_frame_edges);
3891 defsubr (&Spgtk_frame_restack);
3892 defsubr (&Spgtk_set_mouse_absolute_pixel_position);
3893 defsubr (&Spgtk_mouse_absolute_pixel_position);
3894 defsubr (&Sx_display_mm_width);
3895 defsubr (&Sx_display_mm_height);
3896 defsubr (&Sx_display_screens);
3897 defsubr (&Sx_display_planes);
3898 defsubr (&Sx_display_color_cells);
3899 defsubr (&Sx_display_visual_class);
3900 defsubr (&Sx_display_backing_store);
3901 defsubr (&Sx_display_save_under);
3902 defsubr (&Sx_create_frame);
3903 defsubr (&Sx_open_connection);
3904 defsubr (&Sx_close_connection);
3905 defsubr (&Sx_display_list);
3906 defsubr (&Sx_gtk_debug);
3907
3908 defsubr (&Sx_show_tip);
3909 defsubr (&Sx_hide_tip);
3910
3911 defsubr (&Sx_export_frames);
3912 defsubr (&Spgtk_page_setup_dialog);
3913 defsubr (&Spgtk_get_page_setup);
3914 defsubr (&Spgtk_print_frames_dialog);
3915 defsubr (&Spgtk_backend_display_class);
3916
3917 defsubr (&Spgtk_set_monitor_scale_factor);
3918
3919 defsubr (&Sx_file_dialog);
3920 defsubr (&Sx_select_font);
3921
3922 monitor_scale_factor_alist = Qnil;
3923 staticpro (&monitor_scale_factor_alist);
3924
3925 tip_timer = Qnil;
3926 staticpro (&tip_timer);
3927 tip_frame = Qnil;
3928 staticpro (&tip_frame);
3929 tip_last_frame = Qnil;
3930 staticpro (&tip_last_frame);
3931 tip_last_string = Qnil;
3932 staticpro (&tip_last_string);
3933 tip_last_parms = Qnil;
3934 staticpro (&tip_last_parms);
3935
3936
3937 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
3938 doc: );
3939 x_gtk_use_old_file_dialog = false;
3940
3941 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
3942 doc: );
3943 x_gtk_show_hidden_files = false;
3944
3945 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
3946 doc: );
3947 x_gtk_file_dialog_help_text = true;
3948
3949 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
3950 doc: );
3951 Vx_max_tooltip_size = Qnil;
3952
3953 DEFSYM (Qmono, "mono");
3954 DEFSYM (Qassq_delete_all, "assq-delete-all");
3955
3956 DEFSYM (Qpdf, "pdf");
3957
3958 DEFSYM (Qorientation, "orientation");
3959 DEFSYM (Qtop_margin, "top-margin");
3960 DEFSYM (Qbottom_margin, "bottom-margin");
3961 DEFSYM (Qportrait, "portrait");
3962 DEFSYM (Qlandscape, "landscape");
3963 DEFSYM (Qreverse_portrait, "reverse-portrait");
3964 DEFSYM (Qreverse_landscape, "reverse-landscape");
3965 }