aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mackenzie2022-01-22 11:02:50 +0000
committerAlan Mackenzie2022-01-22 11:02:50 +0000
commit14d64a8adcc866deecd758b898e8ef2d836b354a (patch)
tree83cff9669e266f8e283ccb8cd7518e909240f1e1 /src
parentbdd9b5b8a0d37dd09ee530c1dab3a44bee09e0f8 (diff)
parentebe334cdc234de2897263aed4c05ac7088c11857 (diff)
downloademacs-scratch/correct-warning-pos.tar.gz
emacs-scratch/correct-warning-pos.zip
Merge branch 'master' into scratch/correct-warning-posscratch/correct-warning-pos
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in5
-rw-r--r--src/bidi.c8
-rw-r--r--src/buffer.c13
-rw-r--r--src/bytecode.c8
-rw-r--r--src/emacsgtkfixed.c6
-rw-r--r--src/frame.c8
-rw-r--r--src/gtkutil.c20
-rw-r--r--src/haiku_select.cc27
-rw-r--r--src/haiku_support.cc36
-rw-r--r--src/haiku_support.h8
-rw-r--r--src/haikufns.c498
-rw-r--r--src/haikumenu.c12
-rw-r--r--src/haikuselect.c31
-rw-r--r--src/haikuselect.h9
-rw-r--r--src/haikuterm.c90
-rw-r--r--src/haikuterm.h2
-rw-r--r--src/image.c6
-rw-r--r--src/keyboard.c47
-rw-r--r--src/nsterm.m11
-rw-r--r--src/pgtkfns.c14
-rw-r--r--src/pgtkterm.c38
-rw-r--r--src/syntax.c5
-rw-r--r--src/verbose.mk.in31
-rw-r--r--src/w32font.c3
-rw-r--r--src/xdisp.c3
-rw-r--r--src/xfaces.c13
-rw-r--r--src/xfns.c98
-rw-r--r--src/xsettings.h5
-rw-r--r--src/xterm.c374
-rw-r--r--src/xterm.h15
-rw-r--r--src/xwidget.c3
31 files changed, 1015 insertions, 432 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 04fabd5f424..706beb453b6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -616,7 +616,7 @@ endif
616## icon set. 616## icon set.
617 617
618ifeq ($(HAVE_BE_APP),yes) 618ifeq ($(HAVE_BE_APP),yes)
619Emacs: emacs$(EXEEXT) 619Emacs: emacs$(EXEEXT) $(libsrc)/be-resources
620 $(AM_V_GEN) cp -f emacs$(EXEEXT) $@ 620 $(AM_V_GEN) cp -f emacs$(EXEEXT) $@
621 $(AM_V_at) $(libsrc)/be-resources \ 621 $(AM_V_at) $(libsrc)/be-resources \
622 $(etc)/images/icons/hicolor/32x32/apps/emacs.png $@ 622 $(etc)/images/icons/hicolor/32x32/apps/emacs.png $@
@@ -914,6 +914,9 @@ $(bootstrap_pdmp): bootstrap-emacs$(EXEEXT)
914 $(RUN_TEMACS) --batch $(BUILD_DETAILS) -l loadup --temacs=pbootstrap \ 914 $(RUN_TEMACS) --batch $(BUILD_DETAILS) -l loadup --temacs=pbootstrap \
915 --bin-dest $(BIN_DESTDIR) --eln-dest $(ELN_DESTDIR) 915 --bin-dest $(BIN_DESTDIR) --eln-dest $(ELN_DESTDIR)
916 @: Compile some files earlier to speed up further compilation. 916 @: Compile some files earlier to speed up further compilation.
917 @: First, byte compile these files, ....
918 ANCIENT=yes $(MAKE) -C ../lisp compile-first EMACS="$(bootstrap_exe)"
919 @: .... then use their .elcs in native compiling these and other files.
917 $(MAKE) -C ../lisp compile-first EMACS="$(bootstrap_exe)" 920 $(MAKE) -C ../lisp compile-first EMACS="$(bootstrap_exe)"
918endif 921endif
919 922
diff --git a/src/bidi.c b/src/bidi.c
index c5d524f0493..d6ed607f14c 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -3569,7 +3569,9 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
3569ptrdiff_t 3569ptrdiff_t
3570bidi_find_first_overridden (struct bidi_it *bidi_it) 3570bidi_find_first_overridden (struct bidi_it *bidi_it)
3571{ 3571{
3572 ptrdiff_t found_pos = ZV; 3572 ptrdiff_t eob
3573 = STRINGP (bidi_it->string.lstring) ? bidi_it->string.schars : ZV;
3574 ptrdiff_t found_pos = eob;
3573 /* Maximum bidi levels we allow for L2R and R2L characters. Note 3575 /* Maximum bidi levels we allow for L2R and R2L characters. Note
3574 that these are levels after resolving explicit embeddings, 3576 that these are levels after resolving explicit embeddings,
3575 overrides, and isolates, i.e. before resolving implicit levels. */ 3577 overrides, and isolates, i.e. before resolving implicit levels. */
@@ -3607,8 +3609,8 @@ bidi_find_first_overridden (struct bidi_it *bidi_it)
3607 || ((category == WEAK || bidi_it->orig_type == NEUTRAL_ON) 3609 || ((category == WEAK || bidi_it->orig_type == NEUTRAL_ON)
3608 && level > max_weak)) 3610 && level > max_weak))
3609 found_pos = bidi_it->charpos; 3611 found_pos = bidi_it->charpos;
3610 } while (found_pos == ZV 3612 } while (found_pos == eob
3611 && bidi_it->charpos < ZV 3613 && bidi_it->charpos < eob
3612 && bidi_it->ch != BIDI_EOB 3614 && bidi_it->ch != BIDI_EOB
3613 && bidi_it->ch != '\n'); 3615 && bidi_it->ch != '\n');
3614 3616
diff --git a/src/buffer.c b/src/buffer.c
index a3091015d9b..0bdad086ddd 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -912,6 +912,10 @@ does not run the hooks `kill-buffer-hook',
912 Fset (intern ("buffer-save-without-query"), Qnil); 912 Fset (intern ("buffer-save-without-query"), Qnil);
913 Fset (intern ("buffer-file-number"), Qnil); 913 Fset (intern ("buffer-file-number"), Qnil);
914 Fset (intern ("buffer-stale-function"), Qnil); 914 Fset (intern ("buffer-stale-function"), Qnil);
915 /* Cloned buffers need extra setup, to do things such as deep
916 variable copies for list variables that might be mangled due
917 to destructive operations in the indirect buffer. */
918 run_hook (Qclone_indirect_buffer_hook);
915 set_buffer_internal_1 (old_b); 919 set_buffer_internal_1 (old_b);
916 } 920 }
917 921
@@ -5569,6 +5573,8 @@ syms_of_buffer (void)
5569 Fput (Qprotected_field, Qerror_message, 5573 Fput (Qprotected_field, Qerror_message,
5570 build_pure_c_string ("Attempt to modify a protected field")); 5574 build_pure_c_string ("Attempt to modify a protected field"));
5571 5575
5576 DEFSYM (Qclone_indirect_buffer_hook, "clone-indirect-buffer-hook");
5577
5572 DEFVAR_PER_BUFFER ("tab-line-format", 5578 DEFVAR_PER_BUFFER ("tab-line-format",
5573 &BVAR (current_buffer, tab_line_format), 5579 &BVAR (current_buffer, tab_line_format),
5574 Qnil, 5580 Qnil,
@@ -6392,6 +6398,13 @@ If `delete-auto-save-files' is nil, any autosave deletion is inhibited. */);
6392This is the default. If nil, auto-save file deletion is inhibited. */); 6398This is the default. If nil, auto-save file deletion is inhibited. */);
6393 delete_auto_save_files = 1; 6399 delete_auto_save_files = 1;
6394 6400
6401 DEFVAR_LISP ("clone-indirect-buffer-hook", Vclone_indirect_buffer_hook,
6402 doc: /* Normal hook to run in the new buffer at the end of `make-indirect-buffer'.
6403
6404Since `clone-indirect-buffer' calls `make-indirect-buffer', this hook
6405will run for `clone-indirect-buffer' calls as well. */);
6406 Vclone_indirect_buffer_hook = Qnil;
6407
6395 defsubr (&Sbuffer_live_p); 6408 defsubr (&Sbuffer_live_p);
6396 defsubr (&Sbuffer_list); 6409 defsubr (&Sbuffer_list);
6397 defsubr (&Sget_buffer); 6410 defsubr (&Sget_buffer);
diff --git a/src/bytecode.c b/src/bytecode.c
index 472992be180..b7e65d05aef 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1167,13 +1167,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1167 NEXT; 1167 NEXT;
1168 1168
1169 CASE (Bchar_syntax): 1169 CASE (Bchar_syntax):
1170 { 1170 TOP = Fchar_syntax (TOP);
1171 CHECK_CHARACTER (TOP);
1172 int c = XFIXNAT (TOP);
1173 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
1174 c = make_char_multibyte (c);
1175 XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]);
1176 }
1177 NEXT; 1171 NEXT;
1178 1172
1179 CASE (Bbuffer_substring): 1173 CASE (Bbuffer_substring):
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index da56031e2a4..a38ba35ad80 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -164,13 +164,9 @@ XSetWMSizeHints (Display *d,
164 164
165 if ((hints->flags & PMinSize) && f) 165 if ((hints->flags & PMinSize) && f)
166 { 166 {
167#ifdef HAVE_PGTK
168 int w = f->output_data.pgtk->size_hints.min_width;
169 int h = f->output_data.pgtk->size_hints.min_height;
170#else
171 int w = f->output_data.x->size_hints.min_width; 167 int w = f->output_data.x->size_hints.min_width;
172 int h = f->output_data.x->size_hints.min_height; 168 int h = f->output_data.x->size_hints.min_height;
173#endif 169
174 data[5] = w; 170 data[5] = w;
175 data[6] = h; 171 data[6] = h;
176 } 172 }
diff --git a/src/frame.c b/src/frame.c
index e5d74edc168..8aaff949ba2 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -6472,6 +6472,14 @@ This variable is effective only with the X toolkit (and there only when
6472Gtk+ tooltips are not used) and on Windows. */); 6472Gtk+ tooltips are not used) and on Windows. */);
6473 tooltip_reuse_hidden_frame = false; 6473 tooltip_reuse_hidden_frame = false;
6474 6474
6475 DEFVAR_BOOL ("use-system-tooltips", use_system_tooltips,
6476 doc: /* Use the toolkit to display tooltips.
6477This option is only meaningful when Emacs is built with GTK+ or Haiku
6478windowing support, and results in tooltips that look like those
6479displayed by other GTK+ or Haiku programs, but will not be able to
6480display text properties inside tooltip text. */);
6481 use_system_tooltips = true;
6482
6475 DEFVAR_LISP ("iconify-child-frame", iconify_child_frame, 6483 DEFVAR_LISP ("iconify-child-frame", iconify_child_frame,
6476 doc: /* How to handle iconification of child frames. 6484 doc: /* How to handle iconification of child frames.
6477This variable tells Emacs how to proceed when it is asked to iconify a 6485This variable tells Emacs how to proceed when it is asked to iconify a
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 36ed55bc039..eb148560620 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -4534,6 +4534,12 @@ xg_update_scrollbar_pos (struct frame *f,
4534 gtk_widget_show_all (wparent); 4534 gtk_widget_show_all (wparent);
4535 gtk_widget_set_size_request (wscroll, width, height); 4535 gtk_widget_set_size_request (wscroll, width, height);
4536 } 4536 }
4537
4538#if !defined HAVE_PGTK && GTK_CHECK_VERSION (2, 18, 0)
4539 if (!gdk_window_ensure_native (gtk_widget_get_window (wscroll)))
4540 emacs_abort ();
4541#endif
4542
4537 if (oldx != -1 && oldw > 0 && oldh > 0) 4543 if (oldx != -1 && oldw > 0 && oldh > 0)
4538 { 4544 {
4539 /* Clear under old scroll bar position. */ 4545 /* Clear under old scroll bar position. */
@@ -4587,7 +4593,6 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
4587 int width, 4593 int width,
4588 int height) 4594 int height)
4589{ 4595{
4590
4591 GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id); 4596 GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id);
4592 4597
4593 if (wscroll) 4598 if (wscroll)
@@ -4634,6 +4639,11 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
4634 pgtk_clear_area (f, oldx, oldy, oldw, oldh); 4639 pgtk_clear_area (f, oldx, oldy, oldw, oldh);
4635#endif 4640#endif
4636 4641
4642#if !defined HAVE_PGTK && GTK_CHECK_VERSION (2, 18, 0)
4643 if (!gdk_window_ensure_native (gtk_widget_get_window (wscroll)))
4644 emacs_abort ();
4645#endif
4646
4637 /* GTK does not redraw until the main loop is entered again, but 4647 /* GTK does not redraw until the main loop is entered again, but
4638 if there are no X events pending we will not enter it. So we sync 4648 if there are no X events pending we will not enter it. So we sync
4639 here to get some events. */ 4649 here to get some events. */
@@ -6151,6 +6161,7 @@ xg_widget_key_press_event_cb (GtkWidget *widget, GdkEvent *event,
6151 6161
6152 inev.ie.modifiers 6162 inev.ie.modifiers
6153 |= x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), xstate); 6163 |= x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), xstate);
6164 inev.ie.timestamp = event->key.time;
6154 6165
6155 if (event->key.is_modifier) 6166 if (event->key.is_modifier)
6156 goto done; 6167 goto done;
@@ -6256,13 +6267,16 @@ xg_widget_key_press_event_cb (GtkWidget *widget, GdkEvent *event,
6256 } 6267 }
6257 6268
6258 XNoOp (FRAME_X_DISPLAY (f)); 6269 XNoOp (FRAME_X_DISPLAY (f));
6270#ifdef USABLE_SIGIO
6271 raise (SIGIO);
6272#endif
6259 return true; 6273 return true;
6260} 6274}
6261 6275
6262bool 6276bool
6263xg_filter_key (struct frame *frame, XEvent *xkey) 6277xg_filter_key (struct frame *frame, XEvent *xkey)
6264{ 6278{
6265 GdkEvent *xg_event = gdk_event_new ((xkey->type == ButtonPress 6279 GdkEvent *xg_event = gdk_event_new ((xkey->type == KeyPress
6266#ifdef HAVE_XINPUT2 6280#ifdef HAVE_XINPUT2
6267 || (xkey->type == GenericEvent 6281 || (xkey->type == GenericEvent
6268 && xkey->xgeneric.evtype == XI_KeyPress) 6282 && xkey->xgeneric.evtype == XI_KeyPress)
@@ -6321,6 +6335,7 @@ xg_filter_key (struct frame *frame, XEvent *xkey)
6321 NULL, NULL, &consumed); 6335 NULL, NULL, &consumed);
6322 xg_add_virtual_mods (dpyinfo, &xg_event->key); 6336 xg_add_virtual_mods (dpyinfo, &xg_event->key);
6323 xg_event->key.state &= ~consumed; 6337 xg_event->key.state &= ~consumed;
6338 xg_event->key.time = xkey->xkey.time;
6324#if GTK_CHECK_VERSION (3, 6, 0) 6339#if GTK_CHECK_VERSION (3, 6, 0)
6325 xg_event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap, 6340 xg_event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap,
6326 xg_event->key.hardware_keycode); 6341 xg_event->key.hardware_keycode);
@@ -6334,6 +6349,7 @@ xg_filter_key (struct frame *frame, XEvent *xkey)
6334 xg_event->key.hardware_keycode = xev->detail; 6349 xg_event->key.hardware_keycode = xev->detail;
6335 xg_event->key.group = xev->group.effective; 6350 xg_event->key.group = xev->group.effective;
6336 xg_event->key.state = xev->mods.effective; 6351 xg_event->key.state = xev->mods.effective;
6352 xg_event->key.time = xev->time;
6337 gdk_keymap_translate_keyboard_state (keymap, 6353 gdk_keymap_translate_keyboard_state (keymap,
6338 xev->detail, 6354 xev->detail,
6339 xev->mods.effective, 6355 xev->mods.effective,
diff --git a/src/haiku_select.cc b/src/haiku_select.cc
index 041e244f3ea..d39000d8bbe 100644
--- a/src/haiku_select.cc
+++ b/src/haiku_select.cc
@@ -29,6 +29,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
29static BClipboard *primary = NULL; 29static BClipboard *primary = NULL;
30static BClipboard *secondary = NULL; 30static BClipboard *secondary = NULL;
31static BClipboard *system_clipboard = NULL; 31static BClipboard *system_clipboard = NULL;
32static unsigned long count_clipboard = 0;
33static unsigned long count_primary = 0;
34static unsigned long count_secondary = 0;
32 35
33int selection_state_flag; 36int selection_state_flag;
34 37
@@ -174,6 +177,7 @@ BClipboard_set_system_data (const char *type, const char *data,
174 return; 177 return;
175 178
176 BClipboard_set_data (system_clipboard, type, data, len, clear); 179 BClipboard_set_data (system_clipboard, type, data, len, clear);
180 count_clipboard = system_clipboard->SystemCount ();
177} 181}
178 182
179void 183void
@@ -184,6 +188,7 @@ BClipboard_set_primary_selection_data (const char *type, const char *data,
184 return; 188 return;
185 189
186 BClipboard_set_data (primary, type, data, len, clear); 190 BClipboard_set_data (primary, type, data, len, clear);
191 count_primary = primary->SystemCount ();
187} 192}
188 193
189void 194void
@@ -194,6 +199,7 @@ BClipboard_set_secondary_selection_data (const char *type, const char *data,
194 return; 199 return;
195 200
196 BClipboard_set_data (secondary, type, data, len, clear); 201 BClipboard_set_data (secondary, type, data, len, clear);
202 count_secondary = secondary->SystemCount ();
197} 203}
198 204
199void 205void
@@ -220,6 +226,27 @@ BClipboard_secondary_targets (char **buf, int len)
220 BClipboard_get_targets (secondary, buf, len); 226 BClipboard_get_targets (secondary, buf, len);
221} 227}
222 228
229bool
230BClipboard_owns_clipboard (void)
231{
232 return (count_clipboard
233 == system_clipboard->SystemCount ());
234}
235
236bool
237BClipboard_owns_primary (void)
238{
239 return (count_primary
240 == primary->SystemCount ());
241}
242
243bool
244BClipboard_owns_secondary (void)
245{
246 return (count_secondary
247 == secondary->SystemCount ());
248}
249
223void 250void
224init_haiku_select (void) 251init_haiku_select (void)
225{ 252{
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index d49e319b98c..ae2736110ec 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
36#include <interface/MenuBar.h> 36#include <interface/MenuBar.h>
37#include <interface/Alert.h> 37#include <interface/Alert.h>
38#include <interface/Button.h> 38#include <interface/Button.h>
39#include <interface/ControlLook.h>
39 40
40#include <locale/UnicodeChar.h> 41#include <locale/UnicodeChar.h>
41 42
@@ -406,6 +407,7 @@ public:
406 bool menu_bar_active_p = false; 407 bool menu_bar_active_p = false;
407 window_look pre_override_redirect_style; 408 window_look pre_override_redirect_style;
408 window_feel pre_override_redirect_feel; 409 window_feel pre_override_redirect_feel;
410 uint32 pre_override_redirect_workspaces;
409 411
410 EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK, 412 EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
411 B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS) 413 B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
@@ -718,6 +720,7 @@ public:
718 int ret; 720 int ret;
719 msg->FindInt32 ("raw_char", &raw); 721 msg->FindInt32 ("raw_char", &raw);
720 msg->FindInt32 ("key", &key); 722 msg->FindInt32 ("key", &key);
723 msg->FindInt64 ("when", &rq.time);
721 724
722 rq.modifiers = 0; 725 rq.modifiers = 0;
723 uint32_t mods = modifiers (); 726 uint32_t mods = modifiers ();
@@ -1318,7 +1321,6 @@ public:
1318 if (!offscreen_draw_view) 1321 if (!offscreen_draw_view)
1319 gui_abort ("Failed to lock offscreen view during buffer flip"); 1322 gui_abort ("Failed to lock offscreen view during buffer flip");
1320 1323
1321 offscreen_draw_view->Flush ();
1322 offscreen_draw_view->Sync (); 1324 offscreen_draw_view->Sync ();
1323 1325
1324 EmacsWindow *w = (EmacsWindow *) Window (); 1326 EmacsWindow *w = (EmacsWindow *) Window ();
@@ -1381,8 +1383,8 @@ public:
1381 rq.just_exited_p = transit == B_EXITED_VIEW; 1383 rq.just_exited_p = transit == B_EXITED_VIEW;
1382 rq.x = point.x; 1384 rq.x = point.x;
1383 rq.y = point.y; 1385 rq.y = point.y;
1384 rq.be_code = transit;
1385 rq.window = this->Window (); 1386 rq.window = this->Window ();
1387 rq.time = system_time ();
1386 1388
1387 if (ToolTip ()) 1389 if (ToolTip ())
1388 ToolTip ()->SetMouseRelativeLocation (BPoint (-(point.x - tt_absl_pos.x), 1390 ToolTip ()->SetMouseRelativeLocation (BPoint (-(point.x - tt_absl_pos.x),
@@ -1437,6 +1439,7 @@ public:
1437 1439
1438 SetMouseEventMask (B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); 1440 SetMouseEventMask (B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
1439 1441
1442 rq.time = system_time ();
1440 haiku_write (BUTTON_DOWN, &rq); 1443 haiku_write (BUTTON_DOWN, &rq);
1441 } 1444 }
1442 1445
@@ -1483,6 +1486,7 @@ public:
1483 if (!buttons) 1486 if (!buttons)
1484 SetMouseEventMask (0, 0); 1487 SetMouseEventMask (0, 0);
1485 1488
1489 rq.time = system_time ();
1486 haiku_write (BUTTON_UP, &rq); 1490 haiku_write (BUTTON_UP, &rq);
1487 } 1491 }
1488}; 1492};
@@ -1632,17 +1636,17 @@ public:
1632 { 1636 {
1633 struct haiku_menu_bar_help_event rq; 1637 struct haiku_menu_bar_help_event rq;
1634 1638
1635 if (menu_bar_id >= 0) 1639 if (help)
1640 {
1641 Menu ()->SetToolTip (highlight_p ? help : NULL);
1642 }
1643 else if (menu_bar_id >= 0)
1636 { 1644 {
1637 rq.window = wind_ptr; 1645 rq.window = wind_ptr;
1638 rq.mb_idx = highlight_p ? menu_bar_id : -1; 1646 rq.mb_idx = highlight_p ? menu_bar_id : -1;
1639 1647
1640 haiku_write (MENU_BAR_HELP_EVENT, &rq); 1648 haiku_write (MENU_BAR_HELP_EVENT, &rq);
1641 } 1649 }
1642 else if (help)
1643 {
1644 Menu ()->SetToolTip (highlight_p ? help : NULL);
1645 }
1646 1650
1647 BMenuItem::Highlight (highlight_p); 1651 BMenuItem::Highlight (highlight_p);
1648 } 1652 }
@@ -1997,8 +2001,6 @@ BView_move_frame (void *view, int x, int y, int x1, int y1)
1997 gui_abort ("Failed to lock view moving frame"); 2001 gui_abort ("Failed to lock view moving frame");
1998 vw->MoveTo (x, y); 2002 vw->MoveTo (x, y);
1999 vw->ResizeTo (x1 - x, y1 - y); 2003 vw->ResizeTo (x1 - x, y1 - y);
2000 vw->Flush ();
2001 vw->Sync ();
2002 vw->UnlockLooper (); 2004 vw->UnlockLooper ();
2003} 2005}
2004 2006
@@ -2018,7 +2020,9 @@ BView_scroll_bar_update (void *sb, int portion, int whole, int position)
2018int 2020int
2019BScrollBar_default_size (int horizontal_p) 2021BScrollBar_default_size (int horizontal_p)
2020{ 2022{
2021 return horizontal_p ? B_H_SCROLL_BAR_HEIGHT : B_V_SCROLL_BAR_WIDTH; 2023 return be_control_look->GetScrollBarWidth (horizontal_p
2024 ? B_HORIZONTAL
2025 : B_VERTICAL);
2022} 2026}
2023 2027
2024/* Invalidate VIEW, causing it to be drawn again. */ 2028/* Invalidate VIEW, causing it to be drawn again. */
@@ -2224,7 +2228,11 @@ BWindow_set_tooltip_decoration (void *window)
2224 if (!w->LockLooper ()) 2228 if (!w->LockLooper ())
2225 gui_abort ("Failed to lock window while setting ttip decoration"); 2229 gui_abort ("Failed to lock window while setting ttip decoration");
2226 w->SetLook (B_BORDERED_WINDOW_LOOK); 2230 w->SetLook (B_BORDERED_WINDOW_LOOK);
2227 w->SetFeel (B_FLOATING_APP_WINDOW_FEEL); 2231 w->SetFeel (kMenuWindowFeel);
2232 w->SetFlags (B_NOT_ZOOMABLE
2233 | B_NOT_MINIMIZABLE
2234 | B_AVOID_FRONT
2235 | B_AVOID_FOCUS);
2228 w->UnlockLooper (); 2236 w->UnlockLooper ();
2229} 2237}
2230 2238
@@ -2241,7 +2249,6 @@ BWindow_set_avoid_focus (void *window, int avoid_focus_p)
2241 w->SetFlags (w->Flags () & ~B_AVOID_FOCUS); 2249 w->SetFlags (w->Flags () & ~B_AVOID_FOCUS);
2242 else 2250 else
2243 w->SetFlags (w->Flags () | B_AVOID_FOCUS); 2251 w->SetFlags (w->Flags () | B_AVOID_FOCUS);
2244 w->Sync ();
2245 w->UnlockLooper (); 2252 w->UnlockLooper ();
2246} 2253}
2247 2254
@@ -2818,7 +2825,7 @@ be_popup_file_dialog (int open_p, const char *default_dir, int must_match_p, int
2818 enum haiku_event_type type; 2825 enum haiku_event_type type;
2819 char *ptr = NULL; 2826 char *ptr = NULL;
2820 2827
2821 if (!haiku_read_with_timeout (&type, buf, 200, 100000)) 2828 if (!haiku_read_with_timeout (&type, buf, 200, 1000000))
2822 { 2829 {
2823 block_input_function (); 2830 block_input_function ();
2824 if (type != FILE_PANEL_EVENT) 2831 if (type != FILE_PANEL_EVENT)
@@ -3166,11 +3173,14 @@ BWindow_set_override_redirect (void *window, bool override_redirect_p)
3166 w->pre_override_redirect_style = w->Look (); 3173 w->pre_override_redirect_style = w->Look ();
3167 w->SetFeel (kMenuWindowFeel); 3174 w->SetFeel (kMenuWindowFeel);
3168 w->SetLook (B_NO_BORDER_WINDOW_LOOK); 3175 w->SetLook (B_NO_BORDER_WINDOW_LOOK);
3176 w->pre_override_redirect_workspaces = w->Workspaces ();
3177 w->SetWorkspaces (B_ALL_WORKSPACES);
3169 } 3178 }
3170 else 3179 else
3171 { 3180 {
3172 w->SetFeel (w->pre_override_redirect_feel); 3181 w->SetFeel (w->pre_override_redirect_feel);
3173 w->SetLook (w->pre_override_redirect_style); 3182 w->SetLook (w->pre_override_redirect_style);
3183 w->SetWorkspaces (w->pre_override_redirect_workspaces);
3174 } 3184 }
3175 3185
3176 w->UnlockLooper (); 3186 w->UnlockLooper ();
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 83f22972ce2..6ddc28759b5 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -34,6 +34,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
34 34
35#include <math.h> 35#include <math.h>
36 36
37#include <kernel/OS.h>
38
37enum haiku_cursor 39enum haiku_cursor
38 { 40 {
39 CURSOR_ID_NO_CURSOR = 12, 41 CURSOR_ID_NO_CURSOR = 12,
@@ -132,6 +134,9 @@ struct haiku_key_event
132 int modifiers; 134 int modifiers;
133 unsigned keysym; 135 unsigned keysym;
134 uint32_t multibyte_char; 136 uint32_t multibyte_char;
137
138 /* Time the keypress occurred, in microseconds. */
139 bigtime_t time;
135}; 140};
136 141
137struct haiku_activation_event 142struct haiku_activation_event
@@ -146,7 +151,7 @@ struct haiku_mouse_motion_event
146 bool just_exited_p; 151 bool just_exited_p;
147 int x; 152 int x;
148 int y; 153 int y;
149 uint32_t be_code; 154 bigtime_t time;
150}; 155};
151 156
152struct haiku_button_event 157struct haiku_button_event
@@ -156,6 +161,7 @@ struct haiku_button_event
156 int modifiers; 161 int modifiers;
157 int x; 162 int x;
158 int y; 163 int y;
164 bigtime_t time;
159}; 165};
160 166
161struct haiku_iconification_event 167struct haiku_iconification_event
diff --git a/src/haikufns.c b/src/haikufns.c
index 52bb13bc89b..58a2e1d4642 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -45,7 +45,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
45#define BLUE_FROM_ULONG(color) ((color) & 0xff) 45#define BLUE_FROM_ULONG(color) ((color) & 0xff)
46 46
47/* The frame of the currently visible tooltip. */ 47/* The frame of the currently visible tooltip. */
48static Lisp_Object tip_frame; 48Lisp_Object tip_frame;
49 49
50/* The window-system window corresponding to the frame of the 50/* The window-system window corresponding to the frame of the
51 currently visible tooltip. */ 51 currently visible tooltip. */
@@ -452,6 +452,15 @@ haiku_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object o
452} 452}
453 453
454static void 454static void
455initial_setup_back_buffer (struct frame *f)
456{
457 block_input ();
458 if (NILP (CDR (Fassq (Qinhibit_double_buffering, f->param_alist))))
459 EmacsView_set_up_double_buffering (FRAME_HAIKU_VIEW (f));
460 unblock_input ();
461}
462
463static void
455unwind_create_frame (Lisp_Object frame) 464unwind_create_frame (Lisp_Object frame)
456{ 465{
457 struct frame *f = XFRAME (frame); 466 struct frame *f = XFRAME (frame);
@@ -547,13 +556,12 @@ unwind_popup (void)
547} 556}
548 557
549static Lisp_Object 558static Lisp_Object
550haiku_create_frame (Lisp_Object parms, int ttip_p) 559haiku_create_frame (Lisp_Object parms)
551{ 560{
552 struct frame *f; 561 struct frame *f;
553 Lisp_Object frame, tem; 562 Lisp_Object frame, tem;
554 Lisp_Object name; 563 Lisp_Object name;
555 bool minibuffer_only = false; 564 bool minibuffer_only = false;
556 bool face_change_before = face_change;
557 long window_prompting = 0; 565 long window_prompting = 0;
558 ptrdiff_t count = SPECPDL_INDEX (); 566 ptrdiff_t count = SPECPDL_INDEX ();
559 Lisp_Object display; 567 Lisp_Object display;
@@ -593,10 +601,8 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
593 tem = gui_display_get_arg (dpyinfo, parms, Qminibuffer, 601 tem = gui_display_get_arg (dpyinfo, parms, Qminibuffer,
594 "minibuffer", "Minibuffer", 602 "minibuffer", "Minibuffer",
595 RES_TYPE_SYMBOL); 603 RES_TYPE_SYMBOL);
596 if (ttip_p) 604 if (EQ (tem, Qnone) || NILP (tem))
597 f = make_frame (0); 605 f = make_frame_without_minibuffer (Qnil, kb, display);
598 else if (EQ (tem, Qnone) || NILP (tem))
599 f = make_frame_without_minibuffer (Qnil, kb, display);
600 else if (EQ (tem, Qonly)) 606 else if (EQ (tem, Qonly))
601 { 607 {
602 f = make_minibuffer_frame (); 608 f = make_minibuffer_frame ();
@@ -618,22 +624,16 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
618 f->output_data.haiku->pending_zoom_width = INT_MIN; 624 f->output_data.haiku->pending_zoom_width = INT_MIN;
619 f->output_data.haiku->pending_zoom_height = INT_MIN; 625 f->output_data.haiku->pending_zoom_height = INT_MIN;
620 626
621 if (ttip_p)
622 f->wants_modeline = false;
623
624 fset_icon_name (f, gui_display_get_arg (dpyinfo, parms, Qicon_name, 627 fset_icon_name (f, gui_display_get_arg (dpyinfo, parms, Qicon_name,
625 "iconName", "Title", 628 "iconName", "Title",
626 RES_TYPE_STRING)); 629 RES_TYPE_STRING));
627 if (! STRINGP (f->icon_name) || ttip_p) 630 if (! STRINGP (f->icon_name))
628 fset_icon_name (f, Qnil); 631 fset_icon_name (f, Qnil);
629 632
630 FRAME_DISPLAY_INFO (f) = dpyinfo; 633 FRAME_DISPLAY_INFO (f) = dpyinfo;
631 634
632 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */ 635 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
633 if (!ttip_p) 636 record_unwind_protect (unwind_create_frame, frame);
634 record_unwind_protect (unwind_create_frame, frame);
635 else
636 record_unwind_protect (unwind_create_tip_frame, frame);
637 637
638 FRAME_OUTPUT_DATA (f)->parent_desc = NULL; 638 FRAME_OUTPUT_DATA (f)->parent_desc = NULL;
639 FRAME_OUTPUT_DATA (f)->explicit_parent = 0; 639 FRAME_OUTPUT_DATA (f)->explicit_parent = 0;
@@ -660,8 +660,6 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
660#endif 660#endif
661 register_font_driver (&haikufont_driver, f); 661 register_font_driver (&haikufont_driver, f);
662 662
663 f->tooltip = ttip_p;
664
665 image_cache_refcount = 663 image_cache_refcount =
666 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; 664 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
667 665
@@ -674,7 +672,7 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
674 672
675 gui_default_parameter (f, parms, Qborder_width, make_fixnum (0), 673 gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
676 "borderwidth", "BorderWidth", RES_TYPE_NUMBER); 674 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
677 gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (ttip_p ? 1 : 2), 675 gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2),
678 "internalBorderWidth", "InternalBorderWidth", 676 "internalBorderWidth", "InternalBorderWidth",
679 RES_TYPE_NUMBER); 677 RES_TYPE_NUMBER);
680 gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil, 678 gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil,
@@ -684,7 +682,7 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
684 NULL, NULL, RES_TYPE_NUMBER); 682 NULL, NULL, RES_TYPE_NUMBER);
685 gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0), 683 gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
686 NULL, NULL, RES_TYPE_NUMBER); 684 NULL, NULL, RES_TYPE_NUMBER);
687 gui_default_parameter (f, parms, Qvertical_scroll_bars, !ttip_p ? Qt : Qnil, 685 gui_default_parameter (f, parms, Qvertical_scroll_bars, Qt,
688 "verticalScrollBars", "VerticalScrollBars", 686 "verticalScrollBars", "VerticalScrollBars",
689 RES_TYPE_SYMBOL); 687 RES_TYPE_SYMBOL);
690 gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil, 688 gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
@@ -700,7 +698,7 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
700 "leftFringe", "LeftFringe", RES_TYPE_NUMBER); 698 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
701 gui_default_parameter (f, parms, Qright_fringe, Qnil, 699 gui_default_parameter (f, parms, Qright_fringe, Qnil,
702 "rightFringe", "RightFringe", RES_TYPE_NUMBER); 700 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
703 gui_default_parameter (f, parms, Qno_special_glyphs, ttip_p ? Qnil : Qt, 701 gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
704 NULL, NULL, RES_TYPE_BOOLEAN); 702 NULL, NULL, RES_TYPE_BOOLEAN);
705 703
706 init_frame_faces (f); 704 init_frame_faces (f);
@@ -718,57 +716,39 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
718 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, 716 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1,
719 Qx_create_frame_1); 717 Qx_create_frame_1);
720 718
721 if (!ttip_p) 719 gui_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL);
722 { 720 gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
723 gui_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL); 721 NULL, NULL, RES_TYPE_BOOLEAN);
724 gui_default_parameter (f, parms, Qno_focus_on_map, Qnil, 722 gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
725 NULL, NULL, RES_TYPE_BOOLEAN); 723 NULL, NULL, RES_TYPE_BOOLEAN);
726 gui_default_parameter (f, parms, Qno_accept_focus, Qnil, 724
727 NULL, NULL, RES_TYPE_BOOLEAN); 725 /* The resources controlling the menu-bar, tool-bar, and tab-bar are
728 726 processed specially at startup, and reflected in the mode
729 /* The resources controlling the menu-bar, tool-bar, and tab-bar are 727 variables; ignore them here. */
730 processed specially at startup, and reflected in the mode 728 gui_default_parameter (f, parms, Qmenu_bar_lines,
731 variables; ignore them here. */ 729 NILP (Vmenu_bar_mode)
732 gui_default_parameter (f, parms, Qmenu_bar_lines, 730 ? make_fixnum (0) : make_fixnum (1),
733 NILP (Vmenu_bar_mode) 731 NULL, NULL, RES_TYPE_NUMBER);
734 ? make_fixnum (0) : make_fixnum (1), 732 gui_default_parameter (f, parms, Qtab_bar_lines,
735 NULL, NULL, RES_TYPE_NUMBER); 733 NILP (Vtab_bar_mode)
736 gui_default_parameter (f, parms, Qtab_bar_lines, 734 ? make_fixnum (0) : make_fixnum (1),
737 NILP (Vtab_bar_mode) 735 NULL, NULL, RES_TYPE_NUMBER);
738 ? make_fixnum (0) : make_fixnum (1), 736 gui_default_parameter (f, parms, Qtool_bar_lines,
739 NULL, NULL, RES_TYPE_NUMBER); 737 NILP (Vtool_bar_mode)
740 gui_default_parameter (f, parms, Qtool_bar_lines, 738 ? make_fixnum (0) : make_fixnum (1),
741 NILP (Vtool_bar_mode) 739 NULL, NULL, RES_TYPE_NUMBER);
742 ? make_fixnum (0) : make_fixnum (1), 740 gui_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
743 NULL, NULL, RES_TYPE_NUMBER); 741 "BufferPredicate", RES_TYPE_SYMBOL);
744 gui_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate", 742 gui_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
745 "BufferPredicate", RES_TYPE_SYMBOL); 743 RES_TYPE_STRING);
746 gui_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
747 RES_TYPE_STRING);
748 }
749 744
750 parms = get_geometry_from_preferences (dpyinfo, parms); 745 parms = get_geometry_from_preferences (dpyinfo, parms);
751 window_prompting = gui_figure_window_size (f, parms, false, true); 746 window_prompting = gui_figure_window_size (f, parms, false, true);
752 747
753 if (ttip_p)
754 {
755 /* No fringes on tip frame. */
756 f->fringe_cols = 0;
757 f->left_fringe_width = 0;
758 f->right_fringe_width = 0;
759 /* No dividers on tip frame. */
760 f->right_divider_width = 0;
761 f->bottom_divider_width = 0;
762 }
763
764 tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, 748 tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
765 RES_TYPE_BOOLEAN); 749 RES_TYPE_BOOLEAN);
766 f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem)); 750 f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem));
767 751
768 /* Add `tooltip' frame parameter's default value. */
769 if (NILP (Fframe_parameter (frame, Qtooltip)) && ttip_p)
770 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
771
772#define ASSIGN_CURSOR(cursor, be_cursor) \ 752#define ASSIGN_CURSOR(cursor, be_cursor) \
773 (FRAME_OUTPUT_DATA (f)->cursor = be_cursor) 753 (FRAME_OUTPUT_DATA (f)->cursor = be_cursor)
774 754
@@ -803,16 +783,13 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
803 ASSIGN_CURSOR (current_cursor, FRAME_OUTPUT_DATA (f)->text_cursor); 783 ASSIGN_CURSOR (current_cursor, FRAME_OUTPUT_DATA (f)->text_cursor);
804#undef ASSIGN_CURSOR 784#undef ASSIGN_CURSOR
805 785
806
807 if (ttip_p)
808 f->no_split = true;
809 f->terminal->reference_count++; 786 f->terminal->reference_count++;
810 787
811 FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view); 788 FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
812 if (!FRAME_OUTPUT_DATA (f)->window) 789 if (!FRAME_OUTPUT_DATA (f)->window)
813 xsignal1 (Qerror, build_unibyte_string ("Could not create window")); 790 xsignal1 (Qerror, build_unibyte_string ("Could not create window"));
814 791
815 if (!minibuffer_only && !ttip_p && FRAME_EXTERNAL_MENU_BAR (f)) 792 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
816 initialize_frame_menubar (f); 793 initialize_frame_menubar (f);
817 794
818 FRAME_OUTPUT_DATA (f)->window_desc = FRAME_OUTPUT_DATA (f)->window; 795 FRAME_OUTPUT_DATA (f)->window_desc = FRAME_OUTPUT_DATA (f)->window;
@@ -839,58 +816,33 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
839 816
840 gui_default_parameter (f, parms, Qicon_type, Qnil, 817 gui_default_parameter (f, parms, Qicon_type, Qnil,
841 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL); 818 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
842 if (ttip_p) 819 gui_default_parameter (f, parms, Qauto_raise, Qnil,
843 { 820 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
844 gui_default_parameter (f, parms, Qundecorated, Qt, NULL, NULL, RES_TYPE_BOOLEAN); 821 gui_default_parameter (f, parms, Qauto_lower, Qnil,
845 gui_default_parameter (f, parms, Qno_accept_focus, Qt, NULL, NULL, 822 "autoLower", "AutoLower", RES_TYPE_BOOLEAN);
846 RES_TYPE_BOOLEAN); 823 gui_default_parameter (f, parms, Qcursor_type, Qbox,
847 } 824 "cursorType", "CursorType", RES_TYPE_SYMBOL);
848 else 825 gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
849 { 826 "scrollBarWidth", "ScrollBarWidth",
850 gui_default_parameter (f, parms, Qauto_raise, Qnil, 827 RES_TYPE_NUMBER);
851 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN); 828 gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
852 gui_default_parameter (f, parms, Qauto_lower, Qnil, 829 "scrollBarHeight", "ScrollBarHeight",
853 "autoLower", "AutoLower", RES_TYPE_BOOLEAN); 830 RES_TYPE_NUMBER);
854 gui_default_parameter (f, parms, Qcursor_type, Qbox, 831 gui_default_parameter (f, parms, Qalpha, Qnil,
855 "cursorType", "CursorType", RES_TYPE_SYMBOL); 832 "alpha", "Alpha", RES_TYPE_NUMBER);
856 gui_default_parameter (f, parms, Qscroll_bar_width, Qnil, 833 gui_default_parameter (f, parms, Qfullscreen, Qnil,
857 "scrollBarWidth", "ScrollBarWidth", 834 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
858 RES_TYPE_NUMBER);
859 gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
860 "scrollBarHeight", "ScrollBarHeight",
861 RES_TYPE_NUMBER);
862 gui_default_parameter (f, parms, Qalpha, Qnil,
863 "alpha", "Alpha", RES_TYPE_NUMBER);
864 gui_default_parameter (f, parms, Qfullscreen, Qnil,
865 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
866 }
867 835
868 gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil, 836 gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
869 "inhibitDoubleBuffering", "InhibitDoubleBuffering", 837 "inhibitDoubleBuffering", "InhibitDoubleBuffering",
870 RES_TYPE_BOOLEAN); 838 RES_TYPE_BOOLEAN);
871 839
872 if (ttip_p)
873 {
874 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
875
876 call2 (Qface_set_after_frame_default, frame, Qnil);
877
878 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
879 {
880 AUTO_FRAME_ARG (arg, Qbackground_color, bg);
881 Fmodify_frame_parameters (frame, arg);
882 }
883 }
884
885 if (ttip_p)
886 face_change = face_change_before;
887
888 f->can_set_window_size = true; 840 f->can_set_window_size = true;
889 841
890 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 842 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
891 0, true, ttip_p ? Qtip_frame : Qx_create_frame_2); 843 0, true, Qx_create_frame_2);
892 844
893 if (!FRAME_OUTPUT_DATA (f)->explicit_parent && !ttip_p) 845 if (!FRAME_OUTPUT_DATA (f)->explicit_parent)
894 { 846 {
895 Lisp_Object visibility; 847 Lisp_Object visibility;
896 848
@@ -908,13 +860,10 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
908 } 860 }
909 } 861 }
910 862
911 if (!ttip_p) 863 if (FRAME_HAS_MINIBUF_P (f)
912 { 864 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
913 if (FRAME_HAS_MINIBUF_P (f) 865 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
914 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame)) 866 kset_default_minibuffer_frame (kb, frame);
915 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
916 kset_default_minibuffer_frame (kb, frame);
917 }
918 867
919 for (tem = parms; CONSP (tem); tem = XCDR (tem)) 868 for (tem = parms; CONSP (tem); tem = XCDR (tem))
920 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem)))) 869 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
@@ -929,13 +878,230 @@ haiku_create_frame (Lisp_Object parms, int ttip_p)
929 and similar functions. */ 878 and similar functions. */
930 Vwindow_list = Qnil; 879 Vwindow_list = Qnil;
931 880
932 if (ttip_p) 881 return unbind_to (count, frame);
933 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 882}
934 0, true, Qtip_frame); 883
884/* Create a frame for a tooltip. PARMS is a list of frame parameters.
885 TEXT is the string to display in the tip frame. Value is the
886 frame.
887
888 Note that functions called here, esp. gui_default_parameter can
889 signal errors, for instance when a specified color name is
890 undefined. We have to make sure that we're in a consistent state
891 when this happens. */
935 892
893static Lisp_Object
894haiku_create_tip_frame (Lisp_Object parms)
895{
896 struct frame *f;
897 Lisp_Object frame;
898 Lisp_Object name;
899 ptrdiff_t count = SPECPDL_INDEX ();
900 bool face_change_before = face_change;
901 struct haiku_display_info *dpyinfo = x_display_list;
902
903 if (!dpyinfo->terminal->name)
904 error ("Terminal is not live, can't create new frames on it");
905
906 parms = Fcopy_alist (parms);
907
908 /* Get the name of the frame to use for resource lookup. */
909 name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
910 RES_TYPE_STRING);
911 if (!STRINGP (name)
912 && !EQ (name, Qunbound)
913 && !NILP (name))
914 error ("Invalid frame name--not a string or nil");
915
916 frame = Qnil;
917 f = make_frame (false);
918 f->wants_modeline = false;
919 XSETFRAME (frame, f);
920 record_unwind_protect (unwind_create_tip_frame, frame);
921
922 f->terminal = dpyinfo->terminal;
923
924 /* By setting the output method, we're essentially saying that
925 the frame is live, as per FRAME_LIVE_P. If we get a signal
926 from this point on, x_destroy_window might screw up reference
927 counts etc. */
928 f->output_method = output_haiku;
929 f->output_data.haiku = xzalloc (sizeof *f->output_data.haiku);
930
931 f->output_data.haiku->pending_zoom_x = INT_MIN;
932 f->output_data.haiku->pending_zoom_y = INT_MIN;
933 f->output_data.haiku->pending_zoom_width = INT_MIN;
934 f->output_data.haiku->pending_zoom_height = INT_MIN;
935
936 f->tooltip = true;
937 fset_icon_name (f, Qnil);
938 FRAME_DISPLAY_INFO (f) = dpyinfo;
939
940 FRAME_OUTPUT_DATA (f)->parent_desc = NULL;
941 FRAME_OUTPUT_DATA (f)->explicit_parent = 0;
942
943 /* Set the name; the functions to which we pass f expect the name to
944 be set. */
945 if (EQ (name, Qunbound) || NILP (name))
946 f->explicit_name = false;
947 else
948 {
949 fset_name (f, name);
950 f->explicit_name = true;
951 /* use the frame's title when getting resources for this frame. */
952 specbind (Qx_resource_name, name);
953 }
954
955#ifdef USE_BE_CAIRO
956 register_font_driver (&ftcrfont_driver, f);
957#ifdef HAVE_HARFBUZZ
958 register_font_driver (&ftcrhbfont_driver, f);
959#endif
960#endif
961 register_font_driver (&haikufont_driver, f);
962
963 image_cache_refcount =
964 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
965
966 gui_default_parameter (f, parms, Qfont_backend, Qnil,
967 "fontBackend", "FontBackend", RES_TYPE_STRING);
968
969 /* Extract the window parameters from the supplied values that are
970 needed to determine window geometry. */
971 FRAME_RIF (f)->default_font_parameter (f, parms);
972
973 /* This defaults to 1 in order to match xterm. We recognize either
974 internalBorderWidth or internalBorder (which is what xterm calls
975 it). */
976 if (NILP (Fassq (Qinternal_border_width, parms)))
977 {
978 Lisp_Object value;
979
980 value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
981 "internalBorder", "internalBorder",
982 RES_TYPE_NUMBER);
983 if (! EQ (value, Qunbound))
984 parms = Fcons (Fcons (Qinternal_border_width, value),
985 parms);
986 }
987
988 gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1),
989 "internalBorderWidth", "internalBorderWidth",
990 RES_TYPE_NUMBER);
991
992 gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
993 NULL, NULL, RES_TYPE_NUMBER);
994 gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
995 NULL, NULL, RES_TYPE_NUMBER);
996
997 /* Also do the stuff which must be set before the window exists. */
998 gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
999 "foreground", "Foreground", RES_TYPE_STRING);
1000
1001 gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
1002 "background", "Background", RES_TYPE_STRING);
1003 gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
1004 "pointerColor", "Foreground", RES_TYPE_STRING);
1005 gui_default_parameter (f, parms, Qcursor_color, build_string ("black"),
1006 "cursorColor", "Foreground", RES_TYPE_STRING);
1007 gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
1008 "borderColor", "BorderColor", RES_TYPE_STRING);
1009 gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
1010 NULL, NULL, RES_TYPE_BOOLEAN);
1011
1012 /* Init faces before gui_default_parameter is called for the
1013 scroll-bar-width parameter because otherwise we end up in
1014 init_iterator with a null face cache, which should not happen. */
1015 init_frame_faces (f);
1016
1017 gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
1018 "inhibitDoubleBuffering", "InhibitDoubleBuffering",
1019 RES_TYPE_BOOLEAN);
1020
1021 gui_figure_window_size (f, parms, false, false);
1022
1023 {
1024 void *window;
1025
1026 block_input ();
1027 window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
1028
1029 FRAME_OUTPUT_DATA (f)->window = window;
1030 if (!window)
1031 emacs_abort ();
1032
1033 FRAME_OUTPUT_DATA (f)->window_desc = window;
1034 BWindow_set_tooltip_decoration (window);
1035 unblock_input ();
1036 }
1037
1038 gui_default_parameter (f, parms, Qauto_raise, Qnil,
1039 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
1040 gui_default_parameter (f, parms, Qauto_lower, Qnil,
1041 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
1042 gui_default_parameter (f, parms, Qcursor_type, Qbox,
1043 "cursorType", "CursorType", RES_TYPE_SYMBOL);
1044 gui_default_parameter (f, parms, Qalpha, Qnil,
1045 "alpha", "Alpha", RES_TYPE_NUMBER);
1046
1047 initial_setup_back_buffer (f);
1048
1049 /* Add `tooltip' frame parameter's default value. */
1050 if (NILP (Fframe_parameter (frame, Qtooltip)))
1051 {
1052 AUTO_FRAME_ARG (arg, Qtooltip, Qt);
1053 Fmodify_frame_parameters (frame, arg);
1054 }
1055
1056 /* FIXME - can this be done in a similar way to normal frames?
1057 https://lists.gnu.org/r/emacs-devel/2007-10/msg00641.html */
1058
1059 /* Set up faces after all frame parameters are known. This call
1060 also merges in face attributes specified for new frames.
1061
1062 Frame parameters may be changed if .Xdefaults contains
1063 specifications for the default font. For example, if there is an
1064 `Emacs.default.attributeBackground: pink', the `background-color'
1065 attribute of the frame gets set, which let's the internal border
1066 of the tooltip frame appear in pink. Prevent this. */
1067 {
1068 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
1069
1070 call2 (Qface_set_after_frame_default, frame, Qnil);
1071
1072 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
1073 {
1074 AUTO_FRAME_ARG (arg, Qbackground_color, bg);
1075 Fmodify_frame_parameters (frame, arg);
1076 }
1077 }
1078
1079 f->no_split = true;
1080
1081 /* Now that the frame will be official, it counts as a reference to
1082 its display and terminal. */
1083 f->terminal->reference_count++;
1084
1085 /* It is now ok to make the frame official even if we get an error
1086 below. And the frame needs to be on Vframe_list or making it
1087 visible won't work. */
1088 Vframe_list = Fcons (frame, Vframe_list);
1089 f->can_set_window_size = true;
1090 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
1091 0, true, Qtip_frame);
1092
1093 /* Setting attributes of faces of the tooltip frame from resources
1094 and similar will set face_change, which leads to the clearing of
1095 all current matrices. Since this isn't necessary here, avoid it
1096 by resetting face_change to the value it had before we created
1097 the tip frame. */
1098 face_change = face_change_before;
1099
1100 /* Discard the unwind_protect. */
936 return unbind_to (count, frame); 1101 return unbind_to (count, frame);
937} 1102}
938 1103
1104
939static void 1105static void
940compute_tip_xy (struct frame *f, 1106compute_tip_xy (struct frame *f,
941 Lisp_Object parms, Lisp_Object dx, Lisp_Object dy, 1107 Lisp_Object parms, Lisp_Object dx, Lisp_Object dy,
@@ -1440,6 +1606,7 @@ haiku_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object o
1440 1606
1441 if (new_width == old_width) 1607 if (new_width == old_width)
1442 return; 1608 return;
1609
1443 f->internal_border_width = new_width; 1610 f->internal_border_width = new_width;
1444 1611
1445 if (FRAME_HAIKU_WINDOW (f)) 1612 if (FRAME_HAIKU_WINDOW (f))
@@ -1527,9 +1694,9 @@ haiku_set_inhibit_double_buffering (struct frame *f,
1527 Lisp_Object old_value) 1694 Lisp_Object old_value)
1528{ 1695{
1529 block_input (); 1696 block_input ();
1530#ifndef USE_BE_CAIRO
1531 if (FRAME_HAIKU_WINDOW (f)) 1697 if (FRAME_HAIKU_WINDOW (f))
1532 { 1698 {
1699#ifndef USE_BE_CAIRO
1533 if (NILP (new_value)) 1700 if (NILP (new_value))
1534 { 1701 {
1535#endif 1702#endif
@@ -1543,8 +1710,8 @@ haiku_set_inhibit_double_buffering (struct frame *f,
1543 } 1710 }
1544 else 1711 else
1545 EmacsView_disable_double_buffering (FRAME_HAIKU_VIEW (f)); 1712 EmacsView_disable_double_buffering (FRAME_HAIKU_VIEW (f));
1546 }
1547#endif 1713#endif
1714 }
1548 unblock_input (); 1715 unblock_input ();
1549} 1716}
1550 1717
@@ -1709,7 +1876,7 @@ DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
1709 int width, height; 1876 int width, height;
1710 BScreen_px_dim (&width, &height); 1877 BScreen_px_dim (&width, &height);
1711 1878
1712 return make_fixnum (height / (dpyinfo->resy / 25.4)); 1879 return make_fixnum (width / (dpyinfo->resx / 25.4));
1713} 1880}
1714 1881
1715DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1882DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
@@ -1717,7 +1884,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1717 doc: /* SKIP: real doc in xfns.c. */) 1884 doc: /* SKIP: real doc in xfns.c. */)
1718 (Lisp_Object parms) 1885 (Lisp_Object parms)
1719{ 1886{
1720 return haiku_create_frame (parms, 0); 1887 return haiku_create_frame (parms);
1721} 1888}
1722 1889
1723DEFUN ("x-display-visual-class", Fx_display_visual_class, 1890DEFUN ("x-display-visual-class", Fx_display_visual_class,
@@ -1752,12 +1919,13 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1752 ptrdiff_t count = SPECPDL_INDEX (); 1919 ptrdiff_t count = SPECPDL_INDEX ();
1753 ptrdiff_t count_1; 1920 ptrdiff_t count_1;
1754 Lisp_Object window, size, tip_buf; 1921 Lisp_Object window, size, tip_buf;
1755
1756 AUTO_STRING (tip, " *tip*"); 1922 AUTO_STRING (tip, " *tip*");
1757 1923
1758 specbind (Qinhibit_redisplay, Qt); 1924 specbind (Qinhibit_redisplay, Qt);
1759 1925
1760 CHECK_STRING (string); 1926 CHECK_STRING (string);
1927 if (SCHARS (string) == 0)
1928 string = make_unibyte_string (" ", 1);
1761 1929
1762 if (NILP (frame)) 1930 if (NILP (frame))
1763 frame = selected_frame; 1931 frame = selected_frame;
@@ -1778,7 +1946,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1778 else 1946 else
1779 CHECK_FIXNUM (dy); 1947 CHECK_FIXNUM (dy);
1780 1948
1781 if (haiku_use_system_tooltips) 1949 if (use_system_tooltips)
1782 { 1950 {
1783 int root_x, root_y; 1951 int root_x, root_y;
1784 CHECK_STRING (string); 1952 CHECK_STRING (string);
@@ -1821,24 +1989,21 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1821 { 1989 {
1822 if (FRAME_VISIBLE_P (XFRAME (tip_frame)) 1990 if (FRAME_VISIBLE_P (XFRAME (tip_frame))
1823 && EQ (frame, tip_last_frame) 1991 && EQ (frame, tip_last_frame)
1824 && !NILP (Fequal_including_properties (string, tip_last_string)) 1992 && !NILP (Fequal_including_properties (tip_last_string, string))
1825 && !NILP (Fequal (parms, tip_last_parms))) 1993 && !NILP (Fequal (tip_last_parms, parms)))
1826 { 1994 {
1827 /* Only DX and DY have changed. */ 1995 /* Only DX and DY have changed. */
1828 tip_f = XFRAME (tip_frame); 1996 tip_f = XFRAME (tip_frame);
1829 if (!NILP (tip_timer)) 1997 if (!NILP (tip_timer))
1830 { 1998 {
1831 Lisp_Object timer = tip_timer; 1999 call1 (Qcancel_timer, tip_timer);
1832
1833 tip_timer = Qnil; 2000 tip_timer = Qnil;
1834 call1 (Qcancel_timer, timer);
1835 } 2001 }
1836 2002
1837 block_input (); 2003 block_input ();
1838 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f), 2004 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
1839 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y); 2005 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
1840 haiku_set_offset (tip_f, root_x, root_y, 1); 2006 BWindow_set_offset (FRAME_HAIKU_WINDOW (tip_f), root_x, root_y);
1841 haiku_visualize_frame (tip_f);
1842 unblock_input (); 2007 unblock_input ();
1843 2008
1844 goto start_timer; 2009 goto start_timer;
@@ -1849,8 +2014,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1849 Lisp_Object tail, elt, parm, last; 2014 Lisp_Object tail, elt, parm, last;
1850 2015
1851 /* Check if every parameter in PARMS has the same value in 2016 /* Check if every parameter in PARMS has the same value in
1852 tip_last_parms. This may destruct tip_last_parms 2017 tip_last_parms. This may destruct tip_last_parms which,
1853 which, however, will be recreated below. */ 2018 however, will be recreated below. */
1854 for (tail = parms; CONSP (tail); tail = XCDR (tail)) 2019 for (tail = parms; CONSP (tail); tail = XCDR (tail))
1855 { 2020 {
1856 elt = XCAR (tail); 2021 elt = XCAR (tail);
@@ -1876,8 +2041,9 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1876 call2 (Qassq_delete_all, parm, tip_last_parms); 2041 call2 (Qassq_delete_all, parm, tip_last_parms);
1877 } 2042 }
1878 2043
1879 /* Now check if there's a parameter left in tip_last_parms with a 2044 /* Now check if every parameter in what is left of
1880 non-nil value. */ 2045 tip_last_parms with a non-nil value has an association in
2046 PARMS. */
1881 for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail)) 2047 for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
1882 { 2048 {
1883 elt = XCAR (tail); 2049 elt = XCAR (tail);
@@ -1903,10 +2069,6 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1903 tip_last_string = string; 2069 tip_last_string = string;
1904 tip_last_parms = parms; 2070 tip_last_parms = parms;
1905 2071
1906 /* Block input until the tip has been fully drawn, to avoid crashes
1907 when drawing tips in menus. */
1908 block_input ();
1909
1910 if (NILP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame))) 2072 if (NILP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
1911 { 2073 {
1912 /* Add default values to frame parameters. */ 2074 /* Add default values to frame parameters. */
@@ -1917,21 +2079,16 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1917 if (NILP (Fassq (Qborder_width, parms))) 2079 if (NILP (Fassq (Qborder_width, parms)))
1918 parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms); 2080 parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
1919 if (NILP (Fassq (Qborder_color, parms))) 2081 if (NILP (Fassq (Qborder_color, parms)))
1920 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), 2082 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
1921 parms);
1922 if (NILP (Fassq (Qbackground_color, parms))) 2083 if (NILP (Fassq (Qbackground_color, parms)))
1923 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")), 2084 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
1924 parms); 2085 parms);
1925 2086
1926 /* Create a frame for the tooltip and record it in the global 2087 /* Create a frame for the tooltip, and record it in the global
1927 variable tip_frame. */ 2088 variable tip_frame. */
1928 2089 if (NILP (tip_frame = haiku_create_tip_frame (parms)))
1929 if (NILP (tip_frame = haiku_create_frame (parms, 1))) 2090 /* Creating the tip frame failed. */
1930 { 2091 return unbind_to (count, Qnil);
1931 /* Creating the tip frame failed. */
1932 unblock_input ();
1933 return unbind_to (count, Qnil);
1934 }
1935 } 2092 }
1936 2093
1937 tip_f = XFRAME (tip_frame); 2094 tip_f = XFRAME (tip_frame);
@@ -1971,11 +2128,11 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1971 2128
1972 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f); 2129 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
1973 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f); 2130 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
1974 FRAME_TOTAL_COLS (tip_f) = WINDOW_TOTAL_COLS (w); 2131 FRAME_TOTAL_COLS (tip_f) = w->total_cols;
1975 adjust_frame_glyphs (tip_f); 2132 adjust_frame_glyphs (tip_f);
1976 2133
1977 /* Insert STRING into the root window's buffer and fit the frame to 2134 /* Insert STRING into root window's buffer and fit the frame to the
1978 the buffer. */ 2135 buffer. */
1979 count_1 = SPECPDL_INDEX (); 2136 count_1 = SPECPDL_INDEX ();
1980 old_buffer = current_buffer; 2137 old_buffer = current_buffer;
1981 set_buffer_internal_1 (XBUFFER (w->contents)); 2138 set_buffer_internal_1 (XBUFFER (w->contents));
@@ -1996,22 +2153,28 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1996 /* Add the frame's internal border to calculated size. */ 2153 /* Add the frame's internal border to calculated size. */
1997 width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); 2154 width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
1998 height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); 2155 height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
2156
1999 /* Calculate position of tooltip frame. */ 2157 /* Calculate position of tooltip frame. */
2000 compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y); 2158 compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
2001 BWindow_resize (FRAME_HAIKU_WINDOW (tip_f), width, height); 2159
2002 haiku_set_offset (tip_f, root_x, root_y, 1); 2160 /* Show tooltip frame. */
2003 BWindow_set_tooltip_decoration (FRAME_HAIKU_WINDOW (tip_f)); 2161 block_input ();
2004 BView_set_view_cursor (FRAME_HAIKU_VIEW (tip_f), 2162 void *wnd = FRAME_HAIKU_WINDOW (tip_f);
2005 FRAME_OUTPUT_DATA (XFRAME (frame))->current_cursor); 2163 BWindow_resize (wnd, width, height);
2006 SET_FRAME_VISIBLE (tip_f, 1); 2164 BView_resize_to (FRAME_HAIKU_VIEW (tip_f), width, height);
2007 BWindow_set_visible (FRAME_HAIKU_WINDOW (tip_f), 1); 2165 BWindow_set_offset (wnd, root_x, root_y);
2166 BWindow_set_visible (wnd, true);
2167 SET_FRAME_VISIBLE (tip_f, true);
2168 FRAME_PIXEL_WIDTH (tip_f) = width;
2169 FRAME_PIXEL_HEIGHT (tip_f) = height;
2170 BWindow_sync (wnd);
2171 unblock_input ();
2008 2172
2009 w->must_be_updated_p = true; 2173 w->must_be_updated_p = true;
2010 flush_frame (tip_f);
2011 update_single_window (w); 2174 update_single_window (w);
2175 flush_frame (tip_f);
2012 set_buffer_internal_1 (old_buffer); 2176 set_buffer_internal_1 (old_buffer);
2013 unbind_to (count_1, Qnil); 2177 unbind_to (count_1, Qnil);
2014 unblock_input ();
2015 windows_or_buffers_changed = old_windows_or_buffers_changed; 2178 windows_or_buffers_changed = old_windows_or_buffers_changed;
2016 2179
2017 start_timer: 2180 start_timer:
@@ -2459,6 +2622,7 @@ syms_of_haikufns (void)
2459 DEFSYM (Qalways, "always"); 2622 DEFSYM (Qalways, "always");
2460 DEFSYM (Qnot_useful, "not-useful"); 2623 DEFSYM (Qnot_useful, "not-useful");
2461 DEFSYM (Qwhen_mapped, "when-mapped"); 2624 DEFSYM (Qwhen_mapped, "when-mapped");
2625 DEFSYM (Qtooltip_reuse_hidden_frame, "tooltip-reuse-hidden-frame");
2462 2626
2463 defsubr (&Sx_hide_tip); 2627 defsubr (&Sx_hide_tip);
2464 defsubr (&Sxw_display_color_p); 2628 defsubr (&Sxw_display_color_p);
@@ -2508,14 +2672,6 @@ syms_of_haikufns (void)
2508 doc: /* SKIP: real doc in xfns.c. */); 2672 doc: /* SKIP: real doc in xfns.c. */);
2509 Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40)); 2673 Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40));
2510 2674
2511 DEFVAR_BOOL ("haiku-use-system-tooltips", haiku_use_system_tooltips,
2512 doc: /* When non-nil, Emacs will display tooltips using the App Kit.
2513This can avoid a great deal of consing that does not play
2514well with the Haiku memory allocator, but comes with the
2515disadvantage of not being able to use special display properties
2516within tooltips. */);
2517 haiku_use_system_tooltips = 1;
2518
2519#ifdef USE_BE_CAIRO 2675#ifdef USE_BE_CAIRO
2520 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string, 2676 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
2521 doc: /* Version info for cairo. */); 2677 doc: /* Version info for cairo. */);
diff --git a/src/haikumenu.c b/src/haikumenu.c
index f335bdacb40..2922981cb3b 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -142,10 +142,7 @@ digest_menu_items (void *first_menu, int start, int menu_items_used,
142 } 142 }
143 143
144 if (STRINGP (help) && STRING_MULTIBYTE (help)) 144 if (STRINGP (help) && STRING_MULTIBYTE (help))
145 { 145 help = ENCODE_UTF_8 (help);
146 help = ENCODE_UTF_8 (help);
147 ASET (menu_items, i + MENU_ITEMS_ITEM_HELP, help);
148 }
149 146
150 if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used && 147 if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used &&
151 NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH))) 148 NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH)))
@@ -158,6 +155,12 @@ digest_menu_items (void *first_menu, int start, int menu_items_used,
158 !NILP (enable), !NILP (selected), 0, window, 155 !NILP (enable), !NILP (selected), 0, window,
159 !NILP (descrip) ? SSDATA (descrip) : NULL, 156 !NILP (descrip) ? SSDATA (descrip) : NULL,
160 STRINGP (help) ? SSDATA (help) : NULL); 157 STRINGP (help) ? SSDATA (help) : NULL);
158 else if (!use_system_tooltips || NILP (Fsymbol_value (Qtooltip_mode)))
159 BMenu_add_item (menu, SSDATA (item_name),
160 !NILP (def) ? (void *) (intptr_t) i : NULL,
161 !NILP (enable), !NILP (selected), 1, window,
162 !NILP (descrip) ? SSDATA (descrip) : NULL,
163 NULL);
161 else 164 else
162 BMenu_add_item (menu, SSDATA (item_name), 165 BMenu_add_item (menu, SSDATA (item_name),
163 !NILP (def) ? (void *) (intptr_t) i : NULL, 166 !NILP (def) ? (void *) (intptr_t) i : NULL,
@@ -664,6 +667,7 @@ syms_of_haikumenu (void)
664 DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); 667 DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
665 DEFSYM (Qpopup_menu, "popup-menu"); 668 DEFSYM (Qpopup_menu, "popup-menu");
666 DEFSYM (Qmouse_menu_bar_map, "mouse-menu-bar-map"); 669 DEFSYM (Qmouse_menu_bar_map, "mouse-menu-bar-map");
670 DEFSYM (Qtooltip_mode, "tooltip-mode");
667 671
668 defsubr (&Smenu_or_popup_active_p); 672 defsubr (&Smenu_or_popup_active_p);
669 defsubr (&Shaiku_menu_bar_open); 673 defsubr (&Shaiku_menu_bar_open);
diff --git a/src/haikuselect.c b/src/haikuselect.c
index 2e619c69f7a..e65ab827c51 100644
--- a/src/haikuselect.c
+++ b/src/haikuselect.c
@@ -166,6 +166,36 @@ clipboard. */)
166 return Qnil; 166 return Qnil;
167} 167}
168 168
169DEFUN ("haiku-selection-owner-p", Fhaiku_selection_owner_p, Shaiku_selection_owner_p,
170 0, 1, 0,
171 doc: /* Whether the current Emacs process owns the given SELECTION.
172The arg should be the name of the selection in question, typically one
173of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. For
174convenience, the symbol nil is the same as `PRIMARY', and t is the
175same as `SECONDARY'. */)
176 (Lisp_Object selection)
177{
178 bool value;
179
180 if (NILP (selection))
181 selection = QPRIMARY;
182 else if (EQ (selection, Qt))
183 selection = QSECONDARY;
184
185 block_input ();
186 if (EQ (selection, QPRIMARY))
187 value = BClipboard_owns_primary ();
188 else if (EQ (selection, QSECONDARY))
189 value = BClipboard_owns_secondary ();
190 else if (EQ (selection, QCLIPBOARD))
191 value = BClipboard_owns_clipboard ();
192 else
193 value = false;
194 unblock_input ();
195
196 return value ? Qt : Qnil;
197}
198
169void 199void
170syms_of_haikuselect (void) 200syms_of_haikuselect (void)
171{ 201{
@@ -179,4 +209,5 @@ syms_of_haikuselect (void)
179 defsubr (&Shaiku_selection_data); 209 defsubr (&Shaiku_selection_data);
180 defsubr (&Shaiku_selection_put); 210 defsubr (&Shaiku_selection_put);
181 defsubr (&Shaiku_selection_targets); 211 defsubr (&Shaiku_selection_targets);
212 defsubr (&Shaiku_selection_owner_p);
182} 213}
diff --git a/src/haikuselect.h b/src/haikuselect.h
index 80f33c6ed25..566aae596f6 100644
--- a/src/haikuselect.h
+++ b/src/haikuselect.h
@@ -66,6 +66,15 @@ extern "C"
66 extern void 66 extern void
67 BClipboard_secondary_targets (char **buf, int len); 67 BClipboard_secondary_targets (char **buf, int len);
68 68
69 extern bool
70 BClipboard_owns_clipboard (void);
71
72 extern bool
73 BClipboard_owns_primary (void);
74
75 extern bool
76 BClipboard_owns_secondary (void);
77
69 /* Free the returned data. */ 78 /* Free the returned data. */
70 extern void BClipboard_free_data (void *ptr); 79 extern void BClipboard_free_data (void *ptr);
71#ifdef __cplusplus 80#ifdef __cplusplus
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 3e99cc1c8d9..93ba088f5b1 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -55,6 +55,8 @@ struct unhandled_event
55 uint8_t buffer[200]; 55 uint8_t buffer[200];
56}; 56};
57 57
58static bool any_help_event_p = false;
59
58char * 60char *
59get_keysym_name (int keysym) 61get_keysym_name (int keysym)
60{ 62{
@@ -281,7 +283,7 @@ haiku_new_font (struct frame *f, Lisp_Object font_object, int fontset)
281 else 283 else
282 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit; 284 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
283 285
284 if (FRAME_HAIKU_WINDOW (f)) 286 if (FRAME_HAIKU_WINDOW (f) && !FRAME_TOOLTIP_P (f))
285 { 287 {
286 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 288 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
287 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 289 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f),
@@ -370,6 +372,13 @@ haiku_frame_raise_lower (struct frame *f, bool raise_p)
370 BWindow_sync (FRAME_HAIKU_WINDOW (f)); 372 BWindow_sync (FRAME_HAIKU_WINDOW (f));
371 unblock_input (); 373 unblock_input ();
372 } 374 }
375 else
376 {
377 block_input ();
378 BWindow_send_behind (FRAME_HAIKU_WINDOW (f), NULL);
379 BWindow_sync (FRAME_HAIKU_WINDOW (f));
380 unblock_input ();
381 }
373} 382}
374 383
375/* Unfortunately, NOACTIVATE is not implementable on Haiku. */ 384/* Unfortunately, NOACTIVATE is not implementable on Haiku. */
@@ -2472,10 +2481,7 @@ haiku_default_font_parameter (struct frame *f, Lisp_Object parms)
2472 struct haiku_font_pattern ptn; 2481 struct haiku_font_pattern ptn;
2473 ptn.specified = 0; 2482 ptn.specified = 0;
2474 2483
2475 if (f->tooltip) 2484 BFont_populate_fixed_family (&ptn);
2476 BFont_populate_plain_family (&ptn);
2477 else
2478 BFont_populate_fixed_family (&ptn);
2479 2485
2480 if (ptn.specified & FSPEC_FAMILY) 2486 if (ptn.specified & FSPEC_FAMILY)
2481 font = font_open_by_name (f, build_unibyte_string (ptn.family)); 2487 font = font_open_by_name (f, build_unibyte_string (ptn.family));
@@ -2590,6 +2596,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2590 struct unhandled_event *unhandled_events = NULL; 2596 struct unhandled_event *unhandled_events = NULL;
2591 int button_or_motion_p; 2597 int button_or_motion_p;
2592 int need_flush = 0; 2598 int need_flush = 0;
2599 int do_help = 0;
2593 2600
2594 if (!buf) 2601 if (!buf)
2595 buf = xmalloc (200); 2602 buf = xmalloc (200);
@@ -2638,9 +2645,19 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2638 int width = lrint (b->px_widthf); 2645 int width = lrint (b->px_widthf);
2639 int height = lrint (b->px_heightf); 2646 int height = lrint (b->px_heightf);
2640 2647
2648 if (FRAME_TOOLTIP_P (f))
2649 {
2650 FRAME_PIXEL_WIDTH (f) = width;
2651 FRAME_PIXEL_HEIGHT (f) = height;
2652
2653 haiku_clear_under_internal_border (f);
2654 continue;
2655 }
2656
2641 BView_draw_lock (FRAME_HAIKU_VIEW (f)); 2657 BView_draw_lock (FRAME_HAIKU_VIEW (f));
2642 BView_resize_to (FRAME_HAIKU_VIEW (f), width, height); 2658 BView_resize_to (FRAME_HAIKU_VIEW (f), width, height);
2643 BView_draw_unlock (FRAME_HAIKU_VIEW (f)); 2659 BView_draw_unlock (FRAME_HAIKU_VIEW (f));
2660
2644 if (width != FRAME_PIXEL_WIDTH (f) 2661 if (width != FRAME_PIXEL_WIDTH (f)
2645 || height != FRAME_PIXEL_HEIGHT (f) 2662 || height != FRAME_PIXEL_HEIGHT (f)
2646 || (f->new_size_p 2663 || (f->new_size_p
@@ -2708,6 +2725,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2708 inev.kind = inev.code > 127 ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : 2725 inev.kind = inev.code > 127 ? MULTIBYTE_CHAR_KEYSTROKE_EVENT :
2709 ASCII_KEYSTROKE_EVENT; 2726 ASCII_KEYSTROKE_EVENT;
2710 2727
2728 inev.timestamp = b->time / 1000;
2711 inev.modifiers = haiku_modifiers_to_emacs (b->modifiers); 2729 inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
2712 XSETFRAME (inev.frame_or_window, f); 2730 XSETFRAME (inev.frame_or_window, f);
2713 break; 2731 break;
@@ -2746,7 +2764,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2746 Lisp_Object frame; 2764 Lisp_Object frame;
2747 XSETFRAME (frame, f); 2765 XSETFRAME (frame, f);
2748 2766
2749 x_display_list->last_mouse_movement_time = time (NULL); 2767 x_display_list->last_mouse_movement_time = b->time / 1000;
2750 button_or_motion_p = 1; 2768 button_or_motion_p = 1;
2751 2769
2752 if (hlinfo->mouse_face_hidden) 2770 if (hlinfo->mouse_face_hidden)
@@ -2770,14 +2788,25 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2770 } 2788 }
2771 2789
2772 haiku_new_focus_frame (x_display_list->focused_frame); 2790 haiku_new_focus_frame (x_display_list->focused_frame);
2773 help_echo_string = Qnil; 2791
2774 gen_help_event (Qnil, frame, Qnil, Qnil, 0); 2792 if (any_help_event_p)
2793 do_help = -1;
2775 } 2794 }
2776 else 2795 else
2777 { 2796 {
2778 struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); 2797 struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2779 struct haiku_rect r = dpyinfo->last_mouse_glyph; 2798 struct haiku_rect r = dpyinfo->last_mouse_glyph;
2780 2799
2800 /* For an unknown reason Haiku sends phantom motion events when a
2801 tooltip frame is visible. FIXME */
2802 if (FRAMEP (tip_frame)
2803 && FRAME_LIVE_P (XFRAME (tip_frame))
2804 && FRAME_VISIBLE_P (XFRAME (tip_frame))
2805 && f == dpyinfo->last_mouse_motion_frame
2806 && b->x == dpyinfo->last_mouse_motion_x
2807 && b->y == dpyinfo->last_mouse_motion_y)
2808 continue;
2809
2781 dpyinfo->last_mouse_motion_x = b->x; 2810 dpyinfo->last_mouse_motion_x = b->x;
2782 dpyinfo->last_mouse_motion_y = b->y; 2811 dpyinfo->last_mouse_motion_y = b->y;
2783 dpyinfo->last_mouse_motion_frame = f; 2812 dpyinfo->last_mouse_motion_frame = f;
@@ -2816,9 +2845,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2816 remember_mouse_glyph (f, b->x, b->y, 2845 remember_mouse_glyph (f, b->x, b->y,
2817 &FRAME_DISPLAY_INFO (f)->last_mouse_glyph); 2846 &FRAME_DISPLAY_INFO (f)->last_mouse_glyph);
2818 dpyinfo->last_mouse_glyph_frame = f; 2847 dpyinfo->last_mouse_glyph_frame = f;
2819 gen_help_event (help_echo_string, frame, help_echo_window,
2820 help_echo_object, help_echo_pos);
2821 } 2848 }
2849 else
2850 help_echo_string = previous_help_echo_string;
2822 2851
2823 if (!NILP (Vmouse_autoselect_window)) 2852 if (!NILP (Vmouse_autoselect_window))
2824 { 2853 {
@@ -2838,6 +2867,10 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2838 2867
2839 last_mouse_window = window; 2868 last_mouse_window = window;
2840 } 2869 }
2870
2871 if (!NILP (help_echo_string)
2872 || !NILP (previous_help_echo_string))
2873 do_help = 1;
2841 } 2874 }
2842 break; 2875 break;
2843 } 2876 }
@@ -2857,7 +2890,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2857 inev.modifiers = haiku_modifiers_to_emacs (b->modifiers); 2890 inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
2858 2891
2859 x_display_list->last_mouse_glyph_frame = 0; 2892 x_display_list->last_mouse_glyph_frame = 0;
2860 x_display_list->last_mouse_movement_time = time (NULL); 2893 x_display_list->last_mouse_movement_time = b->time / 1000;
2861 button_or_motion_p = 1; 2894 button_or_motion_p = 1;
2862 2895
2863 /* Is this in the tab-bar? */ 2896 /* Is this in the tab-bar? */
@@ -3262,20 +3295,20 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3262 3295
3263 if (inev.kind != NO_EVENT) 3296 if (inev.kind != NO_EVENT)
3264 { 3297 {
3265 if (inev.kind != HELP_EVENT) 3298 if (inev.kind != HELP_EVENT && !inev.timestamp)
3266 inev.timestamp = (button_or_motion_p 3299 inev.timestamp = (button_or_motion_p
3267 ? x_display_list->last_mouse_movement_time 3300 ? x_display_list->last_mouse_movement_time
3268 : time (NULL)); 3301 : system_time () / 1000);
3269 kbd_buffer_store_event_hold (&inev, hold_quit); 3302 kbd_buffer_store_event_hold (&inev, hold_quit);
3270 ++message_count; 3303 ++message_count;
3271 } 3304 }
3272 3305
3273 if (inev2.kind != NO_EVENT) 3306 if (inev2.kind != NO_EVENT)
3274 { 3307 {
3275 if (inev2.kind != HELP_EVENT) 3308 if (inev2.kind != HELP_EVENT && !inev.timestamp)
3276 inev2.timestamp = (button_or_motion_p 3309 inev2.timestamp = (button_or_motion_p
3277 ? x_display_list->last_mouse_movement_time 3310 ? x_display_list->last_mouse_movement_time
3278 : time (NULL)); 3311 : system_time () / 1000);
3279 kbd_buffer_store_event_hold (&inev2, hold_quit); 3312 kbd_buffer_store_event_hold (&inev2, hold_quit);
3280 ++message_count; 3313 ++message_count;
3281 } 3314 }
@@ -3289,6 +3322,28 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3289 xfree (old); 3322 xfree (old);
3290 } 3323 }
3291 3324
3325 if (do_help && !(hold_quit && hold_quit->kind != NO_EVENT))
3326 {
3327 Lisp_Object help_frame = Qnil;
3328
3329 if (x_display_list->last_mouse_frame)
3330 XSETFRAME (help_frame,
3331 x_display_list->last_mouse_frame);
3332
3333 if (do_help > 0)
3334 {
3335 any_help_event_p = true;
3336 gen_help_event (help_echo_string, help_frame,
3337 help_echo_window, help_echo_object,
3338 help_echo_pos);
3339 }
3340 else
3341 {
3342 help_echo_string = Qnil;
3343 gen_help_event (Qnil, help_frame, Qnil, Qnil, 0);
3344 }
3345 }
3346
3292 if (need_flush) 3347 if (need_flush)
3293 flush_dirty_back_buffers (); 3348 flush_dirty_back_buffers ();
3294 3349
@@ -3507,7 +3562,10 @@ put_xrm_resource (Lisp_Object name, Lisp_Object val)
3507void 3562void
3508haiku_clear_under_internal_border (struct frame *f) 3563haiku_clear_under_internal_border (struct frame *f)
3509{ 3564{
3510 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0) 3565 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
3566 /* This is needed because tooltip frames set up the internal
3567 border before init_frame_faces. */
3568 && FRAME_FACE_CACHE (f))
3511 { 3569 {
3512 int border = FRAME_INTERNAL_BORDER_WIDTH (f); 3570 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
3513 int width = FRAME_PIXEL_WIDTH (f); 3571 int width = FRAME_PIXEL_WIDTH (f);
diff --git a/src/haikuterm.h b/src/haikuterm.h
index 3e39403ab4d..de302883e48 100644
--- a/src/haikuterm.h
+++ b/src/haikuterm.h
@@ -178,6 +178,8 @@ struct x_output
178extern struct haiku_display_info *x_display_list; 178extern struct haiku_display_info *x_display_list;
179extern struct font_driver const haikufont_driver; 179extern struct font_driver const haikufont_driver;
180 180
181extern Lisp_Object tip_frame;
182
181struct scroll_bar 183struct scroll_bar
182{ 184{
183 /* These fields are shared by all vectors. */ 185 /* These fields are shared by all vectors. */
diff --git a/src/image.c b/src/image.c
index a4976caba86..ce9af2dd677 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2906,9 +2906,8 @@ x_create_xrender_picture (struct frame *f, Emacs_Pixmap pixmap, int depth)
2906{ 2906{
2907 Picture p; 2907 Picture p;
2908 Display *display = FRAME_X_DISPLAY (f); 2908 Display *display = FRAME_X_DISPLAY (f);
2909 int event_basep, error_basep;
2910 2909
2911 if (XRenderQueryExtension (display, &event_basep, &error_basep)) 2910 if (FRAME_DISPLAY_INFO (f)->xrender_supported_p)
2912 { 2911 {
2913 if (depth <= 0) 2912 if (depth <= 0)
2914 depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f)); 2913 depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
@@ -11198,8 +11197,7 @@ The list of capabilities can include one or more of the following:
11198# elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER) 11197# elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
11199 int event_basep, error_basep; 11198 int event_basep, error_basep;
11200 11199
11201 if (XRenderQueryExtension (FRAME_X_DISPLAY (f), 11200 if (FRAME_DISPLAY_INFO (f)->xrender_supported_p)
11202 &event_basep, &error_basep))
11203 return list2 (Qscale, Qrotate90); 11201 return list2 (Qscale, Qrotate90);
11204# elif defined (HAVE_NTGUI) 11202# elif defined (HAVE_NTGUI)
11205 return (w32_image_rotations_p () 11203 return (w32_image_rotations_p ()
diff --git a/src/keyboard.c b/src/keyboard.c
index d2ab3a80249..441c23e10c7 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1897,6 +1897,9 @@ int poll_suppress_count;
1897 1897
1898static struct atimer *poll_timer; 1898static struct atimer *poll_timer;
1899 1899
1900/* The poll period that constructed this timer. */
1901static Lisp_Object poll_timer_time;
1902
1900#if defined CYGWIN || defined DOS_NT 1903#if defined CYGWIN || defined DOS_NT
1901/* Poll for input, so that we catch a C-g if it comes in. */ 1904/* Poll for input, so that we catch a C-g if it comes in. */
1902void 1905void
@@ -1938,17 +1941,18 @@ start_polling (void)
1938 1941
1939 /* If poll timer doesn't exist, or we need one with 1942 /* If poll timer doesn't exist, or we need one with
1940 a different interval, start a new one. */ 1943 a different interval, start a new one. */
1941 if (poll_timer == NULL 1944 if (NUMBERP (Vpolling_period)
1942 || poll_timer->interval.tv_sec != polling_period) 1945 && (poll_timer == NULL
1946 || NILP (Fequal (Vpolling_period, poll_timer_time))))
1943 { 1947 {
1944 time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t))); 1948 struct timespec interval = dtotimespec (XFLOATINT (Vpolling_period));
1945 struct timespec interval = make_timespec (period, 0);
1946 1949
1947 if (poll_timer) 1950 if (poll_timer)
1948 cancel_atimer (poll_timer); 1951 cancel_atimer (poll_timer);
1949 1952
1950 poll_timer = start_atimer (ATIMER_CONTINUOUS, interval, 1953 poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
1951 poll_for_input, NULL); 1954 poll_for_input, NULL);
1955 poll_timer_time = Vpolling_period;
1952 } 1956 }
1953 1957
1954 /* Let the timer's callback function poll for input 1958 /* Let the timer's callback function poll for input
@@ -2016,14 +2020,28 @@ void
2016bind_polling_period (int n) 2020bind_polling_period (int n)
2017{ 2021{
2018#ifdef POLL_FOR_INPUT 2022#ifdef POLL_FOR_INPUT
2019 intmax_t new = polling_period; 2023 if (FIXNUMP (Vpolling_period))
2024 {
2025 intmax_t new = XFIXNUM (Vpolling_period);
2026
2027 if (n > new)
2028 new = n;
2029
2030 stop_other_atimers (poll_timer);
2031 stop_polling ();
2032 specbind (Qpolling_period, make_int (new));
2033 }
2034 else if (FLOATP (Vpolling_period))
2035 {
2036 double new = XFLOAT_DATA (Vpolling_period);
2020 2037
2021 if (n > new) 2038 stop_other_atimers (poll_timer);
2022 new = n; 2039 stop_polling ();
2040 specbind (Qpolling_period, (n > new
2041 ? make_int (n)
2042 : Vpolling_period));
2043 }
2023 2044
2024 stop_other_atimers (poll_timer);
2025 stop_polling ();
2026 specbind (Qpolling_period, make_int (new));
2027 /* Start a new alarm with the new period. */ 2045 /* Start a new alarm with the new period. */
2028 start_polling (); 2046 start_polling ();
2029#endif 2047#endif
@@ -12066,6 +12084,11 @@ syms_of_keyboard (void)
12066 help_form_saved_window_configs = Qnil; 12084 help_form_saved_window_configs = Qnil;
12067 staticpro (&help_form_saved_window_configs); 12085 staticpro (&help_form_saved_window_configs);
12068 12086
12087#ifdef POLL_FOR_INPUT
12088 poll_timer_time = Qnil;
12089 staticpro (&poll_timer_time);
12090#endif
12091
12069 defsubr (&Scurrent_idle_time); 12092 defsubr (&Scurrent_idle_time);
12070 defsubr (&Sevent_symbol_parse_modifiers); 12093 defsubr (&Sevent_symbol_parse_modifiers);
12071 defsubr (&Sevent_convert_list); 12094 defsubr (&Sevent_convert_list);
@@ -12223,12 +12246,12 @@ The value may be integer or floating point.
12223If the value is zero, don't echo at all. */); 12246If the value is zero, don't echo at all. */);
12224 Vecho_keystrokes = make_fixnum (1); 12247 Vecho_keystrokes = make_fixnum (1);
12225 12248
12226 DEFVAR_INT ("polling-period", polling_period, 12249 DEFVAR_LISP ("polling-period", Vpolling_period,
12227 doc: /* Interval between polling for input during Lisp execution. 12250 doc: /* Interval between polling for input during Lisp execution.
12228The reason for polling is to make C-g work to stop a running program. 12251The reason for polling is to make C-g work to stop a running program.
12229Polling is needed only when using X windows and SIGIO does not work. 12252Polling is needed only when using X windows and SIGIO does not work.
12230Polling is automatically disabled in all other cases. */); 12253Polling is automatically disabled in all other cases. */);
12231 polling_period = 2; 12254 Vpolling_period = make_float (2.0);
12232 12255
12233 DEFVAR_LISP ("double-click-time", Vdouble_click_time, 12256 DEFVAR_LISP ("double-click-time", Vdouble_click_time,
12234 doc: /* Maximum time between mouse clicks to make a double-click. 12257 doc: /* Maximum time between mouse clicks to make a double-click.
diff --git a/src/nsterm.m b/src/nsterm.m
index 4f60cc737da..a3c7b55218c 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7071,6 +7071,9 @@ not_in_argv (NSString *arg)
7071{ 7071{
7072 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); 7072 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe);
7073 struct frame *old_focus = dpyinfo->ns_focus_frame; 7073 struct frame *old_focus = dpyinfo->ns_focus_frame;
7074 struct input_event event;
7075
7076 EVENT_INIT (event);
7074 7077
7075 NSTRACE ("[EmacsView windowDidBecomeKey]"); 7078 NSTRACE ("[EmacsView windowDidBecomeKey]");
7076 7079
@@ -7079,11 +7082,9 @@ not_in_argv (NSString *arg)
7079 7082
7080 ns_frame_rehighlight (emacsframe); 7083 ns_frame_rehighlight (emacsframe);
7081 7084
7082 if (emacs_event) 7085 event.kind = FOCUS_IN_EVENT;
7083 { 7086 XSETFRAME (event.frame_or_window, emacsframe);
7084 emacs_event->kind = FOCUS_IN_EVENT; 7087 kbd_buffer_store_event (&event);
7085 EV_TRAILER ((id)nil);
7086 }
7087} 7088}
7088 7089
7089 7090
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index c604e2f1002..9c37c04810c 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -3128,7 +3128,7 @@ x_hide_tip (bool delete)
3128 value of x_gtk_use_system_tooltips might not be the same as used 3128 value of x_gtk_use_system_tooltips might not be the same as used
3129 for the tooltip we have to hide, see Bug#30399. */ 3129 for the tooltip we have to hide, see Bug#30399. */
3130 if ((NILP (tip_last_frame) && NILP (tip_frame)) 3130 if ((NILP (tip_last_frame) && NILP (tip_frame))
3131 || (!x_gtk_use_system_tooltips 3131 || (!use_system_tooltips
3132 && !delete 3132 && !delete
3133 && FRAMEP (tip_frame) 3133 && FRAMEP (tip_frame)
3134 && FRAME_LIVE_P (XFRAME (tip_frame)) 3134 && FRAME_LIVE_P (XFRAME (tip_frame))
@@ -3161,7 +3161,7 @@ x_hide_tip (bool delete)
3161 /* When using GTK+ system tooltips (compare Bug#41200) reset 3161 /* When using GTK+ system tooltips (compare Bug#41200) reset
3162 tip_last_frame. It will be reassigned when showing the next 3162 tip_last_frame. It will be reassigned when showing the next
3163 GTK+ system tooltip. */ 3163 GTK+ system tooltip. */
3164 if (x_gtk_use_system_tooltips) 3164 if (use_system_tooltips)
3165 tip_last_frame = Qnil; 3165 tip_last_frame = Qnil;
3166 3166
3167 /* Now look whether there's an Emacs tip around. */ 3167 /* Now look whether there's an Emacs tip around. */
@@ -3171,7 +3171,7 @@ x_hide_tip (bool delete)
3171 3171
3172 if (FRAME_LIVE_P (f)) 3172 if (FRAME_LIVE_P (f))
3173 { 3173 {
3174 if (delete || x_gtk_use_system_tooltips) 3174 if (delete || use_system_tooltips)
3175 { 3175 {
3176 /* Delete the Emacs tooltip frame when DELETE is true 3176 /* Delete the Emacs tooltip frame when DELETE is true
3177 or we change the tooltip type from an Emacs one to 3177 or we change the tooltip type from an Emacs one to
@@ -3267,7 +3267,7 @@ Text larger than the specified size is clipped. */)
3267 else 3267 else
3268 CHECK_FIXNUM (dy); 3268 CHECK_FIXNUM (dy);
3269 3269
3270 if (x_gtk_use_system_tooltips) 3270 if (use_system_tooltips)
3271 { 3271 {
3272 bool ok; 3272 bool ok;
3273 3273
@@ -4068,12 +4068,6 @@ If more space for files in the file chooser dialog is wanted, set this to nil
4068to turn the additional text off. */); 4068to turn the additional text off. */);
4069 x_gtk_file_dialog_help_text = true; 4069 x_gtk_file_dialog_help_text = true;
4070 4070
4071 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
4072 doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
4073Otherwise use Emacs own tooltip implementation.
4074When using Gtk+ tooltips, the tooltip face is not used. */);
4075 x_gtk_use_system_tooltips = true;
4076
4077 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size, 4071 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
4078 doc: /* Maximum size for tooltips. 4072 doc: /* Maximum size for tooltips.
4079Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */); 4073Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 0155ae991d3..8073f51c610 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -153,10 +153,24 @@ static int
153evq_flush (struct input_event *hold_quit) 153evq_flush (struct input_event *hold_quit)
154{ 154{
155 struct event_queue_t *evq = &event_q; 155 struct event_queue_t *evq = &event_q;
156 int i, n = evq->nr; 156 int n = 0;
157 for (i = 0; i < n; i++) 157
158 kbd_buffer_store_buffered_event (&evq->q[i], hold_quit); 158 while (evq->nr > 0)
159 evq->nr = 0; 159 {
160 /* kbd_buffer_store_buffered_event may do longjmp, so
161 we need to shift event queue first and pass the event
162 to kbd_buffer_store_buffered_event so that events in
163 queue are not processed twice. Bug#52941 */
164 union buffered_input_event ev = evq->q[0];
165 int i;
166 for (i = 1; i < evq->nr; i++)
167 evq->q[i - 1] = evq->q[i];
168 evq->nr--;
169
170 kbd_buffer_store_buffered_event (&ev, hold_quit);
171 n++;
172 }
173
160 return n; 174 return n;
161} 175}
162 176
@@ -3720,6 +3734,9 @@ pgtk_flash (struct frame *f)
3720 block_input (); 3734 block_input ();
3721 3735
3722 { 3736 {
3737 if (!FRAME_CR_CONTEXT (f))
3738 return;
3739
3723 cairo_surface_t *surface_orig = FRAME_CR_SURFACE (f); 3740 cairo_surface_t *surface_orig = FRAME_CR_SURFACE (f);
3724 3741
3725 int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f); 3742 int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
@@ -7027,13 +7044,12 @@ If set to a non-float value, there will be no wait at all. */);
7027} 7044}
7028 7045
7029/* Cairo does not allow resizing a surface/context after it is 7046/* Cairo does not allow resizing a surface/context after it is
7030 * created, so we need to trash the old context, create a new context 7047 created, so we need to trash the old context, create a new context
7031 * on the next cr_clip_begin with the new dimensions and request a 7048 on the next cr_clip_begin with the new dimensions and request a
7032 * re-draw. 7049 re-draw.
7033 * 7050
7034 * This Will leave the active context available to present on screen 7051 This will leave the active context available to present on screen
7035 * until a redrawn frame is completed. 7052 until a redrawn frame is completed. */
7036 */
7037void 7053void
7038pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height, bool force) 7054pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height, bool force)
7039{ 7055{
diff --git a/src/syntax.c b/src/syntax.c
index 9df878b8edf..13c36fdf3cd 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1101,10 +1101,11 @@ this is probably the wrong function to use, because it can't take
1101`syntax-after' instead. */) 1101`syntax-after' instead. */)
1102 (Lisp_Object character) 1102 (Lisp_Object character)
1103{ 1103{
1104 int char_int;
1105 CHECK_CHARACTER (character); 1104 CHECK_CHARACTER (character);
1106 char_int = XFIXNUM (character); 1105 int char_int = XFIXNAT (character);
1107 SETUP_BUFFER_SYNTAX_TABLE (); 1106 SETUP_BUFFER_SYNTAX_TABLE ();
1107 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
1108 char_int = make_char_multibyte (char_int);
1108 return make_fixnum (syntax_code_spec[SYNTAX (char_int)]); 1109 return make_fixnum (syntax_code_spec[SYNTAX (char_int)]);
1109} 1110}
1110 1111
diff --git a/src/verbose.mk.in b/src/verbose.mk.in
index e3f56783031..eb99e426958 100644
--- a/src/verbose.mk.in
+++ b/src/verbose.mk.in
@@ -33,24 +33,45 @@ AM_V_GLOBALS =
33AM_V_NO_PD = 33AM_V_NO_PD =
34AM_V_RC = 34AM_V_RC =
35else 35else
36
37# Whether $(info ...) works. This is to work around a bug in GNU Make
38# 4.3 and earlier, which implements $(info MSG) via two system calls
39# { write (..., "MSG", 3); write (..., "\n", 1); }
40# which looks bad when make -j interleaves two of these at about the same time.
41#
42# Later versions of GNU Make have the 'notintermediate' feature,
43# so assume that $(info ...) works if this feature is present.
44#
45have_working_info = $(filter notintermediate,$(value .FEATURES))
46#
47# The workaround is to use the shell and 'echo' rather than $(info ...).
48# The workaround is done only for AM_V_ELC and AM_V_ELN,
49# since the bug is not annoying elsewhere.
50
36AM_V_AR = @$(info $ AR $@) 51AM_V_AR = @$(info $ AR $@)
37AM_V_at = @ 52AM_V_at = @
38AM_V_CC = @$(info $ CC $@) 53AM_V_CC = @$(info $ CC $@)
39AM_V_CXX = @$(info $ CXX $@) 54AM_V_CXX = @$(info $ CXX $@)
40AM_V_CCLD = @$(info $ CCLD $@) 55AM_V_CCLD = @$(info $ CCLD $@)
41AM_V_CXXLD = @$(info $ CXXLD $@) 56AM_V_CXXLD = @$(info $ CXXLD $@)
42ifeq ($(HAVE_NATIVE_COMP),yes) 57
43ifeq ($(NATIVE_DISABLED),1) 58ifeq ($(HAVE_NATIVE_COMP)-$(NATIVE_DISABLED)-$(ANCIENT),yes--)
44AM_V_ELC = @$(info $ ELC $@) 59ifdef have_working_info
45AM_V_ELN =
46else
47AM_V_ELC = @$(info $ ELC+ELN $@) 60AM_V_ELC = @$(info $ ELC+ELN $@)
48AM_V_ELN = @$(info $ ELN $@) 61AM_V_ELN = @$(info $ ELN $@)
62else
63AM_V_ELC = @echo " ELC+ELN " $@;
64AM_V_ELN = @echo " ELN " $@;
49endif 65endif
50else 66else
67ifdef have_working_info
51AM_V_ELC = @$(info $ ELC $@) 68AM_V_ELC = @$(info $ ELC $@)
69else
70AM_V_ELC = @echo " ELC " $@;
71endif
52AM_V_ELN = 72AM_V_ELN =
53endif 73endif
74
54AM_V_GEN = @$(info $ GEN $@) 75AM_V_GEN = @$(info $ GEN $@)
55AM_V_GLOBALS = @$(info $ GEN globals.h) 76AM_V_GLOBALS = @$(info $ GEN globals.h)
56AM_V_NO_PD = --no-print-directory 77AM_V_NO_PD = --no-print-directory
diff --git a/src/w32font.c b/src/w32font.c
index 0495099db5c..c4a89446b98 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -2385,7 +2385,6 @@ font_supported_scripts (FONTSIGNATURE * sig)
2385 SUBRANGE (108, Qkharoshthi); 2385 SUBRANGE (108, Qkharoshthi);
2386 SUBRANGE (109, Qtai_xuan_jing_symbol); 2386 SUBRANGE (109, Qtai_xuan_jing_symbol);
2387 SUBRANGE (110, Qcuneiform); 2387 SUBRANGE (110, Qcuneiform);
2388 SUBRANGE (111, Qcuneiform_numbers_and_punctuation);
2389 SUBRANGE (111, Qcounting_rod_numeral); 2388 SUBRANGE (111, Qcounting_rod_numeral);
2390 SUBRANGE (112, Qsundanese); 2389 SUBRANGE (112, Qsundanese);
2391 SUBRANGE (113, Qlepcha); 2390 SUBRANGE (113, Qlepcha);
@@ -2828,8 +2827,6 @@ syms_of_w32font (void)
2828 DEFSYM (Qbuginese, "buginese"); 2827 DEFSYM (Qbuginese, "buginese");
2829 DEFSYM (Qbuhid, "buhid"); 2828 DEFSYM (Qbuhid, "buhid");
2830 DEFSYM (Qcuneiform, "cuneiform"); 2829 DEFSYM (Qcuneiform, "cuneiform");
2831 DEFSYM (Qcuneiform_numbers_and_punctuation,
2832 "cuneiform-numbers-and-punctuation");
2833 DEFSYM (Qcypriot, "cypriot"); 2830 DEFSYM (Qcypriot, "cypriot");
2834 DEFSYM (Qdeseret, "deseret"); 2831 DEFSYM (Qdeseret, "deseret");
2835 DEFSYM (Qglagolitic, "glagolitic"); 2832 DEFSYM (Qglagolitic, "glagolitic");
diff --git a/src/xdisp.c b/src/xdisp.c
index 977d31703fb..c695e466e78 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -19157,7 +19157,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
19157 struct glyph_row *row; 19157 struct glyph_row *row;
19158 19158
19159 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix); 19159 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
19160 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos) 19160 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos
19161 && !row->ends_at_zv_p)
19161 ++row; 19162 ++row;
19162 19163
19163 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row), 19164 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
diff --git a/src/xfaces.c b/src/xfaces.c
index 8064d47c947..6a279f87192 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3165,14 +3165,15 @@ FRAME 0 means change the face on all frames, and change the default
3165 */ 3165 */
3166 valid_p = true; 3166 valid_p = true;
3167 3167
3168 while (!NILP (CAR_SAFE(list))) 3168 while (!NILP (CAR_SAFE (list)))
3169 { 3169 {
3170 key = CAR_SAFE (list); 3170 key = CAR_SAFE (list);
3171 list = CDR_SAFE (list); 3171 list = CDR_SAFE (list);
3172 val = CAR_SAFE (list); 3172 val = CAR_SAFE (list);
3173 list = CDR_SAFE (list); 3173 list = CDR_SAFE (list);
3174 3174
3175 if (NILP (key) || NILP (val)) 3175 if (NILP (key) || (NILP (val)
3176 && !EQ (key, QCposition)))
3176 { 3177 {
3177 valid_p = false; 3178 valid_p = false;
3178 break; 3179 break;
@@ -6423,8 +6424,12 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
6423 cached faces since we've looked up these faces, we need to look 6424 cached faces since we've looked up these faces, we need to look
6424 them up again. */ 6425 them up again. */
6425 if (!default_face) 6426 if (!default_face)
6426 default_face = FACE_FROM_ID (f, 6427 {
6427 lookup_basic_face (w, f, DEFAULT_FACE_ID)); 6428 if (FRAME_FACE_CACHE (f)->used == 0)
6429 recompute_basic_faces (f);
6430 default_face = FACE_FROM_ID (f,
6431 lookup_basic_face (w, f, DEFAULT_FACE_ID));
6432 }
6428 } 6433 }
6429 6434
6430 /* Optimize common cases where we can use the default face. */ 6435 /* Optimize common cases where we can use the default face. */
diff --git a/src/xfns.c b/src/xfns.c
index ffad0bc3d1a..7123198724a 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -40,6 +40,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
40#include <sys/types.h> 40#include <sys/types.h>
41#include <sys/stat.h> 41#include <sys/stat.h>
42 42
43#ifdef USE_XCB
44#include <xcb/xcb.h>
45#include <xcb/xproto.h>
46#include <xcb/xcb_aux.h>
47#endif
48
43#include "bitmaps/gray.xbm" 49#include "bitmaps/gray.xbm"
44#include "xsettings.h" 50#include "xsettings.h"
45 51
@@ -2643,11 +2649,7 @@ best_xim_style (struct x_display_info *dpyinfo,
2643 int nr_supported = ARRAYELTS (supported_xim_styles); 2649 int nr_supported = ARRAYELTS (supported_xim_styles);
2644 2650
2645 if (dpyinfo->preferred_xim_style) 2651 if (dpyinfo->preferred_xim_style)
2646 { 2652 return dpyinfo->preferred_xim_style;
2647 for (j = 0; j < xim->count_styles; ++j)
2648 if (dpyinfo->preferred_xim_style == xim->supported_styles[j])
2649 return dpyinfo->preferred_xim_style;
2650 }
2651 2653
2652 for (i = 0; i < nr_supported; ++i) 2654 for (i = 0; i < nr_supported; ++i)
2653 for (j = 0; j < xim->count_styles; ++j) 2655 for (j = 0; j < xim->count_styles; ++j)
@@ -3049,7 +3051,7 @@ x_xim_text_to_utf8_unix (XIMText *text, ptrdiff_t *length)
3049 } 3051 }
3050 3052
3051 nbytes = strlen (text->string.multi_byte); 3053 nbytes = strlen (text->string.multi_byte);
3052 setup_coding_system (Qutf_8_unix, &coding); 3054 setup_coding_system (Vlocale_coding_system, &coding);
3053 coding.mode |= (CODING_MODE_LAST_BLOCK 3055 coding.mode |= (CODING_MODE_LAST_BLOCK
3054 | CODING_MODE_SAFE_ENCODING); 3056 | CODING_MODE_SAFE_ENCODING);
3055 coding.source = (const unsigned char *) text->string.multi_byte; 3057 coding.source = (const unsigned char *) text->string.multi_byte;
@@ -6486,7 +6488,11 @@ void
6486x_sync (struct frame *f) 6488x_sync (struct frame *f)
6487{ 6489{
6488 block_input (); 6490 block_input ();
6491#ifndef USE_XCB
6489 XSync (FRAME_X_DISPLAY (f), False); 6492 XSync (FRAME_X_DISPLAY (f), False);
6493#else
6494 xcb_aux_sync (FRAME_DISPLAY_INFO (f)->xcb_connection);
6495#endif
6490 unblock_input (); 6496 unblock_input ();
6491} 6497}
6492 6498
@@ -7107,6 +7113,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
7107 gui_figure_window_size (f, parms, false, false); 7113 gui_figure_window_size (f, parms, false, false);
7108 7114
7109 { 7115 {
7116#ifndef USE_XCB
7110 XSetWindowAttributes attrs; 7117 XSetWindowAttributes attrs;
7111 unsigned long mask; 7118 unsigned long mask;
7112 Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip; 7119 Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
@@ -7143,6 +7150,47 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
7143 XA_ATOM, 32, PropModeReplace, 7150 XA_ATOM, 32, PropModeReplace,
7144 (unsigned char *)&type, 1); 7151 (unsigned char *)&type, 1);
7145 unblock_input (); 7152 unblock_input ();
7153#else
7154 uint32_t value_list[4];
7155 xcb_atom_t net_wm_window_type_tooltip
7156 = (xcb_atom_t) dpyinfo->Xatom_net_window_type_tooltip;
7157
7158 f->output_data.x->current_cursor = f->output_data.x->text_cursor;
7159 /* Values are set in the order of their enumeration in `enum
7160 xcb_cw_t'. */
7161 value_list[0] = FRAME_BACKGROUND_PIXEL (f);
7162 value_list[1] = true;
7163 value_list[2] = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
7164 value_list[3] = (xcb_cursor_t) f->output_data.x->text_cursor;
7165
7166 block_input ();
7167 tip_window
7168 = FRAME_X_WINDOW (f)
7169 = (Window) xcb_generate_id (dpyinfo->xcb_connection);
7170
7171 xcb_create_window (dpyinfo->xcb_connection,
7172 XCB_COPY_FROM_PARENT,
7173 (xcb_window_t) tip_window,
7174 (xcb_window_t) dpyinfo->root_window,
7175 0, 0, 1, 1, f->border_width,
7176 XCB_WINDOW_CLASS_INPUT_OUTPUT,
7177 XCB_COPY_FROM_PARENT,
7178 (XCB_CW_BACK_PIXEL
7179 | XCB_CW_OVERRIDE_REDIRECT
7180 | XCB_CW_EVENT_MASK
7181 | XCB_CW_CURSOR),
7182 &value_list);
7183
7184 xcb_change_property (dpyinfo->xcb_connection,
7185 XCB_PROP_MODE_REPLACE,
7186 (xcb_window_t) tip_window,
7187 (xcb_atom_t) dpyinfo->Xatom_net_window_type,
7188 (xcb_atom_t) dpyinfo->Xatom_ATOM,
7189 32, 1, &net_wm_window_type_tooltip);
7190
7191 initial_set_up_x_back_buffer (f);
7192 unblock_input ();
7193#endif
7146 } 7194 }
7147 7195
7148 x_make_gc (f); 7196 x_make_gc (f);
@@ -7361,13 +7409,13 @@ x_hide_tip (bool delete)
7361 } 7409 }
7362 7410
7363#ifdef USE_GTK 7411#ifdef USE_GTK
7364 /* Any GTK+ system tooltip can be found via the x_output structure of 7412 /* Any GTK+ system tooltip can be found via the x_output structure
7365 tip_last_frame, provided that frame is still live. Any Emacs 7413 of tip_last_frame, provided that frame is still live. Any Emacs
7366 tooltip is found via the tip_frame variable. Note that the current 7414 tooltip is found via the tip_frame variable. Note that the
7367 value of x_gtk_use_system_tooltips might not be the same as used 7415 current value of use_system_tooltips might not be the same as
7368 for the tooltip we have to hide, see Bug#30399. */ 7416 used for the tooltip we have to hide, see Bug#30399. */
7369 if ((NILP (tip_last_frame) && NILP (tip_frame)) 7417 if ((NILP (tip_last_frame) && NILP (tip_frame))
7370 || (!x_gtk_use_system_tooltips 7418 || (!use_system_tooltips
7371 && !delete 7419 && !delete
7372 && !NILP (tip_frame) 7420 && !NILP (tip_frame)
7373 && FRAME_LIVE_P (XFRAME (tip_frame)) 7421 && FRAME_LIVE_P (XFRAME (tip_frame))
@@ -7400,7 +7448,7 @@ x_hide_tip (bool delete)
7400 /* When using GTK+ system tooltips (compare Bug#41200) reset 7448 /* When using GTK+ system tooltips (compare Bug#41200) reset
7401 tip_last_frame. It will be reassigned when showing the next 7449 tip_last_frame. It will be reassigned when showing the next
7402 GTK+ system tooltip. */ 7450 GTK+ system tooltip. */
7403 if (x_gtk_use_system_tooltips) 7451 if (use_system_tooltips)
7404 tip_last_frame = Qnil; 7452 tip_last_frame = Qnil;
7405 7453
7406 /* Now look whether there's an Emacs tip around. */ 7454 /* Now look whether there's an Emacs tip around. */
@@ -7410,7 +7458,7 @@ x_hide_tip (bool delete)
7410 7458
7411 if (FRAME_LIVE_P (f)) 7459 if (FRAME_LIVE_P (f))
7412 { 7460 {
7413 if (delete || x_gtk_use_system_tooltips) 7461 if (delete || use_system_tooltips)
7414 { 7462 {
7415 /* Delete the Emacs tooltip frame when DELETE is true 7463 /* Delete the Emacs tooltip frame when DELETE is true
7416 or we change the tooltip type from an Emacs one to 7464 or we change the tooltip type from an Emacs one to
@@ -7569,7 +7617,7 @@ Text larger than the specified size is clipped. */)
7569 CHECK_FIXNUM (dy); 7617 CHECK_FIXNUM (dy);
7570 7618
7571#ifdef USE_GTK 7619#ifdef USE_GTK
7572 if (x_gtk_use_system_tooltips) 7620 if (use_system_tooltips)
7573 { 7621 {
7574 bool ok; 7622 bool ok;
7575 7623
@@ -7765,9 +7813,23 @@ Text larger than the specified size is clipped. */)
7765 7813
7766 /* Show tooltip frame. */ 7814 /* Show tooltip frame. */
7767 block_input (); 7815 block_input ();
7816#ifndef USE_XCB
7768 XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f), 7817 XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
7769 root_x, root_y, width, height); 7818 root_x, root_y, width, height);
7770 XMapRaised (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f)); 7819 XMapRaised (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f));
7820#else
7821 uint32_t values[] = { root_x, root_y, width, height, XCB_STACK_MODE_ABOVE };
7822
7823 xcb_configure_window (FRAME_DISPLAY_INFO (tip_f)->xcb_connection,
7824 (xcb_window_t) FRAME_X_WINDOW (tip_f),
7825 (XCB_CONFIG_WINDOW_X
7826 | XCB_CONFIG_WINDOW_Y
7827 | XCB_CONFIG_WINDOW_WIDTH
7828 | XCB_CONFIG_WINDOW_HEIGHT
7829 | XCB_CONFIG_WINDOW_STACK_MODE), &values);
7830 xcb_map_window (FRAME_DISPLAY_INFO (tip_f)->xcb_connection,
7831 (xcb_window_t) FRAME_X_WINDOW (tip_f));
7832#endif
7771 unblock_input (); 7833 unblock_input ();
7772 7834
7773#ifdef USE_CAIRO 7835#ifdef USE_CAIRO
@@ -8651,12 +8713,6 @@ If more space for files in the file chooser dialog is wanted, set this to nil
8651to turn the additional text off. */); 8713to turn the additional text off. */);
8652 x_gtk_file_dialog_help_text = true; 8714 x_gtk_file_dialog_help_text = true;
8653 8715
8654 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
8655 doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
8656Otherwise use Emacs own tooltip implementation.
8657When using Gtk+ tooltips, the tooltip face is not used. */);
8658 x_gtk_use_system_tooltips = true;
8659
8660 DEFVAR_LISP ("x-gtk-resize-child-frames", x_gtk_resize_child_frames, 8716 DEFVAR_LISP ("x-gtk-resize-child-frames", x_gtk_resize_child_frames,
8661 doc: /* If non-nil, resize child frames specially with GTK builds. 8717 doc: /* If non-nil, resize child frames specially with GTK builds.
8662If this is nil, resize child frames like any other frames. This is the 8718If this is nil, resize child frames like any other frames. This is the
diff --git a/src/xsettings.h b/src/xsettings.h
index 266526df101..ccaa36489d0 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -21,15 +21,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
21#define XSETTINGS_H 21#define XSETTINGS_H
22 22
23#ifndef HAVE_PGTK 23#ifndef HAVE_PGTK
24#include "dispextern.h"
24#include <X11/Xlib.h> 25#include <X11/Xlib.h>
25#endif 26#endif
26 27
27struct x_display_info; 28struct x_display_info;
28struct pgtk_display_info; 29struct pgtk_display_info;
29 30
30#ifndef HAVE_PGTK 31#ifdef HAVE_PGTK
31typedef struct x_display_info Display_Info;
32#else
33typedef struct pgtk_display_info Display_Info; 32typedef struct pgtk_display_info Display_Info;
34#endif 33#endif
35 34
diff --git a/src/xterm.c b/src/xterm.c
index ec415f5ffaf..36e0045d2ed 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -99,6 +99,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
99#include "xterm.h" 99#include "xterm.h"
100#include <X11/cursorfont.h> 100#include <X11/cursorfont.h>
101 101
102#ifdef USE_XCB
103#include <xcb/xproto.h>
104#include <xcb/xcb.h>
105#include <xcb/xcb_aux.h>
106#endif
107
102/* If we have Xfixes extension, use it for pointer blanking. */ 108/* If we have Xfixes extension, use it for pointer blanking. */
103#ifdef HAVE_XFIXES 109#ifdef HAVE_XFIXES
104#include <X11/extensions/Xfixes.h> 110#include <X11/extensions/Xfixes.h>
@@ -167,6 +173,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
167#include "../lwlib/xlwmenu.h" 173#include "../lwlib/xlwmenu.h"
168#endif 174#endif
169 175
176#ifdef HAVE_XWIDGETS
177#include <cairo-xlib.h>
178#endif
179
170#ifdef USE_X_TOOLKIT 180#ifdef USE_X_TOOLKIT
171 181
172/* Include toolkit specific headers for the scroll bar widget. */ 182/* Include toolkit specific headers for the scroll bar widget. */
@@ -206,6 +216,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
206#include <X11/XKBlib.h> 216#include <X11/XKBlib.h>
207#endif 217#endif
208 218
219#if defined USE_XCB && defined USE_CAIRO_XCB
220#define USE_CAIRO_XCB_SURFACE
221#endif
222
209/* Default to using XIM if available. */ 223/* Default to using XIM if available. */
210#ifdef USE_XIM 224#ifdef USE_XIM
211bool use_xim = true; 225bool use_xim = true;
@@ -777,11 +791,19 @@ x_begin_cr_clip (struct frame *f, GC gc)
777 { 791 {
778 int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f); 792 int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
779 int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f); 793 int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
780 cairo_surface_t *surface 794 cairo_surface_t *surface;
781 = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), 795#ifdef USE_CAIRO_XCB_SURFACE
782 FRAME_X_RAW_DRAWABLE (f), 796 if (FRAME_DISPLAY_INFO (f)->xcb_visual)
783 FRAME_X_VISUAL (f), 797 surface = cairo_xcb_surface_create (FRAME_DISPLAY_INFO (f)->xcb_connection,
784 width, height); 798 (xcb_drawable_t) FRAME_X_RAW_DRAWABLE (f),
799 FRAME_DISPLAY_INFO (f)->xcb_visual,
800 width, height);
801 else
802#endif
803 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
804 FRAME_X_RAW_DRAWABLE (f),
805 FRAME_X_VISUAL (f),
806 width, height);
785 807
786 cr = FRAME_CR_CONTEXT (f) = cairo_create (surface); 808 cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
787 cairo_surface_destroy (surface); 809 cairo_surface_destroy (surface);
@@ -850,6 +872,9 @@ x_try_cr_xlib_drawable (struct frame *f, GC gc)
850 switch (cairo_surface_get_type (surface)) 872 switch (cairo_surface_get_type (surface))
851 { 873 {
852 case CAIRO_SURFACE_TYPE_XLIB: 874 case CAIRO_SURFACE_TYPE_XLIB:
875#ifdef USE_CAIRO_XCB_SURFACE
876 case CAIRO_SURFACE_TYPE_XCB:
877#endif
853 cairo_surface_flush (surface); 878 cairo_surface_flush (surface);
854 return true; 879 return true;
855 880
@@ -1262,11 +1287,15 @@ x_clear_window (struct frame *f)
1262 cairo_paint (cr); 1287 cairo_paint (cr);
1263 x_end_cr_clip (f); 1288 x_end_cr_clip (f);
1264#else 1289#else
1290#ifndef USE_GTK
1265 if (FRAME_X_DOUBLE_BUFFERED_P (f)) 1291 if (FRAME_X_DOUBLE_BUFFERED_P (f))
1292#endif
1266 x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); 1293 x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
1294#ifndef USE_GTK
1267 else 1295 else
1268 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 1296 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
1269#endif 1297#endif
1298#endif
1270} 1299}
1271 1300
1272#ifdef USE_CAIRO 1301#ifdef USE_CAIRO
@@ -2768,8 +2797,9 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
2768 and names we've actually looked up; list-colors-display is probably 2797 and names we've actually looked up; list-colors-display is probably
2769 the most color-intensive case we're likely to hit. */ 2798 the most color-intensive case we're likely to hit. */
2770 2799
2771Status x_parse_color (struct frame *f, const char *color_name, 2800Status
2772 XColor *color) 2801x_parse_color (struct frame *f, const char *color_name,
2802 XColor *color)
2773{ 2803{
2774 /* Don't pass #RGB strings directly to XParseColor, because that 2804 /* Don't pass #RGB strings directly to XParseColor, because that
2775 follows the X convention of zero-extending each channel 2805 follows the X convention of zero-extending each channel
@@ -2798,6 +2828,10 @@ Status x_parse_color (struct frame *f, const char *color_name,
2798 } 2828 }
2799 } 2829 }
2800 2830
2831 /* Some X servers send BadValue on empty color names. */
2832 if (!strlen (color_name))
2833 return 0;
2834
2801 if (XParseColor (dpy, cmap, color_name, color) == 0) 2835 if (XParseColor (dpy, cmap, color_name, color) == 0)
2802 /* No caching of negative results, currently. */ 2836 /* No caching of negative results, currently. */
2803 return 0; 2837 return 0;
@@ -4473,15 +4507,19 @@ x_clear_area (struct frame *f, int x, int y, int width, int height)
4473 cairo_fill (cr); 4507 cairo_fill (cr);
4474 x_end_cr_clip (f); 4508 x_end_cr_clip (f);
4475#else 4509#else
4510#ifndef USE_GTK
4476 if (FRAME_X_DOUBLE_BUFFERED_P (f)) 4511 if (FRAME_X_DOUBLE_BUFFERED_P (f))
4512#endif
4477 XFillRectangle (FRAME_X_DISPLAY (f), 4513 XFillRectangle (FRAME_X_DISPLAY (f),
4478 FRAME_X_DRAWABLE (f), 4514 FRAME_X_DRAWABLE (f),
4479 f->output_data.x->reverse_gc, 4515 f->output_data.x->reverse_gc,
4480 x, y, width, height); 4516 x, y, width, height);
4517#ifndef USE_GTK
4481 else 4518 else
4482 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 4519 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4483 x, y, width, height, False); 4520 x, y, width, height, False);
4484#endif 4521#endif
4522#endif
4485} 4523}
4486 4524
4487 4525
@@ -4528,6 +4566,7 @@ x_show_hourglass (struct frame *f)
4528 4566
4529 if (!x->hourglass_window) 4567 if (!x->hourglass_window)
4530 { 4568 {
4569#ifndef USE_XCB
4531 unsigned long mask = CWCursor; 4570 unsigned long mask = CWCursor;
4532 XSetWindowAttributes attrs; 4571 XSetWindowAttributes attrs;
4533#ifdef USE_GTK 4572#ifdef USE_GTK
@@ -4540,12 +4579,41 @@ x_show_hourglass (struct frame *f)
4540 x->hourglass_window = XCreateWindow 4579 x->hourglass_window = XCreateWindow
4541 (dpy, parent, 0, 0, 32000, 32000, 0, 0, 4580 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
4542 InputOnly, CopyFromParent, mask, &attrs); 4581 InputOnly, CopyFromParent, mask, &attrs);
4582#else
4583 uint32_t cursor = (uint32_t) x->hourglass_cursor;
4584#ifdef USE_GTK
4585 xcb_window_t parent = (xcb_window_t) FRAME_X_WINDOW (f);
4586#else
4587 xcb_window_t parent = (xcb_window_t) FRAME_OUTER_WINDOW (f);
4588#endif
4589 x->hourglass_window
4590 = (Window) xcb_generate_id (FRAME_DISPLAY_INFO (f)->xcb_connection);
4591
4592 xcb_create_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
4593 XCB_COPY_FROM_PARENT,
4594 (xcb_window_t) x->hourglass_window,
4595 parent, 0, 0, FRAME_PIXEL_WIDTH (f),
4596 FRAME_PIXEL_HEIGHT (f), 0,
4597 XCB_WINDOW_CLASS_INPUT_OUTPUT,
4598 XCB_COPY_FROM_PARENT, XCB_CW_CURSOR,
4599 &cursor);
4600#endif
4543 } 4601 }
4544 4602
4603#ifndef USE_XCB
4545 XMapRaised (dpy, x->hourglass_window); 4604 XMapRaised (dpy, x->hourglass_window);
4546 XFlush (dpy);
4547 /* Ensure that the spinning hourglass is shown. */ 4605 /* Ensure that the spinning hourglass is shown. */
4548 flush_frame (f); 4606 flush_frame (f);
4607#else
4608 uint32_t value = XCB_STACK_MODE_ABOVE;
4609
4610 xcb_configure_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
4611 (xcb_window_t) x->hourglass_window,
4612 XCB_CONFIG_WINDOW_STACK_MODE, &value);
4613 xcb_map_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
4614 (xcb_window_t) x->hourglass_window);
4615 xcb_flush (FRAME_DISPLAY_INFO (f)->xcb_connection);
4616#endif
4549 } 4617 }
4550 } 4618 }
4551} 4619}
@@ -4560,10 +4628,16 @@ x_hide_hourglass (struct frame *f)
4560 /* Watch out for newly created frames. */ 4628 /* Watch out for newly created frames. */
4561 if (x->hourglass_window) 4629 if (x->hourglass_window)
4562 { 4630 {
4631#ifndef USE_XCB
4563 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window); 4632 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
4564 /* Sync here because XTread_socket looks at the 4633 /* Sync here because XTread_socket looks at the
4565 hourglass_p flag that is reset to zero below. */ 4634 hourglass_p flag that is reset to zero below. */
4566 XSync (FRAME_X_DISPLAY (f), False); 4635 XSync (FRAME_X_DISPLAY (f), False);
4636#else
4637 xcb_unmap_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
4638 (xcb_window_t) x->hourglass_window);
4639 xcb_aux_sync (FRAME_DISPLAY_INFO (f)->xcb_connection);
4640#endif
4567 x->hourglass_p = false; 4641 x->hourglass_p = false;
4568 } 4642 }
4569} 4643}
@@ -4576,38 +4650,6 @@ XTflash (struct frame *f)
4576 block_input (); 4650 block_input ();
4577 4651
4578 { 4652 {
4579#ifdef USE_GTK
4580 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
4581 when the scroll bars and the edit widget share the same X window. */
4582 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4583#ifdef HAVE_GTK3
4584#if GTK_CHECK_VERSION (3, 22, 0)
4585 cairo_region_t *region = gdk_window_get_visible_region (window);
4586 GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
4587 cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
4588#else
4589 cairo_t *cr = gdk_cairo_create (window);
4590#endif
4591 cairo_set_source_rgb (cr, 1, 1, 1);
4592 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
4593#define XFillRectangle(d, win, gc, x, y, w, h) \
4594 do { \
4595 cairo_rectangle (cr, x, y, w, h); \
4596 cairo_fill (cr); \
4597 } \
4598 while (false)
4599#else /* ! HAVE_GTK3 */
4600 GdkGCValues vals;
4601 GdkGC *gc;
4602 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
4603 ^ FRAME_BACKGROUND_PIXEL (f));
4604 vals.function = GDK_XOR;
4605 gc = gdk_gc_new_with_values (window,
4606 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
4607#define XFillRectangle(d, win, gc, x, y, w, h) \
4608 gdk_draw_rectangle (window, gc, true, x, y, w, h)
4609#endif /* ! HAVE_GTK3 */
4610#else /* ! USE_GTK */
4611 GC gc; 4653 GC gc;
4612 4654
4613 /* Create a GC that will use the GXxor function to flip foreground 4655 /* Create a GC that will use the GXxor function to flip foreground
@@ -4622,7 +4664,6 @@ XTflash (struct frame *f)
4622 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 4664 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4623 GCFunction | GCForeground, &values); 4665 GCFunction | GCForeground, &values);
4624 } 4666 }
4625#endif
4626 { 4667 {
4627 /* Get the height not including a menu bar widget. */ 4668 /* Get the height not including a menu bar widget. */
4628 int height = FRAME_PIXEL_HEIGHT (f); 4669 int height = FRAME_PIXEL_HEIGHT (f);
@@ -4698,22 +4739,7 @@ XTflash (struct frame *f)
4698 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, 4739 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4699 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), 4740 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4700 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); 4741 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4701
4702#ifdef USE_GTK
4703#ifdef HAVE_GTK3
4704#if GTK_CHECK_VERSION (3, 22, 0)
4705 gdk_window_end_draw_frame (window, context);
4706 cairo_region_destroy (region);
4707#else
4708 cairo_destroy (cr);
4709#endif
4710#else
4711 g_object_unref (G_OBJECT (gc));
4712#endif
4713#undef XFillRectangle
4714#else
4715 XFreeGC (FRAME_X_DISPLAY (f), gc); 4742 XFreeGC (FRAME_X_DISPLAY (f), gc);
4716#endif
4717 x_flush (f); 4743 x_flush (f);
4718 } 4744 }
4719 } 4745 }
@@ -4921,6 +4947,18 @@ x_scroll_run (struct window *w, struct run *run)
4921 x, to_y); 4947 x, to_y);
4922 cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height); 4948 cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
4923 } 4949 }
4950#ifdef USE_CAIRO_XCB_SURFACE
4951 else if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XCB)
4952 {
4953 cairo_surface_flush (surface);
4954 xcb_copy_area (FRAME_DISPLAY_INFO (f)->xcb_connection,
4955 (xcb_drawable_t) FRAME_X_DRAWABLE (f),
4956 (xcb_drawable_t) FRAME_X_DRAWABLE (f),
4957 (xcb_gcontext_t) XGContextFromGC (f->output_data.x->normal_gc),
4958 x, from_y, x, to_y, width, height);
4959 cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
4960 }
4961#endif
4924 else 4962 else
4925 { 4963 {
4926 cairo_surface_t *s 4964 cairo_surface_t *s
@@ -5436,11 +5474,6 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
5436 int syms_per_code; 5474 int syms_per_code;
5437 XModifierKeymap *mods; 5475 XModifierKeymap *mods;
5438#ifdef HAVE_XKB 5476#ifdef HAVE_XKB
5439 Atom meta;
5440 Atom super;
5441 Atom hyper;
5442 Atom shiftlock;
5443 Atom alt;
5444 int i; 5477 int i;
5445 int found_meta_p = false; 5478 int found_meta_p = false;
5446#endif 5479#endif
@@ -5454,28 +5487,22 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
5454#ifdef HAVE_XKB 5487#ifdef HAVE_XKB
5455 if (dpyinfo->xkb_desc) 5488 if (dpyinfo->xkb_desc)
5456 { 5489 {
5457 meta = XInternAtom (dpyinfo->display, "Meta", False);
5458 super = XInternAtom (dpyinfo->display, "Super", False);
5459 hyper = XInternAtom (dpyinfo->display, "Hyper", False);
5460 shiftlock = XInternAtom (dpyinfo->display, "ShiftLock", False);
5461 alt = XInternAtom (dpyinfo->display, "Alt", False);
5462
5463 for (i = 0; i < XkbNumVirtualMods; i++) 5490 for (i = 0; i < XkbNumVirtualMods; i++)
5464 { 5491 {
5465 uint vmodmask = dpyinfo->xkb_desc->server->vmods[i]; 5492 uint vmodmask = dpyinfo->xkb_desc->server->vmods[i];
5466 5493
5467 if (dpyinfo->xkb_desc->names->vmods[i] == meta) 5494 if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Meta)
5468 { 5495 {
5469 dpyinfo->meta_mod_mask |= vmodmask; 5496 dpyinfo->meta_mod_mask |= vmodmask;
5470 found_meta_p = vmodmask; 5497 found_meta_p = vmodmask;
5471 } 5498 }
5472 else if (dpyinfo->xkb_desc->names->vmods[i] == alt) 5499 else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Alt)
5473 dpyinfo->alt_mod_mask |= vmodmask; 5500 dpyinfo->alt_mod_mask |= vmodmask;
5474 else if (dpyinfo->xkb_desc->names->vmods[i] == super) 5501 else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Super)
5475 dpyinfo->super_mod_mask |= vmodmask; 5502 dpyinfo->super_mod_mask |= vmodmask;
5476 else if (dpyinfo->xkb_desc->names->vmods[i] == hyper) 5503 else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Hyper)
5477 dpyinfo->hyper_mod_mask |= vmodmask; 5504 dpyinfo->hyper_mod_mask |= vmodmask;
5478 else if (dpyinfo->xkb_desc->names->vmods[i] == shiftlock) 5505 else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_ShiftLock)
5479 dpyinfo->shift_lock_mask |= vmodmask; 5506 dpyinfo->shift_lock_mask |= vmodmask;
5480 } 5507 }
5481 5508
@@ -8373,6 +8400,7 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
8373#ifdef USE_GTK 8400#ifdef USE_GTK
8374 } 8401 }
8375 else if (f1 && (event->type == KeyPress 8402 else if (f1 && (event->type == KeyPress
8403 || event->type == KeyRelease
8376#ifdef HAVE_XINPUT2 8404#ifdef HAVE_XINPUT2
8377 || xinput_event 8405 || xinput_event
8378#endif 8406#endif
@@ -8384,6 +8412,11 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
8384 result = xg_filter_key (f1, event); 8412 result = xg_filter_key (f1, event);
8385 unblock_input (); 8413 unblock_input ();
8386 8414
8415 if (result && f1)
8416 /* There will probably be a GDK event generated soon, so
8417 exercise the wire to make pselect return. */
8418 XNoOp (FRAME_X_DISPLAY (f1));
8419
8387 return result; 8420 return result;
8388 } 8421 }
8389 8422
@@ -8434,8 +8467,10 @@ event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
8434 && xev->type == GenericEvent 8467 && xev->type == GenericEvent
8435 && (xev->xgeneric.extension 8468 && (xev->xgeneric.extension
8436 == dpyinfo->xi2_opcode) 8469 == dpyinfo->xi2_opcode)
8437 && (xev->xgeneric.evtype 8470 && ((xev->xgeneric.evtype
8438 == XI_KeyPress)) 8471 == XI_KeyPress)
8472 || (xev->xgeneric.evtype
8473 == XI_KeyRelease)))
8439#endif 8474#endif
8440 )) 8475 ))
8441 { 8476 {
@@ -8947,12 +8982,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8947 if (!FRAME_VISIBLE_P (f)) 8982 if (!FRAME_VISIBLE_P (f))
8948 { 8983 {
8949 block_input (); 8984 block_input ();
8950 /* The following two are commented out to avoid that a 8985 /* By default, do not set the frame's visibility here, see
8951 plain invisible frame gets reported as iconified. That 8986 https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
8952 problem occurred first for Emacs 26 and is described in 8987 The default behavior can be overridden by setting
8953 https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. */ 8988 'x-set-frame-visibility-more-laxly' (Bug#49955,
8954/** SET_FRAME_VISIBLE (f, 1); **/ 8989 Bug#53298). */
8955/** SET_FRAME_ICONIFIED (f, false); **/ 8990 if (EQ (x_set_frame_visibility_more_laxly, Qexpose)
8991 || EQ (x_set_frame_visibility_more_laxly, Qt))
8992 {
8993 SET_FRAME_VISIBLE (f, 1);
8994 SET_FRAME_ICONIFIED (f, false);
8995 }
8956 8996
8957 if (FRAME_X_DOUBLE_BUFFERED_P (f)) 8997 if (FRAME_X_DOUBLE_BUFFERED_P (f))
8958 font_drop_xrender_surfaces (f); 8998 font_drop_xrender_surfaces (f);
@@ -9236,7 +9276,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9236 int modifiers; 9276 int modifiers;
9237 Lisp_Object coding_system = Qlatin_1; 9277 Lisp_Object coding_system = Qlatin_1;
9238 Lisp_Object c; 9278 Lisp_Object c;
9239 /* Event will be modified. */ 9279 /* `xkey' will be modified, but it's not important to modify
9280 `event' itself. */
9240 XKeyEvent xkey = event->xkey; 9281 XKeyEvent xkey = event->xkey;
9241 9282
9242#ifdef USE_GTK 9283#ifdef USE_GTK
@@ -9498,8 +9539,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9498 if (keysym == NoSymbol) 9539 if (keysym == NoSymbol)
9499 break; 9540 break;
9500 } 9541 }
9501 /* FIXME: check side effects and remove this. */
9502 ((XEvent *) event)->xkey = xkey;
9503 } 9542 }
9504 done_keysym: 9543 done_keysym:
9505#ifdef HAVE_X_I18N 9544#ifdef HAVE_X_I18N
@@ -9571,26 +9610,33 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9571 goto OTHER; 9610 goto OTHER;
9572 9611
9573 case FocusIn: 9612 case FocusIn:
9574#ifndef USE_GTK 9613#ifdef USE_GTK
9575 /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap 9614 /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
9576 minimized/iconified windows; thus, for those WMs we won't get 9615 minimized/iconified windows; thus, for those WMs we won't get
9577 a MapNotify when unminimizing/deconifying. Check here if we 9616 a MapNotify when unminimizing/deiconifying. Check here if we
9578 are deiconizing a window (Bug42655). 9617 are deiconizing a window (Bug42655).
9579 9618
9580 But don't do that on GTK since it may cause a plain invisible 9619 But don't do that by default on GTK since it may cause a plain
9581 frame get reported as iconified, compare 9620 invisible frame get reported as iconified, compare
9582 https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. 9621 https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
9583 That is fixed above but bites us here again. */ 9622 That is fixed above but bites us here again.
9584 f = any; 9623
9585 if (f && FRAME_ICONIFIED_P (f)) 9624 The option x_set_frame_visibility_more_laxly allows to override
9586 { 9625 the default behavior (Bug#49955, Bug#53298). */
9587 SET_FRAME_VISIBLE (f, 1); 9626 if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
9588 SET_FRAME_ICONIFIED (f, false); 9627 || EQ (x_set_frame_visibility_more_laxly, Qt))
9589 f->output_data.x->has_been_visible = true;
9590 inev.ie.kind = DEICONIFY_EVENT;
9591 XSETFRAME (inev.ie.frame_or_window, f);
9592 }
9593#endif /* USE_GTK */ 9628#endif /* USE_GTK */
9629 {
9630 f = any;
9631 if (f && FRAME_ICONIFIED_P (f))
9632 {
9633 SET_FRAME_VISIBLE (f, 1);
9634 SET_FRAME_ICONIFIED (f, false);
9635 f->output_data.x->has_been_visible = true;
9636 inev.ie.kind = DEICONIFY_EVENT;
9637 XSETFRAME (inev.ie.frame_or_window, f);
9638 }
9639 }
9594 9640
9595 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 9641 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
9596 goto OTHER; 9642 goto OTHER;
@@ -10194,26 +10240,33 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10194 { 10240 {
10195 case XI_FocusIn: 10241 case XI_FocusIn:
10196 any = x_any_window_to_frame (dpyinfo, focusin->event); 10242 any = x_any_window_to_frame (dpyinfo, focusin->event);
10197#ifndef USE_GTK 10243#ifdef USE_GTK
10198 /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap 10244 /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
10199 minimized/iconified windows; thus, for those WMs we won't get 10245 minimized/iconified windows; thus, for those WMs we won't get
10200 a MapNotify when unminimizing/deconifying. Check here if we 10246 a MapNotify when unminimizing/deiconifying. Check here if we
10201 are deiconizing a window (Bug42655). 10247 are deiconizing a window (Bug42655).
10202 10248
10203 But don't do that on GTK since it may cause a plain invisible 10249 But don't do that by default on GTK since it may cause a plain
10204 frame get reported as iconified, compare 10250 invisible frame get reported as iconified, compare
10205 https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. 10251 https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
10206 That is fixed above but bites us here again. */ 10252 That is fixed above but bites us here again.
10207 f = any; 10253
10208 if (f && FRAME_ICONIFIED_P (f)) 10254 The option x_set_frame_visibility_more_laxly allows to override
10255 the default behavior (Bug#49955, Bug#53298). */
10256 if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
10257 || EQ (x_set_frame_visibility_more_laxly, Qt))
10258#endif /* USE_GTK */
10209 { 10259 {
10210 SET_FRAME_VISIBLE (f, 1); 10260 f = any;
10211 SET_FRAME_ICONIFIED (f, false); 10261 if (f && FRAME_ICONIFIED_P (f))
10212 f->output_data.x->has_been_visible = true; 10262 {
10213 inev.ie.kind = DEICONIFY_EVENT; 10263 SET_FRAME_VISIBLE (f, 1);
10214 XSETFRAME (inev.ie.frame_or_window, f); 10264 SET_FRAME_ICONIFIED (f, false);
10265 f->output_data.x->has_been_visible = true;
10266 inev.ie.kind = DEICONIFY_EVENT;
10267 XSETFRAME (inev.ie.frame_or_window, f);
10268 }
10215 } 10269 }
10216#endif /* USE_GTK */
10217 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 10270 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
10218 goto XI_OTHER; 10271 goto XI_OTHER;
10219 case XI_FocusOut: 10272 case XI_FocusOut:
@@ -10708,7 +10761,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10708 10761
10709 if (f && xev->evtype == XI_ButtonPress 10762 if (f && xev->evtype == XI_ButtonPress
10710 && !popup_activated () 10763 && !popup_activated ()
10711 && !x_window_to_scroll_bar (xev->display, xev->event, 2) 10764 && !x_window_to_scroll_bar (dpyinfo->display, xev->event, 2)
10712 && !FRAME_NO_ACCEPT_FOCUS (f)) 10765 && !FRAME_NO_ACCEPT_FOCUS (f))
10713 { 10766 {
10714 /* When clicking into a child frame or when clicking 10767 /* When clicking into a child frame or when clicking
@@ -10881,7 +10934,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10881 xkey.type = KeyPress; 10934 xkey.type = KeyPress;
10882 xkey.serial = xev->serial; 10935 xkey.serial = xev->serial;
10883 xkey.send_event = xev->send_event; 10936 xkey.send_event = xev->send_event;
10884 xkey.display = xev->display; 10937 xkey.display = dpyinfo->display;
10885 xkey.window = xev->event; 10938 xkey.window = xev->event;
10886 xkey.root = xev->root; 10939 xkey.root = xev->root;
10887 xkey.subwindow = xev->child; 10940 xkey.subwindow = xev->child;
@@ -11227,7 +11280,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
11227 xkey.type = KeyRelease; 11280 xkey.type = KeyRelease;
11228 xkey.serial = xev->serial; 11281 xkey.serial = xev->serial;
11229 xkey.send_event = xev->send_event; 11282 xkey.send_event = xev->send_event;
11230 xkey.display = xev->display; 11283 xkey.display = dpyinfo->display;
11231 xkey.window = xev->event; 11284 xkey.window = xev->event;
11232 xkey.root = xev->root; 11285 xkey.root = xev->root;
11233 xkey.subwindow = xev->child; 11286 xkey.subwindow = xev->child;
@@ -11523,8 +11576,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
11523 XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True); 11576 XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True);
11524 dpyinfo->xkb_desc = NULL; 11577 dpyinfo->xkb_desc = NULL;
11525 } 11578 }
11526
11527 x_find_modifier_meanings (dpyinfo);
11528 } 11579 }
11529 else 11580 else
11530 { 11581 {
@@ -11542,6 +11593,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
11542 } 11593 }
11543 11594
11544 XkbRefreshKeyboardMapping (&xkbevent->map); 11595 XkbRefreshKeyboardMapping (&xkbevent->map);
11596 x_find_modifier_meanings (dpyinfo);
11545 } 11597 }
11546 } 11598 }
11547#endif 11599#endif
@@ -12698,9 +12750,11 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
12698 ret = XRegisterIMInstantiateCallback 12750 ret = XRegisterIMInstantiateCallback
12699 (dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name, 12751 (dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
12700 emacs_class, xim_instantiate_callback, 12752 emacs_class, xim_instantiate_callback,
12701 /* This is XPointer in XFree86 but (XPointer *) 12753 /* This is XPointer in XFree86 but (XPointer *) on Tru64, at
12702 on Tru64, at least, hence the configure test. */ 12754 least, but the configure test doesn't work because
12703 (XRegisterIMInstantiateCallback_arg6) xim_inst); 12755 xim_instantiate_callback can either be XIMProc or
12756 XIDProc, so just cast to void *. */
12757 (void *) xim_inst);
12704 eassert (ret == True); 12758 eassert (ret == True);
12705#else /* not HAVE_X11R6_XIM */ 12759#else /* not HAVE_X11R6_XIM */
12706 xim_open_dpy (dpyinfo, resource_name); 12760 xim_open_dpy (dpyinfo, resource_name);
@@ -12725,8 +12779,7 @@ xim_close_dpy (struct x_display_info *dpyinfo)
12725 { 12779 {
12726 Bool ret = XUnregisterIMInstantiateCallback 12780 Bool ret = XUnregisterIMInstantiateCallback
12727 (dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name, 12781 (dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
12728 emacs_class, xim_instantiate_callback, 12782 emacs_class, xim_instantiate_callback, (void *) xim_inst);
12729 (XRegisterIMInstantiateCallback_arg6) xim_inst);
12730 eassert (ret == True); 12783 eassert (ret == True);
12731 } 12784 }
12732 xfree (xim_inst->resource_name); 12785 xfree (xim_inst->resource_name);
@@ -15261,6 +15314,40 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
15261 dpyinfo->supports_xdbe = true; 15314 dpyinfo->supports_xdbe = true;
15262#endif 15315#endif
15263 15316
15317#ifdef USE_XCB
15318 xcb_screen_t *xcb_screen = NULL;
15319 xcb_screen_iterator_t iter;
15320 xcb_visualid_t wanted = { XVisualIDFromVisual (dpyinfo->visual) };
15321 xcb_depth_iterator_t depth_iter;
15322 xcb_visualtype_iterator_t visual_iter;
15323
15324 int screen = DefaultScreen (dpyinfo->display);
15325
15326 iter = xcb_setup_roots_iterator (xcb_get_setup (dpyinfo->xcb_connection));
15327 for (; iter.rem; --screen, xcb_screen_next (&iter))
15328 {
15329 if (!screen)
15330 xcb_screen = iter.data;
15331 }
15332
15333 if (xcb_screen)
15334 {
15335 depth_iter = xcb_screen_allowed_depths_iterator (xcb_screen);
15336 for (; depth_iter.rem; xcb_depth_next (&depth_iter))
15337 {
15338 visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
15339 for (; visual_iter.rem; xcb_visualtype_next (&visual_iter))
15340 {
15341 if (wanted == visual_iter.data->visual_id)
15342 {
15343 dpyinfo->xcb_visual = visual_iter.data;
15344 break;
15345 }
15346 }
15347 }
15348 }
15349#endif
15350
15264#ifdef HAVE_XINPUT2 15351#ifdef HAVE_XINPUT2
15265 dpyinfo->supports_xi2 = false; 15352 dpyinfo->supports_xi2 = false;
15266 int rc; 15353 int rc;
@@ -15329,9 +15416,19 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
15329 XkbNewKeyboardNotifyMask | XkbMapNotifyMask, 15416 XkbNewKeyboardNotifyMask | XkbMapNotifyMask,
15330 XkbNewKeyboardNotifyMask | XkbMapNotifyMask); 15417 XkbNewKeyboardNotifyMask | XkbMapNotifyMask);
15331 } 15418 }
15419#endif
15332 15420
15333 /* Figure out which modifier bits mean what. */ 15421#ifdef HAVE_XRENDER
15334 x_find_modifier_meanings (dpyinfo); 15422 int event_base, error_base;
15423 dpyinfo->xrender_supported_p
15424 = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
15425
15426 if (dpyinfo->xrender_supported_p)
15427 {
15428 if (!XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
15429 &dpyinfo->xrender_minor))
15430 dpyinfo->xrender_supported_p = false;
15431 }
15335#endif 15432#endif
15336 15433
15337#if defined USE_CAIRO || defined HAVE_XFT 15434#if defined USE_CAIRO || defined HAVE_XFT
@@ -15350,11 +15447,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
15350 or larger than other for other applications, even if it is the same 15447 or larger than other for other applications, even if it is the same
15351 font name (monospace-10 for example). */ 15448 font name (monospace-10 for example). */
15352 15449
15353# ifdef HAVE_XRENDER
15354 int event_base, error_base;
15355 XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
15356# endif
15357
15358 char *v = XGetDefault (dpyinfo->display, "Xft", "dpi"); 15450 char *v = XGetDefault (dpyinfo->display, "Xft", "dpi");
15359 double d; 15451 double d;
15360 if (v != NULL && sscanf (v, "%lf", &d) == 1) 15452 if (v != NULL && sscanf (v, "%lf", &d) == 1)
@@ -15447,6 +15539,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
15447 ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar) 15539 ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar)
15448 ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above) 15540 ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above)
15449 ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below) 15541 ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below)
15542#ifdef HAVE_XKB
15543 ATOM_REFS_INIT ("Meta", Xatom_Meta)
15544 ATOM_REFS_INIT ("Super", Xatom_Super)
15545 ATOM_REFS_INIT ("Hyper", Xatom_Hyper)
15546 ATOM_REFS_INIT ("ShiftLock", Xatom_ShiftLock)
15547 ATOM_REFS_INIT ("Alt", Xatom_Alt)
15548#endif
15450 }; 15549 };
15451 15550
15452 int i; 15551 int i;
@@ -15477,6 +15576,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
15477 dpyinfo->Xatom_xsettings_sel = atoms_return[i]; 15576 dpyinfo->Xatom_xsettings_sel = atoms_return[i];
15478 } 15577 }
15479 15578
15579#ifdef HAVE_XKB
15580 /* Figure out which modifier bits mean what. */
15581 x_find_modifier_meanings (dpyinfo);
15582#endif
15583
15480 dpyinfo->x_dnd_atoms_size = 8; 15584 dpyinfo->x_dnd_atoms_size = 8;
15481 dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms 15585 dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms
15482 * dpyinfo->x_dnd_atoms_size); 15586 * dpyinfo->x_dnd_atoms_size);
@@ -16128,6 +16232,7 @@ always uses gtk_window_move and ignores the value of this variable. */);
16128This option is only effective when Emacs is built with XInput 2 16232This option is only effective when Emacs is built with XInput 2
16129support. */); 16233support. */);
16130 Vx_scroll_event_delta_factor = make_float (1.0); 16234 Vx_scroll_event_delta_factor = make_float (1.0);
16235 DEFSYM (Qexpose, "expose");
16131 16236
16132 DEFVAR_BOOL ("x-gtk-use-native-input", x_gtk_use_native_input, 16237 DEFVAR_BOOL ("x-gtk-use-native-input", x_gtk_use_native_input,
16133 doc: /* Non-nil means to use GTK for input method support. 16238 doc: /* Non-nil means to use GTK for input method support.
@@ -16135,6 +16240,21 @@ This provides better support for some modern input methods, and is
16135only effective when Emacs is built with GTK. */); 16240only effective when Emacs is built with GTK. */);
16136 x_gtk_use_native_input = false; 16241 x_gtk_use_native_input = false;
16137 16242
16243 DEFVAR_LISP ("x-set-frame-visibility-more-laxly",
16244 x_set_frame_visibility_more_laxly,
16245 doc: /* Non-nil means set frame visibility more laxly.
16246If this is nil, Emacs is more strict when marking a frame as visible.
16247Since this may cause problems on some window managers, this variable can
16248be also set as follows: The value `focus-in' means to mark a frame as
16249visible also when a FocusIn event is received for it on GTK builds. The
16250value `expose' means to mark a frame as visible also when an Expose
16251event is received for it on any X build. The value `t' means to mark a
16252frame as visible in either of these two cases.
16253
16254Note that any non-nil setting may cause invisible frames get erroneously
16255reported as iconified. */);
16256 x_set_frame_visibility_more_laxly = Qnil;
16257
16138 DEFVAR_BOOL ("x-input-grab-touch-events", x_input_grab_touch_events, 16258 DEFVAR_BOOL ("x-input-grab-touch-events", x_input_grab_touch_events,
16139 doc: /* Non-nil means to actively grab touch events. 16259 doc: /* Non-nil means to actively grab touch events.
16140This means touch sequences that started on an Emacs frame will 16260This means touch sequences that started on an Emacs frame will
diff --git a/src/xterm.h b/src/xterm.h
index 664db48392d..26b2851590d 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -78,6 +78,9 @@ typedef GtkWidget *xt_or_gtk_widget;
78#ifdef CAIRO_HAS_SVG_SURFACE 78#ifdef CAIRO_HAS_SVG_SURFACE
79#include <cairo-svg.h> 79#include <cairo-svg.h>
80#endif 80#endif
81#ifdef USE_CAIRO_XCB
82#include <cairo-xcb.h>
83#endif
81#endif 84#endif
82 85
83#ifdef HAVE_X_I18N 86#ifdef HAVE_X_I18N
@@ -496,6 +499,11 @@ struct x_display_info
496 /* SM */ 499 /* SM */
497 Atom Xatom_SM_CLIENT_ID; 500 Atom Xatom_SM_CLIENT_ID;
498 501
502#ifdef HAVE_XKB
503 /* Virtual modifiers */
504 Atom Xatom_Meta, Xatom_Super, Xatom_Hyper, Xatom_ShiftLock, Xatom_Alt;
505#endif
506
499#ifdef HAVE_XRANDR 507#ifdef HAVE_XRANDR
500 int xrandr_major_version; 508 int xrandr_major_version;
501 int xrandr_minor_version; 509 int xrandr_minor_version;
@@ -507,6 +515,7 @@ struct x_display_info
507 515
508#ifdef USE_XCB 516#ifdef USE_XCB
509 xcb_connection_t *xcb_connection; 517 xcb_connection_t *xcb_connection;
518 xcb_visualtype_t *xcb_visual;
510#endif 519#endif
511 520
512#ifdef HAVE_XDBE 521#ifdef HAVE_XDBE
@@ -531,6 +540,12 @@ struct x_display_info
531#ifdef USE_GTK 540#ifdef USE_GTK
532 bool prefer_native_input; 541 bool prefer_native_input;
533#endif 542#endif
543
544#ifdef HAVE_XRENDER
545 bool xrender_supported_p;
546 int xrender_major;
547 int xrender_minor;
548#endif
534}; 549};
535 550
536#ifdef HAVE_X_I18N 551#ifdef HAVE_X_I18N
diff --git a/src/xwidget.c b/src/xwidget.c
index 45879b15cbe..fb66a17acd8 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
39#include <webkit2/webkit2.h> 39#include <webkit2/webkit2.h>
40#include <JavaScriptCore/JavaScript.h> 40#include <JavaScriptCore/JavaScript.h>
41#include <cairo.h> 41#include <cairo.h>
42#include <cairo-xlib.h>
42#ifndef HAVE_PGTK 43#ifndef HAVE_PGTK
43#include <X11/Xlib.h> 44#include <X11/Xlib.h>
44#else 45#else
@@ -1855,7 +1856,7 @@ webkit_js_to_lisp (JSCValue *value)
1855 const gint32 dlen = jsc_value_to_int32 (len); 1856 const gint32 dlen = jsc_value_to_int32 (len);
1856 1857
1857 Lisp_Object obj; 1858 Lisp_Object obj;
1858 if (! (0 <= dlen && dlen < PTRDIFF_MAX + 1.0)) 1859 if (! (0 <= dlen && dlen < G_MAXINT32))
1859 memory_full (SIZE_MAX); 1860 memory_full (SIZE_MAX);
1860 1861
1861 ptrdiff_t n = dlen; 1862 ptrdiff_t n = dlen;