mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-26 07:11:34 -08:00
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.
This commit is contained in:
parent
8575962d46
commit
fd016ea997
9 changed files with 181 additions and 5 deletions
|
|
@ -107,6 +107,8 @@ haiku_len (enum haiku_event_type type)
|
|||
return sizeof (struct haiku_scroll_bar_part_event);
|
||||
case SCREEN_CHANGED_EVENT:
|
||||
return sizeof (struct haiku_screen_changed_event);
|
||||
case CLIPBOARD_CHANGED_EVENT:
|
||||
return sizeof (struct haiku_clipboard_changed_event);
|
||||
}
|
||||
|
||||
emacs_abort ();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <config.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Clipboard.h>
|
||||
#include <Message.h>
|
||||
#include <Path.h>
|
||||
|
|
@ -47,6 +48,16 @@ static int64 count_primary = -1;
|
|||
/* The number of times the secondary selection has changed. */
|
||||
static int64 count_secondary = -1;
|
||||
|
||||
/* Whether or not we currently think Emacs owns the primary
|
||||
selection. */
|
||||
static bool owned_primary;
|
||||
|
||||
/* Likewise for the secondary selection. */
|
||||
static bool owned_secondary;
|
||||
|
||||
/* And the clipboard. */
|
||||
static bool owned_clipboard;
|
||||
|
||||
static BClipboard *
|
||||
get_clipboard_object (enum haiku_clipboard clipboard)
|
||||
{
|
||||
|
|
@ -150,14 +161,17 @@ be_update_clipboard_count (enum haiku_clipboard id)
|
|||
{
|
||||
case CLIPBOARD_CLIPBOARD:
|
||||
count_clipboard = system_clipboard->SystemCount ();
|
||||
owned_clipboard = true;
|
||||
break;
|
||||
|
||||
case CLIPBOARD_PRIMARY:
|
||||
count_primary = primary->SystemCount ();
|
||||
owned_primary = true;
|
||||
break;
|
||||
|
||||
case CLIPBOARD_SECONDARY:
|
||||
count_secondary = secondary->SystemCount ();
|
||||
owned_secondary = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -433,3 +447,43 @@ be_unlock_clipboard (enum haiku_clipboard clipboard, bool discard)
|
|||
|
||||
board->Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
be_handle_clipboard_changed_message (void)
|
||||
{
|
||||
if (count_clipboard != -1
|
||||
&& (system_clipboard->SystemCount ()
|
||||
> count_clipboard + 1)
|
||||
&& owned_clipboard)
|
||||
{
|
||||
owned_clipboard = false;
|
||||
haiku_selection_disowned (CLIPBOARD_CLIPBOARD);
|
||||
}
|
||||
|
||||
if (count_primary != -1
|
||||
&& (primary->SystemCount ()
|
||||
> count_primary + 1)
|
||||
&& owned_primary)
|
||||
{
|
||||
owned_primary = false;
|
||||
haiku_selection_disowned (CLIPBOARD_PRIMARY);
|
||||
}
|
||||
|
||||
if (count_secondary != -1
|
||||
&& (secondary->SystemCount ()
|
||||
> count_secondary + 1)
|
||||
&& owned_secondary)
|
||||
{
|
||||
owned_secondary = false;
|
||||
haiku_selection_disowned (CLIPBOARD_SECONDARY);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
be_start_watching_selection (enum haiku_clipboard id)
|
||||
{
|
||||
BClipboard *clipboard;
|
||||
|
||||
clipboard = get_clipboard_object (id);
|
||||
clipboard->StartWatching (be_app);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <app/Application.h>
|
||||
#include <app/Cursor.h>
|
||||
#include <app/Clipboard.h>
|
||||
#include <app/Messenger.h>
|
||||
#include <app/Roster.h>
|
||||
|
||||
|
|
@ -648,8 +649,12 @@ public:
|
|||
void
|
||||
MessageReceived (BMessage *msg)
|
||||
{
|
||||
struct haiku_clipboard_changed_event rq;
|
||||
|
||||
if (msg->what == QUIT_APPLICATION)
|
||||
Quit ();
|
||||
else if (msg->what == B_CLIPBOARD_CHANGED)
|
||||
haiku_write (CLIPBOARD_CHANGED_EVENT, &rq);
|
||||
else
|
||||
BApplication::MessageReceived (msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,8 +114,14 @@ enum haiku_event_type
|
|||
DUMMY_EVENT,
|
||||
SCREEN_CHANGED_EVENT,
|
||||
MENU_BAR_LEFT,
|
||||
CLIPBOARD_CHANGED_EVENT,
|
||||
};
|
||||
|
||||
struct haiku_clipboard_changed_event
|
||||
{
|
||||
char dummy;
|
||||
};
|
||||
|
||||
struct haiku_screen_changed_event
|
||||
{
|
||||
bigtime_t when;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "haikuselect.h"
|
||||
#include "haikuterm.h"
|
||||
#include "haiku_support.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
@ -1020,6 +1021,47 @@ init_haiku_select (void)
|
|||
be_clipboard_init ();
|
||||
}
|
||||
|
||||
void
|
||||
haiku_handle_selection_clear (struct input_event *ie)
|
||||
{
|
||||
CALLN (Frun_hook_with_args,
|
||||
Qhaiku_lost_selection_functions, ie->arg);
|
||||
}
|
||||
|
||||
void
|
||||
haiku_selection_disowned (enum haiku_clipboard id)
|
||||
{
|
||||
struct input_event ie;
|
||||
|
||||
EVENT_INIT (ie);
|
||||
ie.kind = SELECTION_CLEAR_EVENT;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case CLIPBOARD_CLIPBOARD:
|
||||
ie.arg = QCLIPBOARD;
|
||||
break;
|
||||
|
||||
case CLIPBOARD_PRIMARY:
|
||||
ie.arg = QPRIMARY;
|
||||
break;
|
||||
|
||||
case CLIPBOARD_SECONDARY:
|
||||
ie.arg = QSECONDARY;
|
||||
break;
|
||||
}
|
||||
|
||||
kbd_buffer_store_event (&ie);
|
||||
}
|
||||
|
||||
void
|
||||
haiku_start_watching_selections (void)
|
||||
{
|
||||
be_start_watching_selection (CLIPBOARD_CLIPBOARD);
|
||||
be_start_watching_selection (CLIPBOARD_PRIMARY);
|
||||
be_start_watching_selection (CLIPBOARD_SECONDARY);
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_haikuselect (void)
|
||||
{
|
||||
|
|
@ -1035,12 +1077,21 @@ The function is called without any arguments. `mouse-position' can be
|
|||
used to retrieve the current position of the mouse. */);
|
||||
Vhaiku_drag_track_function = Qnil;
|
||||
|
||||
DEFVAR_LISP ("haiku-lost-selection-functions", Vhaiku_lost_selection_functions,
|
||||
doc: /* A list of functions to be called when Emacs loses an X selection.
|
||||
These are only called if a connection to the Haiku display was opened. */);
|
||||
Vhaiku_lost_selection_functions = Qnil;
|
||||
|
||||
DEFSYM (QSECONDARY, "SECONDARY");
|
||||
DEFSYM (QCLIPBOARD, "CLIPBOARD");
|
||||
DEFSYM (QSTRING, "STRING");
|
||||
DEFSYM (QUTF8_STRING, "UTF8_STRING");
|
||||
DEFSYM (Qforeign_selection, "foreign-selection");
|
||||
DEFSYM (QTARGETS, "TARGETS");
|
||||
|
||||
DEFSYM (Qhaiku_lost_selection_functions,
|
||||
"haiku-lost-selection-functions");
|
||||
|
||||
DEFSYM (Qmessage, "message");
|
||||
DEFSYM (Qstring, "string");
|
||||
DEFSYM (Qref, "ref");
|
||||
|
|
|
|||
|
|
@ -38,7 +38,10 @@ enum haiku_clipboard
|
|||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/* Defined in haikuselect.c. */
|
||||
extern void haiku_selection_disowned (enum haiku_clipboard);
|
||||
|
||||
/* Defined in haiku_select.cc. */
|
||||
extern void be_clipboard_init (void);
|
||||
extern char *be_find_clipboard_data (enum haiku_clipboard, const char *, ssize_t *);
|
||||
extern 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);
|
|||
extern int be_add_message_message (void *, const char *, void *);
|
||||
extern int be_lock_clipboard_message (enum haiku_clipboard, void **, bool);
|
||||
extern void be_unlock_clipboard (enum haiku_clipboard, bool);
|
||||
extern void be_handle_clipboard_changed_message (void);
|
||||
extern void be_start_watching_selection (enum haiku_clipboard);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "haiku_support.h"
|
||||
#include "thread.h"
|
||||
#include "window.h"
|
||||
#include "haikuselect.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -4010,6 +4011,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
|
|||
inev.timestamp = b->when / 1000;
|
||||
break;
|
||||
}
|
||||
case CLIPBOARD_CHANGED_EVENT:
|
||||
be_handle_clipboard_changed_message ();
|
||||
break;
|
||||
case APP_QUIT_REQUESTED_EVENT:
|
||||
inev.kind = SAVE_SESSION_EVENT;
|
||||
inev.arg = Qt;
|
||||
|
|
@ -4403,6 +4407,7 @@ haiku_term_init (void)
|
|||
else
|
||||
dpyinfo->default_name = build_string ("GNU Emacs");
|
||||
|
||||
haiku_start_watching_selections ();
|
||||
unblock_input ();
|
||||
|
||||
return dpyinfo;
|
||||
|
|
|
|||
|
|
@ -357,4 +357,6 @@ extern void haiku_end_cr_clip (cairo_t *);
|
|||
|
||||
extern void haiku_merge_cursor_foreground (struct glyph_string *, unsigned long *,
|
||||
unsigned long *);
|
||||
extern void haiku_handle_selection_clear (struct input_event *);
|
||||
extern void haiku_start_watching_selections (void);
|
||||
#endif /* _HAIKU_TERM_H_ */
|
||||
|
|
|
|||
|
|
@ -4012,6 +4012,7 @@ kbd_buffer_get_event (KBOARD **kbp,
|
|||
We return nil for them. */
|
||||
switch (event->kind)
|
||||
{
|
||||
#ifndef HAVE_HAIKU
|
||||
case SELECTION_REQUEST_EVENT:
|
||||
case SELECTION_CLEAR_EVENT:
|
||||
{
|
||||
|
|
@ -4035,6 +4036,20 @@ kbd_buffer_get_event (KBOARD **kbp,
|
|||
#endif
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case SELECTION_REQUEST_EVENT:
|
||||
emacs_abort ();
|
||||
|
||||
case SELECTION_CLEAR_EVENT:
|
||||
{
|
||||
struct input_event copy = event->ie;
|
||||
|
||||
kbd_fetch_ptr = next_kbd_event (event);
|
||||
input_pending = readable_events (0);
|
||||
haiku_handle_selection_clear (©);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MONITORS_CHANGED_EVENT:
|
||||
{
|
||||
|
|
@ -4345,8 +4360,16 @@ kbd_buffer_get_event (KBOARD **kbp,
|
|||
static void
|
||||
process_special_events (void)
|
||||
{
|
||||
for (union buffered_input_event *event = kbd_fetch_ptr;
|
||||
event != kbd_store_ptr; event = next_kbd_event (event))
|
||||
union buffered_input_event *event;
|
||||
#ifndef HAVE_HAIKU
|
||||
struct selection_input_event copy;
|
||||
#else
|
||||
struct input_event copy;
|
||||
#endif
|
||||
int moved_events;
|
||||
|
||||
for (event = kbd_fetch_ptr; event != kbd_store_ptr;
|
||||
event = next_kbd_event (event))
|
||||
{
|
||||
/* If we find a stored X selection request, handle it now. */
|
||||
if (event->kind == SELECTION_REQUEST_EVENT
|
||||
|
|
@ -4360,8 +4383,7 @@ process_special_events (void)
|
|||
between kbd_fetch_ptr and EVENT one slot to the right,
|
||||
cyclically. */
|
||||
|
||||
struct selection_input_event copy = event->sie;
|
||||
int moved_events;
|
||||
copy = event->sie;
|
||||
|
||||
if (event < kbd_fetch_ptr)
|
||||
{
|
||||
|
|
@ -4383,6 +4405,27 @@ process_special_events (void)
|
|||
#else
|
||||
pgtk_handle_selection_event (©);
|
||||
#endif
|
||||
#elif defined HAVE_HAIKU
|
||||
if (event->ie.kind != SELECTION_CLEAR_EVENT)
|
||||
emacs_abort ();
|
||||
|
||||
copy = event->ie;
|
||||
|
||||
if (event < kbd_fetch_ptr)
|
||||
{
|
||||
memmove (kbd_buffer + 1, kbd_buffer,
|
||||
(event - kbd_buffer) * sizeof *kbd_buffer);
|
||||
kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
|
||||
moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
|
||||
}
|
||||
else
|
||||
moved_events = event - kbd_fetch_ptr;
|
||||
|
||||
memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
|
||||
moved_events * sizeof *kbd_fetch_ptr);
|
||||
kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr);
|
||||
input_pending = readable_events (0);
|
||||
haiku_handle_selection_clear (©);
|
||||
#else
|
||||
/* We're getting selection request events, but we don't have
|
||||
a window system. */
|
||||
|
|
@ -13149,7 +13192,10 @@ mark_kboards (void)
|
|||
{
|
||||
/* These two special event types have no Lisp_Objects to mark. */
|
||||
if (event->kind != SELECTION_REQUEST_EVENT
|
||||
&& event->kind != SELECTION_CLEAR_EVENT)
|
||||
#ifndef HAVE_HAIKU
|
||||
&& event->kind != SELECTION_CLEAR_EVENT
|
||||
#endif
|
||||
)
|
||||
{
|
||||
mark_object (event->ie.x);
|
||||
mark_object (event->ie.y);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue