aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-07-07 02:48:19 +0000
committerPo Lu2022-07-07 02:48:19 +0000
commitfd016ea99724f7abedfddbb470ab96ece6ddf4ae (patch)
treee874e42b2a69d1c22411e2a78c1fa9d2a4270284
parent8575962d46d1f1d08836bf00cb74ccd344953bcb (diff)
downloademacs-fd016ea99724f7abedfddbb470ab96ece6ddf4ae.tar.gz
emacs-fd016ea99724f7abedfddbb470ab96ece6ddf4ae.zip
Port `x-lost-selection-functions' to Haiku
* src/haiku_io.c (haiku_len): Add `CLIPBOARD_CHANGED_EVENT'. * src/haiku_select.cc (be_update_clipboard_count): Set ownership flags. (be_handle_clipboard_changed_message): (be_start_watching_selection): New functions. * src/haiku_support.cc (class Emacs): Handle B_CLIPBOARD_CHANGED. * src/haiku_support.h (enum haiku_event_type): New event `CLIPBOARD_CHANGED_EVENT'. (struct haiku_clipboard_changed_event): New struct. * src/haikuselect.c (haiku_handle_selection_clear) (haiku_selection_disowned, haiku_start_watching_selections): New functions. (syms_of_haikuselect): New defsym and defvar. * src/haikuselect.h: Update prototypes. * src/haikuterm.c (haiku_read_socket): Handle selection events. (haiku_term_init): Start watching selections. * src/haikuterm.h: Update prototypes. * src/keyboard.c (kbd_buffer_get_event, process_special_events) (mark_kboards): Handle SELECTON_CLEAR_EVENTs correctly on Haiku.
-rw-r--r--src/haiku_io.c2
-rw-r--r--src/haiku_select.cc54
-rw-r--r--src/haiku_support.cc5
-rw-r--r--src/haiku_support.h6
-rw-r--r--src/haikuselect.c51
-rw-r--r--src/haikuselect.h5
-rw-r--r--src/haikuterm.c5
-rw-r--r--src/haikuterm.h2
-rw-r--r--src/keyboard.c56
9 files changed, 181 insertions, 5 deletions
diff --git a/src/haiku_io.c b/src/haiku_io.c
index d3455276855..5cc70f6f71f 100644
--- a/src/haiku_io.c
+++ b/src/haiku_io.c
@@ -107,6 +107,8 @@ haiku_len (enum haiku_event_type type)
107 return sizeof (struct haiku_scroll_bar_part_event); 107 return sizeof (struct haiku_scroll_bar_part_event);
108 case SCREEN_CHANGED_EVENT: 108 case SCREEN_CHANGED_EVENT:
109 return sizeof (struct haiku_screen_changed_event); 109 return sizeof (struct haiku_screen_changed_event);
110 case CLIPBOARD_CHANGED_EVENT:
111 return sizeof (struct haiku_clipboard_changed_event);
110 } 112 }
111 113
112 emacs_abort (); 114 emacs_abort ();
diff --git a/src/haiku_select.cc b/src/haiku_select.cc
index 80c5d294820..edb821e3132 100644
--- a/src/haiku_select.cc
+++ b/src/haiku_select.cc
@@ -18,6 +18,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
18 18
19#include <config.h> 19#include <config.h>
20 20
21#include <Application.h>
21#include <Clipboard.h> 22#include <Clipboard.h>
22#include <Message.h> 23#include <Message.h>
23#include <Path.h> 24#include <Path.h>
@@ -47,6 +48,16 @@ static int64 count_primary = -1;
47/* The number of times the secondary selection has changed. */ 48/* The number of times the secondary selection has changed. */
48static int64 count_secondary = -1; 49static int64 count_secondary = -1;
49 50
51/* Whether or not we currently think Emacs owns the primary
52 selection. */
53static bool owned_primary;
54
55/* Likewise for the secondary selection. */
56static bool owned_secondary;
57
58/* And the clipboard. */
59static bool owned_clipboard;
60
50static BClipboard * 61static BClipboard *
51get_clipboard_object (enum haiku_clipboard clipboard) 62get_clipboard_object (enum haiku_clipboard clipboard)
52{ 63{
@@ -150,14 +161,17 @@ be_update_clipboard_count (enum haiku_clipboard id)
150 { 161 {
151 case CLIPBOARD_CLIPBOARD: 162 case CLIPBOARD_CLIPBOARD:
152 count_clipboard = system_clipboard->SystemCount (); 163 count_clipboard = system_clipboard->SystemCount ();
164 owned_clipboard = true;
153 break; 165 break;
154 166
155 case CLIPBOARD_PRIMARY: 167 case CLIPBOARD_PRIMARY:
156 count_primary = primary->SystemCount (); 168 count_primary = primary->SystemCount ();
169 owned_primary = true;
157 break; 170 break;
158 171
159 case CLIPBOARD_SECONDARY: 172 case CLIPBOARD_SECONDARY:
160 count_secondary = secondary->SystemCount (); 173 count_secondary = secondary->SystemCount ();
174 owned_secondary = true;
161 break; 175 break;
162 } 176 }
163} 177}
@@ -433,3 +447,43 @@ be_unlock_clipboard (enum haiku_clipboard clipboard, bool discard)
433 447
434 board->Unlock (); 448 board->Unlock ();
435} 449}
450
451void
452be_handle_clipboard_changed_message (void)
453{
454 if (count_clipboard != -1
455 && (system_clipboard->SystemCount ()
456 > count_clipboard + 1)
457 && owned_clipboard)
458 {
459 owned_clipboard = false;
460 haiku_selection_disowned (CLIPBOARD_CLIPBOARD);
461 }
462
463 if (count_primary != -1
464 && (primary->SystemCount ()
465 > count_primary + 1)
466 && owned_primary)
467 {
468 owned_primary = false;
469 haiku_selection_disowned (CLIPBOARD_PRIMARY);
470 }
471
472 if (count_secondary != -1
473 && (secondary->SystemCount ()
474 > count_secondary + 1)
475 && owned_secondary)
476 {
477 owned_secondary = false;
478 haiku_selection_disowned (CLIPBOARD_SECONDARY);
479 }
480}
481
482void
483be_start_watching_selection (enum haiku_clipboard id)
484{
485 BClipboard *clipboard;
486
487 clipboard = get_clipboard_object (id);
488 clipboard->StartWatching (be_app);
489}
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 7819cef5683..9e38d9556fb 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
21 21
22#include <app/Application.h> 22#include <app/Application.h>
23#include <app/Cursor.h> 23#include <app/Cursor.h>
24#include <app/Clipboard.h>
24#include <app/Messenger.h> 25#include <app/Messenger.h>
25#include <app/Roster.h> 26#include <app/Roster.h>
26 27
@@ -648,8 +649,12 @@ public:
648 void 649 void
649 MessageReceived (BMessage *msg) 650 MessageReceived (BMessage *msg)
650 { 651 {
652 struct haiku_clipboard_changed_event rq;
653
651 if (msg->what == QUIT_APPLICATION) 654 if (msg->what == QUIT_APPLICATION)
652 Quit (); 655 Quit ();
656 else if (msg->what == B_CLIPBOARD_CHANGED)
657 haiku_write (CLIPBOARD_CHANGED_EVENT, &rq);
653 else 658 else
654 BApplication::MessageReceived (msg); 659 BApplication::MessageReceived (msg);
655 } 660 }
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 6260b35cbc1..d73f15560be 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -114,8 +114,14 @@ enum haiku_event_type
114 DUMMY_EVENT, 114 DUMMY_EVENT,
115 SCREEN_CHANGED_EVENT, 115 SCREEN_CHANGED_EVENT,
116 MENU_BAR_LEFT, 116 MENU_BAR_LEFT,
117 CLIPBOARD_CHANGED_EVENT,
117 }; 118 };
118 119
120struct haiku_clipboard_changed_event
121{
122 char dummy;
123};
124
119struct haiku_screen_changed_event 125struct haiku_screen_changed_event
120{ 126{
121 bigtime_t when; 127 bigtime_t when;
diff --git a/src/haikuselect.c b/src/haikuselect.c
index fe76e09810c..999a0f5ac29 100644
--- a/src/haikuselect.c
+++ b/src/haikuselect.c
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
24#include "haikuselect.h" 24#include "haikuselect.h"
25#include "haikuterm.h" 25#include "haikuterm.h"
26#include "haiku_support.h" 26#include "haiku_support.h"
27#include "keyboard.h"
27 28
28#include <stdlib.h> 29#include <stdlib.h>
29 30
@@ -1021,6 +1022,47 @@ init_haiku_select (void)
1021} 1022}
1022 1023
1023void 1024void
1025haiku_handle_selection_clear (struct input_event *ie)
1026{
1027 CALLN (Frun_hook_with_args,
1028 Qhaiku_lost_selection_functions, ie->arg);
1029}
1030
1031void
1032haiku_selection_disowned (enum haiku_clipboard id)
1033{
1034 struct input_event ie;
1035
1036 EVENT_INIT (ie);
1037 ie.kind = SELECTION_CLEAR_EVENT;
1038
1039 switch (id)
1040 {
1041 case CLIPBOARD_CLIPBOARD:
1042 ie.arg = QCLIPBOARD;
1043 break;
1044
1045 case CLIPBOARD_PRIMARY:
1046 ie.arg = QPRIMARY;
1047 break;
1048
1049 case CLIPBOARD_SECONDARY:
1050 ie.arg = QSECONDARY;
1051 break;
1052 }
1053
1054 kbd_buffer_store_event (&ie);
1055}
1056
1057void
1058haiku_start_watching_selections (void)
1059{
1060 be_start_watching_selection (CLIPBOARD_CLIPBOARD);
1061 be_start_watching_selection (CLIPBOARD_PRIMARY);
1062 be_start_watching_selection (CLIPBOARD_SECONDARY);
1063}
1064
1065void
1024syms_of_haikuselect (void) 1066syms_of_haikuselect (void)
1025{ 1067{
1026 DEFVAR_BOOL ("haiku-signal-invalid-refs", haiku_signal_invalid_refs, 1068 DEFVAR_BOOL ("haiku-signal-invalid-refs", haiku_signal_invalid_refs,
@@ -1035,12 +1077,21 @@ The function is called without any arguments. `mouse-position' can be
1035used to retrieve the current position of the mouse. */); 1077used to retrieve the current position of the mouse. */);
1036 Vhaiku_drag_track_function = Qnil; 1078 Vhaiku_drag_track_function = Qnil;
1037 1079
1080 DEFVAR_LISP ("haiku-lost-selection-functions", Vhaiku_lost_selection_functions,
1081 doc: /* A list of functions to be called when Emacs loses an X selection.
1082These are only called if a connection to the Haiku display was opened. */);
1083 Vhaiku_lost_selection_functions = Qnil;
1084
1038 DEFSYM (QSECONDARY, "SECONDARY"); 1085 DEFSYM (QSECONDARY, "SECONDARY");
1039 DEFSYM (QCLIPBOARD, "CLIPBOARD"); 1086 DEFSYM (QCLIPBOARD, "CLIPBOARD");
1040 DEFSYM (QSTRING, "STRING"); 1087 DEFSYM (QSTRING, "STRING");
1041 DEFSYM (QUTF8_STRING, "UTF8_STRING"); 1088 DEFSYM (QUTF8_STRING, "UTF8_STRING");
1042 DEFSYM (Qforeign_selection, "foreign-selection"); 1089 DEFSYM (Qforeign_selection, "foreign-selection");
1043 DEFSYM (QTARGETS, "TARGETS"); 1090 DEFSYM (QTARGETS, "TARGETS");
1091
1092 DEFSYM (Qhaiku_lost_selection_functions,
1093 "haiku-lost-selection-functions");
1094
1044 DEFSYM (Qmessage, "message"); 1095 DEFSYM (Qmessage, "message");
1045 DEFSYM (Qstring, "string"); 1096 DEFSYM (Qstring, "string");
1046 DEFSYM (Qref, "ref"); 1097 DEFSYM (Qref, "ref");
diff --git a/src/haikuselect.h b/src/haikuselect.h
index ac8e0698952..d027834e8b6 100644
--- a/src/haikuselect.h
+++ b/src/haikuselect.h
@@ -38,7 +38,10 @@ enum haiku_clipboard
38extern "C" 38extern "C"
39{ 39{
40#endif 40#endif
41/* Defined in haikuselect.c. */
42extern void haiku_selection_disowned (enum haiku_clipboard);
41 43
44/* Defined in haiku_select.cc. */
42extern void be_clipboard_init (void); 45extern void be_clipboard_init (void);
43extern char *be_find_clipboard_data (enum haiku_clipboard, const char *, ssize_t *); 46extern char *be_find_clipboard_data (enum haiku_clipboard, const char *, ssize_t *);
44extern void be_set_clipboard_data (enum haiku_clipboard, const char *, const char *, 47extern void be_set_clipboard_data (enum haiku_clipboard, const char *, const char *,
@@ -61,6 +64,8 @@ extern int be_add_point_data (void *, const char *, float, float);
61extern int be_add_message_message (void *, const char *, void *); 64extern int be_add_message_message (void *, const char *, void *);
62extern int be_lock_clipboard_message (enum haiku_clipboard, void **, bool); 65extern int be_lock_clipboard_message (enum haiku_clipboard, void **, bool);
63extern void be_unlock_clipboard (enum haiku_clipboard, bool); 66extern void be_unlock_clipboard (enum haiku_clipboard, bool);
67extern void be_handle_clipboard_changed_message (void);
68extern void be_start_watching_selection (enum haiku_clipboard);
64 69
65#ifdef __cplusplus 70#ifdef __cplusplus
66}; 71};
diff --git a/src/haikuterm.c b/src/haikuterm.c
index d7247c99e08..bcb3af0e2c3 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
32#include "haiku_support.h" 32#include "haiku_support.h"
33#include "thread.h" 33#include "thread.h"
34#include "window.h" 34#include "window.h"
35#include "haikuselect.h"
35 36
36#include <math.h> 37#include <math.h>
37#include <stdlib.h> 38#include <stdlib.h>
@@ -4010,6 +4011,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
4010 inev.timestamp = b->when / 1000; 4011 inev.timestamp = b->when / 1000;
4011 break; 4012 break;
4012 } 4013 }
4014 case CLIPBOARD_CHANGED_EVENT:
4015 be_handle_clipboard_changed_message ();
4016 break;
4013 case APP_QUIT_REQUESTED_EVENT: 4017 case APP_QUIT_REQUESTED_EVENT:
4014 inev.kind = SAVE_SESSION_EVENT; 4018 inev.kind = SAVE_SESSION_EVENT;
4015 inev.arg = Qt; 4019 inev.arg = Qt;
@@ -4403,6 +4407,7 @@ haiku_term_init (void)
4403 else 4407 else
4404 dpyinfo->default_name = build_string ("GNU Emacs"); 4408 dpyinfo->default_name = build_string ("GNU Emacs");
4405 4409
4410 haiku_start_watching_selections ();
4406 unblock_input (); 4411 unblock_input ();
4407 4412
4408 return dpyinfo; 4413 return dpyinfo;
diff --git a/src/haikuterm.h b/src/haikuterm.h
index ea20289b5d1..46a2218e492 100644
--- a/src/haikuterm.h
+++ b/src/haikuterm.h
@@ -357,4 +357,6 @@ extern void haiku_end_cr_clip (cairo_t *);
357 357
358extern void haiku_merge_cursor_foreground (struct glyph_string *, unsigned long *, 358extern void haiku_merge_cursor_foreground (struct glyph_string *, unsigned long *,
359 unsigned long *); 359 unsigned long *);
360extern void haiku_handle_selection_clear (struct input_event *);
361extern void haiku_start_watching_selections (void);
360#endif /* _HAIKU_TERM_H_ */ 362#endif /* _HAIKU_TERM_H_ */
diff --git a/src/keyboard.c b/src/keyboard.c
index bed8307b6f2..76dc3732b54 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4012,6 +4012,7 @@ kbd_buffer_get_event (KBOARD **kbp,
4012 We return nil for them. */ 4012 We return nil for them. */
4013 switch (event->kind) 4013 switch (event->kind)
4014 { 4014 {
4015#ifndef HAVE_HAIKU
4015 case SELECTION_REQUEST_EVENT: 4016 case SELECTION_REQUEST_EVENT:
4016 case SELECTION_CLEAR_EVENT: 4017 case SELECTION_CLEAR_EVENT:
4017 { 4018 {
@@ -4035,6 +4036,20 @@ kbd_buffer_get_event (KBOARD **kbp,
4035#endif 4036#endif
4036 } 4037 }
4037 break; 4038 break;
4039#else
4040 case SELECTION_REQUEST_EVENT:
4041 emacs_abort ();
4042
4043 case SELECTION_CLEAR_EVENT:
4044 {
4045 struct input_event copy = event->ie;
4046
4047 kbd_fetch_ptr = next_kbd_event (event);
4048 input_pending = readable_events (0);
4049 haiku_handle_selection_clear (&copy);
4050 }
4051 break;
4052#endif
4038 4053
4039 case MONITORS_CHANGED_EVENT: 4054 case MONITORS_CHANGED_EVENT:
4040 { 4055 {
@@ -4345,8 +4360,16 @@ kbd_buffer_get_event (KBOARD **kbp,
4345static void 4360static void
4346process_special_events (void) 4361process_special_events (void)
4347{ 4362{
4348 for (union buffered_input_event *event = kbd_fetch_ptr; 4363 union buffered_input_event *event;
4349 event != kbd_store_ptr; event = next_kbd_event (event)) 4364#ifndef HAVE_HAIKU
4365 struct selection_input_event copy;
4366#else
4367 struct input_event copy;
4368#endif
4369 int moved_events;
4370
4371 for (event = kbd_fetch_ptr; event != kbd_store_ptr;
4372 event = next_kbd_event (event))
4350 { 4373 {
4351 /* If we find a stored X selection request, handle it now. */ 4374 /* If we find a stored X selection request, handle it now. */
4352 if (event->kind == SELECTION_REQUEST_EVENT 4375 if (event->kind == SELECTION_REQUEST_EVENT
@@ -4360,8 +4383,7 @@ process_special_events (void)
4360 between kbd_fetch_ptr and EVENT one slot to the right, 4383 between kbd_fetch_ptr and EVENT one slot to the right,
4361 cyclically. */ 4384 cyclically. */
4362 4385
4363 struct selection_input_event copy = event->sie; 4386 copy = event->sie;
4364 int moved_events;
4365 4387
4366 if (event < kbd_fetch_ptr) 4388 if (event < kbd_fetch_ptr)
4367 { 4389 {
@@ -4383,6 +4405,27 @@ process_special_events (void)
4383#else 4405#else
4384 pgtk_handle_selection_event (&copy); 4406 pgtk_handle_selection_event (&copy);
4385#endif 4407#endif
4408#elif defined HAVE_HAIKU
4409 if (event->ie.kind != SELECTION_CLEAR_EVENT)
4410 emacs_abort ();
4411
4412 copy = event->ie;
4413
4414 if (event < kbd_fetch_ptr)
4415 {
4416 memmove (kbd_buffer + 1, kbd_buffer,
4417 (event - kbd_buffer) * sizeof *kbd_buffer);
4418 kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
4419 moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
4420 }
4421 else
4422 moved_events = event - kbd_fetch_ptr;
4423
4424 memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
4425 moved_events * sizeof *kbd_fetch_ptr);
4426 kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr);
4427 input_pending = readable_events (0);
4428 haiku_handle_selection_clear (&copy);
4386#else 4429#else
4387 /* We're getting selection request events, but we don't have 4430 /* We're getting selection request events, but we don't have
4388 a window system. */ 4431 a window system. */
@@ -13149,7 +13192,10 @@ mark_kboards (void)
13149 { 13192 {
13150 /* These two special event types have no Lisp_Objects to mark. */ 13193 /* These two special event types have no Lisp_Objects to mark. */
13151 if (event->kind != SELECTION_REQUEST_EVENT 13194 if (event->kind != SELECTION_REQUEST_EVENT
13152 && event->kind != SELECTION_CLEAR_EVENT) 13195#ifndef HAVE_HAIKU
13196 && event->kind != SELECTION_CLEAR_EVENT
13197#endif
13198 )
13153 { 13199 {
13154 mark_object (event->ie.x); 13200 mark_object (event->ie.x);
13155 mark_object (event->ie.y); 13201 mark_object (event->ie.y);