This source file includes following definitions.
- get_keysym_name
- haiku_window_to_frame
- haiku_coords_from_parent
- haiku_toolkit_position
- haiku_delete_terminal
- haiku_get_string_resource
- haiku_update_size_hints
- haiku_clip_to_string
- haiku_clip_to_string_exactly
- haiku_flip_buffers
- haiku_frame_up_to_date
- haiku_buffer_flipping_unblocked_hook
- haiku_clear_frame_area
- haiku_clear_frame
- haiku_new_font
- haiku_valid_modifier_p
- haiku_add_modifier
- haiku_modifiers_to_emacs
- haiku_rehighlight
- haiku_frame_raise_lower
- haiku_mouse_or_wdesc_frame
- haiku_set_scroll_bar_thumb
- haiku_set_horizontal_scroll_bar_thumb
- haiku_scroll_bar_from_widget
- haiku_focus_frame
- haiku_new_focus_frame
- haiku_implicitly_set_name
- haiku_query_frame_background_color
- haiku_defined_color
- haiku_draw_box_rect
- haiku_calculate_relief_colors
- haiku_draw_relief_rect
- haiku_get_scale_factor
- haiku_draw_underwave
- haiku_draw_text_decoration
- haiku_draw_string_box
- haiku_draw_plain_background
- haiku_get_bitmap_rec
- haiku_update_bitmap_rec
- haiku_draw_stipple_background
- haiku_draw_background_rect
- haiku_maybe_draw_background
- haiku_mouse_face_colors
- haiku_draw_glyph_string_foreground
- haiku_draw_glyphless_glyph_string_foreground
- haiku_draw_stretch_glyph_string
- haiku_start_clip
- haiku_end_clip
- haiku_clip_to_row
- haiku_update_begin
- haiku_update_end
- haiku_draw_composite_glyph_string_foreground
- haiku_draw_image_relief
- haiku_translate_transform
- haiku_draw_image_glyph_string
- haiku_draw_glyph_string
- haiku_after_update_window_line
- haiku_set_window_size
- haiku_draw_hollow_cursor
- haiku_draw_bar_cursor
- haiku_draw_window_cursor
- haiku_show_hourglass
- haiku_hide_hourglass
- haiku_compute_glyph_string_overhangs
- haiku_draw_vertical_window_border
- haiku_set_scroll_bar_default_width
- haiku_set_scroll_bar_default_height
- haiku_draw_window_divider
- haiku_condemn_scroll_bars
- haiku_redeem_scroll_bar
- haiku_judge_scroll_bars
- haiku_scroll_bar_create
- haiku_set_horizontal_scroll_bar
- haiku_set_vertical_scroll_bar
- haiku_draw_fringe_bitmap
- haiku_define_fringe_bitmap
- haiku_destroy_fringe_bitmap
- haiku_scroll_run
- haiku_mouse_position
- haiku_flush
- haiku_define_frame_cursor
- haiku_default_font_parameter
- haiku_make_fullscreen_consistent
- haiku_flush_dirty_back_buffer_on
- haiku_wait_for_event
- haiku_read_socket
- haiku_get_focus_frame
- haiku_frame_rehighlight
- haiku_delete_window
- haiku_free_pixmap
- haiku_flash
- haiku_beep
- haiku_toggle_invisible_pointer
- haiku_fullscreen
- haiku_create_terminal
- haiku_term_init
- put_xrm_resource
- haiku_clear_under_internal_border
- mark_haiku_display
- haiku_scroll_bar_remove
- haiku_set_offset
- haiku_begin_cr_clip
- haiku_end_cr_clip
- haiku_merge_cursor_foreground
- syms_of_haikuterm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21 #include "dispextern.h"
22 #include "frame.h"
23 #include "lisp.h"
24 #include "haikugui.h"
25 #include "keyboard.h"
26 #include "haikuterm.h"
27 #include "blockinput.h"
28 #include "termchar.h"
29 #include "termhooks.h"
30 #include "menu.h"
31 #include "buffer.h"
32 #include "haiku_support.h"
33 #include "thread.h"
34 #include "window.h"
35 #include "haikuselect.h"
36
37 #include <math.h>
38 #include <stdlib.h>
39
40 #ifdef USE_BE_CAIRO
41 #include <cairo.h>
42 #endif
43
44
45 #define BE_SB_MAX 12000000
46
47
48 struct haiku_display_info *x_display_list;
49
50
51
52 static int up_to_date_count;
53
54
55 static void **fringe_bmps;
56
57
58 static int max_fringe_bmp;
59
60
61 static Lisp_Object rdb;
62
63
64
65 static bool any_help_event_p;
66
67 char *
68 get_keysym_name (int keysym)
69 {
70 static char value[16];
71 sprintf (value, "%d", keysym);
72 return value;
73 }
74
75 static struct frame *
76 haiku_window_to_frame (void *window)
77 {
78 Lisp_Object tail, tem;
79 struct frame *f;
80
81 FOR_EACH_FRAME (tail, tem)
82 {
83 f = XFRAME (tem);
84 if (!FRAME_HAIKU_P (f))
85 continue;
86
87 eassert (FRAME_DISPLAY_INFO (f) == x_display_list);
88
89 if (FRAME_HAIKU_WINDOW (f) == window)
90 return f;
91 }
92
93 return 0;
94 }
95
96 static void
97 haiku_coords_from_parent (struct frame *f, int *x, int *y)
98 {
99 struct frame *p = FRAME_PARENT_FRAME (f);
100
101 *x -= FRAME_OUTPUT_DATA (p)->frame_x;
102 *y -= FRAME_OUTPUT_DATA (p)->frame_y;
103 }
104
105 static void
106 haiku_toolkit_position (struct frame *f, int x, int y,
107 bool *menu_bar_p, bool *tool_bar_p)
108 {
109 if (FRAME_OUTPUT_DATA (f)->menubar)
110 *menu_bar_p = (x >= 0 && x < FRAME_PIXEL_WIDTH (f)
111 && y >= 0 && y < FRAME_MENU_BAR_HEIGHT (f));
112 }
113
114 static void
115 haiku_delete_terminal (struct terminal *terminal)
116 {
117 error ("The Haiku terminal cannot be deleted");
118 }
119
120 static const char *
121 haiku_get_string_resource (void *ignored, const char *name,
122 const char *class)
123 {
124 const char *native;
125
126 if (!name)
127 return NULL;
128
129 Lisp_Object lval = assoc_no_quit (build_string (name), rdb);
130
131 if (!NILP (lval))
132 return SSDATA (XCDR (lval));
133
134 if ((native = be_find_setting (name)))
135 return native;
136
137 return NULL;
138 }
139
140 static void
141 haiku_update_size_hints (struct frame *f)
142 {
143 if (f->tooltip)
144 return;
145
146 block_input ();
147 BWindow_set_size_alignment (FRAME_HAIKU_WINDOW (f),
148 (frame_resize_pixelwise
149 ? 1 : FRAME_COLUMN_WIDTH (f)),
150 (frame_resize_pixelwise
151 ? 1 : FRAME_LINE_HEIGHT (f)));
152 unblock_input ();
153 }
154
155 static void
156 haiku_clip_to_string (struct glyph_string *s)
157 {
158 struct haiku_rect r[2];
159 int n = get_glyph_string_clip_rects (s, (struct haiku_rect *) &r, 2);
160
161 if (n)
162 {
163
164
165 if (r[0].width <= 0)
166 BView_ClipToRect (FRAME_HAIKU_DRAWABLE (s->f),
167 FRAME_PIXEL_WIDTH (s->f),
168 FRAME_PIXEL_HEIGHT (s->f),
169 10, 10);
170 else
171 {
172 BView_ClipToRect (FRAME_HAIKU_DRAWABLE (s->f), r[0].x,
173 r[0].y, r[0].width, r[0].height);
174 BView_invalidate_region (FRAME_HAIKU_DRAWABLE (s->f), r[0].x,
175 r[0].y, r[0].width, r[0].height);
176 }
177 }
178
179 if (n > 1)
180 {
181
182
183 if (r[1].width <= 0)
184 BView_ClipToRect (FRAME_HAIKU_DRAWABLE (s->f),
185 FRAME_PIXEL_WIDTH (s->f),
186 FRAME_PIXEL_HEIGHT (s->f),
187 10, 10);
188 else
189 {
190 BView_ClipToRect (FRAME_HAIKU_DRAWABLE (s->f), r[1].x, r[1].y,
191 r[1].width, r[1].height);
192 BView_invalidate_region (FRAME_HAIKU_DRAWABLE (s->f), r[1].x,
193 r[1].y, r[1].width, r[1].height);
194 }
195 }
196 }
197
198 static void
199 haiku_clip_to_string_exactly (struct glyph_string *s, struct glyph_string *dst)
200 {
201 BView_ClipToRect (FRAME_HAIKU_DRAWABLE (s->f), s->x, s->y,
202 s->width, s->height);
203 BView_invalidate_region (FRAME_HAIKU_DRAWABLE (s->f), s->x,
204 s->y, s->width, s->height);
205 }
206
207 static void
208 haiku_flip_buffers (struct frame *f)
209 {
210 void *view = FRAME_OUTPUT_DATA (f)->view;
211 block_input ();
212
213 BView_draw_lock (view, false, 0, 0, 0, 0);
214 FRAME_DIRTY_P (f) = 0;
215 EmacsView_flip_and_blit (view);
216 BView_draw_unlock (view);
217
218 unblock_input ();
219 }
220
221 static void
222 haiku_frame_up_to_date (struct frame *f)
223 {
224 block_input ();
225 FRAME_MOUSE_UPDATE (f);
226 if (FRAME_DIRTY_P (f) && !buffer_flipping_blocked_p ())
227 haiku_flip_buffers (f);
228
229 up_to_date_count++;
230 if (up_to_date_count == 50)
231 {
232 be_evict_font_cache ();
233 up_to_date_count = 0;
234 }
235
236
237 FRAME_COMPLETE_P (f) = true;
238 unblock_input ();
239 }
240
241 static void
242 haiku_buffer_flipping_unblocked_hook (struct frame *f)
243 {
244 if (FRAME_DIRTY_P (f))
245 haiku_flip_buffers (f);
246 }
247
248 static void
249 haiku_clear_frame_area (struct frame *f, int x, int y,
250 int width, int height)
251 {
252 void *vw = FRAME_HAIKU_DRAWABLE (f);
253 block_input ();
254 BView_draw_lock (vw, true, x, y, width, height);
255 BView_StartClip (vw);
256 BView_ClipToRect (vw, x, y, width, height);
257 BView_SetHighColor (vw, FRAME_BACKGROUND_PIXEL (f));
258 BView_FillRectangle (vw, x, y, width, height);
259 BView_EndClip (vw);
260 BView_draw_unlock (vw);
261 unblock_input ();
262 }
263
264 static void
265 haiku_clear_frame (struct frame *f)
266 {
267 void *view = FRAME_HAIKU_DRAWABLE (f);
268
269 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
270
271 FRAME_COMPLETE_P (f) = false;
272
273 block_input ();
274 BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f),
275 FRAME_PIXEL_HEIGHT (f));
276 BView_StartClip (view);
277 BView_ClipToRect (view, 0, 0, FRAME_PIXEL_WIDTH (f),
278 FRAME_PIXEL_HEIGHT (f));
279 BView_SetHighColor (view, FRAME_BACKGROUND_PIXEL (f));
280 BView_FillRectangle (view, 0, 0, FRAME_PIXEL_WIDTH (f) ,
281 FRAME_PIXEL_HEIGHT (f));
282 BView_EndClip (view);
283 BView_draw_unlock (view);
284 unblock_input ();
285 }
286
287
288
289
290
291
292 static Lisp_Object
293 haiku_new_font (struct frame *f, Lisp_Object font_object, int fontset)
294 {
295 struct font *font;
296 int ascent, descent, unit;
297
298 font = XFONT_OBJECT (font_object);
299
300 if (fontset < 0)
301 fontset = fontset_from_font (font_object);
302
303 FRAME_FONTSET (f) = fontset;
304
305 if (FRAME_FONT (f) == font)
306 return font_object;
307
308 FRAME_FONT (f) = font;
309 FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
310 FRAME_COLUMN_WIDTH (f) = font->average_width;
311
312 get_font_ascent_descent (font, &ascent, &descent);
313 FRAME_LINE_HEIGHT (f) = ascent + descent;
314 FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
315
316 unit = FRAME_COLUMN_WIDTH (f);
317 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
318 FRAME_CONFIG_SCROLL_BAR_COLS (f)
319 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
320 else
321 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
322
323 if (FRAME_HAIKU_WINDOW (f) && !FRAME_TOOLTIP_P (f))
324 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
325 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f),
326 3, false, Qfont);
327
328 return font_object;
329 }
330
331 static int
332 haiku_valid_modifier_p (Lisp_Object sym)
333 {
334 return EQ (sym, Qcommand) || EQ (sym, Qshift)
335 || EQ (sym, Qcontrol) || EQ (sym, Qoption);
336 }
337
338 #define MODIFIER_OR(obj, def) (haiku_valid_modifier_p (obj) ? obj : def)
339
340 static void
341 haiku_add_modifier (int modifier, int toput, Lisp_Object qtem, int *modifiers)
342 {
343 if ((modifier & HAIKU_MODIFIER_ALT && EQ (qtem, Qcommand))
344 || (modifier & HAIKU_MODIFIER_SHIFT && EQ (qtem, Qshift))
345 || (modifier & HAIKU_MODIFIER_CTRL && EQ (qtem, Qcontrol))
346 || (modifier & HAIKU_MODIFIER_SUPER && EQ (qtem, Qoption)))
347 *modifiers |= toput;
348 }
349
350 static int
351 haiku_modifiers_to_emacs (int haiku_key)
352 {
353 int modifiers = 0;
354 haiku_add_modifier (haiku_key, shift_modifier,
355 MODIFIER_OR (Vhaiku_shift_keysym, Qshift), &modifiers);
356 haiku_add_modifier (haiku_key, super_modifier,
357 MODIFIER_OR (Vhaiku_super_keysym, Qoption), &modifiers);
358 haiku_add_modifier (haiku_key, meta_modifier,
359 MODIFIER_OR (Vhaiku_meta_keysym, Qcommand), &modifiers);
360 haiku_add_modifier (haiku_key, ctrl_modifier,
361 MODIFIER_OR (Vhaiku_control_keysym, Qcontrol), &modifiers);
362 return modifiers;
363 }
364
365 #undef MODIFIER_OR
366
367 static void
368 haiku_rehighlight (void)
369 {
370 eassert (x_display_list && !x_display_list->next);
371
372 block_input ();
373
374 struct frame *old_hl = x_display_list->highlight_frame;
375
376 if (x_display_list->focused_frame)
377 {
378 x_display_list->highlight_frame
379 = ((FRAMEP (FRAME_FOCUS_FRAME (x_display_list->focused_frame)))
380 ? XFRAME (FRAME_FOCUS_FRAME (x_display_list->focused_frame))
381 : x_display_list->focused_frame);
382 if (!FRAME_LIVE_P (x_display_list->highlight_frame))
383 {
384 fset_focus_frame (x_display_list->focused_frame, Qnil);
385 x_display_list->highlight_frame = x_display_list->focused_frame;
386 }
387 }
388 else
389 x_display_list->highlight_frame = 0;
390
391 if (old_hl)
392 gui_update_cursor (old_hl, true);
393
394 if (x_display_list->highlight_frame)
395 gui_update_cursor (x_display_list->highlight_frame, true);
396 unblock_input ();
397 }
398
399 static void
400 haiku_frame_raise_lower (struct frame *f, bool raise_p)
401 {
402 if (raise_p)
403 {
404 block_input ();
405 BWindow_activate (FRAME_HAIKU_WINDOW (f));
406 BWindow_sync (FRAME_HAIKU_WINDOW (f));
407 unblock_input ();
408 }
409 else
410 {
411 block_input ();
412 BWindow_send_behind (FRAME_HAIKU_WINDOW (f), NULL);
413 BWindow_sync (FRAME_HAIKU_WINDOW (f));
414 unblock_input ();
415 }
416 }
417
418 static struct frame *
419 haiku_mouse_or_wdesc_frame (void *window, bool accept_tooltip)
420 {
421 struct frame *lm_f = (gui_mouse_grabbed (x_display_list)
422 ? x_display_list->last_mouse_frame
423 : NULL);
424
425 if (lm_f && !EQ (track_mouse, Qdropping)
426 && !EQ (track_mouse, Qdrag_source))
427 return lm_f;
428 else
429 {
430 struct frame *w_f = haiku_window_to_frame (window);
431
432
433 if (!w_f || (FRAME_TOOLTIP_P (w_f) && !accept_tooltip))
434 return EQ (track_mouse, Qdropping) ? lm_f : NULL;
435 else
436
437
438 return w_f;
439 }
440 }
441
442
443
444
445
446 static void
447 haiku_set_scroll_bar_thumb (struct scroll_bar *bar, int portion,
448 int position, int whole)
449 {
450 void *scroll_bar = bar->scroll_bar;
451 double top, shown, size, value;
452
453 if (scroll_bar_adjust_thumb_portion_p)
454 {
455
456
457
458
459
460
461
462 portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30;
463
464
465 whole += portion;
466 }
467 else
468 bar->page_size = 0;
469
470 if (whole <= 0)
471 top = 0, shown = 1;
472 else
473 {
474 top = (double) position / whole;
475 shown = (double) portion / whole;
476 }
477
478
479
480
481 size = clip_to_bounds (1, shown * BE_SB_MAX, BE_SB_MAX);
482
483
484 value = top * BE_SB_MAX;
485 value = min (value, BE_SB_MAX - size);
486
487 if (!bar->dragging && scroll_bar_adjust_thumb_portion_p)
488 bar->page_size = size;
489
490 BView_scroll_bar_update (scroll_bar, lrint (size),
491 BE_SB_MAX, ceil (value),
492 (scroll_bar_adjust_thumb_portion_p
493 ? bar->dragging : bar->dragging ? -1 : 0),
494 !scroll_bar_adjust_thumb_portion_p);
495 }
496
497 static void
498 haiku_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion,
499 int position, int whole)
500 {
501 void *scroll_bar = bar->scroll_bar;
502 double size, value, shown, top;
503
504 shown = (double) portion / whole;
505 top = (double) position / whole;
506
507 size = shown * BE_SB_MAX;
508 value = top * BE_SB_MAX;
509
510 if (!bar->dragging)
511 bar->page_size = size;
512
513 BView_scroll_bar_update (scroll_bar, lrint (size), BE_SB_MAX,
514 ceil (value), bar->dragging ? -1 : 0, true);
515 }
516
517 static struct scroll_bar *
518 haiku_scroll_bar_from_widget (void *scroll_bar, void *window)
519 {
520 Lisp_Object tem;
521 struct frame *frame = haiku_window_to_frame (window);
522
523 if (!frame)
524 return NULL;
525
526 if (!scroll_bar)
527 return NULL;
528
529 if (!NILP (FRAME_SCROLL_BARS (frame)))
530 {
531 for (tem = FRAME_SCROLL_BARS (frame); !NILP (tem);
532 tem = XSCROLL_BAR (tem)->next)
533 {
534 if (XSCROLL_BAR (tem)->scroll_bar == scroll_bar)
535 return XSCROLL_BAR (tem);
536 }
537 }
538
539 return NULL;
540 }
541
542
543 static void
544 haiku_focus_frame (struct frame *frame, bool noactivate)
545 {
546 if (x_display_list->focused_frame != frame)
547 haiku_frame_raise_lower (frame, 1);
548 }
549
550 static void
551 haiku_new_focus_frame (struct frame *frame)
552 {
553 eassert (x_display_list && !x_display_list->next);
554
555 block_input ();
556 if (frame != x_display_list->focused_frame)
557 {
558 if (x_display_list->focused_frame &&
559 x_display_list->focused_frame->auto_lower)
560 haiku_frame_raise_lower (x_display_list->focused_frame, 0);
561
562 x_display_list->focused_frame = frame;
563
564 if (frame && frame->auto_raise && !popup_activated_p)
565 haiku_frame_raise_lower (frame, 1);
566 }
567 unblock_input ();
568
569 haiku_rehighlight ();
570 }
571
572 static void
573 haiku_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
574 {
575 haiku_set_name (f, arg, 0);
576 }
577
578 static void
579 haiku_query_frame_background_color (struct frame *f, Emacs_Color *bgcolor)
580 {
581 haiku_query_color (FRAME_BACKGROUND_PIXEL (f), bgcolor);
582 }
583
584 static bool
585 haiku_defined_color (struct frame *f, const char *name,
586 Emacs_Color *color, bool alloc, bool make_index)
587 {
588 int rc;
589
590 rc = !haiku_get_color (name, color);
591
592 if (rc && f->gamma && alloc)
593 gamma_correct (f, color);
594
595 return rc;
596 }
597
598
599 static void
600 haiku_draw_box_rect (struct glyph_string *s, int left_x, int top_y,
601 int right_x, int bottom_y, int hwidth, int vwidth,
602 bool left_p, bool right_p, struct haiku_rect *clip_rect)
603 {
604 void *view = FRAME_HAIKU_DRAWABLE (s->f);
605 struct face *face = s->face;
606
607 BView_SetHighColor (view, face->box_color);
608 if (clip_rect)
609 BView_ClipToRect (view, clip_rect->x, clip_rect->y, clip_rect->width,
610 clip_rect->height);
611 BView_FillRectangle (view, left_x, top_y, right_x - left_x + 1, hwidth);
612 if (left_p)
613 BView_FillRectangle (view, left_x, top_y, vwidth, bottom_y - top_y + 1);
614
615 BView_FillRectangle (view, left_x, bottom_y - hwidth + 1,
616 right_x - left_x + 1, hwidth);
617 if (right_p)
618 BView_FillRectangle (view, right_x - vwidth + 1,
619 top_y, vwidth, bottom_y - top_y + 1);
620 }
621
622 static void
623 haiku_calculate_relief_colors (struct glyph_string *s, uint32_t *rgbout_w,
624 uint32_t *rgbout_b)
625 {
626 double h, cs, l;
627 uint32_t rgbin;
628 struct haiku_output *di;
629
630 if (s->face->use_box_color_for_shadows_p)
631 rgbin = s->face->box_color;
632 else if (s->first_glyph->type == IMAGE_GLYPH
633 && s->img->pixmap
634 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
635 rgbin = IMAGE_BACKGROUND (s->img, s->f, 0);
636 else
637 rgbin = s->face->background;
638
639 di = FRAME_OUTPUT_DATA (s->f);
640
641 if (s->hl == DRAW_CURSOR)
642 rgbin = FRAME_CURSOR_COLOR (s->f).pixel;
643
644 if (di->relief_background != rgbin)
645 {
646 di->relief_background = rgbin & 0xffffffff;
647
648 rgb_color_hsl (rgbin, &h, &cs, &l);
649 hsl_color_rgb (h, cs, fmin (1.0, fmax (0.2, l) * 0.6),
650 &di->black_relief_pixel);
651 hsl_color_rgb (h, cs, fmin (1.0, fmax (0.2, l) * 1.2),
652 &di->white_relief_pixel);
653 }
654
655 *rgbout_w = di->white_relief_pixel;
656 *rgbout_b = di->black_relief_pixel;
657 }
658
659 static void
660 haiku_draw_relief_rect (struct glyph_string *s, int left_x, int top_y,
661 int right_x, int bottom_y, int hwidth, int vwidth,
662 bool raised_p, bool top_p, bool bot_p, bool left_p,
663 bool right_p, struct haiku_rect *clip_rect)
664 {
665 uint32_t color_white, color_black;
666 void *view;
667
668 view = FRAME_HAIKU_DRAWABLE (s->f);
669 haiku_calculate_relief_colors (s, &color_white, &color_black);
670
671 BView_SetHighColor (view, raised_p ? color_white : color_black);
672
673 if (clip_rect)
674 {
675 BView_StartClip (view);
676 haiku_clip_to_string (s);
677 BView_ClipToRect (view, clip_rect->x, clip_rect->y,
678 clip_rect->width, clip_rect->height);
679 }
680
681 if (top_p)
682 BView_FillRectangle (view, left_x, top_y,
683 right_x - left_x + 1, hwidth);
684
685 if (left_p)
686 BView_FillRectangle (view, left_x, top_y,
687 vwidth, bottom_y - top_y + 1);
688
689 BView_SetHighColor (view, !raised_p ? color_white : color_black);
690
691 if (bot_p)
692 BView_FillRectangle (view, left_x, bottom_y - hwidth + 1,
693 right_x - left_x + 1, hwidth);
694 if (right_p)
695 BView_FillRectangle (view, right_x - vwidth + 1, top_y,
696 vwidth, bottom_y - top_y + 1);
697
698
699 if (bot_p && left_p)
700 {
701 BView_SetHighColor (view, raised_p ? color_white : color_black);
702 BView_FillTriangle (view, left_x, bottom_y - hwidth, left_x + vwidth,
703 bottom_y - hwidth, left_x, bottom_y);
704 }
705
706
707 if (top_p && right_p)
708 {
709 BView_SetHighColor (view, raised_p ? color_white : color_black);
710 BView_FillTriangle (view, right_x - vwidth, top_y,
711 right_x, top_y,
712 right_x - vwidth, top_y + hwidth);
713 }
714
715
716
717
718 BView_SetHighColor (view, color_black);
719
720 if (hwidth > 1 && top_p)
721 BView_StrokeLine (view, left_x, top_y, right_x, top_y);
722 if (hwidth > 1 && bot_p)
723 BView_StrokeLine (view, left_x, bottom_y, right_x, bottom_y);
724 if (vwidth > 1 && left_p)
725 BView_StrokeLine (view, left_x, top_y, left_x, bottom_y);
726 if (vwidth > 1 && right_p)
727 BView_StrokeLine (view, right_x, top_y, right_x, bottom_y);
728
729 BView_SetHighColor (view, FRAME_BACKGROUND_PIXEL (s->f));
730
731
732 if (hwidth > 1 && vwidth > 1)
733 {
734 if (left_p && top_p)
735 BView_FillRectangle (view, left_x, top_y, 1, 1);
736 if (left_p && bot_p)
737 BView_FillRectangle (view, left_x, bottom_y, 1, 1);
738 if (right_p && top_p)
739 BView_FillRectangle (view, right_x, top_y, 1, 1);
740 if (right_p && bot_p)
741 BView_FillRectangle (view, right_x, bottom_y, 1, 1);
742 }
743
744 if (clip_rect)
745 BView_EndClip (view);
746 }
747
748 static void
749 haiku_get_scale_factor (int *scale_x, int *scale_y)
750 {
751 struct haiku_display_info *dpyinfo = x_display_list;
752
753 if (dpyinfo->resx > 96)
754 *scale_x = floor (dpyinfo->resx / 96);
755 if (dpyinfo->resy > 96)
756 *scale_y = floor (dpyinfo->resy / 96);
757 }
758
759 static void
760 haiku_draw_underwave (struct glyph_string *s, int width, int x)
761 {
762 int wave_height, wave_length;
763 int y, dx, dy, odd, xmax, scale_x, scale_y;
764 float ax, ay, bx, by;
765 void *view;
766
767 scale_x = 1;
768 scale_y = 1;
769 haiku_get_scale_factor (&scale_x, &scale_y);
770 wave_height = 3 * scale_y;
771 wave_length = 2 * scale_x;
772
773 dx = wave_length;
774 dy = wave_height - 1;
775 y = s->ybase - wave_height + 3;
776 xmax = x + width;
777 view = FRAME_HAIKU_DRAWABLE (s->f);
778
779 BView_StartClip (view);
780 haiku_clip_to_string (s);
781 BView_ClipToRect (view, x, y, width, wave_height);
782
783 ax = x - ((int) (x) % dx) + (float) 0.5;
784 bx = ax + dx;
785 odd = (int) (ax / dx) % 2;
786 ay = by = y + 0.5;
787
788 if (odd)
789 ay += dy;
790 else
791 by += dy;
792
793 BView_SetPenSize (view, scale_y);
794
795 while (ax <= xmax)
796 {
797 BView_StrokeLine (view, ax, ay, bx, by);
798 ax = bx, ay = by;
799 bx += dx, by = y + 0.5 + odd * dy;
800 odd = !odd;
801 }
802
803 BView_SetPenSize (view, 1);
804 BView_EndClip (view);
805 }
806
807 static void
808 haiku_draw_text_decoration (struct glyph_string *s, struct face *face,
809 int width, int x)
810 {
811 unsigned long cursor_color;
812
813 if (s->for_overlaps)
814 return;
815
816 if (s->hl == DRAW_CURSOR)
817 haiku_merge_cursor_foreground (s, &cursor_color, NULL);
818
819 void *view = FRAME_HAIKU_DRAWABLE (s->f);
820
821 if (face->underline)
822 {
823 if (s->hl == DRAW_CURSOR)
824 BView_SetHighColor (view, cursor_color);
825 else if (!face->underline_defaulted_p)
826 BView_SetHighColor (view, face->underline_color);
827 else
828 BView_SetHighColor (view, face->foreground);
829
830 if (face->underline == FACE_UNDER_WAVE)
831 haiku_draw_underwave (s, width, x);
832 else if (face->underline == FACE_UNDER_LINE)
833 {
834 unsigned long thickness, position;
835 int y;
836
837 if (s->prev
838 && s->prev->face->underline == FACE_UNDER_LINE
839 && (s->prev->face->underline_at_descent_line_p
840 == s->face->underline_at_descent_line_p)
841 && (s->prev->face->underline_pixels_above_descent_line
842 == s->face->underline_pixels_above_descent_line))
843 {
844
845 thickness = s->prev->underline_thickness;
846 position = s->prev->underline_position;
847 }
848 else
849 {
850 struct font *font = font_for_underline_metrics (s);
851 unsigned long minimum_offset;
852 bool underline_at_descent_line;
853 bool use_underline_position_properties;
854 Lisp_Object val = (WINDOW_BUFFER_LOCAL_VALUE
855 (Qunderline_minimum_offset, s->w));
856
857 if (FIXNUMP (val))
858 minimum_offset = max (0, XFIXNUM (val));
859 else
860 minimum_offset = 1;
861
862 val = (WINDOW_BUFFER_LOCAL_VALUE
863 (Qx_underline_at_descent_line, s->w));
864 underline_at_descent_line
865 = (!(NILP (val) || BASE_EQ (val, Qunbound))
866 || s->face->underline_at_descent_line_p);
867
868 val = (WINDOW_BUFFER_LOCAL_VALUE
869 (Qx_use_underline_position_properties, s->w));
870 use_underline_position_properties
871 = !(NILP (val) || BASE_EQ (val, Qunbound));
872
873
874 if (font && font->underline_thickness > 0)
875 thickness = font->underline_thickness;
876 else
877 thickness = 1;
878 if (underline_at_descent_line)
879 position = ((s->height - thickness)
880 - (s->ybase - s->y)
881 - s->face->underline_pixels_above_descent_line);
882 else
883 {
884
885
886
887
888
889
890
891
892
893 if (use_underline_position_properties
894 && font && font->underline_position >= 0)
895 position = font->underline_position;
896 else if (font)
897 position = (font->descent + 1) / 2;
898 else
899 position = minimum_offset;
900 }
901 position = max (position, minimum_offset);
902 }
903
904
905 if (s->y + s->height <= s->ybase + position)
906 position = (s->height - 1) - (s->ybase - s->y);
907 if (s->y + s->height < s->ybase + position + thickness)
908 thickness = (s->y + s->height) - (s->ybase + position);
909 s->underline_thickness = thickness;
910 s->underline_position = position;
911 y = s->ybase + position;
912
913 BView_FillRectangle (view, s->x, y, s->width, thickness);
914 }
915 }
916
917 if (face->overline_p)
918 {
919 unsigned long dy = 0, h = 1;
920 if (s->hl == DRAW_CURSOR)
921 BView_SetHighColor (view, cursor_color);
922 else if (!face->overline_color_defaulted_p)
923 BView_SetHighColor (view, face->overline_color);
924 else
925 BView_SetHighColor (view, face->foreground);
926
927 BView_FillRectangle (view, s->x, s->y + dy, s->width, h);
928 }
929
930 if (face->strike_through_p)
931 {
932
933
934
935
936
937 int glyph_y = s->ybase - s->first_glyph->ascent;
938 int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
939
940
941 unsigned long h = 1;
942 unsigned long dy = (glyph_height - h) / 2;
943
944 if (s->hl == DRAW_CURSOR)
945 BView_SetHighColor (view, cursor_color);
946 else if (!face->strike_through_color_defaulted_p)
947 BView_SetHighColor (view, face->strike_through_color);
948 else
949 BView_SetHighColor (view, face->foreground);
950
951 BView_FillRectangle (view, s->x, glyph_y + dy, s->width, h);
952 }
953 }
954
955 static void
956 haiku_draw_string_box (struct glyph_string *s)
957 {
958 int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
959 bool raised_p, left_p, right_p;
960 struct glyph *last_glyph;
961 struct face *face = s->face;
962
963 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
964 ? WINDOW_RIGHT_EDGE_X (s->w)
965 : window_box_right (s->w, s->area));
966
967
968
969
970 if (s->cmp || s->img)
971 last_glyph = s->first_glyph;
972 else if (s->first_glyph->type == COMPOSITE_GLYPH
973 && s->first_glyph->u.cmp.automatic)
974 {
975
976
977 struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
978 struct glyph *g = s->first_glyph;
979 for (last_glyph = g++;
980 g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
981 && g->slice.cmp.to < s->cmp_to;
982 last_glyph = g++)
983 ;
984 }
985 else
986 last_glyph = s->first_glyph + s->nchars - 1;
987
988 vwidth = eabs (face->box_vertical_line_width);
989 hwidth = eabs (face->box_horizontal_line_width);
990 raised_p = face->box == FACE_RAISED_BOX;
991 left_x = s->x;
992 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
993 ? last_x - 1
994 : min (last_x, s->x + s->background_width) - 1);
995
996 top_y = s->y;
997 bottom_y = top_y + s->height - 1;
998
999 left_p = (s->first_glyph->left_box_line_p
1000 || (s->hl == DRAW_MOUSE_FACE
1001 && (s->prev == NULL
1002 || s->prev->hl != s->hl)));
1003 right_p = (last_glyph->right_box_line_p
1004 || (s->hl == DRAW_MOUSE_FACE
1005 && (s->next == NULL
1006 || s->next->hl != s->hl)));
1007
1008 if (face->box == FACE_SIMPLE_BOX)
1009 haiku_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
1010 vwidth, left_p, right_p, NULL);
1011 else
1012 haiku_draw_relief_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
1013 vwidth, raised_p, true, true, left_p, right_p,
1014 NULL);
1015 }
1016
1017 static void
1018 haiku_draw_plain_background (struct glyph_string *s, struct face *face,
1019 int x, int y, int width, int height)
1020 {
1021 void *view = FRAME_HAIKU_DRAWABLE (s->f);
1022 unsigned long cursor_color;
1023
1024 if (s->hl == DRAW_CURSOR)
1025 {
1026 haiku_merge_cursor_foreground (s, NULL, &cursor_color);
1027 BView_SetHighColor (view, cursor_color);
1028 }
1029 else
1030 BView_SetHighColor (view, face->background_defaulted_p ?
1031 FRAME_BACKGROUND_PIXEL (s->f) :
1032 face->background);
1033
1034 BView_FillRectangle (view, x, y, width, height);
1035 }
1036
1037 static struct haiku_bitmap_record *
1038 haiku_get_bitmap_rec (struct frame *f, ptrdiff_t id)
1039 {
1040 return &FRAME_DISPLAY_INFO (f)->bitmaps[id - 1];
1041 }
1042
1043 static void
1044 haiku_update_bitmap_rec (struct haiku_bitmap_record *rec,
1045 uint32_t new_foreground,
1046 uint32_t new_background)
1047 {
1048 char *bits;
1049 int x, y, bytes_per_line;
1050
1051 if (new_foreground == rec->stipple_foreground
1052 && new_background == rec->stipple_background)
1053 return;
1054
1055 bits = rec->stipple_bits;
1056 bytes_per_line = (rec->width + 7) / 8;
1057
1058 for (y = 0; y < rec->height; y++)
1059 {
1060 for (x = 0; x < rec->width; x++)
1061 haiku_put_pixel (rec->img, x, y,
1062 ((bits[x / 8] >> (x % 8)) & 1
1063 ? new_foreground : new_background));
1064
1065 bits += bytes_per_line;
1066 }
1067
1068 rec->stipple_foreground = new_foreground;
1069 rec->stipple_background = new_background;
1070 }
1071
1072 static void
1073 haiku_draw_stipple_background (struct glyph_string *s, struct face *face,
1074 int x, int y, int width, int height,
1075 bool explicit_colors_p,
1076 uint32 explicit_background,
1077 uint32 explicit_foreground)
1078 {
1079 struct haiku_bitmap_record *rec;
1080 unsigned long foreground, background;
1081 void *view;
1082
1083 view = FRAME_HAIKU_DRAWABLE (s->f);
1084 rec = haiku_get_bitmap_rec (s->f, s->face->stipple);
1085
1086 if (explicit_colors_p)
1087 {
1088 background = explicit_background;
1089 foreground = explicit_foreground;
1090 }
1091 else if (s->hl == DRAW_CURSOR)
1092 haiku_merge_cursor_foreground (s, &foreground, &background);
1093 else
1094 {
1095 foreground = s->face->foreground;
1096 background = s->face->background;
1097 }
1098
1099 haiku_update_bitmap_rec (rec, foreground, background);
1100
1101 BView_StartClip (view);
1102 haiku_clip_to_string (s);
1103 BView_ClipToRect (view, x, y, width, height);
1104 BView_DrawBitmapTiled (view, rec->img, 0, 0, -1, -1,
1105 0, 0, x + width, y + height);
1106 BView_EndClip (view);
1107 }
1108
1109 void
1110 haiku_draw_background_rect (struct glyph_string *s, struct face *face,
1111 int x, int y, int width, int height)
1112 {
1113 if (!s->stippled_p)
1114 haiku_draw_plain_background (s, face, x, y, width, height);
1115 else
1116 haiku_draw_stipple_background (s, face, x, y, width, height,
1117 false, 0, 0);
1118 }
1119
1120 static void
1121 haiku_maybe_draw_background (struct glyph_string *s, int force_p)
1122 {
1123 if ((s->first_glyph->type != IMAGE_GLYPH) && !s->background_filled_p)
1124 {
1125 struct face *face = s->face;
1126 int box_line_width = max (face->box_horizontal_line_width, 0);
1127 int box_vline_width = max (face->box_vertical_line_width, 0);
1128
1129 if (FONT_HEIGHT (s->font) < s->height - 2 * box_vline_width
1130 || FONT_TOO_HIGH (s->font)
1131 || s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
1132 {
1133 haiku_draw_background_rect (s, s->face, s->x, s->y + box_line_width,
1134 s->background_width,
1135 s->height - 2 * box_line_width);
1136
1137 s->background_filled_p = 1;
1138 }
1139 }
1140 }
1141
1142 static void
1143 haiku_mouse_face_colors (struct glyph_string *s, uint32_t *fg,
1144 uint32_t *bg)
1145 {
1146 int face_id;
1147 struct face *face;
1148
1149
1150 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1151 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1152 if (face == NULL)
1153 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1154
1155 if (s->first_glyph->type == CHAR_GLYPH)
1156 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1157 else
1158 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1159
1160 face = FACE_FROM_ID (s->f, face_id);
1161 prepare_face_for_display (s->f, s->face);
1162
1163 if (fg)
1164 *fg = face->foreground;
1165 if (bg)
1166 *bg = face->background;
1167 }
1168
1169 static void
1170 haiku_draw_glyph_string_foreground (struct glyph_string *s)
1171 {
1172 struct face *face = s->face;
1173
1174 int i, x;
1175 if (face->box != FACE_NO_BOX
1176 && s->first_glyph->left_box_line_p)
1177 x = s->x + max (face->box_vertical_line_width, 0);
1178 else
1179 x = s->x;
1180
1181 void *view = FRAME_HAIKU_DRAWABLE (s->f);
1182
1183 if (s->font_not_found_p)
1184 {
1185 if (s->hl == DRAW_CURSOR)
1186 BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
1187 else
1188 BView_SetHighColor (view, face->foreground);
1189 for (i = 0; i < s->nchars; ++i)
1190 {
1191 struct glyph *g = s->first_glyph + i;
1192
1193 BView_SetPenSize (view, 1);
1194 BView_StrokeRectangle (view, x, s->y, g->pixel_width,
1195 s->height);
1196 x += g->pixel_width;
1197 }
1198 }
1199 else
1200 {
1201 struct font *ft = s->font;
1202 int off = ft->baseline_offset;
1203 int y;
1204
1205 if (ft->vertical_centering)
1206 off = VCENTER_BASELINE_OFFSET (ft, s->f) - off;
1207 y = s->ybase - off;
1208 if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR))
1209 ft->driver->draw (s, 0, s->nchars, x, y, false);
1210 else
1211 ft->driver->draw (s, 0, s->nchars, x, y, true);
1212
1213 if (face->overstrike)
1214 ft->driver->draw (s, 0, s->nchars, x + 1, y, false);
1215 }
1216 }
1217
1218 static void
1219 haiku_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1220 {
1221 struct glyph *glyph = s->first_glyph;
1222 unsigned char2b[8];
1223 int x, i, j;
1224 struct face *face = s->face;
1225 unsigned long color;
1226
1227
1228
1229 if (face && face->box != FACE_NO_BOX
1230 && s->first_glyph->left_box_line_p)
1231 x = s->x + max (face->box_vertical_line_width, 0);
1232 else
1233 x = s->x;
1234
1235 s->char2b = char2b;
1236
1237 for (i = 0; i < s->nchars; i++, glyph++)
1238 {
1239 #ifdef GCC_LINT
1240 enum { PACIFY_GCC_BUG_81401 = 1 };
1241 #else
1242 enum { PACIFY_GCC_BUG_81401 = 0 };
1243 #endif
1244 char buf[7 + PACIFY_GCC_BUG_81401];
1245 char *str = NULL;
1246 int len = glyph->u.glyphless.len;
1247
1248 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1249 {
1250 if (len > 0
1251 && CHAR_TABLE_P (Vglyphless_char_display)
1252 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1253 >= 1))
1254 {
1255 Lisp_Object acronym
1256 = (! glyph->u.glyphless.for_no_font
1257 ? CHAR_TABLE_REF (Vglyphless_char_display,
1258 glyph->u.glyphless.ch)
1259 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
1260 if (CONSP (acronym))
1261 acronym = XCAR (acronym);
1262 if (STRINGP (acronym))
1263 str = SSDATA (acronym);
1264 }
1265 }
1266 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1267 {
1268 unsigned int ch = glyph->u.glyphless.ch;
1269 eassume (ch <= MAX_CHAR);
1270 sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
1271 str = buf;
1272 }
1273
1274 if (str)
1275 {
1276 int upper_len = (len + 1) / 2;
1277
1278
1279 for (j = 0; j < len; j++)
1280 char2b[j] = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
1281
1282 s->font->driver->draw (s, 0, upper_len,
1283 x + glyph->slice.glyphless.upper_xoff,
1284 s->ybase + glyph->slice.glyphless.upper_yoff,
1285 false);
1286 s->font->driver->draw (s, upper_len, len,
1287 x + glyph->slice.glyphless.lower_xoff,
1288 s->ybase + glyph->slice.glyphless.lower_yoff,
1289 false);
1290 }
1291
1292 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
1293 {
1294 if (s->hl == DRAW_CURSOR)
1295 haiku_merge_cursor_foreground (s, NULL, &color);
1296 else
1297 color = s->face->foreground;
1298
1299 BView_SetHighColor (FRAME_HAIKU_DRAWABLE (s->f), color);
1300 BView_SetPenSize (FRAME_HAIKU_DRAWABLE (s->f), 1);
1301 BView_StrokeRectangle (FRAME_HAIKU_DRAWABLE (s->f),
1302 x, s->ybase - glyph->ascent,
1303 glyph->pixel_width,
1304 glyph->ascent + glyph->descent);
1305 }
1306 x += glyph->pixel_width;
1307 }
1308 }
1309
1310 static void
1311 haiku_draw_stretch_glyph_string (struct glyph_string *s)
1312 {
1313 struct face *face = s->face;
1314 uint32_t bkg;
1315
1316 if (s->hl == DRAW_CURSOR && !x_stretch_cursor_p)
1317 {
1318 int width, background_width = s->background_width;
1319 int x = s->x;
1320
1321 if (!s->row->reversed_p)
1322 {
1323 int left_x = window_box_left_offset (s->w, TEXT_AREA);
1324
1325 if (x < left_x)
1326 {
1327 background_width -= left_x - x;
1328 x = left_x;
1329 }
1330 }
1331 else
1332 {
1333
1334
1335 int right_x = window_box_right (s->w, TEXT_AREA);
1336 if (x + background_width > right_x)
1337 background_width -= x - right_x;
1338 x += background_width;
1339 }
1340
1341 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
1342 if (s->row->reversed_p)
1343 x -= width;
1344
1345 void *view = FRAME_HAIKU_DRAWABLE (s->f);
1346 unsigned long cursor_color;
1347
1348 haiku_merge_cursor_foreground (s, NULL, &cursor_color);
1349 BView_SetHighColor (view, cursor_color);
1350 BView_FillRectangle (view, x, s->y, width, s->height);
1351
1352 if (width < background_width)
1353 {
1354 if (!s->row->reversed_p)
1355 x += width;
1356 else
1357 x = s->x;
1358
1359 int y = s->y;
1360 int w = background_width - width, h = s->height;
1361
1362
1363
1364
1365 if (!face->stipple)
1366 {
1367 if (s->row->mouse_face_p && cursor_in_mouse_face_p (s->w))
1368 haiku_mouse_face_colors (s, NULL, &bkg);
1369 else
1370 bkg = face->background;
1371
1372 BView_SetHighColor (view, bkg);
1373 BView_FillRectangle (view, x, y, w, h);
1374 }
1375 else
1376 {
1377 if (s->row->mouse_face_p && cursor_in_mouse_face_p (s->w))
1378 haiku_mouse_face_colors (s, NULL, &bkg);
1379 else
1380 bkg = face->background;
1381
1382 haiku_draw_stipple_background (s, s->face, x, y, w, h,
1383 true, bkg, face->foreground);
1384 }
1385 }
1386 }
1387 else if (!s->background_filled_p)
1388 {
1389 int background_width = s->background_width;
1390 int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
1391
1392
1393
1394 if (s->area == TEXT_AREA
1395 && x < text_left_x && !s->row->mode_line_p)
1396 {
1397 background_width -= text_left_x - x;
1398 x = text_left_x;
1399 }
1400
1401 if (background_width > 0)
1402 haiku_draw_background_rect (s, s->face, s->x, s->y,
1403 background_width, s->height);
1404 }
1405 s->background_filled_p = 1;
1406 }
1407
1408 static void
1409 haiku_start_clip (struct glyph_string *s)
1410 {
1411 void *view = FRAME_HAIKU_DRAWABLE (s->f);
1412 BView_StartClip (view);
1413 }
1414
1415 static void
1416 haiku_end_clip (struct glyph_string *s)
1417 {
1418 void *view = FRAME_HAIKU_DRAWABLE (s->f);
1419 BView_EndClip (view);
1420 }
1421
1422 static void
1423 haiku_clip_to_row (struct window *w, struct glyph_row *row,
1424 enum glyph_row_area area)
1425 {
1426 struct frame *f = WINDOW_XFRAME (w);
1427 int window_x, window_y, window_width;
1428 int x, y, width, height;
1429
1430 window_box (w, area, &window_x, &window_y, &window_width, 0);
1431
1432 x = window_x;
1433 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
1434 y = max (y, window_y);
1435 width = window_width;
1436 height = row->visible_height;
1437
1438 BView_ClipToRect (FRAME_HAIKU_DRAWABLE (f), x, y, width, height);
1439 }
1440
1441 static void
1442 haiku_update_begin (struct frame *f)
1443 {
1444
1445
1446 FRAME_COMPLETE_P (f) = false;
1447 }
1448
1449 static void
1450 haiku_update_end (struct frame *f)
1451 {
1452 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1453 BWindow_Flush (FRAME_HAIKU_WINDOW (f));
1454 }
1455
1456 static void
1457 haiku_draw_composite_glyph_string_foreground (struct glyph_string *s)
1458 {
1459 int i, j, x;
1460 struct font *font = s->font;
1461 void *view = FRAME_HAIKU_DRAWABLE (s->f);
1462 struct face *face = s->face;
1463
1464
1465
1466 if (face && face->box != FACE_NO_BOX
1467 && s->first_glyph->left_box_line_p)
1468 x = s->x + max (face->box_vertical_line_width, 0);
1469 else
1470 x = s->x;
1471
1472
1473
1474
1475
1476
1477
1478
1479 if (s->font_not_found_p && !s->cmp_from)
1480 {
1481 if (s->hl == DRAW_CURSOR)
1482 BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
1483 else
1484 BView_SetHighColor (view, s->face->foreground);
1485
1486 BView_SetPenSize (view, 1);
1487 BView_StrokeRectangle (view, s->x, s->y,
1488 s->width, s->height);
1489 }
1490 else if (!s->first_glyph->u.cmp.automatic)
1491 {
1492 int y = s->ybase;
1493
1494 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1495
1496
1497 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1498 {
1499 int xx = x + s->cmp->offsets[j * 2];
1500 int yy = y - s->cmp->offsets[j * 2 + 1];
1501
1502 font->driver->draw (s, j, j + 1, xx, yy, false);
1503 if (face->overstrike)
1504 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1505 }
1506 }
1507 else
1508 {
1509 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1510 Lisp_Object glyph;
1511 int y = s->ybase;
1512 int width = 0;
1513
1514 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1515 {
1516 glyph = LGSTRING_GLYPH (gstring, i);
1517 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1518 width += LGLYPH_WIDTH (glyph);
1519 else
1520 {
1521 int xoff, yoff, wadjust;
1522
1523 if (j < i)
1524 {
1525 font->driver->draw (s, j, i, x, y, false);
1526 if (s->face->overstrike)
1527 font->driver->draw (s, j, i, x + 1, y, false);
1528 x += width;
1529 }
1530 xoff = LGLYPH_XOFF (glyph);
1531 yoff = LGLYPH_YOFF (glyph);
1532 wadjust = LGLYPH_WADJUST (glyph);
1533 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1534 if (face->overstrike)
1535 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1536 false);
1537 x += wadjust;
1538 j = i + 1;
1539 width = 0;
1540 }
1541 }
1542 if (j < i)
1543 {
1544 font->driver->draw (s, j, i, x, y, false);
1545 if (face->overstrike)
1546 font->driver->draw (s, j, i, x + 1, y, false);
1547 }
1548 }
1549 }
1550
1551 static void
1552 haiku_draw_image_relief (struct glyph_string *s)
1553 {
1554 int x1, y1, thick;
1555 bool raised_p, top_p, bot_p, left_p, right_p;
1556 int extra_x, extra_y;
1557 struct haiku_rect r;
1558 int x = s->x;
1559 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
1560
1561 struct face *face = s->face;
1562
1563
1564
1565 if (face->box != FACE_NO_BOX
1566 && s->first_glyph->left_box_line_p
1567 && s->slice.x == 0)
1568 x += max (face->box_vertical_line_width, 0);
1569
1570
1571
1572 if (s->slice.x == 0)
1573 x += s->img->hmargin;
1574 if (s->slice.y == 0)
1575 y += s->img->vmargin;
1576
1577 if (s->hl == DRAW_IMAGE_SUNKEN
1578 || s->hl == DRAW_IMAGE_RAISED)
1579 {
1580 if (s->face->id == TAB_BAR_FACE_ID)
1581 thick = (tab_bar_button_relief < 0
1582 ? DEFAULT_TAB_BAR_BUTTON_RELIEF
1583 : min (tab_bar_button_relief, 1000000));
1584 else
1585 thick = (tool_bar_button_relief < 0
1586 ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
1587 : min (tool_bar_button_relief, 1000000));
1588 raised_p = s->hl == DRAW_IMAGE_RAISED;
1589 }
1590 else
1591 {
1592 thick = eabs (s->img->relief);
1593 raised_p = s->img->relief > 0;
1594 }
1595
1596 x1 = x + s->slice.width - 1;
1597 y1 = y + s->slice.height - 1;
1598
1599 extra_x = extra_y = 0;
1600
1601 if (s->face->id == TAB_BAR_FACE_ID)
1602 {
1603 if (CONSP (Vtab_bar_button_margin)
1604 && FIXNUMP (XCAR (Vtab_bar_button_margin))
1605 && FIXNUMP (XCDR (Vtab_bar_button_margin)))
1606 {
1607 extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
1608 extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
1609 }
1610 else if (FIXNUMP (Vtab_bar_button_margin))
1611 extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
1612 }
1613
1614 if (s->face->id == TOOL_BAR_FACE_ID)
1615 {
1616 if (CONSP (Vtool_bar_button_margin)
1617 && FIXNUMP (XCAR (Vtool_bar_button_margin))
1618 && FIXNUMP (XCDR (Vtool_bar_button_margin)))
1619 {
1620 extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
1621 extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
1622 }
1623 else if (FIXNUMP (Vtool_bar_button_margin))
1624 extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
1625 }
1626
1627 top_p = bot_p = left_p = right_p = 0;
1628
1629 if (s->slice.x == 0)
1630 x -= thick + extra_x, left_p = 1;
1631 if (s->slice.y == 0)
1632 y -= thick + extra_y, top_p = 1;
1633 if (s->slice.x + s->slice.width == s->img->width)
1634 x1 += thick + extra_x, right_p = 1;
1635 if (s->slice.y + s->slice.height == s->img->height)
1636 y1 += thick + extra_y, bot_p = 1;
1637
1638 get_glyph_string_clip_rect (s, &r);
1639 haiku_draw_relief_rect (s, x, y, x1, y1, thick, thick, raised_p,
1640 top_p, bot_p, left_p, right_p, &r);
1641 }
1642
1643 static void
1644 haiku_translate_transform (double (*transform)[3], double dx,
1645 double dy)
1646 {
1647 transform[0][2] += dx;
1648 transform[1][2] += dy;
1649 }
1650
1651 static void
1652 haiku_draw_image_glyph_string (struct glyph_string *s)
1653 {
1654 struct face *face = s->face;
1655 void *view, *bitmap, *mask;
1656 int box_line_hwidth = max (face->box_vertical_line_width, 0);
1657 int box_line_vwidth = max (face->box_horizontal_line_width, 0);
1658 int x, y, height, width, relief;
1659 struct haiku_rect nr;
1660 Emacs_Rectangle cr, ir, r;
1661 unsigned long background;
1662 double image_transform[3][3];
1663
1664 height = s->height;
1665 if (s->slice.y == 0)
1666 height -= box_line_vwidth;
1667 if (s->slice.y + s->slice.height >= s->img->height)
1668 height -= box_line_vwidth;
1669
1670 width = s->background_width;
1671 x = s->x;
1672 if (s->first_glyph->left_box_line_p
1673 && s->slice.x == 0)
1674 {
1675 x += box_line_hwidth;
1676 width -= box_line_hwidth;
1677 }
1678
1679 y = s->y;
1680 if (s->slice.y == 0)
1681 y += box_line_vwidth;
1682
1683 view = FRAME_HAIKU_DRAWABLE (s->f);
1684 bitmap = s->img->pixmap;
1685
1686 s->stippled_p = face->stipple != 0;
1687
1688 if (s->hl == DRAW_CURSOR)
1689 haiku_merge_cursor_foreground (s, NULL, &background);
1690 else
1691 background = face->background;
1692
1693 haiku_draw_background_rect (s, face, x, y,
1694 width, height);
1695
1696 if (bitmap)
1697 {
1698 get_glyph_string_clip_rect (s, &nr);
1699 CONVERT_TO_EMACS_RECT (cr, nr);
1700 x = s->x;
1701 y = s->ybase - image_ascent (s->img, face, &s->slice);
1702
1703 if (s->slice.x == 0)
1704 x += s->img->hmargin;
1705 if (s->slice.y == 0)
1706 y += s->img->vmargin;
1707
1708 if (face->box != FACE_NO_BOX
1709 && s->first_glyph->left_box_line_p
1710 && s->slice.x == 0)
1711 x += max (face->box_vertical_line_width, 0);
1712
1713 ir.x = x;
1714 ir.y = y;
1715 ir.width = s->slice.width;
1716 ir.height = s->slice.height;
1717 r = ir;
1718
1719 mask = s->img->mask;
1720
1721 if (gui_intersect_rectangles (&cr, &ir, &r))
1722 {
1723 memcpy (&image_transform, &s->img->transform,
1724 sizeof image_transform);
1725
1726 if (s->slice.x != x || s->slice.y != y
1727 || s->slice.width != s->img->width
1728 || s->slice.height != s->img->height)
1729 {
1730 BView_StartClip (view);
1731 BView_ClipToRect (view, r.x, r.y, r.width, r.height);
1732 }
1733
1734 haiku_translate_transform (image_transform,
1735 x - s->slice.x,
1736 y - s->slice.y);
1737
1738 be_apply_affine_transform (view,
1739 image_transform[0][0],
1740 image_transform[0][1],
1741 image_transform[0][2],
1742 image_transform[1][0],
1743 image_transform[1][1],
1744 image_transform[1][2]);
1745
1746 if (!s->stippled_p || !mask)
1747 {
1748 BView_DrawBitmap (view, bitmap, 0, 0,
1749 s->img->original_width,
1750 s->img->original_height,
1751 0, 0,
1752 s->img->original_width,
1753 s->img->original_height,
1754 s->img->use_bilinear_filtering);
1755
1756 if (mask)
1757 be_draw_image_mask (mask, view, 0, 0,
1758 s->img->original_width,
1759 s->img->original_height,
1760 0, 0,
1761 s->img->original_width,
1762 s->img->original_height,
1763 background);
1764 }
1765 else
1766
1767
1768
1769 be_draw_bitmap_with_mask (view, bitmap, mask, 0, 0,
1770 s->img->original_width,
1771 s->img->original_height,
1772 0, 0,
1773 s->img->original_width,
1774 s->img->original_height,
1775 s->img->use_bilinear_filtering);
1776
1777 if (s->slice.x != x || s->slice.y != y
1778 || s->slice.width != s->img->width
1779 || s->slice.height != s->img->height)
1780 BView_EndClip (view);
1781
1782 be_apply_affine_transform (view, 1, 0, 0, 0, 1, 0);
1783 }
1784
1785 if (!s->img->mask)
1786 {
1787
1788
1789
1790
1791
1792
1793
1794 if (s->hl == DRAW_CURSOR)
1795 {
1796 relief = eabs (s->img->relief);
1797
1798 BView_SetPenSize (view, 1);
1799 BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel);
1800 BView_StrokeRectangle (view, x - relief, y - relief,
1801 s->slice.width + relief * 2,
1802 s->slice.height + relief * 2);
1803 }
1804 }
1805 }
1806
1807 if (s->img->relief
1808 || s->hl == DRAW_IMAGE_RAISED
1809 || s->hl == DRAW_IMAGE_SUNKEN)
1810 haiku_draw_image_relief (s);
1811 }
1812
1813 static void
1814 haiku_draw_glyph_string (struct glyph_string *s)
1815 {
1816 void *view = FRAME_HAIKU_DRAWABLE (s->f);;
1817 struct face *face = s->face;
1818
1819 block_input ();
1820 BView_draw_lock (view, false, 0, 0, 0, 0);
1821 prepare_face_for_display (s->f, s->face);
1822
1823 s->stippled_p = s->hl != DRAW_CURSOR && face->stipple;
1824
1825 if (s->next && s->right_overhang && !s->for_overlaps)
1826 {
1827 int width;
1828 struct glyph_string *next;
1829
1830 for (width = 0, next = s->next;
1831 next && width < s->right_overhang;
1832 width += next->width, next = next->next)
1833 if (next->first_glyph->type != IMAGE_GLYPH)
1834 {
1835 prepare_face_for_display (s->f, next->face);
1836 next->stippled_p
1837 = next->hl != DRAW_CURSOR && next->face->stipple;
1838
1839 haiku_start_clip (next);
1840 haiku_clip_to_string (next);
1841 if (next->first_glyph->type != STRETCH_GLYPH)
1842 haiku_maybe_draw_background (next, true);
1843 else
1844 haiku_draw_stretch_glyph_string (next);
1845 haiku_end_clip (s);
1846 }
1847 }
1848
1849 haiku_start_clip (s);
1850
1851 int box_filled_p = 0;
1852
1853 if (!s->for_overlaps && face->box != FACE_NO_BOX
1854 && (s->first_glyph->type == CHAR_GLYPH
1855 || s->first_glyph->type == COMPOSITE_GLYPH))
1856 {
1857 haiku_clip_to_string (s);
1858 haiku_maybe_draw_background (s, 1);
1859 box_filled_p = 1;
1860 haiku_draw_string_box (s);
1861 }
1862 else if (!s->clip_head
1863 && !s->clip_tail
1864 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
1865 || (s->next && s->next->hl != s->hl && s->right_overhang)))
1866
1867
1868
1869 haiku_clip_to_string_exactly (s, s);
1870 else
1871 haiku_clip_to_string (s);
1872
1873 if (s->for_overlaps)
1874 s->background_filled_p = 1;
1875
1876 switch (s->first_glyph->type)
1877 {
1878 case COMPOSITE_GLYPH:
1879 if (s->for_overlaps || (s->cmp_from > 0
1880 && ! s->first_glyph->u.cmp.automatic))
1881 s->background_filled_p = 1;
1882 else
1883 haiku_maybe_draw_background (s, 1);
1884 haiku_draw_composite_glyph_string_foreground (s);
1885 break;
1886 case CHAR_GLYPH:
1887 if (s->for_overlaps)
1888 s->background_filled_p = 1;
1889 else
1890 haiku_maybe_draw_background (s, 0);
1891 haiku_draw_glyph_string_foreground (s);
1892 break;
1893 case STRETCH_GLYPH:
1894 haiku_draw_stretch_glyph_string (s);
1895 break;
1896 case IMAGE_GLYPH:
1897 haiku_draw_image_glyph_string (s);
1898 break;
1899 case GLYPHLESS_GLYPH:
1900 if (s->for_overlaps)
1901 s->background_filled_p = 1;
1902 else
1903 haiku_maybe_draw_background (s, 1);
1904 haiku_draw_glyphless_glyph_string_foreground (s);
1905 break;
1906 default:
1907 emacs_abort ();
1908 }
1909
1910 if (!s->for_overlaps)
1911 {
1912 if (!box_filled_p && face->box != FACE_NO_BOX)
1913 haiku_draw_string_box (s);
1914 else
1915 haiku_draw_text_decoration (s, face, s->width, s->x);
1916
1917 if (s->prev)
1918 {
1919 struct glyph_string *prev;
1920
1921 for (prev = s->prev; prev; prev = prev->prev)
1922 if (prev->hl != s->hl
1923 && prev->x + prev->width + prev->right_overhang > s->x)
1924 {
1925
1926
1927 enum draw_glyphs_face save = prev->hl;
1928
1929 prev->hl = s->hl;
1930 haiku_start_clip (s);
1931 haiku_clip_to_string (s);
1932 haiku_clip_to_string_exactly (s, prev);
1933 if (prev->first_glyph->type == CHAR_GLYPH)
1934 haiku_draw_glyph_string_foreground (prev);
1935 else
1936 haiku_draw_composite_glyph_string_foreground (prev);
1937 haiku_end_clip (s);
1938 prev->hl = save;
1939 }
1940 }
1941
1942 if (s->next)
1943 {
1944 struct glyph_string *next;
1945
1946 for (next = s->next; next; next = next->next)
1947 if (next->hl != s->hl
1948 && next->x - next->left_overhang < s->x + s->width)
1949 {
1950
1951
1952 enum draw_glyphs_face save = next->hl;
1953
1954 next->hl = s->hl;
1955 haiku_start_clip (s);
1956 haiku_clip_to_string (s);
1957 haiku_clip_to_string_exactly (s, next);
1958 if (next->first_glyph->type == CHAR_GLYPH)
1959 haiku_draw_glyph_string_foreground (next);
1960 else
1961 haiku_draw_composite_glyph_string_foreground (next);
1962 haiku_end_clip (s);
1963
1964 next->hl = save;
1965 next->clip_head = s->next;
1966 }
1967 }
1968 }
1969
1970 haiku_end_clip (s);
1971 BView_draw_unlock (view);
1972
1973
1974
1975
1976
1977 if (s->face->stipple
1978 && (s->first_glyph->type == STRETCH_GLYPH
1979 || s->hl != DRAW_CURSOR))
1980 s->row->stipple_p = true;
1981
1982 unblock_input ();
1983 }
1984
1985 static void
1986 haiku_after_update_window_line (struct window *w,
1987 struct glyph_row *desired_row)
1988 {
1989 eassert (w);
1990 struct frame *f;
1991 int width, height;
1992
1993 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1994 desired_row->redraw_fringe_bitmaps_p = true;
1995
1996 if (windows_or_buffers_changed
1997 && desired_row->full_width_p
1998 && (f = XFRAME (w->frame),
1999 width = FRAME_INTERNAL_BORDER_WIDTH (f),
2000 width != 0)
2001 && (height = desired_row->visible_height,
2002 height > 0))
2003 {
2004 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
2005 int face_id =
2006 !NILP (Vface_remapping_alist)
2007 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
2008 : INTERNAL_BORDER_FACE_ID;
2009 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
2010
2011 block_input ();
2012 if (face)
2013 {
2014 void *view = FRAME_HAIKU_DRAWABLE (f);
2015 BView_draw_lock (view, false, 0, 0, 0, 0);
2016 BView_StartClip (view);
2017 BView_SetHighColor (view, (face->background_defaulted_p
2018 ? FRAME_BACKGROUND_PIXEL (f)
2019 : face->background));
2020 BView_FillRectangle (view, 0, y, width, height);
2021 BView_FillRectangle (view, FRAME_PIXEL_WIDTH (f) - width,
2022 y, width, height);
2023 BView_invalidate_region (FRAME_HAIKU_DRAWABLE (f),
2024 0, y, width, height);
2025 BView_invalidate_region (view, FRAME_PIXEL_WIDTH (f) - width,
2026 y, width, height);
2027 BView_EndClip (view);
2028 BView_draw_unlock (view);
2029 }
2030 else
2031 {
2032 haiku_clear_frame_area (f, 0, y, width, height);
2033 haiku_clear_frame_area (f, FRAME_PIXEL_WIDTH (f) - width,
2034 y, width, height);
2035 }
2036 unblock_input ();
2037 }
2038 }
2039
2040 static void
2041 haiku_set_window_size (struct frame *f, bool change_gravity,
2042 int width, int height)
2043 {
2044 Lisp_Object frame;
2045
2046
2047
2048
2049 XSETFRAME (frame, f);
2050 if (!NILP (Fframe_parameter (frame, Qfullscreen))
2051
2052
2053 && f->want_fullscreen == FULLSCREEN_NONE
2054
2055
2056
2057 && FRAME_OUTPUT_DATA (f)->configury_done)
2058 return;
2059
2060 haiku_update_size_hints (f);
2061
2062 if (FRAME_HAIKU_WINDOW (f))
2063 {
2064 block_input ();
2065 BWindow_resize (FRAME_HAIKU_WINDOW (f),
2066 width, height);
2067
2068 if (FRAME_VISIBLE_P (f)
2069 && (width != FRAME_PIXEL_WIDTH (f)
2070 || height != FRAME_PIXEL_HEIGHT (f)))
2071 haiku_wait_for_event (f, FRAME_RESIZED);
2072 unblock_input ();
2073 }
2074
2075 do_pending_window_change (false);
2076 }
2077
2078 static void
2079 haiku_draw_hollow_cursor (struct window *w, struct glyph_row *row)
2080 {
2081 struct frame *f;
2082 int x, y, wd, h;
2083 struct glyph *cursor_glyph;
2084 uint32_t foreground;
2085 void *view;
2086
2087 f = XFRAME (WINDOW_FRAME (w));
2088 view = FRAME_HAIKU_DRAWABLE (f);
2089
2090
2091
2092 cursor_glyph = get_phys_cursor_glyph (w);
2093 if (cursor_glyph == NULL)
2094 return;
2095
2096
2097 get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
2098 wd = w->phys_cursor_width;
2099
2100
2101
2102 foreground = FRAME_CURSOR_COLOR (f).pixel;
2103
2104
2105
2106
2107 if ((cursor_glyph->resolved_level & 1) != 0
2108 && cursor_glyph->pixel_width > wd)
2109 x += cursor_glyph->pixel_width - wd;
2110
2111
2112
2113
2114 BView_draw_lock (view, true, x, y, wd, h);
2115 BView_StartClip (view);
2116 haiku_clip_to_row (w, row, TEXT_AREA);
2117
2118
2119 BView_SetHighColor (view, foreground);
2120 BView_SetPenSize (view, 1);
2121
2122
2123 BView_StrokeRectangle (view, x, y, wd, h);
2124
2125
2126 BView_EndClip (view);
2127 BView_draw_unlock (view);
2128 }
2129
2130 static void
2131 haiku_draw_bar_cursor (struct window *w, struct glyph_row *row,
2132 int width, enum text_cursor_kinds kind)
2133 {
2134 struct frame *f;
2135 struct glyph *cursor_glyph;
2136 struct glyph_row *r;
2137 struct face *face;
2138 uint32_t foreground;
2139 void *view;
2140 int x, y, dummy_x, dummy_y, dummy_h;
2141
2142 f = XFRAME (w->frame);
2143
2144
2145
2146
2147 cursor_glyph = get_phys_cursor_glyph (w);
2148 if (cursor_glyph == NULL)
2149 return;
2150
2151
2152
2153
2154 if (cursor_glyph->type == IMAGE_GLYPH)
2155 {
2156 r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
2157 draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
2158 }
2159 else
2160 {
2161 view = FRAME_HAIKU_DRAWABLE (f);
2162 face = FACE_FROM_ID (f, cursor_glyph->face_id);
2163
2164
2165
2166
2167
2168
2169 if (face->background == FRAME_CURSOR_COLOR (f).pixel)
2170 foreground = face->foreground;
2171 else
2172 foreground = FRAME_CURSOR_COLOR (f).pixel;
2173
2174 BView_draw_lock (view, false, 0, 0, 0, 0);
2175 BView_StartClip (view);
2176 BView_SetHighColor (view, foreground);
2177 haiku_clip_to_row (w, row, TEXT_AREA);
2178
2179 if (kind == BAR_CURSOR)
2180 {
2181 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
2182 y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
2183
2184 if (width < 0)
2185 width = FRAME_CURSOR_WIDTH (f);
2186 width = min (cursor_glyph->pixel_width, width);
2187
2188 w->phys_cursor_width = width;
2189
2190
2191
2192 if ((cursor_glyph->resolved_level & 1) != 0)
2193 x += cursor_glyph->pixel_width - width;
2194
2195 BView_FillRectangle (view, x, y, width, row->height);
2196 BView_invalidate_region (view, x, y, width, row->height);
2197 }
2198 else
2199 {
2200 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
2201 y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
2202 row->height - width);
2203
2204 if (width < 0)
2205 width = row->height;
2206
2207 width = min (row->height, width);
2208
2209 get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
2210 &dummy_y, &dummy_h);
2211
2212 if ((cursor_glyph->resolved_level & 1) != 0
2213 && cursor_glyph->pixel_width > w->phys_cursor_width - 1)
2214 x += cursor_glyph->pixel_width - w->phys_cursor_width + 1;
2215
2216 BView_FillRectangle (view, x, y, w->phys_cursor_width - 1,
2217 width);
2218 BView_invalidate_region (view, x, y, w->phys_cursor_width - 1,
2219 width);
2220 }
2221
2222 BView_EndClip (view);
2223 BView_draw_unlock (view);
2224 }
2225 }
2226
2227 static void
2228 haiku_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2229 int x, int y, enum text_cursor_kinds cursor_type,
2230 int cursor_width, bool on_p, bool active_p)
2231 {
2232 if (on_p)
2233 {
2234 w->phys_cursor_type = cursor_type;
2235 w->phys_cursor_on_p = true;
2236
2237 if (glyph_row->exact_window_width_line_p
2238 && (glyph_row->reversed_p
2239 ? (w->phys_cursor.hpos < 0)
2240 : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
2241 {
2242 glyph_row->cursor_in_fringe_p = true;
2243 draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
2244 }
2245 else
2246 {
2247 switch (cursor_type)
2248 {
2249 case HOLLOW_BOX_CURSOR:
2250 haiku_draw_hollow_cursor (w, glyph_row);
2251 break;
2252
2253 case FILLED_BOX_CURSOR:
2254 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
2255 break;
2256
2257 case BAR_CURSOR:
2258 haiku_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
2259 break;
2260
2261 case HBAR_CURSOR:
2262 haiku_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
2263 break;
2264
2265 case NO_CURSOR:
2266 w->phys_cursor_width = 0;
2267 break;
2268
2269 default:
2270 emacs_abort ();
2271 }
2272 }
2273 }
2274 }
2275
2276 static void
2277 haiku_show_hourglass (struct frame *f)
2278 {
2279 if (FRAME_TOOLTIP_P (f)
2280 || FRAME_OUTPUT_DATA (f)->hourglass_p)
2281 return;
2282
2283 block_input ();
2284 FRAME_OUTPUT_DATA (f)->hourglass_p = 1;
2285
2286 if (FRAME_HAIKU_VIEW (f))
2287 BView_set_view_cursor (FRAME_HAIKU_VIEW (f),
2288 FRAME_OUTPUT_DATA (f)->hourglass_cursor);
2289 unblock_input ();
2290 }
2291
2292 static void
2293 haiku_hide_hourglass (struct frame *f)
2294 {
2295 if (FRAME_TOOLTIP_P (f)
2296 || !FRAME_OUTPUT_DATA (f)->hourglass_p)
2297 return;
2298
2299 block_input ();
2300 FRAME_OUTPUT_DATA (f)->hourglass_p = 0;
2301
2302 if (FRAME_HAIKU_VIEW (f))
2303 BView_set_view_cursor (FRAME_HAIKU_VIEW (f),
2304 FRAME_OUTPUT_DATA (f)->current_cursor);
2305 unblock_input ();
2306 }
2307
2308 static void
2309 haiku_compute_glyph_string_overhangs (struct glyph_string *s)
2310 {
2311 if (s->cmp == NULL
2312 && (s->first_glyph->type == CHAR_GLYPH
2313 || s->first_glyph->type == COMPOSITE_GLYPH))
2314 {
2315 struct font_metrics metrics;
2316
2317 if (s->first_glyph->type == CHAR_GLYPH)
2318 {
2319 struct font *font = s->font;
2320 font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
2321 }
2322 else
2323 {
2324 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
2325
2326 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
2327 }
2328 s->right_overhang = (metrics.rbearing > metrics.width
2329 ? metrics.rbearing - metrics.width : 0);
2330 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
2331 }
2332 else if (s->cmp)
2333 {
2334 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
2335 s->left_overhang = - s->cmp->lbearing;
2336 }
2337 }
2338
2339 static void
2340 haiku_draw_vertical_window_border (struct window *w,
2341 int x, int y_0, int y_1)
2342 {
2343 struct frame *f = XFRAME (WINDOW_FRAME (w));
2344 struct face *face;
2345
2346 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
2347 void *view = FRAME_HAIKU_DRAWABLE (f);
2348 BView_draw_lock (view, true, x, y_0, 1, y_1);
2349 BView_StartClip (view);
2350 if (face)
2351 BView_SetHighColor (view, face->foreground);
2352 BView_StrokeLine (view, x, y_0, x, y_1);
2353 BView_EndClip (view);
2354 BView_draw_unlock (view);
2355 }
2356
2357 static void
2358 haiku_set_scroll_bar_default_width (struct frame *f)
2359 {
2360 int unit, size;
2361
2362 unit = FRAME_COLUMN_WIDTH (f);
2363 size = BScrollBar_default_size (0) + 1;
2364
2365 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = size;
2366 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (size + unit - 1) / unit;
2367 }
2368
2369 static void
2370 haiku_set_scroll_bar_default_height (struct frame *f)
2371 {
2372 int height, size;
2373
2374 height = FRAME_LINE_HEIGHT (f);
2375 size = BScrollBar_default_size (true) + 1;
2376
2377 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = size;
2378 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (size + height - 1) / height;
2379 }
2380
2381 static void
2382 haiku_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
2383 {
2384 struct frame *f = XFRAME (WINDOW_FRAME (w));
2385 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
2386 struct face *face_first
2387 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
2388 struct face *face_last
2389 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
2390 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
2391 unsigned long color_first = (face_first
2392 ? face_first->foreground
2393 : FRAME_FOREGROUND_PIXEL (f));
2394 unsigned long color_last = (face_last
2395 ? face_last->foreground
2396 : FRAME_FOREGROUND_PIXEL (f));
2397 void *view = FRAME_HAIKU_DRAWABLE (f);
2398
2399 BView_draw_lock (view, true, x0, y0, x1 - x0 + 1, y1 - y0 + 1);
2400 BView_StartClip (view);
2401
2402 if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
2403
2404
2405 {
2406 BView_SetHighColor (view, color_first);
2407 BView_StrokeLine (view, x0, y0, x0, y1 - 1);
2408 BView_SetHighColor (view, color);
2409 BView_FillRectangle (view, x0 + 1, y0, x1 - x0 - 2, y1 - y0);
2410 BView_SetHighColor (view, color_last);
2411 BView_StrokeLine (view, x1 - 1, y0, x1 - 1, y1 - 1);
2412 }
2413 else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
2414
2415
2416 {
2417 BView_SetHighColor (view, color_first);
2418 BView_StrokeLine (view, x0, y0, x1 - 1, y0);
2419 BView_SetHighColor (view, color);
2420 BView_FillRectangle (view, x0, y0 + 1, x1 - x0, y1 - y0 - 2);
2421 BView_SetHighColor (view, color_last);
2422 BView_FillRectangle (view, x0, y1 - 1, x1 - x0, 1);
2423 }
2424 else
2425 {
2426 BView_SetHighColor (view, color);
2427 BView_FillRectangleAbs (view, x0, y0, x1, y1);
2428 }
2429 BView_EndClip (view);
2430 BView_draw_unlock (view);
2431 }
2432
2433 static void
2434 haiku_condemn_scroll_bars (struct frame *frame)
2435 {
2436 if (!NILP (FRAME_SCROLL_BARS (frame)))
2437 {
2438 if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
2439 {
2440
2441 Lisp_Object last = FRAME_SCROLL_BARS (frame);
2442
2443 while (!NILP (XSCROLL_BAR (last)->next))
2444 last = XSCROLL_BAR (last)->next;
2445
2446 XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
2447 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
2448 }
2449
2450 fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
2451 fset_scroll_bars (frame, Qnil);
2452 }
2453 }
2454
2455 static void
2456 haiku_redeem_scroll_bar (struct window *w)
2457 {
2458 struct scroll_bar *bar;
2459 Lisp_Object barobj;
2460 struct frame *f;
2461
2462 if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
2463 {
2464 bar = XSCROLL_BAR (w->vertical_scroll_bar);
2465
2466 f = XFRAME (WINDOW_FRAME (w));
2467 if (NILP (bar->prev))
2468 {
2469
2470
2471 if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
2472
2473 goto horizontal;
2474 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
2475 w->vertical_scroll_bar))
2476 fset_condemned_scroll_bars (f, bar->next);
2477 else
2478
2479
2480 emacs_abort ();
2481 }
2482 else
2483 XSCROLL_BAR (bar->prev)->next = bar->next;
2484
2485 if (! NILP (bar->next))
2486 XSCROLL_BAR (bar->next)->prev = bar->prev;
2487
2488 bar->next = FRAME_SCROLL_BARS (f);
2489 bar->prev = Qnil;
2490 XSETVECTOR (barobj, bar);
2491 fset_scroll_bars (f, barobj);
2492 if (! NILP (bar->next))
2493 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
2494 }
2495 horizontal:
2496 if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
2497 {
2498 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
2499
2500 f = XFRAME (WINDOW_FRAME (w));
2501 if (NILP (bar->prev))
2502 {
2503
2504
2505 if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
2506
2507 return;
2508 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
2509 w->horizontal_scroll_bar))
2510 fset_condemned_scroll_bars (f, bar->next);
2511 else
2512
2513
2514 emacs_abort ();
2515 }
2516 else
2517 XSCROLL_BAR (bar->prev)->next = bar->next;
2518
2519 if (! NILP (bar->next))
2520 XSCROLL_BAR (bar->next)->prev = bar->prev;
2521
2522 bar->next = FRAME_SCROLL_BARS (f);
2523 bar->prev = Qnil;
2524 XSETVECTOR (barobj, bar);
2525 fset_scroll_bars (f, barobj);
2526 if (! NILP (bar->next))
2527 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
2528 }
2529 }
2530
2531 static void
2532 haiku_judge_scroll_bars (struct frame *f)
2533 {
2534 Lisp_Object bar, next;
2535
2536 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
2537
2538
2539
2540 fset_condemned_scroll_bars (f, Qnil);
2541
2542 for (; ! NILP (bar); bar = next)
2543 {
2544 struct scroll_bar *b = XSCROLL_BAR (bar);
2545
2546 haiku_scroll_bar_remove (b);
2547
2548 next = b->next;
2549 b->next = b->prev = Qnil;
2550 }
2551
2552
2553
2554 }
2555
2556 static struct scroll_bar *
2557 haiku_scroll_bar_create (struct window *w, int left, int top,
2558 int width, int height, bool horizontal_p)
2559 {
2560 struct frame *f;
2561 Lisp_Object barobj;
2562 struct scroll_bar *bar;
2563 void *scroll_bar;
2564 void *view;
2565
2566 f = XFRAME (WINDOW_FRAME (w));
2567 view = FRAME_HAIKU_DRAWABLE (f);
2568
2569 block_input ();
2570 bar = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev, PVEC_OTHER);
2571
2572 XSETWINDOW (bar->window, w);
2573 bar->top = top;
2574 bar->left = left;
2575 bar->width = width;
2576 bar->height = height;
2577 bar->position = 0;
2578 bar->total = 0;
2579 bar->dragging = 0;
2580 bar->update = -1;
2581 bar->horizontal = horizontal_p;
2582
2583 scroll_bar = be_make_scroll_bar_for_view (view, horizontal_p,
2584 left, top, left + width - 1,
2585 top + height - 1);
2586 BView_publish_scroll_bar (view, left, top, width, height);
2587
2588 bar->next = FRAME_SCROLL_BARS (f);
2589 bar->prev = Qnil;
2590 bar->scroll_bar = scroll_bar;
2591 XSETVECTOR (barobj, bar);
2592 fset_scroll_bars (f, barobj);
2593
2594 if (!NILP (bar->next))
2595 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
2596
2597 unblock_input ();
2598 return bar;
2599 }
2600
2601 static void
2602 haiku_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int position)
2603 {
2604 Lisp_Object barobj;
2605 struct scroll_bar *bar;
2606 int top, height, left, width;
2607 int window_x, window_width;
2608 void *view;
2609
2610 eassert (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w));
2611
2612 window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
2613 left = window_x;
2614 width = window_width;
2615 top = WINDOW_SCROLL_BAR_AREA_Y (w);
2616 height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w);
2617 view = FRAME_HAIKU_DRAWABLE (WINDOW_XFRAME (w));
2618
2619 block_input ();
2620
2621 if (NILP (w->horizontal_scroll_bar))
2622 {
2623 bar = haiku_scroll_bar_create (w, left, top, width, height, true);
2624 bar->update = position;
2625 bar->position = position;
2626 bar->total = whole;
2627 }
2628 else
2629 {
2630 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
2631
2632 if (bar->left != left || bar->top != top
2633 || bar->width != width || bar->height != height)
2634 {
2635 BView_forget_scroll_bar (view, bar->left, bar->top,
2636 bar->width, bar->height);
2637 BView_move_frame (bar->scroll_bar, left, top,
2638 left + width - 1, top + height - 1);
2639 BView_publish_scroll_bar (view, left, top, width, height);
2640
2641 bar->left = left;
2642 bar->top = top;
2643 bar->width = width;
2644 bar->height = height;
2645 }
2646 }
2647
2648 haiku_set_horizontal_scroll_bar_thumb (bar, portion, position, whole);
2649 bar->position = position;
2650 bar->total = whole;
2651 XSETVECTOR (barobj, bar);
2652 wset_horizontal_scroll_bar (w, barobj);
2653 unblock_input ();
2654 }
2655
2656 static void
2657 haiku_set_vertical_scroll_bar (struct window *w, int portion, int whole, int position)
2658 {
2659 Lisp_Object barobj;
2660 struct scroll_bar *bar;
2661 int top, height, left, width;
2662 int window_y, window_height;
2663 void *view;
2664
2665 eassert (WINDOW_HAS_VERTICAL_SCROLL_BAR (w));
2666
2667
2668 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
2669 top = window_y;
2670 height = window_height;
2671
2672
2673 left = WINDOW_SCROLL_BAR_AREA_X (w);
2674 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2675
2676 view = FRAME_HAIKU_DRAWABLE (WINDOW_XFRAME (w));
2677
2678 block_input ();
2679 if (NILP (w->vertical_scroll_bar))
2680 {
2681 bar = haiku_scroll_bar_create (w, left, top, width, height, false);
2682 bar->position = position;
2683 bar->total = whole;
2684 }
2685 else
2686 {
2687 bar = XSCROLL_BAR (w->vertical_scroll_bar);
2688
2689 if (bar->left != left || bar->top != top
2690 || bar->width != width || bar->height != height)
2691 {
2692 BView_forget_scroll_bar (view, bar->left, bar->top,
2693 bar->width, bar->height);
2694 BView_move_frame (bar->scroll_bar, left, top,
2695 left + width - 1, top + height - 1);
2696 BView_publish_scroll_bar (view, left, top, width, height);
2697
2698 bar->left = left;
2699 bar->top = top;
2700 bar->width = width;
2701 bar->height = height;
2702 }
2703 }
2704
2705 haiku_set_scroll_bar_thumb (bar, portion, position, whole);
2706 bar->position = position;
2707 bar->total = whole;
2708
2709 XSETVECTOR (barobj, bar);
2710 wset_vertical_scroll_bar (w, barobj);
2711 unblock_input ();
2712 }
2713
2714 static void
2715 haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2716 struct draw_fringe_bitmap_params *p)
2717 {
2718 struct face *face;
2719 struct frame *f;
2720 struct haiku_bitmap_record *rec;
2721 void *view, *bitmap;
2722 uint32 col;
2723
2724 f = XFRAME (WINDOW_FRAME (w));
2725 view = FRAME_HAIKU_DRAWABLE (f);
2726 face = p->face;
2727
2728 block_input ();
2729 BView_draw_lock (view, true, 0, 0, 0, 0);
2730 BView_StartClip (view);
2731
2732 if (p->wd && p->h)
2733 BView_invalidate_region (view, p->x, p->y, p->wd, p->h);
2734
2735 haiku_clip_to_row (w, row, ANY_AREA);
2736
2737 if (p->bx >= 0 && !p->overlay_p)
2738 {
2739 BView_invalidate_region (view, p->bx, p->by, p->nx, p->ny);
2740
2741 if (!face->stipple)
2742 {
2743 BView_SetHighColor (view, face->background);
2744 BView_FillRectangle (view, p->bx, p->by, p->nx, p->ny);
2745 }
2746 else
2747 {
2748 rec = haiku_get_bitmap_rec (f, face->stipple);
2749 haiku_update_bitmap_rec (rec, face->foreground,
2750 face->background);
2751
2752 BView_StartClip (view);
2753 haiku_clip_to_row (w, row, ANY_AREA);
2754 BView_ClipToRect (view, p->bx, p->by, p->nx, p->ny);
2755 BView_DrawBitmapTiled (view, rec->img, 0, 0, -1, -1,
2756 0, 0, FRAME_PIXEL_WIDTH (f),
2757 FRAME_PIXEL_HEIGHT (f));
2758 BView_EndClip (view);
2759
2760 row->stipple_p = true;
2761 }
2762 }
2763
2764 if (p->which
2765 && p->which < max_fringe_bmp
2766 && p->which < max_used_fringe_bitmap)
2767 {
2768 bitmap = fringe_bmps[p->which];
2769
2770 if (!bitmap)
2771 {
2772
2773
2774
2775
2776
2777
2778 gui_define_fringe_bitmap (WINDOW_XFRAME (w), p->which);
2779 bitmap = fringe_bmps[p->which];
2780 }
2781
2782 if (!p->cursor_p)
2783 col = face->foreground;
2784 else if (p->overlay_p)
2785 col = face->background;
2786 else
2787 col = FRAME_CURSOR_COLOR (XFRAME (WINDOW_FRAME (w))).pixel;
2788
2789 if (!p->overlay_p)
2790 {
2791 BView_SetHighColor (view, face->background);
2792 BView_FillRectangle (view, p->x, p->y, p->wd, p->h);
2793 }
2794
2795 BView_SetLowColor (view, col);
2796 BView_DrawBitmapWithEraseOp (view, bitmap, p->x, p->y, p->wd, p->h);
2797 }
2798 BView_EndClip (view);
2799 BView_draw_unlock (view);
2800 unblock_input ();
2801 }
2802
2803 static void
2804 haiku_define_fringe_bitmap (int which, unsigned short *bits,
2805 int h, int wd)
2806 {
2807 if (which >= max_fringe_bmp)
2808 {
2809 int i = max_fringe_bmp;
2810 max_fringe_bmp = which + 20;
2811 fringe_bmps = !i ? xmalloc (max_fringe_bmp * sizeof (void *)) :
2812 xrealloc (fringe_bmps, max_fringe_bmp * sizeof (void *));
2813
2814 while (i < max_fringe_bmp)
2815 fringe_bmps[i++] = NULL;
2816 }
2817
2818 block_input ();
2819 fringe_bmps[which] = BBitmap_new (wd, h, 1);
2820 if (!fringe_bmps[which])
2821 memory_full (SIZE_MAX);
2822 BBitmap_import_fringe_bitmap (fringe_bmps[which], bits, wd, h);
2823 unblock_input ();
2824 }
2825
2826 static void
2827 haiku_destroy_fringe_bitmap (int which)
2828 {
2829 if (which >= max_fringe_bmp)
2830 return;
2831
2832 if (fringe_bmps[which])
2833 BBitmap_free (fringe_bmps[which]);
2834 fringe_bmps[which] = NULL;
2835 }
2836
2837 static void
2838 haiku_scroll_run (struct window *w, struct run *run)
2839 {
2840 struct frame *f = XFRAME (w->frame);
2841 void *view = FRAME_HAIKU_DRAWABLE (f);
2842 int x, y, width, height, from_y, to_y, bottom_y;
2843 window_box (w, ANY_AREA, &x, &y, &width, &height);
2844
2845 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
2846 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
2847 bottom_y = y + height;
2848
2849 if (to_y < from_y)
2850 {
2851
2852
2853 if (from_y + run->height > bottom_y)
2854 height = bottom_y - from_y;
2855 else
2856 height = run->height;
2857 }
2858 else
2859 {
2860
2861
2862 if (to_y + run->height > bottom_y)
2863 height = bottom_y - to_y;
2864 else
2865 height = run->height;
2866 }
2867
2868 block_input ();
2869 gui_clear_cursor (w);
2870
2871 BView_draw_lock (view, true, x, to_y, width, height);
2872 BView_StartClip (view);
2873 BView_CopyBits (view, x, from_y, width, height,
2874 x, to_y, width, height);
2875 BView_EndClip (view);
2876 BView_draw_unlock (view);
2877
2878 unblock_input ();
2879 }
2880
2881
2882
2883
2884
2885
2886
2887 static void
2888 haiku_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
2889 enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
2890 Time *timestamp)
2891 {
2892 Lisp_Object frame, tail;
2893 struct frame *f1;
2894 int screen_x, screen_y;
2895 void *view;
2896
2897 if (!fp)
2898 return;
2899
2900 f1 = NULL;
2901 block_input ();
2902
2903 FOR_EACH_FRAME (tail, frame)
2904 {
2905 if (FRAME_HAIKU_P (XFRAME (frame)))
2906 XFRAME (frame)->mouse_moved = false;
2907 }
2908
2909 if (gui_mouse_grabbed (x_display_list)
2910 && !EQ (track_mouse, Qdropping)
2911 && !EQ (track_mouse, Qdrag_source))
2912 f1 = x_display_list->last_mouse_frame;
2913 else
2914 f1 = x_display_list->last_mouse_motion_frame;
2915
2916 if (!f1 && FRAME_HAIKU_P (SELECTED_FRAME ()))
2917 f1 = SELECTED_FRAME ();
2918
2919 if (!f1 || (!FRAME_HAIKU_P (f1) && (insist > 0)))
2920 FOR_EACH_FRAME (tail, frame)
2921 if (FRAME_HAIKU_P (XFRAME (frame)) &&
2922 !FRAME_TOOLTIP_P (XFRAME (frame)))
2923 f1 = XFRAME (frame);
2924
2925 if (f1 && FRAME_TOOLTIP_P (f1))
2926 f1 = NULL;
2927
2928 if (f1 && FRAME_HAIKU_P (f1))
2929 {
2930 view = FRAME_HAIKU_VIEW (f1);
2931
2932 if (view)
2933 {
2934 BView_get_mouse (view, &screen_x, &screen_y);
2935 remember_mouse_glyph (f1, screen_x, screen_y,
2936 &x_display_list->last_mouse_glyph);
2937 x_display_list->last_mouse_glyph_frame = f1;
2938
2939 *bar_window = Qnil;
2940 *part = scroll_bar_nowhere;
2941
2942
2943
2944
2945 if (EQ (track_mouse, Qdrag_source)
2946 && (screen_x < 0 || screen_y < 0
2947 || screen_x >= FRAME_PIXEL_WIDTH (f1)
2948 || screen_y >= FRAME_PIXEL_HEIGHT (f1)))
2949 *fp = NULL;
2950 else
2951 *fp = f1;
2952
2953 *timestamp = x_display_list->last_mouse_movement_time;
2954 XSETINT (*x, screen_x);
2955 XSETINT (*y, screen_y);
2956 }
2957 }
2958
2959 unblock_input ();
2960 }
2961
2962 static void
2963 haiku_flush (struct frame *f)
2964 {
2965
2966
2967 if (FRAME_DIRTY_P (f) && !buffer_flipping_blocked_p ())
2968 haiku_flip_buffers (f);
2969
2970
2971
2972 FRAME_COMPLETE_P (f) = true;
2973
2974 if (FRAME_VISIBLE_P (f) && !FRAME_TOOLTIP_P (f))
2975 BWindow_Flush (FRAME_HAIKU_WINDOW (f));
2976 }
2977
2978 static void
2979 haiku_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
2980 {
2981 if (FRAME_TOOLTIP_P (f))
2982 return;
2983
2984 block_input ();
2985 if (!f->pointer_invisible && FRAME_HAIKU_VIEW (f)
2986 && !FRAME_OUTPUT_DATA (f)->hourglass_p)
2987 BView_set_view_cursor (FRAME_HAIKU_VIEW (f), cursor);
2988 unblock_input ();
2989 FRAME_OUTPUT_DATA (f)->current_cursor = cursor;
2990 }
2991
2992 static void
2993 haiku_default_font_parameter (struct frame *f, Lisp_Object parms)
2994 {
2995 struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2996 Lisp_Object font_param = gui_display_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
2997 RES_TYPE_STRING);
2998 Lisp_Object font = Qnil;
2999 if (BASE_EQ (font_param, Qunbound))
3000 font_param = Qnil;
3001
3002 if (NILP (font_param))
3003
3004
3005
3006
3007 font = font_open_by_spec (f, Ffont_get_system_font ());
3008
3009 if (NILP (font))
3010 font = (!NILP (font_param)
3011 ? font_param
3012 : gui_display_get_arg (dpyinfo, parms, Qfont,
3013 "font", "Font",
3014 RES_TYPE_STRING));
3015
3016 if (! FONTP (font) && ! STRINGP (font))
3017 {
3018 const char **names = (const char *[]) { "monospace-12",
3019 "Noto Sans Mono-12",
3020 "Source Code Pro-12",
3021 NULL };
3022 int i;
3023
3024 for (i = 0; names[i]; i++)
3025 {
3026 font
3027 = font_open_by_name (f, build_unibyte_string (names[i]));
3028 if (!NILP (font))
3029 break;
3030 }
3031 if (NILP (font))
3032 error ("No suitable font was found");
3033 }
3034
3035 gui_default_parameter (f, parms, Qfont, font, "font", "Font",
3036 RES_TYPE_STRING);
3037 }
3038
3039 static struct redisplay_interface haiku_redisplay_interface =
3040 {
3041 haiku_frame_parm_handlers,
3042 gui_produce_glyphs,
3043 gui_write_glyphs,
3044 gui_insert_glyphs,
3045 gui_clear_end_of_line,
3046 haiku_scroll_run,
3047 haiku_after_update_window_line,
3048 NULL,
3049 NULL,
3050 haiku_flush,
3051 gui_clear_window_mouse_face,
3052 gui_get_glyph_overhangs,
3053 gui_fix_overlapping_area,
3054 haiku_draw_fringe_bitmap,
3055 haiku_define_fringe_bitmap,
3056 haiku_destroy_fringe_bitmap,
3057 haiku_compute_glyph_string_overhangs,
3058 haiku_draw_glyph_string,
3059 haiku_define_frame_cursor,
3060 haiku_clear_frame_area,
3061 haiku_clear_under_internal_border,
3062 haiku_draw_window_cursor,
3063 haiku_draw_vertical_window_border,
3064 haiku_draw_window_divider,
3065 NULL,
3066 haiku_show_hourglass,
3067 haiku_hide_hourglass,
3068 haiku_default_font_parameter,
3069 };
3070
3071 static void
3072 haiku_make_fullscreen_consistent (struct frame *f)
3073 {
3074 Lisp_Object lval;
3075 struct haiku_output *output;
3076
3077 output = FRAME_OUTPUT_DATA (f);
3078
3079 if (output->fullscreen_mode == FULLSCREEN_MODE_BOTH)
3080 lval = Qfullboth;
3081 else if (output->fullscreen_mode == FULLSCREEN_MODE_WIDTH)
3082 lval = Qfullwidth;
3083 else if (output->fullscreen_mode == FULLSCREEN_MODE_HEIGHT)
3084 lval = Qfullheight;
3085 else if (output->fullscreen_mode == FULLSCREEN_MODE_MAXIMIZED)
3086 lval = Qmaximized;
3087 else
3088 lval = Qnil;
3089
3090 store_frame_param (f, Qfullscreen, lval);
3091 }
3092
3093 static void
3094 haiku_flush_dirty_back_buffer_on (struct frame *f)
3095 {
3096 if (FRAME_GARBAGED_P (f)
3097 || buffer_flipping_blocked_p ()
3098
3099
3100 || !FRAME_COMPLETE_P (f)
3101 || !FRAME_DIRTY_P (f))
3102 return;
3103
3104 haiku_flip_buffers (f);
3105 }
3106
3107
3108
3109 void
3110 haiku_wait_for_event (struct frame *f, int type)
3111 {
3112 int input_blocked_to;
3113 object_wait_info info;
3114 specpdl_ref depth;
3115
3116 input_blocked_to = interrupt_input_blocked;
3117 info.object = port_application_to_emacs;
3118 info.type = B_OBJECT_TYPE_PORT;
3119 info.events = B_EVENT_READ;
3120
3121 depth = SPECPDL_INDEX ();
3122 specbind (Qinhibit_quit, Qt);
3123
3124 FRAME_OUTPUT_DATA (f)->wait_for_event_type = type;
3125
3126 while (FRAME_OUTPUT_DATA (f)->wait_for_event_type == type)
3127 {
3128 if (wait_for_objects (&info, 1) < B_OK)
3129 continue;
3130
3131 pending_signals = true;
3132
3133 totally_unblock_input ();
3134 interrupt_input_blocked = input_blocked_to;
3135 info.events = B_EVENT_READ;
3136 }
3137
3138 unbind_to (depth, Qnil);
3139 }
3140
3141 static int
3142 haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3143 {
3144 int message_count;
3145 void *buf;
3146 ssize_t b_size;
3147 int button_or_motion_p, do_help;
3148 enum haiku_event_type type;
3149 struct input_event inev, inev2;
3150 struct frame *mouse_frame;
3151
3152 message_count = 0;
3153 button_or_motion_p = 0;
3154 do_help = 0;
3155
3156 buf = alloca (200);
3157
3158 block_input ();
3159 haiku_read_size (&b_size, false);
3160 while (b_size >= 0)
3161 {
3162 if (b_size > 200)
3163 emacs_abort ();
3164
3165 EVENT_INIT (inev);
3166 EVENT_INIT (inev2);
3167 inev.kind = NO_EVENT;
3168 inev2.kind = NO_EVENT;
3169 inev.arg = Qnil;
3170 inev2.arg = Qnil;
3171
3172 button_or_motion_p = 0;
3173 haiku_read (&type, buf, b_size);
3174
3175 switch (type)
3176 {
3177 case QUIT_REQUESTED:
3178 {
3179 struct haiku_quit_requested_event *b = buf;
3180 struct frame *f = haiku_window_to_frame (b->window);
3181
3182 if (!f)
3183 continue;
3184
3185 inev.kind = DELETE_WINDOW_EVENT;
3186 XSETFRAME (inev.frame_or_window, f);
3187 break;
3188 }
3189 case FRAME_RESIZED:
3190 {
3191 struct haiku_resize_event *b = buf;
3192 struct frame *f = haiku_window_to_frame (b->window);
3193
3194 if (!f)
3195 continue;
3196
3197 int width = lrint (b->width);
3198 int height = lrint (b->height);
3199
3200 if (FRAME_OUTPUT_DATA (f)->wait_for_event_type
3201 == FRAME_RESIZED)
3202 FRAME_OUTPUT_DATA (f)->wait_for_event_type = -1;
3203
3204 if (FRAME_TOOLTIP_P (f))
3205 {
3206 if (FRAME_PIXEL_WIDTH (f) != width
3207 || FRAME_PIXEL_HEIGHT (f) != height)
3208 SET_FRAME_GARBAGED (f);
3209
3210 FRAME_PIXEL_WIDTH (f) = width;
3211 FRAME_PIXEL_HEIGHT (f) = height;
3212
3213 haiku_clear_under_internal_border (f);
3214
3215
3216
3217
3218 haiku_flush (f);
3219 continue;
3220 }
3221
3222 BView_draw_lock (FRAME_HAIKU_DRAWABLE (f), false, 0, 0, 0, 0);
3223 BView_resize_to (FRAME_HAIKU_DRAWABLE (f), width, height);
3224 BView_draw_unlock (FRAME_HAIKU_DRAWABLE (f));
3225
3226 if (width != FRAME_PIXEL_WIDTH (f)
3227 || height != FRAME_PIXEL_HEIGHT (f)
3228 || (f->new_size_p
3229 && ((f->new_width >= 0 && width != f->new_width)
3230 || (f->new_height >= 0 && height != f->new_height))))
3231 {
3232 change_frame_size (f, width, height, false, true, false);
3233 SET_FRAME_GARBAGED (f);
3234 cancel_mouse_face (f);
3235 haiku_clear_under_internal_border (f);
3236 }
3237
3238 break;
3239 }
3240 case FRAME_EXPOSED:
3241 {
3242 struct haiku_expose_event *b = buf;
3243 struct frame *f = haiku_window_to_frame (b->window);
3244
3245 if (!f)
3246 continue;
3247
3248 expose_frame (f, b->x, b->y, b->width, b->height);
3249 haiku_clear_under_internal_border (f);
3250 break;
3251 }
3252 case KEY_DOWN:
3253 {
3254 struct haiku_key_event *b = buf;
3255 Mouse_HLInfo *hlinfo = &x_display_list->mouse_highlight;
3256 struct frame *f = haiku_window_to_frame (b->window);
3257
3258 if (!f)
3259 continue;
3260
3261
3262
3263 if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
3264 && (f == 0
3265 || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)
3266 || !EQ (f->tab_bar_window, hlinfo->mouse_face_window)))
3267 {
3268 mouse_frame = hlinfo->mouse_face_mouse_frame;
3269
3270 clear_mouse_face (hlinfo);
3271 hlinfo->mouse_face_hidden = true;
3272
3273 if (mouse_frame)
3274 haiku_flush_dirty_back_buffer_on (mouse_frame);
3275 }
3276
3277 inev.code = b->keysym ? b->keysym : b->multibyte_char;
3278
3279 if (b->keysym)
3280 inev.kind = NON_ASCII_KEYSTROKE_EVENT;
3281 else
3282 inev.kind = inev.code > 127 ? MULTIBYTE_CHAR_KEYSTROKE_EVENT :
3283 ASCII_KEYSTROKE_EVENT;
3284
3285 inev.timestamp = b->time / 1000;
3286 inev.modifiers = (haiku_modifiers_to_emacs (b->modifiers)
3287 | (extra_keyboard_modifiers
3288 & (meta_modifier
3289 | hyper_modifier
3290 | ctrl_modifier
3291 | alt_modifier
3292 | shift_modifier)));
3293
3294 XSETFRAME (inev.frame_or_window, f);
3295 break;
3296 }
3297 case ACTIVATION:
3298 {
3299 struct haiku_activation_event *b = buf;
3300 struct frame *f = haiku_window_to_frame (b->window);
3301
3302 if (!f)
3303 continue;
3304
3305 if ((x_display_list->focus_event_frame != f && b->activated_p)
3306 || (x_display_list->focus_event_frame == f && !b->activated_p))
3307 {
3308 haiku_new_focus_frame (b->activated_p ? f : NULL);
3309 if (b->activated_p)
3310 x_display_list->focus_event_frame = f;
3311 else
3312 x_display_list->focus_event_frame = NULL;
3313 inev.kind = b->activated_p ? FOCUS_IN_EVENT : FOCUS_OUT_EVENT;
3314 XSETFRAME (inev.frame_or_window, f);
3315 }
3316
3317 break;
3318 }
3319 case MENU_BAR_LEFT:
3320 {
3321 struct haiku_menu_bar_left_event *b = buf;
3322 struct frame *f = haiku_window_to_frame (b->window);
3323
3324 if (!f)
3325 continue;
3326
3327 if (b->y > 0 && b->y <= FRAME_PIXEL_HEIGHT (f)
3328 && b->x > 0 && b->x <= FRAME_PIXEL_WIDTH (f))
3329 break;
3330
3331 if (f->auto_lower && !popup_activated_p)
3332 haiku_frame_raise_lower (f, 0);
3333
3334 break;
3335 }
3336 case MOUSE_MOTION:
3337 {
3338 struct haiku_mouse_motion_event *b = buf;
3339 struct frame *f = haiku_mouse_or_wdesc_frame (b->window, true);
3340 Mouse_HLInfo *hlinfo = &x_display_list->mouse_highlight;
3341 Lisp_Object frame;
3342
3343 if (!f)
3344 continue;
3345
3346 if (FRAME_TOOLTIP_P (f))
3347 {
3348
3349
3350
3351
3352
3353
3354
3355 if (any_help_event_p
3356 && !(be_drag_and_drop_in_progress ()
3357 && haiku_dnd_follow_tooltip)
3358 && !((EQ (track_mouse, Qdrag_source)
3359 || EQ (track_mouse, Qdropping))
3360 && gui_mouse_grabbed (x_display_list)))
3361 do_help = -1;
3362 break;
3363 }
3364
3365 XSETFRAME (frame, f);
3366
3367 x_display_list->last_mouse_movement_time = b->time / 1000;
3368 button_or_motion_p = 1;
3369
3370 if (hlinfo->mouse_face_hidden)
3371 {
3372 hlinfo->mouse_face_hidden = false;
3373 clear_mouse_face (hlinfo);
3374 haiku_flush_dirty_back_buffer_on (f);
3375 }
3376
3377 if (b->just_exited_p)
3378 {
3379 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
3380
3381 if (f == hlinfo->mouse_face_mouse_frame)
3382 {
3383
3384
3385 clear_mouse_face (hlinfo);
3386 hlinfo->mouse_face_mouse_frame = 0;
3387
3388 haiku_flush_dirty_back_buffer_on (f);
3389 }
3390
3391 if (f == x_display_list->last_mouse_glyph_frame)
3392 x_display_list->last_mouse_glyph_frame = NULL;
3393
3394 if (f->auto_lower && !popup_activated_p
3395
3396 && !BView_inside_scroll_bar (FRAME_HAIKU_VIEW (f),
3397 b->x, b->y))
3398 {
3399
3400
3401
3402 if (b->x > FRAME_PIXEL_WIDTH (f)
3403 || b->y >= FRAME_MENU_BAR_HEIGHT (f)
3404 || b->x < 0
3405 || b->y < 0)
3406 haiku_frame_raise_lower (f, 0);
3407 }
3408
3409 haiku_new_focus_frame (x_display_list->focused_frame);
3410
3411 if (any_help_event_p
3412 && !((EQ (track_mouse, Qdrag_source)
3413 || EQ (track_mouse, Qdropping))
3414 && gui_mouse_grabbed (x_display_list)))
3415 do_help = -1;
3416 }
3417 else
3418 {
3419 struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
3420 struct haiku_rect r = dpyinfo->last_mouse_glyph;
3421
3422
3423
3424 if (FRAMEP (tip_frame)
3425 && FRAME_LIVE_P (XFRAME (tip_frame))
3426 && FRAME_VISIBLE_P (XFRAME (tip_frame))
3427 && f == dpyinfo->last_mouse_motion_frame
3428 && b->x == dpyinfo->last_mouse_motion_x
3429 && b->y == dpyinfo->last_mouse_motion_y)
3430 continue;
3431
3432 dpyinfo->last_mouse_motion_x = b->x;
3433 dpyinfo->last_mouse_motion_y = b->y;
3434 dpyinfo->last_mouse_motion_frame = f;
3435
3436 previous_help_echo_string = help_echo_string;
3437 help_echo_string = Qnil;
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451 if (hlinfo->mouse_face_hidden
3452 || (f != hlinfo->mouse_face_mouse_frame
3453 && !NILP (hlinfo->mouse_face_window)))
3454 {
3455 hlinfo->mouse_face_hidden = 0;
3456 clear_mouse_face (hlinfo);
3457 }
3458
3459 if (f != dpyinfo->last_mouse_glyph_frame
3460 || b->x < r.x || b->x >= r.x + r.width
3461 || b->y < r.y || b->y >= r.y + r.height)
3462 {
3463 f->mouse_moved = true;
3464 note_mouse_highlight (f, b->x, b->y);
3465 remember_mouse_glyph (f, b->x, b->y,
3466 &FRAME_DISPLAY_INFO (f)->last_mouse_glyph);
3467 dpyinfo->last_mouse_glyph_frame = f;
3468 }
3469 else
3470 help_echo_string = previous_help_echo_string;
3471
3472 if (!NILP (Vmouse_autoselect_window))
3473 {
3474 static Lisp_Object last_mouse_window;
3475 Lisp_Object window = window_from_coordinates (f, b->x, b->y, 0, 0, 0);
3476
3477 if (WINDOWP (window)
3478 && !EQ (window, last_mouse_window)
3479 && !EQ (window, selected_window)
3480 && !popup_activated_p
3481 && !MINI_WINDOW_P (XWINDOW (selected_window))
3482 && (!NILP (focus_follows_mouse)
3483 || f == SELECTED_FRAME ()))
3484 {
3485 inev2.kind = SELECT_WINDOW_EVENT;
3486 inev2.frame_or_window = window;
3487 }
3488
3489 last_mouse_window = window;
3490 }
3491
3492 if (f->auto_raise)
3493 {
3494 if (!BWindow_is_active (FRAME_HAIKU_WINDOW (f)))
3495 haiku_frame_raise_lower (f, 1);
3496 }
3497
3498 if (!NILP (help_echo_string)
3499 || !NILP (previous_help_echo_string))
3500 do_help = 1;
3501
3502 if (b->dnd_message)
3503 {
3504
3505
3506
3507 if (any_help_event_p || do_help)
3508 do_help = -1;
3509
3510 if (!be_drag_and_drop_in_progress ())
3511 {
3512 inev.kind = DRAG_N_DROP_EVENT;
3513 inev.arg = Qlambda;
3514
3515 XSETINT (inev.x, b->x);
3516 XSETINT (inev.y, b->y);
3517 XSETFRAME (inev.frame_or_window, f);
3518 }
3519 else
3520 haiku_note_drag_motion ();
3521
3522 break;
3523 }
3524 }
3525
3526 if (FRAME_DIRTY_P (f))
3527 haiku_flush_dirty_back_buffer_on (f);
3528 break;
3529 }
3530 case BUTTON_UP:
3531 case BUTTON_DOWN:
3532 {
3533 struct haiku_button_event *b = buf;
3534 struct frame *f = haiku_mouse_or_wdesc_frame (b->window, false);
3535 Lisp_Object tab_bar_arg = Qnil;
3536 int tab_bar_p = 0, tool_bar_p = 0;
3537 bool up_okay_p = false;
3538 struct scroll_bar *bar;
3539
3540 if (popup_activated_p || !f)
3541 continue;
3542
3543 inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
3544 bar = haiku_scroll_bar_from_widget (b->scroll_bar, b->window);
3545
3546 x_display_list->last_mouse_glyph_frame = 0;
3547 x_display_list->last_mouse_movement_time = b->time / 1000;
3548 button_or_motion_p = 1;
3549
3550
3551 if (WINDOWP (f->tab_bar_window)
3552 && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
3553 {
3554 Lisp_Object window;
3555 int x = b->x;
3556 int y = b->y;
3557
3558 window = window_from_coordinates (f, x, y, 0, true, true);
3559 tab_bar_p = EQ (window, f->tab_bar_window);
3560
3561 if (tab_bar_p)
3562 {
3563 tab_bar_arg = handle_tab_bar_click
3564 (f, x, y, type == BUTTON_DOWN, inev.modifiers);
3565 haiku_flush_dirty_back_buffer_on (f);
3566 }
3567 }
3568
3569 if (WINDOWP (f->tool_bar_window)
3570 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
3571 {
3572 Lisp_Object window;
3573 int x = b->x;
3574 int y = b->y;
3575
3576 window = window_from_coordinates (f, x, y, 0, true, true);
3577 tool_bar_p = (EQ (window, f->tool_bar_window)
3578 && (type != BUTTON_UP
3579 || f->last_tool_bar_item != -1));
3580
3581 if (tool_bar_p)
3582 {
3583 handle_tool_bar_click
3584 (f, x, y, type == BUTTON_DOWN, inev.modifiers);
3585 haiku_flush_dirty_back_buffer_on (f);
3586 }
3587 }
3588
3589 if (type == BUTTON_UP)
3590 {
3591 inev.modifiers |= up_modifier;
3592 up_okay_p = (x_display_list->grabbed & (1 << b->btn_no));
3593 x_display_list->grabbed &= ~(1 << b->btn_no);
3594 }
3595 else
3596 {
3597 up_okay_p = true;
3598 inev.modifiers |= down_modifier;
3599 x_display_list->last_mouse_frame = f;
3600 x_display_list->grabbed |= (1 << b->btn_no);
3601 if (f && !tab_bar_p)
3602 f->last_tab_bar_item = -1;
3603 if (f && !tool_bar_p)
3604 f->last_tool_bar_item = -1;
3605 }
3606
3607 if (bar)
3608 {
3609 inev.kind = (bar->horizontal
3610 ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT
3611 : SCROLL_BAR_CLICK_EVENT);
3612 inev.part = (bar->horizontal
3613 ? scroll_bar_horizontal_handle
3614 : scroll_bar_handle);
3615 }
3616 else if (up_okay_p
3617 && !(tab_bar_p && NILP (tab_bar_arg))
3618 && !tool_bar_p)
3619 inev.kind = MOUSE_CLICK_EVENT;
3620
3621 inev.arg = tab_bar_arg;
3622 inev.code = b->btn_no;
3623
3624 f->mouse_moved = false;
3625
3626 if (bar)
3627 {
3628 if (bar->horizontal)
3629 {
3630 XSETINT (inev.x, min (max (0, b->x - bar->left),
3631 bar->width));
3632 XSETINT (inev.y, bar->width);
3633 }
3634 else
3635 {
3636 XSETINT (inev.x, min (max (0, b->y - bar->top),
3637 bar->height));
3638 XSETINT (inev.y, bar->height);
3639 }
3640
3641 inev.frame_or_window = bar->window;
3642 }
3643 else
3644 {
3645 XSETINT (inev.x, b->x);
3646 XSETINT (inev.y, b->y);
3647 XSETFRAME (inev.frame_or_window, f);
3648 }
3649
3650 break;
3651 }
3652 case ICONIFICATION:
3653 {
3654 struct haiku_iconification_event *b = buf;
3655 struct frame *f = haiku_window_to_frame (b->window);
3656
3657 if (!f)
3658 continue;
3659
3660 if (!b->iconified_p)
3661 {
3662 SET_FRAME_VISIBLE (f, 1);
3663 SET_FRAME_ICONIFIED (f, 0);
3664 inev.kind = DEICONIFY_EVENT;
3665
3666
3667
3668
3669 if (!EmacsView_double_buffered_p (FRAME_HAIKU_VIEW (f)))
3670 {
3671 SET_FRAME_GARBAGED (f);
3672 expose_frame (f, 0, 0, 0, 0);
3673 }
3674 }
3675 else
3676 {
3677 SET_FRAME_VISIBLE (f, 0);
3678 SET_FRAME_ICONIFIED (f, 1);
3679 inev.kind = ICONIFY_EVENT;
3680 }
3681
3682 XSETFRAME (inev.frame_or_window, f);
3683 break;
3684 }
3685 case MOVE_EVENT:
3686 {
3687 struct haiku_move_event *b = buf;
3688 struct frame *f = haiku_window_to_frame (b->window);
3689 int top, left;
3690 struct frame *p;
3691
3692 if (!f)
3693 continue;
3694
3695 FRAME_OUTPUT_DATA (f)->frame_x = b->x;
3696 FRAME_OUTPUT_DATA (f)->frame_y = b->y;
3697
3698 if (FRAME_PARENT_FRAME (f))
3699 haiku_coords_from_parent (f, &b->x, &b->y);
3700
3701 left = b->x - b->decorator_width;
3702 top = b->y - b->decorator_height;
3703
3704 if (left != f->left_pos || top != f->top_pos)
3705 {
3706 inev.kind = MOVE_FRAME_EVENT;
3707
3708 XSETINT (inev.x, left);
3709 XSETINT (inev.y, top);
3710
3711 f->left_pos = left;
3712 f->top_pos = top;
3713
3714 p = FRAME_PARENT_FRAME (f);
3715
3716 if (p)
3717 EmacsWindow_move_weak_child (FRAME_HAIKU_WINDOW (p),
3718 b->window, left, top);
3719
3720 XSETFRAME (inev.frame_or_window, f);
3721 }
3722
3723 haiku_make_fullscreen_consistent (f);
3724 break;
3725 }
3726 case SCROLL_BAR_VALUE_EVENT:
3727 {
3728 struct haiku_scroll_bar_value_event *b = buf;
3729 struct scroll_bar *bar
3730 = haiku_scroll_bar_from_widget (b->scroll_bar, b->window);
3731 int portion, whole;
3732
3733 if (!bar)
3734 continue;
3735
3736 struct window *w = XWINDOW (bar->window);
3737
3738 if (bar->update != -1)
3739 {
3740 bar->update = -1;
3741 break;
3742 }
3743
3744 if (bar->position != b->position)
3745 {
3746 inev.kind = (bar->horizontal
3747 ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT :
3748 SCROLL_BAR_CLICK_EVENT);
3749 inev.part = (bar->horizontal
3750 ? scroll_bar_horizontal_handle
3751 : scroll_bar_handle);
3752
3753 if (bar->horizontal)
3754 {
3755 portion = bar->total * ((float) b->position
3756 / BE_SB_MAX);
3757 whole = (bar->total
3758 * ((float) (BE_SB_MAX - bar->page_size)
3759 / BE_SB_MAX));
3760 portion = min (portion, whole);
3761 }
3762 else
3763 {
3764 whole = BE_SB_MAX - bar->page_size;
3765 portion = min (b->position, whole);
3766 }
3767
3768 XSETINT (inev.x, portion);
3769 XSETINT (inev.y, whole);
3770 XSETWINDOW (inev.frame_or_window, w);
3771 }
3772 break;
3773 }
3774 case SCROLL_BAR_PART_EVENT:
3775 {
3776 struct haiku_scroll_bar_part_event *b = buf;
3777 struct scroll_bar *bar
3778 = haiku_scroll_bar_from_widget (b->scroll_bar, b->window);
3779
3780 if (!bar)
3781 continue;
3782
3783 inev.kind = (bar->horizontal ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT
3784 : SCROLL_BAR_CLICK_EVENT);
3785
3786 bar->dragging = 0;
3787
3788 switch (b->part)
3789 {
3790 case HAIKU_SCROLL_BAR_UP_BUTTON:
3791 inev.part = (bar->horizontal
3792 ? scroll_bar_left_arrow
3793 : scroll_bar_up_arrow);
3794 break;
3795 case HAIKU_SCROLL_BAR_DOWN_BUTTON:
3796 inev.part = (bar->horizontal
3797 ? scroll_bar_right_arrow
3798 : scroll_bar_down_arrow);
3799 break;
3800 }
3801
3802 XSETINT (inev.x, 0);
3803 XSETINT (inev.y, 0);
3804 inev.frame_or_window = bar->window;
3805
3806 break;
3807 }
3808 case SCROLL_BAR_DRAG_EVENT:
3809 {
3810 struct haiku_scroll_bar_drag_event *b = buf;
3811 struct scroll_bar *bar
3812 = haiku_scroll_bar_from_widget (b->scroll_bar, b->window);
3813
3814 if (!bar)
3815 continue;
3816
3817 bar->dragging = b->dragging_p;
3818 if (!b->dragging_p && bar->horizontal)
3819 set_horizontal_scroll_bar (XWINDOW (bar->window));
3820 else if (!b->dragging_p)
3821 set_vertical_scroll_bar (XWINDOW (bar->window));
3822 break;
3823 }
3824 case WHEEL_MOVE_EVENT:
3825 {
3826 struct haiku_wheel_move_event *b = buf;
3827 struct frame *f = haiku_window_to_frame (b->window);
3828 int x, y, scroll_width, scroll_height;
3829 static float px = 0.0f, py = 0.0f;
3830 Lisp_Object wheel_window;
3831
3832 if (!f)
3833 continue;
3834
3835 BView_get_mouse (FRAME_HAIKU_VIEW (f), &x, &y);
3836
3837 wheel_window = window_from_coordinates (f, x, y, 0, false, false);
3838
3839 if (NILP (wheel_window))
3840 {
3841 scroll_width = FRAME_PIXEL_WIDTH (f);
3842 scroll_height = FRAME_PIXEL_HEIGHT (f);
3843 }
3844 else
3845 {
3846 scroll_width = XWINDOW (wheel_window)->pixel_width;
3847 scroll_height = XWINDOW (wheel_window)->pixel_height;
3848 }
3849
3850 inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
3851
3852 inev2.modifiers = inev.modifiers;
3853
3854 if (signbit (px) != signbit (b->delta_x))
3855 px = 0;
3856
3857 if (signbit (py) != signbit (b->delta_y))
3858 py = 0;
3859
3860 px += (b->delta_x
3861 * powf (scroll_width, 2.0f / 3.0f));
3862 py += (b->delta_y
3863 * powf (scroll_height, 2.0f / 3.0f));
3864
3865 if (fabsf (py) >= FRAME_LINE_HEIGHT (f)
3866 || fabsf (px) >= FRAME_COLUMN_WIDTH (f)
3867 || !mwheel_coalesce_scroll_events)
3868 {
3869 inev.kind = (fabsf (px) > fabsf (py)
3870 ? HORIZ_WHEEL_EVENT
3871 : WHEEL_EVENT);
3872 inev.code = 0;
3873
3874 XSETINT (inev.x, x);
3875 XSETINT (inev.y, y);
3876 inev.arg = list3 (Qnil, make_float (-px),
3877 make_float (-py));
3878 XSETFRAME (inev.frame_or_window, f);
3879
3880 inev.modifiers |= (signbit (inev.kind == HORIZ_WHEEL_EVENT
3881 ? px : py)
3882 ? up_modifier
3883 : down_modifier);
3884 py = 0.0f;
3885 px = 0.0f;
3886
3887 if (be_drag_and_drop_in_progress ())
3888 haiku_note_drag_wheel (&inev);
3889 }
3890
3891 break;
3892 }
3893 case MENU_BAR_RESIZE:
3894 {
3895 struct haiku_menu_bar_resize_event *b = buf;
3896 struct frame *f = haiku_window_to_frame (b->window);
3897
3898 if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
3899 continue;
3900
3901 if (FRAME_OUTPUT_DATA (f)->wait_for_event_type
3902 == MENU_BAR_RESIZE)
3903 FRAME_OUTPUT_DATA (f)->wait_for_event_type = -1;
3904
3905 int old_height = FRAME_MENU_BAR_HEIGHT (f);
3906
3907 FRAME_MENU_BAR_HEIGHT (f) = b->height;
3908 FRAME_MENU_BAR_LINES (f)
3909 = (b->height + FRAME_LINE_HEIGHT (f)) / FRAME_LINE_HEIGHT (f);
3910
3911 if (old_height != b->height)
3912 {
3913 adjust_frame_size (f, -1, -1, 3, true, Qmenu_bar_lines);
3914 haiku_clear_under_internal_border (f);
3915 }
3916 break;
3917 }
3918 case MENU_BAR_CLICK:
3919 {
3920 struct haiku_menu_bar_click_event *b = buf;
3921 struct frame *f = haiku_window_to_frame (b->window);
3922
3923 if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
3924 continue;
3925
3926 if (!FRAME_OUTPUT_DATA (f)->saved_menu_event)
3927 FRAME_OUTPUT_DATA (f)->saved_menu_event = xmalloc (sizeof *b);
3928 *FRAME_OUTPUT_DATA (f)->saved_menu_event = *b;
3929 inev.kind = MENU_BAR_ACTIVATE_EVENT;
3930 XSETFRAME (inev.frame_or_window, f);
3931 break;
3932 }
3933 case MENU_BAR_OPEN:
3934 case MENU_BAR_CLOSE:
3935 {
3936 struct haiku_menu_bar_state_event *b = buf;
3937 struct frame *f = haiku_window_to_frame (b->window);
3938
3939 if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
3940 continue;
3941
3942 if (type == MENU_BAR_OPEN)
3943 {
3944 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
3945 popup_activated_p += 1;
3946 }
3947 else
3948 {
3949 if (!popup_activated_p)
3950 emacs_abort ();
3951
3952 if (FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
3953 {
3954 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 0;
3955 popup_activated_p -= 1;
3956 }
3957 }
3958 break;
3959 }
3960 case MENU_BAR_SELECT_EVENT:
3961 {
3962 struct haiku_menu_bar_select_event *b = buf;
3963 struct frame *f = haiku_window_to_frame (b->window);
3964
3965 if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
3966 continue;
3967
3968 find_and_call_menu_selection (f, f->menu_bar_items_used,
3969 f->menu_bar_vector, b->ptr);
3970 break;
3971 }
3972 case MENU_BAR_HELP_EVENT:
3973 {
3974 struct haiku_menu_bar_help_event *b = buf;
3975
3976 if (!popup_activated_p)
3977 continue;
3978
3979 struct frame *f = haiku_window_to_frame (b->window);
3980 if (!f || !FRAME_EXTERNAL_MENU_BAR (f)
3981 || !FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
3982 continue;
3983
3984 run_menu_bar_help_event (f, b->mb_idx);
3985 break;
3986 }
3987 case ZOOM_EVENT:
3988 {
3989 struct haiku_zoom_event *b = buf;
3990 struct frame *f = haiku_window_to_frame (b->window);
3991
3992 if (!f)
3993 continue;
3994
3995 if (b->fullscreen_mode == FULLSCREEN_MODE_MAXIMIZED)
3996 f->want_fullscreen = FULLSCREEN_NONE;
3997 else
3998 f->want_fullscreen = FULLSCREEN_MAXIMIZED;
3999
4000 FRAME_TERMINAL (f)->fullscreen_hook (f);
4001 break;
4002 }
4003 case DRAG_AND_DROP_EVENT:
4004 {
4005 struct haiku_drag_and_drop_event *b = buf;
4006 struct frame *f = haiku_window_to_frame (b->window);
4007
4008 if (!f)
4009 {
4010 BMessage_delete (b->message);
4011 continue;
4012 }
4013
4014 inev.kind = DRAG_N_DROP_EVENT;
4015 inev.arg = haiku_message_to_lisp (b->message);
4016
4017 XSETINT (inev.x, b->x);
4018 XSETINT (inev.y, b->y);
4019 XSETFRAME (inev.frame_or_window, f);
4020
4021 BMessage_delete (b->message);
4022 break;
4023 }
4024 case SCREEN_CHANGED_EVENT:
4025 {
4026 struct haiku_screen_changed_event *b = buf;
4027
4028 inev.kind = MONITORS_CHANGED_EVENT;
4029 XSETTERMINAL (inev.arg, x_display_list->terminal);
4030 inev.timestamp = b->when / 1000;
4031 break;
4032 }
4033 case CLIPBOARD_CHANGED_EVENT:
4034 be_handle_clipboard_changed_message ();
4035 break;
4036 case APP_QUIT_REQUESTED_EVENT:
4037 inev.kind = SAVE_SESSION_EVENT;
4038 inev.arg = Qt;
4039 break;
4040 case FONT_CHANGE_EVENT:
4041
4042
4043 haiku_handle_font_change_event (buf, &inev);
4044 break;
4045
4046 case NOTIFICATION_CLICK_EVENT:
4047
4048 #if 0
4049 {
4050 struct haiku_notification_click_event *b = buf;
4051
4052 inev.kind = NOTIFICATION_CLICKED_EVENT;
4053 inev.arg = make_int (b->id);
4054 break;
4055 }
4056 #endif
4057
4058 case KEY_UP:
4059 case DUMMY_EVENT:
4060 default:
4061 break;
4062 }
4063
4064 haiku_read_size (&b_size, false);
4065
4066 if (inev.kind != NO_EVENT)
4067 {
4068 if (inev.kind != HELP_EVENT && !inev.timestamp)
4069 inev.timestamp = (button_or_motion_p
4070 ? x_display_list->last_mouse_movement_time
4071 : system_time () / 1000);
4072 kbd_buffer_store_event_hold (&inev, hold_quit);
4073 ++message_count;
4074 }
4075
4076 if (inev2.kind != NO_EVENT)
4077 {
4078 if (inev2.kind != HELP_EVENT && !inev.timestamp)
4079 inev2.timestamp = (button_or_motion_p
4080 ? x_display_list->last_mouse_movement_time
4081 : system_time () / 1000);
4082 kbd_buffer_store_event_hold (&inev2, hold_quit);
4083 ++message_count;
4084 }
4085 }
4086
4087 if (do_help && !(hold_quit && hold_quit->kind != NO_EVENT))
4088 {
4089 Lisp_Object help_frame = Qnil;
4090
4091 if (x_display_list->last_mouse_frame)
4092 XSETFRAME (help_frame,
4093 x_display_list->last_mouse_frame);
4094
4095 if (do_help > 0)
4096 {
4097 any_help_event_p = true;
4098 gen_help_event (help_echo_string, help_frame,
4099 help_echo_window, help_echo_object,
4100 help_echo_pos);
4101 }
4102 else
4103 {
4104 help_echo_string = Qnil;
4105 gen_help_event (Qnil, help_frame, Qnil, Qnil, 0);
4106 }
4107 }
4108
4109 unblock_input ();
4110
4111 return message_count;
4112 }
4113
4114 static Lisp_Object
4115 haiku_get_focus_frame (struct frame *f)
4116 {
4117 Lisp_Object lisp_focus;
4118 struct frame *focus;
4119
4120 focus = FRAME_DISPLAY_INFO (f)->focused_frame;
4121
4122 if (!focus)
4123 return Qnil;
4124
4125 XSETFRAME (lisp_focus, focus);
4126 return lisp_focus;
4127 }
4128
4129 static void
4130 haiku_frame_rehighlight (struct frame *frame)
4131 {
4132 haiku_rehighlight ();
4133 }
4134
4135 static void
4136 haiku_delete_window (struct frame *f)
4137 {
4138 check_window_system (f);
4139 haiku_free_frame_resources (f);
4140 }
4141
4142 static void
4143 haiku_free_pixmap (struct frame *f, Emacs_Pixmap pixmap)
4144 {
4145 BBitmap_free (pixmap);
4146 }
4147
4148 static void
4149 haiku_flash (struct frame *f)
4150 {
4151
4152 int height = FRAME_PIXEL_HEIGHT (f);
4153
4154 int flash_height = FRAME_LINE_HEIGHT (f);
4155
4156 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
4157 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
4158 int width = flash_right - flash_left;
4159 void *view = FRAME_HAIKU_DRAWABLE (f);
4160 object_wait_info info;
4161 bigtime_t wakeup;
4162
4163 info.object = port_application_to_emacs;
4164 info.type = B_OBJECT_TYPE_PORT;
4165 info.events = B_EVENT_READ;
4166 wakeup = system_time () + 150000;
4167
4168 BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f),
4169 FRAME_PIXEL_HEIGHT (f));
4170 BView_StartClip (view);
4171
4172 if (height > 3 * FRAME_LINE_HEIGHT (f))
4173 {
4174 BView_InvertRect (view, flash_left,
4175 (FRAME_INTERNAL_BORDER_WIDTH (f)
4176 + FRAME_TOP_MARGIN_HEIGHT (f)),
4177 width, flash_height);
4178
4179 BView_InvertRect (view, flash_left,
4180 (height - flash_height
4181 - FRAME_INTERNAL_BORDER_WIDTH (f)
4182 - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
4183 width, flash_height);
4184 }
4185 else
4186
4187 BView_InvertRect (view, flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4188 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4189 BView_EndClip (view);
4190 BView_draw_unlock (view);
4191
4192 flush_frame (f);
4193
4194 if (EmacsView_double_buffered_p (view))
4195 haiku_flip_buffers (f);
4196
4197
4198
4199 while (!detect_input_pending ())
4200 {
4201
4202 if (wakeup < system_time ())
4203 break;
4204
4205
4206 wait_for_objects_etc (&info, 1, B_ABSOLUTE_TIMEOUT, wakeup);
4207
4208 if (info.events & B_EVENT_READ)
4209 break;
4210
4211 info.events = B_EVENT_READ;
4212 }
4213
4214 BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f),
4215 FRAME_PIXEL_HEIGHT (f));
4216 BView_StartClip (view);
4217
4218 if (height > 3 * FRAME_LINE_HEIGHT (f))
4219 {
4220 BView_InvertRect (view, flash_left,
4221 (FRAME_INTERNAL_BORDER_WIDTH (f)
4222 + FRAME_TOP_MARGIN_HEIGHT (f)),
4223 width, flash_height);
4224
4225 BView_InvertRect (view, flash_left,
4226 (height - flash_height
4227 - FRAME_INTERNAL_BORDER_WIDTH (f)
4228 - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
4229 width, flash_height);
4230 }
4231 else
4232
4233 BView_InvertRect (view, flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4234 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4235 BView_EndClip (view);
4236 BView_draw_unlock (view);
4237
4238 flush_frame (f);
4239 if (EmacsView_double_buffered_p (view))
4240 haiku_flip_buffers (f);
4241 }
4242
4243 static void
4244 haiku_beep (struct frame *f)
4245 {
4246 if (visible_bell)
4247 {
4248 void *view = FRAME_HAIKU_VIEW (f);
4249 if (view)
4250 {
4251 block_input ();
4252 haiku_flash (f);
4253 unblock_input ();
4254 }
4255 }
4256 else
4257 haiku_ring_bell ();
4258 }
4259
4260 static void
4261 haiku_toggle_invisible_pointer (struct frame *f, bool invisible_p)
4262 {
4263 void *view = FRAME_HAIKU_VIEW (f);
4264
4265 if (view && !FRAME_TOOLTIP_P (f))
4266 {
4267 block_input ();
4268 BView_set_view_cursor (view, (invisible_p
4269 ? FRAME_OUTPUT_DATA (f)->no_cursor
4270 : FRAME_OUTPUT_DATA (f)->current_cursor));
4271 f->pointer_invisible = invisible_p;
4272 unblock_input ();
4273 }
4274 }
4275
4276 static void
4277 haiku_fullscreen (struct frame *f)
4278 {
4279 enum haiku_fullscreen_mode mode;
4280
4281
4282
4283
4284
4285 if (!FRAME_OUTPUT_DATA (f)->configury_done)
4286 return;
4287
4288 if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
4289 mode = FULLSCREEN_MODE_MAXIMIZED;
4290 else if (f->want_fullscreen == FULLSCREEN_BOTH)
4291 mode = FULLSCREEN_MODE_BOTH;
4292 else if (f->want_fullscreen == FULLSCREEN_WIDTH)
4293 mode = FULLSCREEN_MODE_WIDTH;
4294 else if (f->want_fullscreen == FULLSCREEN_HEIGHT)
4295 mode = FULLSCREEN_MODE_HEIGHT;
4296 else
4297 mode = FULLSCREEN_MODE_NONE;
4298
4299 f->want_fullscreen = FULLSCREEN_NONE;
4300 be_set_window_fullscreen_mode (FRAME_HAIKU_WINDOW (f), mode);
4301 FRAME_OUTPUT_DATA (f)->fullscreen_mode = mode;
4302
4303 haiku_update_size_hints (f);
4304 haiku_make_fullscreen_consistent (f);
4305 }
4306
4307 static struct terminal *
4308 haiku_create_terminal (struct haiku_display_info *dpyinfo)
4309 {
4310 struct terminal *terminal;
4311
4312 terminal = create_terminal (output_haiku, &haiku_redisplay_interface);
4313
4314 terminal->display_info.haiku = dpyinfo;
4315 dpyinfo->terminal = terminal;
4316 terminal->kboard = allocate_kboard (Qhaiku);
4317
4318 terminal->iconify_frame_hook = haiku_iconify_frame;
4319 terminal->focus_frame_hook = haiku_focus_frame;
4320 terminal->ring_bell_hook = haiku_beep;
4321 terminal->popup_dialog_hook = haiku_popup_dialog;
4322 terminal->frame_visible_invisible_hook = haiku_set_frame_visible_invisible;
4323 terminal->set_frame_offset_hook = haiku_set_offset;
4324 terminal->delete_terminal_hook = haiku_delete_terminal;
4325 terminal->get_string_resource_hook = haiku_get_string_resource;
4326 terminal->set_new_font_hook = haiku_new_font;
4327 terminal->defined_color_hook = haiku_defined_color;
4328 terminal->set_window_size_hook = haiku_set_window_size;
4329 terminal->read_socket_hook = haiku_read_socket;
4330 terminal->implicit_set_name_hook = haiku_implicitly_set_name;
4331 terminal->mouse_position_hook = haiku_mouse_position;
4332 terminal->delete_frame_hook = haiku_delete_window;
4333 terminal->frame_up_to_date_hook = haiku_frame_up_to_date;
4334 terminal->buffer_flipping_unblocked_hook = haiku_buffer_flipping_unblocked_hook;
4335 terminal->clear_frame_hook = haiku_clear_frame;
4336 terminal->change_tab_bar_height_hook = haiku_change_tab_bar_height;
4337 terminal->change_tool_bar_height_hook = haiku_change_tool_bar_height;
4338 terminal->set_vertical_scroll_bar_hook = haiku_set_vertical_scroll_bar;
4339 terminal->set_horizontal_scroll_bar_hook = haiku_set_horizontal_scroll_bar;
4340 terminal->set_scroll_bar_default_height_hook = haiku_set_scroll_bar_default_height;
4341 terminal->set_scroll_bar_default_width_hook = haiku_set_scroll_bar_default_width;
4342 terminal->judge_scroll_bars_hook = haiku_judge_scroll_bars;
4343 terminal->condemn_scroll_bars_hook = haiku_condemn_scroll_bars;
4344 terminal->redeem_scroll_bar_hook = haiku_redeem_scroll_bar;
4345 terminal->update_begin_hook = haiku_update_begin;
4346 terminal->update_end_hook = haiku_update_end;
4347 terminal->frame_rehighlight_hook = haiku_frame_rehighlight;
4348 terminal->query_frame_background_color = haiku_query_frame_background_color;
4349 terminal->free_pixmap = haiku_free_pixmap;
4350 terminal->frame_raise_lower_hook = haiku_frame_raise_lower;
4351 terminal->menu_show_hook = haiku_menu_show;
4352 terminal->toggle_invisible_pointer_hook = haiku_toggle_invisible_pointer;
4353 terminal->fullscreen_hook = haiku_fullscreen;
4354 terminal->toolkit_position_hook = haiku_toolkit_position;
4355 terminal->activate_menubar_hook = haiku_activate_menubar;
4356 terminal->get_focus_frame = haiku_get_focus_frame;
4357
4358 return terminal;
4359 }
4360
4361 struct haiku_display_info *
4362 haiku_term_init (void)
4363 {
4364 struct haiku_display_info *dpyinfo;
4365 struct terminal *terminal;
4366 Lisp_Object color_file, color_map, system_name;
4367 ptrdiff_t nbytes;
4368 void *name_buffer;
4369
4370 block_input ();
4371
4372 Fset_input_interrupt_mode (Qt);
4373 baud_rate = 19200;
4374 dpyinfo = xzalloc (sizeof *dpyinfo);
4375 haiku_io_init ();
4376
4377 if (port_application_to_emacs < B_OK
4378 || port_emacs_to_session_manager < B_OK)
4379 emacs_abort ();
4380
4381 color_file = Fexpand_file_name (build_string ("rgb.txt"),
4382 Fsymbol_value (Qdata_directory));
4383 color_map = Fx_load_color_file (color_file);
4384
4385 if (NILP (color_map))
4386 fatal ("Could not read %s.\n", SDATA (color_file));
4387
4388 dpyinfo->color_map = color_map;
4389 dpyinfo->display = BApplication_setup ();
4390 dpyinfo->next = x_display_list;
4391 dpyinfo->n_planes = be_get_display_planes ();
4392 be_get_display_resolution (&dpyinfo->resx, &dpyinfo->resy);
4393
4394 x_display_list = dpyinfo;
4395
4396 terminal = haiku_create_terminal (dpyinfo);
4397 if (current_kboard == initial_kboard)
4398 current_kboard = terminal->kboard;
4399
4400 terminal->kboard->reference_count++;
4401
4402
4403 terminal->reference_count++;
4404 terminal->name = xstrdup ("be");
4405
4406 dpyinfo->name_list_element = Fcons (build_string ("be"), Qnil);
4407 dpyinfo->smallest_font_height = 1;
4408 dpyinfo->smallest_char_width = 1;
4409
4410 gui_init_fringe (terminal->rif);
4411
4412 #define ASSIGN_CURSOR(cursor, cursor_id) \
4413 (dpyinfo->cursor = be_create_cursor_from_id (cursor_id))
4414 ASSIGN_CURSOR (text_cursor, CURSOR_ID_I_BEAM);
4415 ASSIGN_CURSOR (nontext_cursor, CURSOR_ID_SYSTEM_DEFAULT);
4416 ASSIGN_CURSOR (modeline_cursor, CURSOR_ID_CONTEXT_MENU);
4417 ASSIGN_CURSOR (hand_cursor, CURSOR_ID_GRAB);
4418 ASSIGN_CURSOR (hourglass_cursor, CURSOR_ID_PROGRESS);
4419 ASSIGN_CURSOR (horizontal_drag_cursor, CURSOR_ID_RESIZE_EAST_WEST);
4420 ASSIGN_CURSOR (vertical_drag_cursor, CURSOR_ID_RESIZE_NORTH_SOUTH);
4421 ASSIGN_CURSOR (left_edge_cursor, CURSOR_ID_RESIZE_WEST);
4422 ASSIGN_CURSOR (top_left_corner_cursor, CURSOR_ID_RESIZE_NORTH_WEST);
4423 ASSIGN_CURSOR (top_edge_cursor, CURSOR_ID_RESIZE_NORTH);
4424 ASSIGN_CURSOR (top_right_corner_cursor, CURSOR_ID_RESIZE_NORTH_EAST);
4425 ASSIGN_CURSOR (right_edge_cursor, CURSOR_ID_RESIZE_EAST);
4426 ASSIGN_CURSOR (bottom_right_corner_cursor, CURSOR_ID_RESIZE_SOUTH_EAST);
4427 ASSIGN_CURSOR (bottom_edge_cursor, CURSOR_ID_RESIZE_SOUTH);
4428 ASSIGN_CURSOR (bottom_left_corner_cursor, CURSOR_ID_RESIZE_SOUTH_WEST);
4429 ASSIGN_CURSOR (no_cursor, CURSOR_ID_NO_CURSOR);
4430 #undef ASSIGN_CURSOR
4431
4432 system_name = Fsystem_name ();
4433
4434 if (STRINGP (system_name))
4435 {
4436 nbytes = sizeof "GNU Emacs" + sizeof " at ";
4437
4438 if (ckd_add (&nbytes, nbytes, SBYTES (system_name)))
4439 memory_full (SIZE_MAX);
4440
4441 name_buffer = alloca (nbytes);
4442 sprintf (name_buffer, "%s%s%s", "GNU Emacs",
4443 " at ", SDATA (system_name));
4444 dpyinfo->default_name = build_string (name_buffer);
4445 }
4446 else
4447 dpyinfo->default_name = build_string ("GNU Emacs");
4448
4449 haiku_start_watching_selections ();
4450
4451
4452 be_listen_font_settings ();
4453 unblock_input ();
4454
4455 return dpyinfo;
4456 }
4457
4458 void
4459 put_xrm_resource (Lisp_Object name, Lisp_Object val)
4460 {
4461 eassert (STRINGP (name));
4462 eassert (STRINGP (val) || NILP (val));
4463
4464 Lisp_Object lval = assoc_no_quit (name, rdb);
4465 if (!NILP (lval))
4466 Fsetcdr (lval, val);
4467 else
4468 rdb = Fcons (Fcons (name, val), rdb);
4469 }
4470
4471 void
4472 haiku_clear_under_internal_border (struct frame *f)
4473 {
4474 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
4475
4476
4477 && FRAME_FACE_CACHE (f))
4478 {
4479 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
4480 int width = FRAME_PIXEL_WIDTH (f);
4481 int height = FRAME_PIXEL_HEIGHT (f);
4482 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
4483 int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
4484 int face_id = (FRAME_PARENT_FRAME (f)
4485 ? (!NILP (Vface_remapping_alist)
4486 ? lookup_basic_face (NULL, f,
4487 CHILD_FRAME_BORDER_FACE_ID)
4488 : CHILD_FRAME_BORDER_FACE_ID)
4489 : (!NILP (Vface_remapping_alist)
4490 ? lookup_basic_face (NULL, f,
4491 INTERNAL_BORDER_FACE_ID)
4492 : INTERNAL_BORDER_FACE_ID));
4493 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
4494 void *view = FRAME_HAIKU_DRAWABLE (f);
4495
4496 block_input ();
4497 BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f),
4498 FRAME_PIXEL_HEIGHT (f));
4499 BView_StartClip (view);
4500 BView_ClipToRect (view, 0, 0, FRAME_PIXEL_WIDTH (f),
4501 FRAME_PIXEL_HEIGHT (f));
4502
4503 if (face)
4504 BView_SetHighColor (view, face->background);
4505 else
4506 BView_SetHighColor (view, FRAME_BACKGROUND_PIXEL (f));
4507
4508 BView_FillRectangle (view, 0, margin, width, border);
4509 BView_FillRectangle (view, 0, 0, border, height);
4510 BView_FillRectangle (view, 0, margin, width, border);
4511 BView_FillRectangle (view, width - border, 0, border, height);
4512 BView_FillRectangle (view, 0, height - bottom_margin - border,
4513 width, border);
4514 BView_EndClip (view);
4515 BView_draw_unlock (view);
4516 unblock_input ();
4517 }
4518 }
4519
4520 void
4521 mark_haiku_display (void)
4522 {
4523 if (x_display_list)
4524 {
4525 mark_object (x_display_list->color_map);
4526 mark_object (x_display_list->default_name);
4527 }
4528 }
4529
4530 void
4531 haiku_scroll_bar_remove (struct scroll_bar *bar)
4532 {
4533 void *view;
4534 struct frame *f;
4535
4536 f = WINDOW_XFRAME (XWINDOW (bar->window));
4537 view = FRAME_HAIKU_DRAWABLE (f);
4538
4539 block_input ();
4540 BView_forget_scroll_bar (view, bar->left, bar->top,
4541 bar->width, bar->height);
4542 BScrollBar_delete (bar->scroll_bar);
4543 expose_frame (WINDOW_XFRAME (XWINDOW (bar->window)),
4544 bar->left, bar->top, bar->width, bar->height);
4545
4546 if (bar->horizontal)
4547 wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
4548 else
4549 wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
4550 unblock_input ();
4551 };
4552
4553 void
4554 haiku_set_offset (struct frame *frame, int x, int y,
4555 int change_gravity)
4556 {
4557 Lisp_Object lframe;
4558
4559
4560
4561
4562 XSETFRAME (lframe, frame);
4563 if (EQ (Fframe_parameter (lframe, Qfullscreen), Qfullboth)
4564
4565
4566 && frame->want_fullscreen == FULLSCREEN_NONE
4567
4568
4569
4570 && FRAME_OUTPUT_DATA (frame)->configury_done)
4571 return;
4572
4573 if (change_gravity > 0)
4574 {
4575 frame->top_pos = y;
4576 frame->left_pos = x;
4577 frame->size_hint_flags &= ~ (XNegative | YNegative);
4578 if (x < 0)
4579 frame->size_hint_flags |= XNegative;
4580 if (y < 0)
4581 frame->size_hint_flags |= YNegative;
4582 frame->win_gravity = NorthWestGravity;
4583 }
4584
4585 haiku_update_size_hints (frame);
4586
4587 block_input ();
4588 if (change_gravity)
4589 BWindow_set_offset (FRAME_HAIKU_WINDOW (frame), x, y);
4590 unblock_input ();
4591 }
4592
4593 #ifdef USE_BE_CAIRO
4594 cairo_t *
4595 haiku_begin_cr_clip (struct frame *f, struct glyph_string *s)
4596 {
4597 cairo_t *cr = FRAME_CR_CONTEXT (f);
4598
4599 if (!cr)
4600 return NULL;
4601
4602 cairo_save (cr);
4603 return cr;
4604 }
4605
4606 void
4607 haiku_end_cr_clip (cairo_t *cr)
4608 {
4609 if (!cr)
4610 return;
4611
4612 cairo_restore (cr);
4613 }
4614 #endif
4615
4616 void
4617 haiku_merge_cursor_foreground (struct glyph_string *s,
4618 unsigned long *foreground_out,
4619 unsigned long *background_out)
4620 {
4621 unsigned long background = FRAME_CURSOR_COLOR (s->f).pixel;
4622 unsigned long foreground = s->face->background;
4623
4624 if (background == foreground)
4625 foreground = s->face->background;
4626 if (background == foreground)
4627 foreground = FRAME_OUTPUT_DATA (s->f)->cursor_fg;
4628 if (background == foreground)
4629 foreground = s->face->foreground;
4630
4631 if (background == s->face->background
4632 && foreground == s->face->foreground)
4633 {
4634 background = s->face->foreground;
4635 foreground = s->face->background;
4636 }
4637
4638 if (foreground_out)
4639 *foreground_out = foreground;
4640 if (background_out)
4641 *background_out = background;
4642 }
4643
4644 void
4645 syms_of_haikuterm (void)
4646 {
4647 DEFVAR_BOOL ("haiku-initialized", haiku_initialized,
4648 doc: );
4649
4650 DEFVAR_BOOL ("x-use-underline-position-properties",
4651 x_use_underline_position_properties,
4652 doc: );
4653 x_use_underline_position_properties = 1;
4654
4655 DEFVAR_BOOL ("x-underline-at-descent-line",
4656 x_underline_at_descent_line,
4657 doc: );
4658 x_underline_at_descent_line = 0;
4659
4660 DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
4661 doc: );
4662 Vx_toolkit_scroll_bars = Qt;
4663
4664 DEFVAR_BOOL ("haiku-debug-on-fatal-error", haiku_debug_on_fatal_error,
4665 doc: );
4666 haiku_debug_on_fatal_error = 1;
4667
4668 DEFSYM (Qshift, "shift");
4669 DEFSYM (Qcontrol, "control");
4670 DEFSYM (Qoption, "option");
4671 DEFSYM (Qcommand, "command");
4672
4673 DEFSYM (Qdata_directory, "data-directory");
4674
4675 DEFVAR_LISP ("haiku-meta-keysym", Vhaiku_meta_keysym,
4676 doc:
4677
4678
4679
4680 );
4681 Vhaiku_meta_keysym = Qnil;
4682
4683 DEFVAR_LISP ("haiku-control-keysym", Vhaiku_control_keysym,
4684 doc:
4685
4686
4687
4688 );
4689 Vhaiku_control_keysym = Qnil;
4690
4691 DEFVAR_LISP ("haiku-super-keysym", Vhaiku_super_keysym,
4692 doc:
4693
4694
4695
4696 );
4697 Vhaiku_super_keysym = Qnil;
4698
4699 DEFVAR_LISP ("haiku-shift-keysym", Vhaiku_shift_keysym,
4700 doc:
4701
4702
4703
4704 );
4705 Vhaiku_shift_keysym = Qnil;
4706
4707 DEFSYM (Qx_use_underline_position_properties,
4708 "x-use-underline-position-properties");
4709
4710 DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line");
4711
4712 rdb = Qnil;
4713 staticpro (&rdb);
4714
4715 Fprovide (Qhaiku, Qnil);
4716 #ifdef USE_BE_CAIRO
4717 Fprovide (intern_c_string ("cairo"), Qnil);
4718 #endif
4719 }