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