1 /* Haiku window system support
2 Copyright (C) 2021 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or (at
9 your option) any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
18
19 #include <config.h>
20
21 #include <math.h>
22
23 #include "lisp.h"
24 #include "frame.h"
25 #include "blockinput.h"
26 #include "termchar.h"
27 #include "font.h"
28 #include "keyboard.h"
29 #include "buffer.h"
30 #include "dispextern.h"
31
32 #include "haikugui.h"
33 #include "haikuterm.h"
34 #include "haiku_support.h"
35 #include "termhooks.h"
36
37 #include <stdlib.h>
38
39 #include <kernel/OS.h>
40
41 #define RGB_TO_ULONG(r, g, b) \
42 (((r) << 16) | ((g) << 8) | (b));
43 #define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
44 #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
45 #define BLUE_FROM_ULONG(color) ((color) & 0xff)
46
47 /* The frame of the currently visible tooltip. */
48 static Lisp_Object tip_frame;
49
50 /* The window-system window corresponding to the frame of the
51 currently visible tooltip. */
52 static Window tip_window;
53
54 /* A timer that hides or deletes the currently visible tooltip when it
55 fires. */
56 static Lisp_Object tip_timer;
57
58 /* STRING argument of last `x-show-tip' call. */
59 static Lisp_Object tip_last_string;
60
61 /* Normalized FRAME argument of last `x-show-tip' call. */
62 static Lisp_Object tip_last_frame;
63
64 /* PARMS argument of last `x-show-tip' call. */
65 static Lisp_Object tip_last_parms;
66
67 static void
68 haiku_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
69 static void
70 haiku_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name);
71
72 static ptrdiff_t image_cache_refcount;
73
74 static Lisp_Object
get_geometry_from_preferences(struct haiku_display_info * dpyinfo,Lisp_Object parms)75 get_geometry_from_preferences (struct haiku_display_info *dpyinfo,
76 Lisp_Object parms)
77 {
78 struct {
79 const char *val;
80 const char *cls;
81 Lisp_Object tem;
82 } r[] = {
83 { "width", "Width", Qwidth },
84 { "height", "Height", Qheight },
85 { "left", "Left", Qleft },
86 { "top", "Top", Qtop },
87 };
88
89 int i;
90 for (i = 0; i < ARRAYELTS (r); ++i)
91 {
92 if (NILP (Fassq (r[i].tem, parms)))
93 {
94 Lisp_Object value
95 = gui_display_get_arg (dpyinfo, parms, r[i].tem, r[i].val, r[i].cls,
96 RES_TYPE_NUMBER);
97 if (! EQ (value, Qunbound))
98 parms = Fcons (Fcons (r[i].tem, value), parms);
99 }
100 }
101
102 return parms;
103 }
104
105 void
haiku_change_tool_bar_height(struct frame * f,int height)106 haiku_change_tool_bar_height (struct frame *f, int height)
107 {
108 int unit = FRAME_LINE_HEIGHT (f);
109 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
110 int lines = (height + unit - 1) / unit;
111 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
112
113 /* Make sure we redisplay all windows in this frame. */
114 fset_redisplay (f);
115
116 FRAME_TOOL_BAR_HEIGHT (f) = height;
117 FRAME_TOOL_BAR_LINES (f) = lines;
118 store_frame_param (f, Qtool_bar_lines, make_fixnum (lines));
119
120 if (FRAME_HAIKU_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
121 {
122 clear_frame (f);
123 clear_current_matrices (f);
124 }
125
126 if ((height < old_height) && WINDOWP (f->tool_bar_window))
127 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
128
129 if (!f->tool_bar_resized)
130 {
131 /* As long as tool_bar_resized is false, effectively try to change
132 F's native height. */
133 if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
134 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
135 1, false, Qtool_bar_lines);
136 else
137 adjust_frame_size (f, -1, -1, 4, false, Qtool_bar_lines);
138
139 f->tool_bar_resized = f->tool_bar_redisplayed;
140 }
141 else
142 /* Any other change may leave the native size of F alone. */
143 adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_lines);
144
145 /* adjust_frame_size might not have done anything, garbage frame
146 here. */
147 adjust_frame_glyphs (f);
148 SET_FRAME_GARBAGED (f);
149
150 if (FRAME_HAIKU_WINDOW (f))
151 haiku_clear_under_internal_border (f);
152 }
153
154 void
haiku_change_tab_bar_height(struct frame * f,int height)155 haiku_change_tab_bar_height (struct frame *f, int height)
156 {
157 int unit = FRAME_LINE_HEIGHT (f);
158 int old_height = FRAME_TAB_BAR_HEIGHT (f);
159 int lines = (height + unit - 1) / unit;
160 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
161
162 /* Make sure we redisplay all windows in this frame. */
163 fset_redisplay (f);
164
165 /* Recalculate tab bar and frame text sizes. */
166 FRAME_TAB_BAR_HEIGHT (f) = height;
167 FRAME_TAB_BAR_LINES (f) = lines;
168 store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
169
170 if (FRAME_HAIKU_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
171 {
172 clear_frame (f);
173 clear_current_matrices (f);
174 }
175
176 if ((height < old_height) && WINDOWP (f->tab_bar_window))
177 clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
178
179 if (!f->tab_bar_resized)
180 {
181 /* As long as tab_bar_resized is false, effectively try to change
182 F's native height. */
183 if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
184 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
185 1, false, Qtab_bar_lines);
186 else
187 adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
188
189 f->tab_bar_resized = f->tab_bar_redisplayed;
190 }
191 else
192 /* Any other change may leave the native size of F alone. */
193 adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
194
195 /* adjust_frame_size might not have done anything, garbage frame
196 here. */
197 adjust_frame_glyphs (f);
198 SET_FRAME_GARBAGED (f);
199 if (FRAME_HAIKU_WINDOW (f))
200 haiku_clear_under_internal_border (f);
201 }
202
203 static void
haiku_set_no_focus_on_map(struct frame * f,Lisp_Object value,Lisp_Object oldval)204 haiku_set_no_focus_on_map (struct frame *f, Lisp_Object value,
205 Lisp_Object oldval)
206 {
207 if (!EQ (value, oldval))
208 FRAME_NO_FOCUS_ON_MAP (f) = !NILP (value);
209 }
210
211 static void
haiku_set_tool_bar_lines(struct frame * f,Lisp_Object value,Lisp_Object oldval)212 haiku_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
213 {
214 if (FRAME_TOOLTIP_P (f))
215 return;
216 int nlines;
217
218 /* Treat tool bars like menu bars. */
219 if (FRAME_MINIBUF_ONLY_P (f))
220 return;
221
222 /* Use VALUE only if an int >= 0. */
223 if (RANGED_FIXNUMP (0, value, INT_MAX))
224 nlines = XFIXNAT (value);
225 else
226 nlines = 0;
227
228 haiku_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
229 }
230
231 static void
haiku_set_tab_bar_lines(struct frame * f,Lisp_Object value,Lisp_Object oldval)232 haiku_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
233 {
234 if (FRAME_TOOLTIP_P (f))
235 return;
236 int olines = FRAME_TAB_BAR_LINES (f);
237 int nlines;
238
239 /* Treat tab bars like menu bars. */
240 if (FRAME_MINIBUF_ONLY_P (f))
241 return;
242
243 /* Use VALUE only if an int >= 0. */
244 if (RANGED_FIXNUMP (0, value, INT_MAX))
245 nlines = XFIXNAT (value);
246 else
247 nlines = 0;
248
249 if (nlines != olines && (olines == 0 || nlines == 0))
250 haiku_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
251 }
252
253
254 int
haiku_get_color(const char * name,Emacs_Color * color)255 haiku_get_color (const char *name, Emacs_Color *color)
256 {
257 unsigned short r16, g16, b16;
258 Lisp_Object tem;
259
260 if (parse_color_spec (name, &r16, &g16, &b16))
261 {
262 color->pixel = RGB_TO_ULONG (r16 / 256, g16 / 256, b16 / 256);
263 color->red = r16;
264 color->green = g16;
265 color->blue = b16;
266 return 0;
267 }
268 else
269 {
270 block_input ();
271 eassert (x_display_list && !NILP (x_display_list->color_map));
272 tem = x_display_list->color_map;
273 for (; CONSP (tem); tem = XCDR (tem))
274 {
275 Lisp_Object col = XCAR (tem);
276 if (CONSP (col) && !xstrcasecmp (SSDATA (XCAR (col)), name))
277 {
278 int32_t clr = XFIXNUM (XCDR (col));
279 color->pixel = clr;
280 color->red = RED_FROM_ULONG (clr) * 257;
281 color->green = GREEN_FROM_ULONG (clr) * 257;
282 color->blue = BLUE_FROM_ULONG (clr) * 257;
283 unblock_input ();
284 return 0;
285 }
286 }
287
288 unblock_input ();
289 }
290
291 return 1;
292 }
293
294 static struct haiku_display_info *
haiku_display_info_for_name(Lisp_Object name)295 haiku_display_info_for_name (Lisp_Object name)
296 {
297 CHECK_STRING (name);
298
299 if (!NILP (Fstring_equal (name, build_string ("be"))))
300 {
301 if (!x_display_list)
302 return x_display_list;
303
304 error ("Be windowing not initialized");
305 }
306
307 error ("Be displays can only be named \"be\"");
308 }
309
310 static struct haiku_display_info *
check_haiku_display_info(Lisp_Object object)311 check_haiku_display_info (Lisp_Object object)
312 {
313 struct haiku_display_info *dpyinfo = NULL;
314
315 if (NILP (object))
316 {
317 struct frame *sf = XFRAME (selected_frame);
318
319 if (FRAME_HAIKU_P (sf) && FRAME_LIVE_P (sf))
320 dpyinfo = FRAME_DISPLAY_INFO (sf);
321 else if (x_display_list)
322 dpyinfo = x_display_list;
323 else
324 error ("Be windowing not present");
325 }
326 else if (TERMINALP (object))
327 {
328 struct terminal *t = decode_live_terminal (object);
329
330 if (t->type != output_haiku)
331 error ("Terminal %d is not a Be display", t->id);
332
333 dpyinfo = t->display_info.haiku;
334 }
335 else if (STRINGP (object))
336 dpyinfo = haiku_display_info_for_name (object);
337 else
338 {
339 struct frame *f = decode_window_system_frame (object);
340 dpyinfo = FRAME_DISPLAY_INFO (f);
341 }
342
343 return dpyinfo;
344 }
345
346 static void
haiku_set_title_bar_text(struct frame * f,Lisp_Object text)347 haiku_set_title_bar_text (struct frame *f, Lisp_Object text)
348 {
349 if (FRAME_HAIKU_WINDOW (f))
350 {
351 block_input ();
352 BWindow_retitle (FRAME_HAIKU_WINDOW (f), SSDATA (ENCODE_UTF_8 (text)));
353 unblock_input ();
354 }
355 }
356
357 static void
haiku_set_title(struct frame * f,Lisp_Object name,Lisp_Object old_name)358 haiku_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
359 {
360 /* Don't change the title if it's already NAME. */
361 if (EQ (name, f->title))
362 return;
363
364 update_mode_lines = 26;
365
366 fset_title (f, name);
367
368 if (NILP (name))
369 name = f->name;
370
371 haiku_set_title_bar_text (f, name);
372 }
373
374 static void
haiku_set_child_frame_border_width(struct frame * f,Lisp_Object arg,Lisp_Object oldval)375 haiku_set_child_frame_border_width (struct frame *f,
376 Lisp_Object arg, Lisp_Object oldval)
377 {
378 int border;
379
380 if (NILP (arg))
381 border = -1;
382 else if (RANGED_FIXNUMP (0, arg, INT_MAX))
383 border = XFIXNAT (arg);
384 else
385 signal_error ("Invalid child frame border width", arg);
386
387 if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
388 {
389 f->child_frame_border_width = border;
390
391 if (FRAME_HAIKU_WINDOW (f))
392 adjust_frame_size (f, -1, -1, 3, 0, Qchild_frame_border_width);
393
394 SET_FRAME_GARBAGED (f);
395 }
396 }
397
398 static void
haiku_set_parent_frame(struct frame * f,Lisp_Object new_value,Lisp_Object old_value)399 haiku_set_parent_frame (struct frame *f,
400 Lisp_Object new_value, Lisp_Object old_value)
401 {
402 struct frame *p = NULL;
403 block_input ();
404 if (!NILP (new_value)
405 && (!FRAMEP (new_value)
406 || !FRAME_LIVE_P (p = XFRAME (new_value))
407 || !FRAME_HAIKU_P (p)))
408 {
409 store_frame_param (f, Qparent_frame, old_value);
410 unblock_input ();
411 error ("Invalid specification of `parent-frame'");
412 }
413
414 if (EQ (new_value, old_value))
415 {
416 unblock_input ();
417 return;
418 }
419
420 if (!NILP (old_value))
421 EmacsWindow_unparent (FRAME_HAIKU_WINDOW (f));
422 if (!NILP (new_value))
423 {
424 EmacsWindow_parent_to (FRAME_HAIKU_WINDOW (f),
425 FRAME_HAIKU_WINDOW (p));
426 BWindow_set_offset (FRAME_HAIKU_WINDOW (f),
427 f->left_pos, f->top_pos);
428 }
429 fset_parent_frame (f, new_value);
430 unblock_input ();
431 }
432
433 static void
haiku_explicitly_set_name(struct frame * f,Lisp_Object arg,Lisp_Object oldval)434 haiku_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
435 {
436 haiku_set_name (f, arg, 1);
437 }
438
439 static void
haiku_set_no_accept_focus(struct frame * f,Lisp_Object new_value,Lisp_Object old_value)440 haiku_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
441 {
442 block_input ();
443 if (!EQ (new_value, old_value))
444 FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value);
445
446 if (FRAME_HAIKU_WINDOW (f))
447 {
448 BWindow_set_avoid_focus (FRAME_HAIKU_WINDOW (f),
449 FRAME_NO_ACCEPT_FOCUS (f));
450 }
451 unblock_input ();
452 }
453
454 static void
unwind_create_frame(Lisp_Object frame)455 unwind_create_frame (Lisp_Object frame)
456 {
457 struct frame *f = XFRAME (frame);
458
459 /* If frame is already dead, nothing to do. This can happen if the
460 display is disconnected after the frame has become official, but
461 before x_create_frame removes the unwind protect. */
462 if (!FRAME_LIVE_P (f))
463 return;
464
465 /* If frame is ``official'', nothing to do. */
466 if (NILP (Fmemq (frame, Vframe_list)))
467 {
468 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
469 struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
470 #endif
471
472 /* If the frame's image cache refcount is still the same as our
473 private shadow variable, it means we are unwinding a frame
474 for which we didn't yet call init_frame_faces, where the
475 refcount is incremented. Therefore, we increment it here, so
476 that free_frame_faces, called in free_frame_resources later,
477 will not mistakenly decrement the counter that was not
478 incremented yet to account for this new frame. */
479 if (FRAME_IMAGE_CACHE (f) != NULL
480 && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
481 FRAME_IMAGE_CACHE (f)->refcount++;
482
483 haiku_free_frame_resources (f);
484 free_glyphs (f);
485
486 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
487 /* Check that reference counts are indeed correct. */
488 if (dpyinfo->terminal->image_cache)
489 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
490 #endif
491 }
492 }
493
494 static void
unwind_create_tip_frame(Lisp_Object frame)495 unwind_create_tip_frame (Lisp_Object frame)
496 {
497 unwind_create_frame (frame);
498 tip_window = NULL;
499 tip_frame = Qnil;
500 }
501
502 static void
haiku_set_foreground_color(struct frame * f,Lisp_Object arg,Lisp_Object oldval)503 haiku_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
504 {
505 struct haiku_output *output = FRAME_OUTPUT_DATA (f);
506 unsigned long old_fg;
507
508 Emacs_Color color;
509
510 if (haiku_get_color (SSDATA (arg), &color))
511 {
512 store_frame_param (f, Qforeground_color, oldval);
513 unblock_input ();
514 error ("Bad color");
515 }
516
517 old_fg = FRAME_FOREGROUND_PIXEL (f);
518 FRAME_FOREGROUND_PIXEL (f) = color.pixel;
519
520 if (FRAME_HAIKU_WINDOW (f))
521 {
522
523 block_input ();
524 if (output->cursor_color.pixel == old_fg)
525 {
526 output->cursor_color.pixel = old_fg;
527 output->cursor_color.red = RED_FROM_ULONG (old_fg);
528 output->cursor_color.green = GREEN_FROM_ULONG (old_fg);
529 output->cursor_color.blue = BLUE_FROM_ULONG (old_fg);
530 }
531
532 unblock_input ();
533
534 update_face_from_frame_parameter (f, Qforeground_color, arg);
535
536 if (FRAME_VISIBLE_P (f))
537 redraw_frame (f);
538 }
539 }
540
541 static void
unwind_popup(void)542 unwind_popup (void)
543 {
544 if (!popup_activated_p)
545 emacs_abort ();
546 --popup_activated_p;
547 }
548
549 static Lisp_Object
haiku_create_frame(Lisp_Object parms,int ttip_p)550 haiku_create_frame (Lisp_Object parms, int ttip_p)
551 {
552 struct frame *f;
553 Lisp_Object frame, tem;
554 Lisp_Object name;
555 bool minibuffer_only = false;
556 bool face_change_before = face_change;
557 long window_prompting = 0;
558 ptrdiff_t count = SPECPDL_INDEX ();
559 Lisp_Object display;
560 struct haiku_display_info *dpyinfo = NULL;
561 struct kboard *kb;
562
563 parms = Fcopy_alist (parms);
564
565 Vx_resource_name = Vinvocation_name;
566
567 display = gui_display_get_arg (dpyinfo, parms, Qterminal, 0, 0,
568 RES_TYPE_STRING);
569 if (EQ (display, Qunbound))
570 display = Qnil;
571 dpyinfo = check_haiku_display_info (display);
572 kb = dpyinfo->terminal->kboard;
573
574 if (!dpyinfo->terminal->name)
575 error ("Terminal is not live, can't create new frames on it");
576
577 name = gui_display_get_arg (dpyinfo, parms, Qname, 0, 0,
578 RES_TYPE_STRING);
579 if (!STRINGP (name)
580 && ! EQ (name, Qunbound)
581 && ! NILP (name))
582 error ("Invalid frame name--not a string or nil");
583
584 if (STRINGP (name))
585 Vx_resource_name = name;
586
587 block_input ();
588
589 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
590 /* No need to protect DISPLAY because that's not used after passing
591 it to make_frame_without_minibuffer. */
592 frame = Qnil;
593 tem = gui_display_get_arg (dpyinfo, parms, Qminibuffer,
594 "minibuffer", "Minibuffer",
595 RES_TYPE_SYMBOL);
596 if (ttip_p)
597 f = make_frame (0);
598 else if (EQ (tem, Qnone) || NILP (tem))
599 f = make_frame_without_minibuffer (Qnil, kb, display);
600 else if (EQ (tem, Qonly))
601 {
602 f = make_minibuffer_frame ();
603 minibuffer_only = 1;
604 }
605 else if (WINDOWP (tem))
606 f = make_frame_without_minibuffer (tem, kb, display);
607 else
608 f = make_frame (1);
609 XSETFRAME (frame, f);
610
611 f->terminal = dpyinfo->terminal;
612
613 f->output_method = output_haiku;
614 f->output_data.haiku = xzalloc (sizeof *f->output_data.haiku);
615
616 f->output_data.haiku->pending_zoom_x = INT_MIN;
617 f->output_data.haiku->pending_zoom_y = INT_MIN;
618 f->output_data.haiku->pending_zoom_width = INT_MIN;
619 f->output_data.haiku->pending_zoom_height = INT_MIN;
620
621 if (ttip_p)
622 f->wants_modeline = false;
623
624 fset_icon_name (f, gui_display_get_arg (dpyinfo, parms, Qicon_name,
625 "iconName", "Title",
626 RES_TYPE_STRING));
627 if (! STRINGP (f->icon_name) || ttip_p)
628 fset_icon_name (f, Qnil);
629
630 FRAME_DISPLAY_INFO (f) = dpyinfo;
631
632 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
633 if (!ttip_p)
634 record_unwind_protect (unwind_create_frame, frame);
635 else
636 record_unwind_protect (unwind_create_tip_frame, frame);
637
638 FRAME_OUTPUT_DATA (f)->parent_desc = NULL;
639 FRAME_OUTPUT_DATA (f)->explicit_parent = 0;
640
641 /* Set the name; the functions to which we pass f expect the name to
642 be set. */
643 if (EQ (name, Qunbound) || NILP (name) || ! STRINGP (name))
644 {
645 fset_name (f, Vinvocation_name);
646 f->explicit_name = 0;
647 }
648 else
649 {
650 fset_name (f, name);
651 f->explicit_name = 1;
652 specbind (Qx_resource_name, name);
653 }
654
655 #ifdef USE_BE_CAIRO
656 register_font_driver (&ftcrfont_driver, f);
657 #ifdef HAVE_HARFBUZZ
658 register_font_driver (&ftcrhbfont_driver, f);
659 #endif
660 #endif
661 register_font_driver (&haikufont_driver, f);
662
663 f->tooltip = ttip_p;
664
665 image_cache_refcount =
666 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
667
668 gui_default_parameter (f, parms, Qfont_backend, Qnil,
669 "fontBackend", "FontBackend", RES_TYPE_STRING);
670
671 FRAME_RIF (f)->default_font_parameter (f, parms);
672
673 unblock_input ();
674
675 gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
676 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
677 gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (ttip_p ? 1 : 2),
678 "internalBorderWidth", "InternalBorderWidth",
679 RES_TYPE_NUMBER);
680 gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil,
681 "childFrameBorderWidth", "childFrameBorderWidth",
682 RES_TYPE_NUMBER);
683 gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
684 NULL, NULL, RES_TYPE_NUMBER);
685 gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
686 NULL, NULL, RES_TYPE_NUMBER);
687 gui_default_parameter (f, parms, Qvertical_scroll_bars, !ttip_p ? Qt : Qnil,
688 "verticalScrollBars", "VerticalScrollBars",
689 RES_TYPE_SYMBOL);
690 gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
691 "horizontalScrollBars", "HorizontalScrollBars",
692 RES_TYPE_SYMBOL);
693 gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
694 "foreground", "Foreground", RES_TYPE_STRING);
695 gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
696 "background", "Background", RES_TYPE_STRING);
697 gui_default_parameter (f, parms, Qline_spacing, Qnil,
698 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
699 gui_default_parameter (f, parms, Qleft_fringe, Qnil,
700 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
701 gui_default_parameter (f, parms, Qright_fringe, Qnil,
702 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
703 gui_default_parameter (f, parms, Qno_special_glyphs, ttip_p ? Qnil : Qt,
704 NULL, NULL, RES_TYPE_BOOLEAN);
705
706 init_frame_faces (f);
707
708 /* Read comment about this code in corresponding place in xfns.c. */
709 tem = gui_display_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL,
710 RES_TYPE_NUMBER);
711 if (FIXNUMP (tem))
712 store_frame_param (f, Qmin_width, tem);
713 tem = gui_display_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL,
714 RES_TYPE_NUMBER);
715 if (FIXNUMP (tem))
716 store_frame_param (f, Qmin_height, tem);
717 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
718 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1,
719 Qx_create_frame_1);
720
721 if (!ttip_p)
722 {
723 gui_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL);
724 gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
725 NULL, NULL, RES_TYPE_BOOLEAN);
726 gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
727 NULL, NULL, RES_TYPE_BOOLEAN);
728
729 /* The resources controlling the menu-bar, tool-bar, and tab-bar are
730 processed specially at startup, and reflected in the mode
731 variables; ignore them here. */
732 gui_default_parameter (f, parms, Qmenu_bar_lines,
733 NILP (Vmenu_bar_mode)
734 ? make_fixnum (0) : make_fixnum (1),
735 NULL, NULL, RES_TYPE_NUMBER);
736 gui_default_parameter (f, parms, Qtab_bar_lines,
737 NILP (Vtab_bar_mode)
738 ? make_fixnum (0) : make_fixnum (1),
739 NULL, NULL, RES_TYPE_NUMBER);
740 gui_default_parameter (f, parms, Qtool_bar_lines,
741 NILP (Vtool_bar_mode)
742 ? make_fixnum (0) : make_fixnum (1),
743 NULL, NULL, RES_TYPE_NUMBER);
744 gui_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
745 "BufferPredicate", RES_TYPE_SYMBOL);
746 gui_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
747 RES_TYPE_STRING);
748 }
749
750 parms = get_geometry_from_preferences (dpyinfo, parms);
751 window_prompting = gui_figure_window_size (f, parms, false, true);
752
753 if (ttip_p)
754 {
755 /* No fringes on tip frame. */
756 f->fringe_cols = 0;
757 f->left_fringe_width = 0;
758 f->right_fringe_width = 0;
759 /* No dividers on tip frame. */
760 f->right_divider_width = 0;
761 f->bottom_divider_width = 0;
762 }
763
764 tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
765 RES_TYPE_BOOLEAN);
766 f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem));
767
768 /* Add `tooltip' frame parameter's default value. */
769 if (NILP (Fframe_parameter (frame, Qtooltip)) && ttip_p)
770 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
771
772 #define ASSIGN_CURSOR(cursor, be_cursor) \
773 (FRAME_OUTPUT_DATA (f)->cursor = be_cursor)
774
775 ASSIGN_CURSOR (text_cursor, BCursor_create_i_beam ());
776 ASSIGN_CURSOR (nontext_cursor, BCursor_create_default ());
777 ASSIGN_CURSOR (modeline_cursor, BCursor_create_modeline ());
778 ASSIGN_CURSOR (hand_cursor, BCursor_create_grab ());
779 ASSIGN_CURSOR (hourglass_cursor, BCursor_create_progress_cursor ());
780 ASSIGN_CURSOR (horizontal_drag_cursor,
781 BCursor_from_id (CURSOR_ID_RESIZE_EAST_WEST));
782 ASSIGN_CURSOR (vertical_drag_cursor,
783 BCursor_from_id (CURSOR_ID_RESIZE_NORTH_SOUTH));
784 ASSIGN_CURSOR (left_edge_cursor,
785 BCursor_from_id (CURSOR_ID_RESIZE_WEST));
786 ASSIGN_CURSOR (top_left_corner_cursor,
787 BCursor_from_id (CURSOR_ID_RESIZE_NORTH_WEST));
788 ASSIGN_CURSOR (top_edge_cursor,
789 BCursor_from_id (CURSOR_ID_RESIZE_NORTH));
790 ASSIGN_CURSOR (top_right_corner_cursor,
791 BCursor_from_id (CURSOR_ID_RESIZE_NORTH_EAST));
792 ASSIGN_CURSOR (right_edge_cursor,
793 BCursor_from_id (CURSOR_ID_RESIZE_EAST));
794 ASSIGN_CURSOR (bottom_right_corner_cursor,
795 BCursor_from_id (CURSOR_ID_RESIZE_SOUTH_EAST));
796 ASSIGN_CURSOR (bottom_edge_cursor,
797 BCursor_from_id (CURSOR_ID_RESIZE_SOUTH));
798 ASSIGN_CURSOR (bottom_left_corner_cursor,
799 BCursor_from_id (CURSOR_ID_RESIZE_SOUTH_WEST));
800 ASSIGN_CURSOR (no_cursor,
801 BCursor_from_id (CURSOR_ID_NO_CURSOR));
802
803 ASSIGN_CURSOR (current_cursor, FRAME_OUTPUT_DATA (f)->text_cursor);
804 #undef ASSIGN_CURSOR
805
806
807 if (ttip_p)
808 f->no_split = true;
809 f->terminal->reference_count++;
810
811 FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
812 if (!FRAME_OUTPUT_DATA (f)->window)
813 xsignal1 (Qerror, build_unibyte_string ("Could not create window"));
814
815 if (!minibuffer_only && !ttip_p && FRAME_EXTERNAL_MENU_BAR (f))
816 initialize_frame_menubar (f);
817
818 FRAME_OUTPUT_DATA (f)->window_desc = FRAME_OUTPUT_DATA (f)->window;
819
820 Vframe_list = Fcons (frame, Vframe_list);
821
822 Lisp_Object parent_frame = gui_display_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
823 RES_TYPE_SYMBOL);
824
825 if (EQ (parent_frame, Qunbound)
826 || NILP (parent_frame)
827 || !FRAMEP (parent_frame)
828 || !FRAME_LIVE_P (XFRAME (parent_frame)))
829 parent_frame = Qnil;
830
831 fset_parent_frame (f, parent_frame);
832 store_frame_param (f, Qparent_frame, parent_frame);
833
834 if (!NILP (parent_frame))
835 haiku_set_parent_frame (f, parent_frame, Qnil);
836
837 gui_default_parameter (f, parms, Qundecorated, Qnil, NULL, NULL, RES_TYPE_BOOLEAN);
838
839 gui_default_parameter (f, parms, Qicon_type, Qnil,
840 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
841 if (ttip_p)
842 {
843 gui_default_parameter (f, parms, Qundecorated, Qt, NULL, NULL, RES_TYPE_BOOLEAN);
844 gui_default_parameter (f, parms, Qno_accept_focus, Qt, NULL, NULL,
845 RES_TYPE_BOOLEAN);
846 }
847 else
848 {
849 gui_default_parameter (f, parms, Qauto_raise, Qnil,
850 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
851 gui_default_parameter (f, parms, Qauto_lower, Qnil,
852 "autoLower", "AutoLower", RES_TYPE_BOOLEAN);
853 gui_default_parameter (f, parms, Qcursor_type, Qbox,
854 "cursorType", "CursorType", RES_TYPE_SYMBOL);
855 gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
856 "scrollBarWidth", "ScrollBarWidth",
857 RES_TYPE_NUMBER);
858 gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
859 "scrollBarHeight", "ScrollBarHeight",
860 RES_TYPE_NUMBER);
861 gui_default_parameter (f, parms, Qalpha, Qnil,
862 "alpha", "Alpha", RES_TYPE_NUMBER);
863 gui_default_parameter (f, parms, Qfullscreen, Qnil,
864 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
865 }
866
867 gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
868 "inhibitDoubleBuffering", "InhibitDoubleBuffering",
869 RES_TYPE_BOOLEAN);
870
871 if (ttip_p)
872 {
873 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
874
875 call2 (Qface_set_after_frame_default, frame, Qnil);
876
877 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
878 {
879 AUTO_FRAME_ARG (arg, Qbackground_color, bg);
880 Fmodify_frame_parameters (frame, arg);
881 }
882 }
883
884 if (ttip_p)
885 face_change = face_change_before;
886
887 f->can_set_window_size = true;
888
889 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
890 0, true, ttip_p ? Qtip_frame : Qx_create_frame_2);
891
892 if (!FRAME_OUTPUT_DATA (f)->explicit_parent && !ttip_p)
893 {
894 Lisp_Object visibility;
895
896 visibility = gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
897 RES_TYPE_SYMBOL);
898 if (EQ (visibility, Qunbound))
899 visibility = Qt;
900 if (EQ (visibility, Qicon))
901 haiku_iconify_frame (f);
902 else if (!NILP (visibility))
903 haiku_visualize_frame (f);
904 else /* Qnil */
905 {
906 f->was_invisible = true;
907 }
908 }
909
910 if (!ttip_p)
911 {
912 if (FRAME_HAS_MINIBUF_P (f)
913 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
914 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
915 kset_default_minibuffer_frame (kb, frame);
916 }
917
918 for (tem = parms; CONSP (tem); tem = XCDR (tem))
919 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
920 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
921
922 if (window_prompting & (USPosition | PPosition))
923 haiku_set_offset (f, f->left_pos, f->top_pos, 1);
924 else
925 BWindow_center_on_screen (FRAME_HAIKU_WINDOW (f));
926
927 /* Make sure windows on this frame appear in calls to next-window
928 and similar functions. */
929 Vwindow_list = Qnil;
930
931 if (ttip_p)
932 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
933 0, true, Qtip_frame);
934
935 return unbind_to (count, frame);
936 }
937
938 static void
compute_tip_xy(struct frame * f,Lisp_Object parms,Lisp_Object dx,Lisp_Object dy,int width,int height,int * root_x,int * root_y)939 compute_tip_xy (struct frame *f,
940 Lisp_Object parms, Lisp_Object dx, Lisp_Object dy,
941 int width, int height, int *root_x, int *root_y)
942 {
943 Lisp_Object left, top, right, bottom;
944 int min_x = 0, min_y = 0, max_x = 0, max_y = 0;
945
946 /* User-specified position? */
947 left = Fcdr (Fassq (Qleft, parms));
948 top = Fcdr (Fassq (Qtop, parms));
949 right = Fcdr (Fassq (Qright, parms));
950 bottom = Fcdr (Fassq (Qbottom, parms));
951
952 /* Move the tooltip window where the mouse pointer is. Resize and
953 show it. */
954 if ((!FIXNUMP (left) && !FIXNUMP (right))
955 || (!FIXNUMP (top) && !FIXNUMP (bottom)))
956 {
957 int x, y;
958
959 /* Default min and max values. */
960 min_x = 0;
961 min_y = 0;
962 BScreen_px_dim (&max_x, &max_y);
963
964 block_input ();
965 BView_get_mouse (FRAME_HAIKU_VIEW (f), &x, &y);
966 BView_convert_to_screen (FRAME_HAIKU_VIEW (f), &x, &y);
967 *root_x = x;
968 *root_y = y;
969 unblock_input ();
970 }
971
972 if (FIXNUMP (top))
973 *root_y = XFIXNUM (top);
974 else if (FIXNUMP (bottom))
975 *root_y = XFIXNUM (bottom) - height;
976 else if (*root_y + XFIXNUM (dy) <= min_y)
977 *root_y = min_y; /* Can happen for negative dy */
978 else if (*root_y + XFIXNUM (dy) + height <= max_y)
979 /* It fits below the pointer */
980 *root_y += XFIXNUM (dy);
981 else if (height + XFIXNUM (dy) + min_y <= *root_y)
982 /* It fits above the pointer. */
983 *root_y -= height + XFIXNUM (dy);
984 else
985 /* Put it on the top. */
986 *root_y = min_y;
987
988 if (FIXNUMP (left))
989 *root_x = XFIXNUM (left);
990 else if (FIXNUMP (right))
991 *root_x = XFIXNUM (right) - width;
992 else if (*root_x + XFIXNUM (dx) <= min_x)
993 *root_x = 0; /* Can happen for negative dx */
994 else if (*root_x + XFIXNUM (dx) + width <= max_x)
995 /* It fits to the right of the pointer. */
996 *root_x += XFIXNUM (dx);
997 else if (width + XFIXNUM (dx) + min_x <= *root_x)
998 /* It fits to the left of the pointer. */
999 *root_x -= width + XFIXNUM (dx);
1000 else
1001 /* Put it left justified on the screen -- it ought to fit that way. */
1002 *root_x = min_x;
1003 }
1004
1005 static Lisp_Object
haiku_hide_tip(bool delete)1006 haiku_hide_tip (bool delete)
1007 {
1008 if (!NILP (tip_timer))
1009 {
1010 call1 (Qcancel_timer, tip_timer);
1011 tip_timer = Qnil;
1012 }
1013
1014 Lisp_Object it, frame;
1015 FOR_EACH_FRAME (it, frame)
1016 if (FRAME_WINDOW_P (XFRAME (frame)) &&
1017 FRAME_HAIKU_VIEW (XFRAME (frame)))
1018 BView_set_tooltip (FRAME_HAIKU_VIEW (XFRAME (frame)), NULL);
1019
1020 if (NILP (tip_frame)
1021 || (!delete && !NILP (tip_frame)
1022 && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
1023 return Qnil;
1024 else
1025 {
1026 ptrdiff_t count;
1027 Lisp_Object was_open = Qnil;
1028
1029 count = SPECPDL_INDEX ();
1030 specbind (Qinhibit_redisplay, Qt);
1031 specbind (Qinhibit_quit, Qt);
1032
1033 if (!NILP (tip_frame))
1034 {
1035 if (FRAME_LIVE_P (XFRAME (tip_frame)))
1036 {
1037 if (delete)
1038 {
1039 delete_frame (tip_frame, Qnil);
1040 tip_frame = Qnil;
1041 }
1042 else
1043 haiku_unvisualize_frame (XFRAME (tip_frame));
1044
1045 was_open = Qt;
1046 }
1047 else
1048 tip_frame = Qnil;
1049 }
1050 else
1051 tip_frame = Qnil;
1052
1053 return unbind_to (count, was_open);
1054 }
1055 }
1056
1057 static void
haiku_set_undecorated(struct frame * f,Lisp_Object new_value,Lisp_Object old_value)1058 haiku_set_undecorated (struct frame *f, Lisp_Object new_value,
1059 Lisp_Object old_value)
1060 {
1061 if (EQ (new_value, old_value))
1062 return;
1063
1064 block_input ();
1065 FRAME_UNDECORATED (f) = !NILP (new_value);
1066 BWindow_change_decoration (FRAME_HAIKU_WINDOW (f), NILP (new_value));
1067 unblock_input ();
1068 }
1069
1070 static void
haiku_set_menu_bar_lines(struct frame * f,Lisp_Object value,Lisp_Object oldval)1071 haiku_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1072 {
1073 if (FRAME_TOOLTIP_P (f))
1074 return;
1075 int nlines;
1076 if (TYPE_RANGED_FIXNUMP (int, value))
1077 nlines = XFIXNUM (value);
1078 else
1079 nlines = 0;
1080
1081 fset_redisplay (f);
1082
1083 FRAME_MENU_BAR_LINES (f) = 0;
1084 FRAME_MENU_BAR_HEIGHT (f) = 0;
1085
1086 if (nlines)
1087 {
1088 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1089 if (FRAME_HAIKU_P (f) && !FRAME_HAIKU_MENU_BAR (f))
1090 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
1091 }
1092 else
1093 {
1094 if (FRAME_EXTERNAL_MENU_BAR (f))
1095 free_frame_menubar (f);
1096 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1097 if (FRAME_HAIKU_P (f))
1098 FRAME_HAIKU_MENU_BAR (f) = 0;
1099 }
1100
1101 adjust_frame_glyphs (f);
1102 }
1103
1104 /* Return geometric attributes of FRAME. According to the value of
1105 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the inner
1106 edges of FRAME, the root window edges of frame (Qroot_edges). Any
1107 other value means to return the geometry as returned by
1108 Fx_frame_geometry. */
1109 static Lisp_Object
frame_geometry(Lisp_Object frame,Lisp_Object attribute)1110 frame_geometry (Lisp_Object frame, Lisp_Object attribute)
1111 {
1112 struct frame *f = decode_live_frame (frame);
1113 check_window_system (f);
1114
1115 if (EQ (attribute, Qouter_edges))
1116 return list4i (f->left_pos, f->top_pos,
1117 f->left_pos, f->top_pos);
1118 else if (EQ (attribute, Qnative_edges))
1119 return list4i (f->left_pos, f->top_pos,
1120 f->left_pos + FRAME_PIXEL_WIDTH (f),
1121 f->top_pos + FRAME_PIXEL_HEIGHT (f));
1122 else if (EQ (attribute, Qinner_edges))
1123 return list4i (f->left_pos + FRAME_INTERNAL_BORDER_WIDTH (f),
1124 f->top_pos + FRAME_INTERNAL_BORDER_WIDTH (f) +
1125 FRAME_MENU_BAR_HEIGHT (f) + FRAME_TOOL_BAR_HEIGHT (f),
1126 f->left_pos - FRAME_INTERNAL_BORDER_WIDTH (f) +
1127 FRAME_PIXEL_WIDTH (f),
1128 f->top_pos + FRAME_PIXEL_HEIGHT (f) -
1129 FRAME_INTERNAL_BORDER_WIDTH (f));
1130
1131 else
1132 return
1133 list (Fcons (Qouter_position,
1134 Fcons (make_fixnum (f->left_pos),
1135 make_fixnum (f->top_pos))),
1136 Fcons (Qouter_size,
1137 Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)),
1138 make_fixnum (FRAME_PIXEL_HEIGHT (f)))),
1139 Fcons (Qexternal_border_size,
1140 Fcons (make_fixnum (0), make_fixnum (0))),
1141 Fcons (Qtitle_bar_size,
1142 Fcons (make_fixnum (0), make_fixnum (0))),
1143 Fcons (Qmenu_bar_external, Qnil),
1144 Fcons (Qmenu_bar_size, Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f) -
1145 (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
1146 make_fixnum (FRAME_MENU_BAR_HEIGHT (f)))),
1147 Fcons (Qtool_bar_external, Qnil),
1148 Fcons (Qtool_bar_position, Qtop),
1149 Fcons (Qtool_bar_size, Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f) -
1150 (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
1151 make_fixnum (FRAME_TOOL_BAR_HEIGHT (f)))),
1152 Fcons (Qinternal_border_width, make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))));
1153 }
1154
1155 void
haiku_set_background_color(struct frame * f,Lisp_Object arg,Lisp_Object oldval)1156 haiku_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1157 {
1158 CHECK_STRING (arg);
1159
1160 block_input ();
1161 Emacs_Color color;
1162
1163 if (haiku_get_color (SSDATA (arg), &color))
1164 {
1165 store_frame_param (f, Qbackground_color, oldval);
1166 unblock_input ();
1167 error ("Bad color");
1168 }
1169
1170 FRAME_OUTPUT_DATA (f)->cursor_fg = color.pixel;
1171 FRAME_BACKGROUND_PIXEL (f) = color.pixel;
1172
1173 if (FRAME_HAIKU_VIEW (f))
1174 {
1175 struct face *defface;
1176
1177 BView_draw_lock (FRAME_HAIKU_VIEW (f));
1178 BView_SetViewColor (FRAME_HAIKU_VIEW (f), color.pixel);
1179 BView_draw_unlock (FRAME_HAIKU_VIEW (f));
1180
1181 defface = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID);
1182 if (defface)
1183 {
1184 defface->background = color.pixel;
1185 update_face_from_frame_parameter (f, Qbackground_color, arg);
1186 clear_frame (f);
1187 }
1188 }
1189
1190 if (FRAME_VISIBLE_P (f))
1191 SET_FRAME_GARBAGED (f);
1192 unblock_input ();
1193 }
1194
1195 void
haiku_set_cursor_color(struct frame * f,Lisp_Object arg,Lisp_Object oldval)1196 haiku_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1197 {
1198 CHECK_STRING (arg);
1199
1200 block_input ();
1201 Emacs_Color color;
1202
1203 if (haiku_get_color (SSDATA (arg), &color))
1204 {
1205 store_frame_param (f, Qcursor_color, oldval);
1206 unblock_input ();
1207 error ("Bad color");
1208 }
1209
1210 FRAME_CURSOR_COLOR (f) = color;
1211 if (FRAME_VISIBLE_P (f))
1212 {
1213 gui_update_cursor (f, 0);
1214 gui_update_cursor (f, 1);
1215 }
1216 update_face_from_frame_parameter (f, Qcursor_color, arg);
1217 unblock_input ();
1218 }
1219
1220 void
haiku_set_cursor_type(struct frame * f,Lisp_Object arg,Lisp_Object oldval)1221 haiku_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1222 {
1223 set_frame_cursor_types (f, arg);
1224 }
1225
1226 unsigned long
haiku_get_pixel(haiku bitmap,int x,int y)1227 haiku_get_pixel (haiku bitmap, int x, int y)
1228 {
1229 unsigned char *data;
1230 int32_t bytes_per_row;
1231 int mono_p;
1232 int left;
1233 int right;
1234 int top;
1235 int bottom;
1236
1237 data = BBitmap_data (bitmap);
1238 BBitmap_dimensions (bitmap, &left, &top, &right, &bottom,
1239 &bytes_per_row, &mono_p);
1240
1241 if (x < left || x > right || y < top || y > bottom)
1242 emacs_abort ();
1243
1244 if (!mono_p)
1245 return ((uint32_t *) (data + (bytes_per_row * y)))[x];
1246
1247 int byte = y * bytes_per_row + x / 8;
1248 return data[byte] & (1 << (x % 8));
1249 }
1250
1251 void
haiku_put_pixel(haiku bitmap,int x,int y,unsigned long pixel)1252 haiku_put_pixel (haiku bitmap, int x, int y, unsigned long pixel)
1253 {
1254 unsigned char *data;
1255 int32_t bytes_per_row;
1256 int mono_p;
1257 int left;
1258 int right;
1259 int top;
1260 int bottom;
1261
1262 data = BBitmap_data (bitmap);
1263 BBitmap_dimensions (bitmap, &left, &top, &right, &bottom,
1264 &bytes_per_row, &mono_p);
1265
1266 if (x < left || x > right || y < top || y > bottom)
1267 emacs_abort ();
1268
1269 if (mono_p)
1270 {
1271 ptrdiff_t off = y * bytes_per_row;
1272 ptrdiff_t bit = x % 8;
1273 ptrdiff_t xoff = x / 8;
1274
1275 unsigned char *byte = data + off + xoff;
1276 if (!pixel)
1277 *byte &= ~(1 << bit);
1278 else
1279 *byte |= 1 << bit;
1280 }
1281 else
1282 ((uint32_t *) (data + (bytes_per_row * y)))[x] = pixel;
1283 }
1284
1285 void
haiku_free_frame_resources(struct frame * f)1286 haiku_free_frame_resources (struct frame *f)
1287 {
1288 haiku window, drawable, mbar;
1289 Mouse_HLInfo *hlinfo;
1290 struct haiku_display_info *dpyinfo;
1291 Lisp_Object bar;
1292 struct scroll_bar *b;
1293
1294 block_input ();
1295 check_window_system (f);
1296
1297 hlinfo = MOUSE_HL_INFO (f);
1298 window = FRAME_HAIKU_WINDOW (f);
1299 drawable = FRAME_HAIKU_VIEW (f);
1300 mbar = FRAME_HAIKU_MENU_BAR (f);
1301 dpyinfo = FRAME_DISPLAY_INFO (f);
1302
1303 free_frame_faces (f);
1304
1305 /* Free scroll bars */
1306 for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next)
1307 {
1308 b = XSCROLL_BAR (bar);
1309 haiku_scroll_bar_remove (b);
1310 }
1311
1312 if (f == dpyinfo->highlight_frame)
1313 dpyinfo->highlight_frame = 0;
1314 if (f == dpyinfo->focused_frame)
1315 dpyinfo->focused_frame = 0;
1316 if (f == dpyinfo->last_mouse_motion_frame)
1317 dpyinfo->last_mouse_motion_frame = NULL;
1318 if (f == dpyinfo->last_mouse_frame)
1319 dpyinfo->last_mouse_frame = NULL;
1320 if (f == dpyinfo->focus_event_frame)
1321 dpyinfo->focus_event_frame = NULL;
1322
1323 if (f == hlinfo->mouse_face_mouse_frame)
1324 reset_mouse_highlight (hlinfo);
1325
1326 if (mbar)
1327 {
1328 BMenuBar_delete (mbar);
1329 if (f->output_data.haiku->menu_bar_open_p)
1330 {
1331 --popup_activated_p;
1332 f->output_data.haiku->menu_bar_open_p = 0;
1333 }
1334 }
1335
1336 if (drawable)
1337 BView_emacs_delete (drawable);
1338
1339 if (window)
1340 BWindow_quit (window);
1341
1342 /* Free cursors */
1343
1344 BCursor_delete (f->output_data.haiku->text_cursor);
1345 BCursor_delete (f->output_data.haiku->nontext_cursor);
1346 BCursor_delete (f->output_data.haiku->modeline_cursor);
1347 BCursor_delete (f->output_data.haiku->hand_cursor);
1348 BCursor_delete (f->output_data.haiku->hourglass_cursor);
1349 BCursor_delete (f->output_data.haiku->horizontal_drag_cursor);
1350 BCursor_delete (f->output_data.haiku->vertical_drag_cursor);
1351 BCursor_delete (f->output_data.haiku->left_edge_cursor);
1352 BCursor_delete (f->output_data.haiku->top_left_corner_cursor);
1353 BCursor_delete (f->output_data.haiku->top_edge_cursor);
1354 BCursor_delete (f->output_data.haiku->top_right_corner_cursor);
1355 BCursor_delete (f->output_data.haiku->right_edge_cursor);
1356 BCursor_delete (f->output_data.haiku->bottom_right_corner_cursor);
1357 BCursor_delete (f->output_data.haiku->bottom_edge_cursor);
1358 BCursor_delete (f->output_data.haiku->bottom_left_corner_cursor);
1359 BCursor_delete (f->output_data.haiku->no_cursor);
1360
1361 xfree (FRAME_OUTPUT_DATA (f));
1362 FRAME_OUTPUT_DATA (f) = NULL;
1363
1364 unblock_input ();
1365 }
1366
1367 void
haiku_iconify_frame(struct frame * frame)1368 haiku_iconify_frame (struct frame *frame)
1369 {
1370 if (FRAME_ICONIFIED_P (frame))
1371 return;
1372
1373 block_input ();
1374
1375 SET_FRAME_VISIBLE (frame, false);
1376 SET_FRAME_ICONIFIED (frame, true);
1377
1378 BWindow_iconify (FRAME_HAIKU_WINDOW (frame));
1379
1380 unblock_input ();
1381 }
1382
1383 void
haiku_visualize_frame(struct frame * f)1384 haiku_visualize_frame (struct frame *f)
1385 {
1386 block_input ();
1387
1388 if (!FRAME_VISIBLE_P (f))
1389 {
1390 if (FRAME_NO_FOCUS_ON_MAP (f))
1391 BWindow_set_avoid_focus (FRAME_HAIKU_WINDOW (f), 1);
1392 BWindow_set_visible (FRAME_HAIKU_WINDOW (f), 1);
1393 if (FRAME_NO_FOCUS_ON_MAP (f) &&
1394 !FRAME_NO_ACCEPT_FOCUS (f))
1395 BWindow_set_avoid_focus (FRAME_HAIKU_WINDOW (f), 0);
1396
1397 haiku_set_offset (f, f->left_pos, f->top_pos, 0);
1398
1399 SET_FRAME_VISIBLE (f, 1);
1400 SET_FRAME_ICONIFIED (f, 0);
1401 }
1402
1403 unblock_input ();
1404 }
1405
1406 void
haiku_unvisualize_frame(struct frame * f)1407 haiku_unvisualize_frame (struct frame *f)
1408 {
1409 block_input ();
1410
1411 BWindow_set_visible (FRAME_HAIKU_WINDOW (f), 0);
1412 SET_FRAME_VISIBLE (f, 0);
1413 SET_FRAME_ICONIFIED (f, 0);
1414
1415 unblock_input ();
1416 }
1417
1418 void
haiku_set_internal_border_width(struct frame * f,Lisp_Object arg,Lisp_Object oldval)1419 haiku_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1420 {
1421 int old_width = FRAME_INTERNAL_BORDER_WIDTH (f);
1422 int new_width = check_int_nonnegative (arg);
1423
1424 if (new_width == old_width)
1425 return;
1426 f->internal_border_width = new_width;
1427
1428 if (FRAME_HAIKU_WINDOW (f))
1429 {
1430 adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
1431 haiku_clear_under_internal_border (f);
1432 }
1433
1434 SET_FRAME_GARBAGED (f);
1435 }
1436
1437 void
haiku_set_frame_visible_invisible(struct frame * f,bool visible_p)1438 haiku_set_frame_visible_invisible (struct frame *f, bool visible_p)
1439 {
1440 if (visible_p)
1441 haiku_visualize_frame (f);
1442 else
1443 haiku_unvisualize_frame (f);
1444 }
1445
1446 void
frame_set_mouse_pixel_position(struct frame * f,int pix_x,int pix_y)1447 frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
1448 {
1449 block_input ();
1450
1451 BView_convert_to_screen (FRAME_HAIKU_VIEW (f), &pix_x, &pix_y);
1452 be_warp_pointer (pix_x, pix_y);
1453
1454 unblock_input ();
1455 }
1456
1457 void
haiku_query_color(uint32_t col,Emacs_Color * color_def)1458 haiku_query_color (uint32_t col, Emacs_Color *color_def)
1459 {
1460 color_def->red = RED_FROM_ULONG (col) * 257;
1461 color_def->green = GREEN_FROM_ULONG (col) * 257;
1462 color_def->blue = BLUE_FROM_ULONG (col) * 257;
1463
1464 color_def->pixel = col;
1465 }
1466
1467 Display_Info *
check_x_display_info(Lisp_Object object)1468 check_x_display_info (Lisp_Object object)
1469 {
1470 return check_haiku_display_info (object);
1471 }
1472
1473 /* Rename frame F to NAME. If NAME is nil, set F's name to "GNU
1474 Emacs". If EXPLICIT_P is non-zero, that indicates Lisp code is
1475 setting the name, not redisplay; in that case, set F's name to NAME
1476 and set F->explicit_name; if NAME is nil, clear F->explicit_name.
1477
1478 If EXPLICIT_P is zero, it means redisplay is setting the name; the
1479 name provided will be ignored if explicit_name is set. */
1480 void
haiku_set_name(struct frame * f,Lisp_Object name,bool explicit_p)1481 haiku_set_name (struct frame *f, Lisp_Object name, bool explicit_p)
1482 {
1483 if (explicit_p)
1484 {
1485 if (f->explicit_name && NILP (name))
1486 update_mode_lines = 24;
1487
1488 f->explicit_name = !NILP (name);
1489 }
1490 else if (f->explicit_name)
1491 return;
1492
1493 if (NILP (name))
1494 name = build_unibyte_string ("GNU Emacs");
1495
1496 if (!NILP (Fstring_equal (name, f->name)))
1497 return;
1498
1499 fset_name (f, name);
1500
1501 if (!NILP (f->title))
1502 name = f->title;
1503
1504 haiku_set_title_bar_text (f, name);
1505 }
1506
1507 static void
haiku_set_inhibit_double_buffering(struct frame * f,Lisp_Object new_value,Lisp_Object old_value)1508 haiku_set_inhibit_double_buffering (struct frame *f,
1509 Lisp_Object new_value,
1510 Lisp_Object old_value)
1511 {
1512 block_input ();
1513 #ifndef USE_BE_CAIRO
1514 if (FRAME_HAIKU_WINDOW (f))
1515 {
1516 if (NILP (new_value))
1517 {
1518 #endif
1519 EmacsView_set_up_double_buffering (FRAME_HAIKU_VIEW (f));
1520 if (!NILP (old_value))
1521 {
1522 SET_FRAME_GARBAGED (f);
1523 expose_frame (f, 0, 0, 0, 0);
1524 }
1525 #ifndef USE_BE_CAIRO
1526 }
1527 else
1528 EmacsView_disable_double_buffering (FRAME_HAIKU_VIEW (f));
1529 }
1530 #endif
1531 unblock_input ();
1532 }
1533
1534
1535
1536 DEFUN ("haiku-set-mouse-absolute-pixel-position",
1537 Fhaiku_set_mouse_absolute_pixel_position,
1538 Shaiku_set_mouse_absolute_pixel_position, 2, 2, 0,
1539 doc: /* Move mouse pointer to a pixel position at (X, Y). The
1540 coordinates X and Y are interpreted to start from the top-left
1541 corner of the screen. */)
1542 (Lisp_Object x, Lisp_Object y)
1543 {
1544 int xval = check_integer_range (x, INT_MIN, INT_MAX);
1545 int yval = check_integer_range (y, INT_MIN, INT_MAX);
1546
1547 if (!x_display_list)
1548 error ("Window system not initialized");
1549
1550 block_input ();
1551 be_warp_pointer (xval, yval);
1552 unblock_input ();
1553 return Qnil;
1554 }
1555
1556 DEFUN ("haiku-mouse-absolute-pixel-position", Fhaiku_mouse_absolute_pixel_position,
1557 Shaiku_mouse_absolute_pixel_position, 0, 0, 0,
1558 doc: /* Return absolute position of mouse cursor in pixels.
1559 The position is returned as a cons cell (X . Y) of the coordinates of
1560 the mouse cursor position in pixels relative to a position (0, 0) of the
1561 selected frame's display. */)
1562 (void)
1563 {
1564 if (!x_display_list)
1565 return Qnil;
1566
1567 struct frame *f = SELECTED_FRAME ();
1568
1569 if (FRAME_INITIAL_P (f) || !FRAME_HAIKU_P (f)
1570 || !FRAME_HAIKU_VIEW (f))
1571 return Qnil;
1572
1573 block_input ();
1574 void *view = FRAME_HAIKU_VIEW (f);
1575
1576 int x, y;
1577 BView_get_mouse (view, &x, &y);
1578 BView_convert_to_screen (view, &x, &y);
1579 unblock_input ();
1580
1581 return Fcons (make_fixnum (x), make_fixnum (y));
1582 }
1583
1584 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
1585 doc: /* SKIP: real doc in xfns.c. */)
1586 (Lisp_Object terminal)
1587 {
1588 return Qt;
1589 }
1590
1591 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
1592 doc: /* SKIP: real doc in xfns.c. */)
1593 (Lisp_Object color, Lisp_Object frame)
1594 {
1595 Emacs_Color col;
1596 CHECK_STRING (color);
1597 decode_window_system_frame (frame);
1598
1599 return haiku_get_color (SSDATA (color), &col) ? Qnil : Qt;
1600 }
1601
1602 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
1603 doc: /* SKIP: real doc in xfns.c. */)
1604 (Lisp_Object color, Lisp_Object frame)
1605 {
1606 Emacs_Color col;
1607 CHECK_STRING (color);
1608 decode_window_system_frame (frame);
1609
1610 block_input ();
1611 if (haiku_get_color (SSDATA (color), &col))
1612 {
1613 unblock_input ();
1614 return Qnil;
1615 }
1616 unblock_input ();
1617 return list3i (lrint (col.red), lrint (col.green), lrint (col.blue));
1618 }
1619
1620 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
1621 0, 1, 0,
1622 doc: /* SKIP: real doc in xfns.c. */)
1623 (Lisp_Object terminal)
1624 {
1625 return Qnil;
1626 }
1627
1628 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
1629 1, 3, 0,
1630 doc: /* SKIP: real doc in xfns.c. */)
1631 (Lisp_Object display, Lisp_Object resource_string, Lisp_Object must_succeed)
1632 {
1633 struct haiku_display_info *dpy_info;
1634 CHECK_STRING (display);
1635
1636 if (NILP (Fstring_equal (display, build_string ("be"))))
1637 !NILP (must_succeed) ? fatal ("Bad display") : error ("Bad display");
1638 dpy_info = haiku_term_init ();
1639
1640 if (!dpy_info)
1641 !NILP (must_succeed) ? fatal ("Display not responding") :
1642 error ("Display not responding");
1643
1644 return Qnil;
1645 }
1646
1647 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
1648 0, 1, 0,
1649 doc: /* SKIP: real doc in xfns.c. */)
1650 (Lisp_Object terminal)
1651
1652 {
1653 check_haiku_display_info (terminal);
1654
1655 int width, height;
1656 BScreen_px_dim (&width, &height);
1657 return make_fixnum (width);
1658 }
1659
1660 DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height,
1661 0, 1, 0,
1662 doc: /* SKIP: real doc in xfns.c. */)
1663 (Lisp_Object terminal)
1664
1665 {
1666 check_haiku_display_info (terminal);
1667
1668 int width, height;
1669 BScreen_px_dim (&width, &height);
1670 return make_fixnum (width);
1671 }
1672
1673 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
1674 doc: /* SKIP: real doc in xfns.c. */)
1675 (Lisp_Object terminal)
1676 {
1677 struct haiku_display_info *dpyinfo = check_haiku_display_info (terminal);
1678
1679 int width, height;
1680 BScreen_px_dim (&width, &height);
1681
1682 return make_fixnum (height / (dpyinfo->resy / 25.4));
1683 }
1684
1685
1686 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
1687 doc: /* SKIP: real doc in xfns.c. */)
1688 (Lisp_Object terminal)
1689 {
1690 struct haiku_display_info *dpyinfo = check_haiku_display_info (terminal);
1691
1692 int width, height;
1693 BScreen_px_dim (&width, &height);
1694
1695 return make_fixnum (height / (dpyinfo->resy / 25.4));
1696 }
1697
1698 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1699 1, 1, 0,
1700 doc: /* SKIP: real doc in xfns.c. */)
1701 (Lisp_Object parms)
1702 {
1703 return haiku_create_frame (parms, 0);
1704 }
1705
1706 DEFUN ("x-display-visual-class", Fx_display_visual_class,
1707 Sx_display_visual_class, 0, 1, 0,
1708 doc: /* SKIP: real doc in xfns.c. */)
1709 (Lisp_Object terminal)
1710 {
1711 check_haiku_display_info (terminal);
1712
1713 int planes = be_get_display_planes ();
1714
1715 if (planes == 8)
1716 return intern ("static-color");
1717 else if (planes == 16 || planes == 15)
1718 return intern ("pseudo-color");
1719
1720 return intern ("direct-color");
1721 }
1722
1723 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1724 doc: /* SKIP: real doc in xfns.c. */)
1725 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
1726 Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
1727 {
1728 struct frame *tip_f;
1729 struct window *w;
1730 int root_x, root_y;
1731 struct buffer *old_buffer;
1732 struct text_pos pos;
1733 int width, height;
1734 int old_windows_or_buffers_changed = windows_or_buffers_changed;
1735 ptrdiff_t count = SPECPDL_INDEX ();
1736 ptrdiff_t count_1;
1737 Lisp_Object window, size, tip_buf;
1738
1739 AUTO_STRING (tip, " *tip*");
1740
1741 specbind (Qinhibit_redisplay, Qt);
1742
1743 CHECK_STRING (string);
1744
1745 if (NILP (frame))
1746 frame = selected_frame;
1747 decode_window_system_frame (frame);
1748
1749 if (NILP (timeout))
1750 timeout = make_fixnum (5);
1751 else
1752 CHECK_FIXNAT (timeout);
1753
1754 if (NILP (dx))
1755 dx = make_fixnum (5);
1756 else
1757 CHECK_FIXNUM (dx);
1758
1759 if (NILP (dy))
1760 dy = make_fixnum (-10);
1761 else
1762 CHECK_FIXNUM (dy);
1763
1764 if (haiku_use_system_tooltips)
1765 {
1766 int root_x, root_y;
1767 CHECK_STRING (string);
1768 if (STRING_MULTIBYTE (string))
1769 string = ENCODE_UTF_8 (string);
1770
1771 if (NILP (frame))
1772 frame = selected_frame;
1773
1774 struct frame *f = decode_window_system_frame (frame);
1775 block_input ();
1776
1777 char *str = xstrdup (SSDATA (string));
1778 int height = be_plain_font_height ();
1779 int width;
1780 char *tok = strtok (str, "\n");
1781 width = be_string_width_with_plain_font (tok);
1782
1783 while ((tok = strtok (NULL, "\n")))
1784 {
1785 height = be_plain_font_height ();
1786 int w = be_string_width_with_plain_font (tok);
1787 if (w > width)
1788 w = width;
1789 }
1790 free (str);
1791
1792 height += 16; /* Default margin. */
1793 width += 16; /* Ditto. Unfortunately there isn't a more
1794 reliable way to get it. */
1795 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
1796 BView_convert_from_screen (FRAME_HAIKU_VIEW (f), &root_x, &root_y);
1797 BView_set_and_show_sticky_tooltip (FRAME_HAIKU_VIEW (f), SSDATA (string),
1798 root_x, root_y);
1799 unblock_input ();
1800 goto start_timer;
1801 }
1802
1803 if (!NILP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
1804 {
1805 if (FRAME_VISIBLE_P (XFRAME (tip_frame))
1806 && EQ (frame, tip_last_frame)
1807 && !NILP (Fequal_including_properties (string, tip_last_string))
1808 && !NILP (Fequal (parms, tip_last_parms)))
1809 {
1810 /* Only DX and DY have changed. */
1811 tip_f = XFRAME (tip_frame);
1812 if (!NILP (tip_timer))
1813 {
1814 Lisp_Object timer = tip_timer;
1815
1816 tip_timer = Qnil;
1817 call1 (Qcancel_timer, timer);
1818 }
1819
1820 block_input ();
1821 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
1822 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
1823 haiku_set_offset (tip_f, root_x, root_y, 1);
1824 haiku_visualize_frame (tip_f);
1825 unblock_input ();
1826
1827 goto start_timer;
1828 }
1829 else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
1830 {
1831 bool delete = false;
1832 Lisp_Object tail, elt, parm, last;
1833
1834 /* Check if every parameter in PARMS has the same value in
1835 tip_last_parms. This may destruct tip_last_parms
1836 which, however, will be recreated below. */
1837 for (tail = parms; CONSP (tail); tail = XCDR (tail))
1838 {
1839 elt = XCAR (tail);
1840 parm = Fcar (elt);
1841 /* The left, top, right and bottom parameters are handled
1842 by compute_tip_xy so they can be ignored here. */
1843 if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
1844 && !EQ (parm, Qright) && !EQ (parm, Qbottom))
1845 {
1846 last = Fassq (parm, tip_last_parms);
1847 if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
1848 {
1849 /* We lost, delete the old tooltip. */
1850 delete = true;
1851 break;
1852 }
1853 else
1854 tip_last_parms =
1855 call2 (Qassq_delete_all, parm, tip_last_parms);
1856 }
1857 else
1858 tip_last_parms =
1859 call2 (Qassq_delete_all, parm, tip_last_parms);
1860 }
1861
1862 /* Now check if there's a parameter left in tip_last_parms with a
1863 non-nil value. */
1864 for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
1865 {
1866 elt = XCAR (tail);
1867 parm = Fcar (elt);
1868 if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright)
1869 && !EQ (parm, Qbottom) && !NILP (Fcdr (elt)))
1870 {
1871 /* We lost, delete the old tooltip. */
1872 delete = true;
1873 break;
1874 }
1875 }
1876
1877 haiku_hide_tip (delete);
1878 }
1879 else
1880 haiku_hide_tip (true);
1881 }
1882 else
1883 haiku_hide_tip (true);
1884
1885 tip_last_frame = frame;
1886 tip_last_string = string;
1887 tip_last_parms = parms;
1888
1889 /* Block input until the tip has been fully drawn, to avoid crashes
1890 when drawing tips in menus. */
1891 block_input ();
1892
1893 if (NILP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
1894 {
1895 /* Add default values to frame parameters. */
1896 if (NILP (Fassq (Qname, parms)))
1897 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
1898 if (NILP (Fassq (Qinternal_border_width, parms)))
1899 parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), parms);
1900 if (NILP (Fassq (Qborder_width, parms)))
1901 parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
1902 if (NILP (Fassq (Qborder_color, parms)))
1903 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")),
1904 parms);
1905 if (NILP (Fassq (Qbackground_color, parms)))
1906 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
1907 parms);
1908
1909 /* Create a frame for the tooltip and record it in the global
1910 variable tip_frame. */
1911
1912 if (NILP (tip_frame = haiku_create_frame (parms, 1)))
1913 {
1914 /* Creating the tip frame failed. */
1915 unblock_input ();
1916 return unbind_to (count, Qnil);
1917 }
1918 }
1919
1920 tip_f = XFRAME (tip_frame);
1921 window = FRAME_ROOT_WINDOW (tip_f);
1922 tip_buf = Fget_buffer_create (tip, Qnil);
1923 /* We will mark the tip window a "pseudo-window" below, and such
1924 windows cannot have display margins. */
1925 bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
1926 bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
1927 set_window_buffer (window, tip_buf, false, false);
1928 w = XWINDOW (window);
1929 w->pseudo_window_p = true;
1930 /* Try to avoid that `other-window' select us (Bug#47207). */
1931 Fset_window_parameter (window, Qno_other_window, Qt);
1932
1933 /* Set up the frame's root window. Note: The following code does not
1934 try to size the window or its frame correctly. Its only purpose is
1935 to make the subsequent text size calculations work. The right
1936 sizes should get installed when the toolkit gets back to us. */
1937 w->left_col = 0;
1938 w->top_line = 0;
1939 w->pixel_left = 0;
1940 w->pixel_top = 0;
1941
1942 if (CONSP (Vx_max_tooltip_size)
1943 && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
1944 && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
1945 {
1946 w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size));
1947 w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size));
1948 }
1949 else
1950 {
1951 w->total_cols = 80;
1952 w->total_lines = 40;
1953 }
1954
1955 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
1956 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
1957 FRAME_TOTAL_COLS (tip_f) = WINDOW_TOTAL_COLS (w);
1958 adjust_frame_glyphs (tip_f);
1959
1960 /* Insert STRING into the root window's buffer and fit the frame to
1961 the buffer. */
1962 count_1 = SPECPDL_INDEX ();
1963 old_buffer = current_buffer;
1964 set_buffer_internal_1 (XBUFFER (w->contents));
1965 bset_truncate_lines (current_buffer, Qnil);
1966 specbind (Qinhibit_read_only, Qt);
1967 specbind (Qinhibit_modification_hooks, Qt);
1968 specbind (Qinhibit_point_motion_hooks, Qt);
1969 Ferase_buffer ();
1970 Finsert (1, &string);
1971 clear_glyph_matrix (w->desired_matrix);
1972 clear_glyph_matrix (w->current_matrix);
1973 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
1974 try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
1975 /* Calculate size of tooltip window. */
1976 size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
1977 make_fixnum (w->pixel_height), Qnil,
1978 Qnil);
1979 /* Add the frame's internal border to calculated size. */
1980 width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
1981 height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
1982 /* Calculate position of tooltip frame. */
1983 compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
1984 BWindow_resize (FRAME_HAIKU_WINDOW (tip_f), width, height);
1985 haiku_set_offset (tip_f, root_x, root_y, 1);
1986 BWindow_set_tooltip_decoration (FRAME_HAIKU_WINDOW (tip_f));
1987 BView_set_view_cursor (FRAME_HAIKU_VIEW (tip_f),
1988 FRAME_OUTPUT_DATA (XFRAME (frame))->current_cursor);
1989 SET_FRAME_VISIBLE (tip_f, 1);
1990 BWindow_set_visible (FRAME_HAIKU_WINDOW (tip_f), 1);
1991
1992 w->must_be_updated_p = true;
1993 flush_frame (tip_f);
1994 update_single_window (w);
1995 set_buffer_internal_1 (old_buffer);
1996 unbind_to (count_1, Qnil);
1997 unblock_input ();
1998 windows_or_buffers_changed = old_windows_or_buffers_changed;
1999
2000 start_timer:
2001 /* Let the tip disappear after timeout seconds. */
2002 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
2003 intern ("x-hide-tip"));
2004
2005 return unbind_to (count, Qnil);
2006 }
2007
2008 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
2009 doc: /* SKIP: real doc in xfns.c. */)
2010 (void)
2011 {
2012 return haiku_hide_tip (!tooltip_reuse_hidden_frame);
2013 }
2014
2015 DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection, 1, 1, 0,
2016 doc: /* SKIP: real doc in xfns.c. */
2017 attributes: noreturn)
2018 (Lisp_Object terminal)
2019 {
2020 check_haiku_display_info (terminal);
2021
2022 error ("Cannot close Haiku displays");
2023 }
2024
2025 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
2026 doc: /* SKIP: real doc in xfns.c. */)
2027 (void)
2028 {
2029 if (!x_display_list)
2030 return Qnil;
2031
2032 return list1 (XCAR (x_display_list->name_list_element));
2033 }
2034
2035 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2036 doc: /* SKIP: real doc in xfns.c. */)
2037 (Lisp_Object terminal)
2038 {
2039 check_haiku_display_info (terminal);
2040 return build_string ("Haiku, Inc.");
2041 }
2042
2043 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2044 doc: /* SKIP: real doc in xfns.c. */)
2045 (Lisp_Object terminal)
2046 {
2047 check_haiku_display_info (terminal);
2048 return list3i (5, 1, 1);
2049 }
2050
2051 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2052 doc: /* SKIP: real doc in xfns.c. */)
2053 (Lisp_Object terminal)
2054 {
2055 check_haiku_display_info (terminal);
2056 return make_fixnum (be_get_display_screens ());
2057 }
2058
2059 DEFUN ("haiku-get-version-string", Fhaiku_get_version_string,
2060 Shaiku_get_version_string, 0, 0, 0,
2061 doc: /* Return a string describing the current Haiku version. */)
2062 (void)
2063 {
2064 char buf[1024];
2065
2066 be_get_version_string ((char *) &buf, sizeof buf);
2067 return build_string (buf);
2068 }
2069
2070 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2071 0, 1, 0,
2072 doc: /* SKIP: real doc in xfns.c. */)
2073 (Lisp_Object terminal)
2074 {
2075 check_haiku_display_info (terminal);
2076
2077 return make_fixnum (be_get_display_color_cells ());
2078 }
2079
2080 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2081 0, 1, 0,
2082 doc: /* SKIP: real doc in xfns.c. */)
2083 (Lisp_Object terminal)
2084 {
2085 check_haiku_display_info (terminal);
2086
2087 return make_fixnum (be_get_display_planes ());
2088 }
2089
2090 DEFUN ("x-double-buffered-p", Fx_double_buffered_p, Sx_double_buffered_p,
2091 0, 1, 0,
2092 doc: /* SKIP: real doc in xfns.c. */)
2093 (Lisp_Object frame)
2094 {
2095 struct frame *f = decode_live_frame (frame);
2096 check_window_system (f);
2097
2098 return EmacsView_double_buffered_p (FRAME_HAIKU_VIEW (f)) ? Qt : Qnil;
2099 }
2100
2101 DEFUN ("x-display-backing-store", Fx_display_backing_store, Sx_display_backing_store,
2102 0, 1, 0,
2103 doc: /* SKIP: real doc in xfns.c. */)
2104 (Lisp_Object terminal)
2105 {
2106 if (FRAMEP (terminal))
2107 {
2108 CHECK_LIVE_FRAME (terminal);
2109 struct frame *f = decode_window_system_frame (terminal);
2110
2111 if (FRAME_HAIKU_VIEW (f) &&
2112 EmacsView_double_buffered_p (FRAME_HAIKU_VIEW (f)))
2113 return FRAME_PARENT_FRAME (f) ? Qwhen_mapped : Qalways;
2114 else
2115 return Qnot_useful;
2116 }
2117 else
2118 {
2119 check_haiku_display_info (terminal);
2120 return Qnot_useful;
2121 }
2122 }
2123
2124 DEFUN ("haiku-frame-geometry", Fhaiku_frame_geometry, Shaiku_frame_geometry, 0, 1, 0,
2125 doc: /* Return geometric attributes of FRAME.
2126 FRAME must be a live frame and defaults to the selected one. The return
2127 value is an association list of the attributes listed below. All height
2128 and width values are in pixels.
2129
2130 `outer-position' is a cons of the outer left and top edges of FRAME
2131 relative to the origin - the position (0, 0) - of FRAME's display.
2132
2133 `outer-size' is a cons of the outer width and height of FRAME. The
2134 outer size includes the title bar and the external borders as well as
2135 any menu and/or tool bar of frame.
2136
2137 `external-border-size' is a cons of the horizontal and vertical width of
2138 FRAME's external borders as supplied by the window manager.
2139
2140 `title-bar-size' is a cons of the width and height of the title bar of
2141 FRAME as supplied by the window manager. If both of them are zero,
2142 FRAME has no title bar. If only the width is zero, Emacs was not
2143 able to retrieve the width information.
2144
2145 `menu-bar-external', if non-nil, means the menu bar is external (never
2146 included in the inner edges of FRAME).
2147
2148 `menu-bar-size' is a cons of the width and height of the menu bar of
2149 FRAME.
2150
2151 `tool-bar-external', if non-nil, means the tool bar is external (never
2152 included in the inner edges of FRAME).
2153
2154 `tool-bar-position' tells on which side the tool bar on FRAME is and can
2155 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
2156 has no tool bar.
2157
2158 `tool-bar-size' is a cons of the width and height of the tool bar of
2159 FRAME.
2160
2161 `internal-border-width' is the width of the internal border of
2162 FRAME. */)
2163 (Lisp_Object frame)
2164 {
2165 return frame_geometry (frame, Qnil);
2166 }
2167
2168 DEFUN ("haiku-frame-edges", Fhaiku_frame_edges, Shaiku_frame_edges, 0, 2, 0,
2169 doc: /* Return edge coordinates of FRAME.
2170 FRAME must be a live frame and defaults to the selected one. The return
2171 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
2172 in pixels relative to the origin - the position (0, 0) - of FRAME's
2173 display.
2174
2175 If optional argument TYPE is the symbol `outer-edges', return the outer
2176 edges of FRAME. The outer edges comprise the decorations of the window
2177 manager (like the title bar or external borders) as well as any external
2178 menu or tool bar of FRAME. If optional argument TYPE is the symbol
2179 `native-edges' or nil, return the native edges of FRAME. The native
2180 edges exclude the decorations of the window manager and any external
2181 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
2182 the inner edges of FRAME. These edges exclude title bar, any borders,
2183 menu bar or tool bar of FRAME. */)
2184 (Lisp_Object frame, Lisp_Object type)
2185 {
2186 return frame_geometry (frame, ((EQ (type, Qouter_edges)
2187 || EQ (type, Qinner_edges))
2188 ? type
2189 : Qnative_edges));
2190 }
2191
2192 DEFUN ("haiku-read-file-name", Fhaiku_read_file_name, Shaiku_read_file_name, 1, 6, 0,
2193 doc: /* Use a graphical panel to read a file name, using prompt PROMPT.
2194 Optional arg FRAME specifies a frame on which to display the file panel.
2195 If it is nil, the current frame is used instead.
2196 The frame being used will be brought to the front of
2197 the display after the file panel is closed.
2198 Optional arg DIR, if non-nil, supplies a default directory.
2199 Optional arg MUSTMATCH, if non-nil, means the returned file or
2200 directory must exist.
2201 Optional arg DIR_ONLY_P, if non-nil, means choose only directories.
2202 Optional arg SAVE_TEXT, if non-nil, specifies some text to show in the entry field. */)
2203 (Lisp_Object prompt, Lisp_Object frame,
2204 Lisp_Object dir, Lisp_Object mustmatch,
2205 Lisp_Object dir_only_p, Lisp_Object save_text)
2206 {
2207 ptrdiff_t idx;
2208 if (!x_display_list)
2209 error ("Be windowing not initialized");
2210
2211 if (!NILP (dir))
2212 CHECK_STRING (dir);
2213
2214 if (!NILP (save_text))
2215 CHECK_STRING (save_text);
2216
2217 if (NILP (frame))
2218 frame = selected_frame;
2219
2220 CHECK_STRING (prompt);
2221
2222 CHECK_LIVE_FRAME (frame);
2223 check_window_system (XFRAME (frame));
2224
2225 idx = SPECPDL_INDEX ();
2226 record_unwind_protect_void (unwind_popup);
2227
2228 struct frame *f = XFRAME (frame);
2229
2230 FRAME_DISPLAY_INFO (f)->focus_event_frame = f;
2231
2232 ++popup_activated_p;
2233 char *fn = be_popup_file_dialog (!NILP (mustmatch) || !NILP (dir_only_p),
2234 !NILP (dir) ? SSDATA (ENCODE_UTF_8 (dir)) : NULL,
2235 !NILP (mustmatch), !NILP (dir_only_p),
2236 FRAME_HAIKU_WINDOW (f),
2237 !NILP (save_text) ? SSDATA (ENCODE_UTF_8 (save_text)) : NULL,
2238 SSDATA (ENCODE_UTF_8 (prompt)),
2239 block_input, unblock_input);
2240
2241 unbind_to (idx, Qnil);
2242
2243 block_input ();
2244 BWindow_activate (FRAME_HAIKU_WINDOW (f));
2245 unblock_input ();
2246
2247 if (!fn)
2248 return Qnil;
2249
2250 Lisp_Object p = build_string_from_utf8 (fn);
2251 free (fn);
2252 return p;
2253 }
2254
2255 DEFUN ("haiku-put-resource", Fhaiku_put_resource, Shaiku_put_resource,
2256 2, 2, 0, doc: /* Place STRING by the key RESOURCE in the resource database.
2257 It can later be retrieved with `x-get-resource'. */)
2258 (Lisp_Object resource, Lisp_Object string)
2259 {
2260 CHECK_STRING (resource);
2261 if (!NILP (string))
2262 CHECK_STRING (string);
2263
2264 put_xrm_resource (resource, string);
2265 return Qnil;
2266 }
2267
2268 DEFUN ("haiku-frame-list-z-order", Fhaiku_frame_list_z_order,
2269 Shaiku_frame_list_z_order, 0, 1, 0,
2270 doc: /* Return list of Emacs' frames, in Z (stacking) order.
2271 If TERMINAL is non-nil and specifies a live frame, return the child
2272 frames of that frame in Z (stacking) order.
2273
2274 As it is impossible to reliably determine the frame stacking order on
2275 Haiku, the selected frame is always the first element of the returned
2276 list, while the rest are not guaranteed to be in any particular order.
2277
2278 Frames are listed from topmost (first) to bottommost (last). */)
2279 (Lisp_Object terminal)
2280 {
2281 Lisp_Object frames = Qnil;
2282 Lisp_Object head, tail;
2283 Lisp_Object sel = Qnil;
2284
FOR_EACH_FRAME(head,tail)2285 FOR_EACH_FRAME (head, tail)
2286 {
2287 struct frame *f = XFRAME (tail);
2288 if (!FRAME_HAIKU_P (f) ||
2289 (FRAMEP (terminal) &&
2290 FRAME_LIVE_P (XFRAME (terminal)) &&
2291 !EQ (terminal, get_frame_param (f, Qparent_frame))))
2292 continue;
2293
2294 if (EQ (tail, selected_frame))
2295 sel = tail;
2296 else
2297 frames = Fcons (tail, frames);
2298 }
2299
2300 if (NILP (sel))
2301 return frames;
2302 return Fcons (sel, frames);
2303 }
2304
2305 DEFUN ("x-display-save-under", Fx_display_save_under,
2306 Sx_display_save_under, 0, 1, 0,
2307 doc: /* SKIP: real doc in xfns.c. */)
2308 (Lisp_Object terminal)
2309 {
2310 check_haiku_display_info (terminal);
2311
2312 if (FRAMEP (terminal))
2313 {
2314 struct frame *f = decode_window_system_frame (terminal);
2315 return FRAME_HAIKU_VIEW (f) && EmacsView_double_buffered_p (FRAME_HAIKU_VIEW (f)) ?
2316 Qt : Qnil;
2317 }
2318
2319 return Qnil;
2320 }
2321
2322 frame_parm_handler haiku_frame_parm_handlers[] =
2323 {
2324 gui_set_autoraise,
2325 gui_set_autolower,
2326 haiku_set_background_color,
2327 NULL, /* x_set_border_color */
2328 gui_set_border_width,
2329 haiku_set_cursor_color,
2330 haiku_set_cursor_type,
2331 gui_set_font,
2332 haiku_set_foreground_color,
2333 NULL, /* set icon name */
2334 NULL, /* set icon type */
2335 haiku_set_child_frame_border_width,
2336 haiku_set_internal_border_width,
2337 gui_set_right_divider_width,
2338 gui_set_bottom_divider_width,
2339 haiku_set_menu_bar_lines,
2340 NULL, /* set mouse color */
2341 haiku_explicitly_set_name,
2342 gui_set_scroll_bar_width,
2343 gui_set_scroll_bar_height,
2344 haiku_set_title,
2345 gui_set_unsplittable,
2346 gui_set_vertical_scroll_bars,
2347 gui_set_horizontal_scroll_bars,
2348 gui_set_visibility,
2349 haiku_set_tab_bar_lines,
2350 haiku_set_tool_bar_lines,
2351 NULL, /* set scroll bar fg */
2352 NULL, /* set scroll bar bkg */
2353 gui_set_screen_gamma,
2354 gui_set_line_spacing,
2355 gui_set_left_fringe,
2356 gui_set_right_fringe,
2357 NULL, /* x wait for wm */
2358 gui_set_fullscreen,
2359 gui_set_font_backend,
2360 gui_set_alpha,
2361 NULL, /* set sticky */
2362 NULL, /* set tool bar pos */
2363 haiku_set_inhibit_double_buffering,
2364 haiku_set_undecorated,
2365 haiku_set_parent_frame,
2366 NULL, /* set skip taskbar */
2367 haiku_set_no_focus_on_map,
2368 haiku_set_no_accept_focus,
2369 NULL, /* set z group */
2370 NULL, /* set override redir */
2371 gui_set_no_special_glyphs
2372 };
2373
2374 void
syms_of_haikufns(void)2375 syms_of_haikufns (void)
2376 {
2377 DEFSYM (Qfont_parameter, "font-parameter");
2378 DEFSYM (Qcancel_timer, "cancel-timer");
2379 DEFSYM (Qassq_delete_all, "assq-delete-all");
2380
2381 DEFSYM (Qalways, "always");
2382 DEFSYM (Qnot_useful, "not-useful");
2383 DEFSYM (Qwhen_mapped, "when-mapped");
2384
2385 defsubr (&Sx_hide_tip);
2386 defsubr (&Sxw_display_color_p);
2387 defsubr (&Sx_display_grayscale_p);
2388 defsubr (&Sx_open_connection);
2389 defsubr (&Sx_create_frame);
2390 defsubr (&Sx_display_pixel_width);
2391 defsubr (&Sx_display_pixel_height);
2392 defsubr (&Sxw_color_values);
2393 defsubr (&Sxw_color_defined_p);
2394 defsubr (&Sx_display_visual_class);
2395 defsubr (&Sx_show_tip);
2396 defsubr (&Sx_display_mm_height);
2397 defsubr (&Sx_display_mm_width);
2398 defsubr (&Sx_close_connection);
2399 defsubr (&Sx_display_list);
2400 defsubr (&Sx_server_vendor);
2401 defsubr (&Sx_server_version);
2402 defsubr (&Sx_display_screens);
2403 defsubr (&Shaiku_get_version_string);
2404 defsubr (&Sx_display_color_cells);
2405 defsubr (&Sx_display_planes);
2406 defsubr (&Shaiku_set_mouse_absolute_pixel_position);
2407 defsubr (&Shaiku_mouse_absolute_pixel_position);
2408 defsubr (&Shaiku_frame_geometry);
2409 defsubr (&Shaiku_frame_edges);
2410 defsubr (&Sx_double_buffered_p);
2411 defsubr (&Sx_display_backing_store);
2412 defsubr (&Shaiku_read_file_name);
2413 defsubr (&Shaiku_put_resource);
2414 defsubr (&Shaiku_frame_list_z_order);
2415 defsubr (&Sx_display_save_under);
2416
2417 tip_timer = Qnil;
2418 staticpro (&tip_timer);
2419 tip_frame = Qnil;
2420 staticpro (&tip_frame);
2421 tip_last_frame = Qnil;
2422 staticpro (&tip_last_frame);
2423 tip_last_string = Qnil;
2424 staticpro (&tip_last_string);
2425 tip_last_parms = Qnil;
2426 staticpro (&tip_last_parms);
2427
2428 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
2429 doc: /* SKIP: real doc in xfns.c. */);
2430 Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40));
2431
2432 DEFVAR_BOOL ("haiku-use-system-tooltips", haiku_use_system_tooltips,
2433 doc: /* When non-nil, Emacs will display tooltips using the App Kit.
2434 This can avoid a great deal of consing that does not play
2435 well with the Haiku memory allocator, but comes with the
2436 disadvantage of not being able to use special display properties
2437 within tooltips. */);
2438 haiku_use_system_tooltips = 1;
2439
2440 #ifdef USE_BE_CAIRO
2441 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
2442 doc: /* Version info for cairo. */);
2443 {
2444 char cairo_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
2445 int len = sprintf (cairo_version, "%d.%d.%d",
2446 CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
2447 CAIRO_VERSION_MICRO);
2448 Vcairo_version_string = make_pure_string (cairo_version, len, len, false);
2449 }
2450 #endif
2451
2452 return;
2453 }
2454