From 0bea75c95a7e59c50be437956916cc0835655575 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 27 Apr 2022 05:18:50 +0000 Subject: [PATCH] Add simple session management support to Haiku * lisp/term/common-win.el (emacs-save-session-functions): Move from x-win.el to common-win.el. * lisp/term/haiku-win.el (haiku-save-session-reply) (emacs-session-save, handle-save-session): New functions. * lisp/term/x-win.el (emacs-save-session-functions): Delete. * src/haiku_font_support.cc (font_style_to_flags): * src/haiku_support.h (enum haiku_font_weight): Turn weight macros into enum. (struct haiku_font_pattern): Likewise. (struct haiku_session_manager_reply): New struct. * src/haiku_io.c (haiku_io_init): Create sm port. * src/haiku_support.cc (QuitRequested): Wait for reply from sm port. * src/haikufns.c (Fhaiku_save_session_reply): New function. (syms_of_haikufns): Define new subr. * src/haikuterm.c (haiku_read_socket): Send session management events. (haiku_term_init): Check new port. --- lisp/term/common-win.el | 10 ++++++++++ lisp/term/haiku-win.el | 22 ++++++++++++++++++++ lisp/term/x-win.el | 8 -------- src/haiku_font_support.cc | 9 +++++---- src/haiku_io.c | 5 +++++ src/haiku_support.cc | 12 ++++++++++- src/haiku_support.h | 42 ++++++++++++++++++++++++--------------- src/haikufns.c | 27 ++++++++++++++++++++++++- src/haikuterm.c | 10 ++++++---- 9 files changed, 111 insertions(+), 34 deletions(-) diff --git a/lisp/term/common-win.el b/lisp/term/common-win.el index 7a48fc04c6c..b219014a73c 100644 --- a/lisp/term/common-win.el +++ b/lisp/term/common-win.el @@ -419,6 +419,16 @@ the operating system.") (setq defined-colors (cons this-color defined-colors)))) defined-colors))) +;;;; Session management. + +(defvar emacs-save-session-functions nil + "Special hook run when a save-session event occurs. +The functions do not get any argument. +Functions can return non-nil to inform the session manager that the +window system shutdown should be aborted. + +See also `emacs-session-save'.") + (provide 'term/common-win) ;;; common-win.el ends here diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index c83e0a5c3da..51a6c3c501e 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el @@ -358,6 +358,28 @@ take effect on menu items until the menu bar is updated again." (add-variable-watcher 'use-system-tooltips #'haiku-use-system-tooltips-watcher) + +;;;; Session management. + +(declare-function haiku-save-session-reply "haikufns.c") + +(defun emacs-session-save () + "SKIP: real doc in x-win.el." + (with-temp-buffer ; Saving sessions is not yet supported. + (condition-case nil + ;; A return of t means cancel the shutdown. + (run-hook-with-args-until-success + 'emacs-save-session-functions) + (error t)))) + +(defun handle-save-session (_event) + "SKIP: real doc in xsmfns.c." + (interactive "e") + (let ((cancel-shutdown t)) + (unwind-protect + (setq cancel-shutdown (emacs-session-save)) + (haiku-save-session-reply (not cancel-shutdown))))) + (provide 'haiku-win) (provide 'term/haiku-win) diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index 4c6fcc904c0..ca38a0a8c92 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -109,14 +109,6 @@ (setq x-session-previous-id (car x-invocation-args) x-invocation-args (cdr x-invocation-args))) -(defvar emacs-save-session-functions nil - "Special hook run when a save-session event occurs. -The functions do not get any argument. -Functions can return non-nil to inform the session manager that the -window system shutdown should be aborted. - -See also `emacs-session-save'.") - (defun emacs-session-filename (session-id) "Construct a filename to save the session in based on SESSION-ID. Return a filename in `user-emacs-directory', unless the session file diff --git a/src/haiku_font_support.cc b/src/haiku_font_support.cc index 8da2437d660..9acdd652e34 100644 --- a/src/haiku_font_support.cc +++ b/src/haiku_font_support.cc @@ -292,10 +292,11 @@ font_style_to_flags (char *st, struct haiku_font_pattern *pattern) { char *style = strdup (st); char *token; - pattern->weight = -1; + int tok = 0; + + pattern->weight = NO_WEIGHT; pattern->width = NO_WIDTH; pattern->slant = NO_SLANT; - int tok = 0; while ((token = std::strtok (!tok ? style : NULL, " ")) && tok < 3) { @@ -317,7 +318,7 @@ font_style_to_flags (char *st, struct haiku_font_pattern *pattern) if (pattern->width == NO_WIDTH) pattern->width = NORMAL_WIDTH; - if (pattern->weight == -1) + if (pattern->weight == NO_WEIGHT) pattern->weight = HAIKU_REGULAR; } else if (token && (!strcmp (token, "SemiBold") @@ -370,7 +371,7 @@ font_style_to_flags (char *st, struct haiku_font_pattern *pattern) tok++; } - if (pattern->weight != -1) + if (pattern->weight != NO_WEIGHT) pattern->specified |= FSPEC_WEIGHT; if (pattern->slant != NO_SLANT) pattern->specified |= FSPEC_SLANT; diff --git a/src/haiku_io.c b/src/haiku_io.c index 1830ac01e55..0db5d26314b 100644 --- a/src/haiku_io.c +++ b/src/haiku_io.c @@ -40,10 +40,15 @@ port_id port_application_to_emacs; thread to Emacs. */ port_id port_popup_menu_to_emacs; +/* The port used to send replies to the application after a session + management event. */ +port_id port_emacs_to_session_manager; + void haiku_io_init (void) { port_application_to_emacs = create_port (PORT_CAP, "application emacs port"); + port_emacs_to_session_manager = create_port (1, "session manager port"); } static ssize_t diff --git a/src/haiku_support.cc b/src/haiku_support.cc index f19631a22ab..b2edcd30998 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -453,8 +453,18 @@ public: QuitRequested (void) { struct haiku_app_quit_requested_event rq; + struct haiku_session_manager_reply reply; + int32 reply_type; + haiku_write (APP_QUIT_REQUESTED_EVENT, &rq); - return 0; + + if (read_port (port_emacs_to_session_manager, + &reply_type, &reply, sizeof reply) < B_OK) + /* Return true so the system kills us, since there's no real + alternative if this read fails. */ + return true; + + return reply.quit_reply; } void diff --git a/src/haiku_support.h b/src/haiku_support.h index 6660b011a69..d442635476d 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -286,6 +286,26 @@ enum haiku_font_language MAX_LANGUAGE /* This isn't a language. */ }; +enum haiku_font_weight + { + NO_WEIGHT = -1, + HAIKU_THIN = 0, + HAIKU_ULTRALIGHT = 20, + HAIKU_EXTRALIGHT = 40, + HAIKU_LIGHT = 50, + HAIKU_SEMI_LIGHT = 75, + HAIKU_REGULAR = 100, + HAIKU_SEMI_BOLD = 180, + HAIKU_BOLD = 200, + HAIKU_EXTRA_BOLD = 205, + HAIKU_ULTRA_BOLD = 210, + HAIKU_BOOK = 400, + HAIKU_HEAVY = 800, + HAIKU_ULTRA_HEAVY = 900, + HAIKU_BLACK = 1000, + HAIKU_MEDIUM = 2000, + }; + struct haiku_font_pattern { int specified; @@ -297,13 +317,13 @@ struct haiku_font_pattern struct haiku_font_pattern *next_family; haiku_font_family_or_style family; haiku_font_family_or_style style; - int weight; int mono_spacing_p; int want_chars_len; int need_one_of_len; enum haiku_font_slant slant; enum haiku_font_width width; enum haiku_font_language language; + enum haiku_font_weight weight; int *wanted_chars; int *need_one_of; @@ -349,21 +369,10 @@ struct haiku_menu_bar_state_event void *window; }; -#define HAIKU_THIN 0 -#define HAIKU_ULTRALIGHT 20 -#define HAIKU_EXTRALIGHT 40 -#define HAIKU_LIGHT 50 -#define HAIKU_SEMI_LIGHT 75 -#define HAIKU_REGULAR 100 -#define HAIKU_SEMI_BOLD 180 -#define HAIKU_BOLD 200 -#define HAIKU_EXTRA_BOLD 205 -#define HAIKU_ULTRA_BOLD 210 -#define HAIKU_BOOK 400 -#define HAIKU_HEAVY 800 -#define HAIKU_ULTRA_HEAVY 900 -#define HAIKU_BLACK 1000 -#define HAIKU_MEDIUM 2000 +struct haiku_session_manager_reply +{ + bool quit_reply; +}; #ifdef __cplusplus /* Haiku's built in Height and Width functions for calculating @@ -420,6 +429,7 @@ extern unsigned long haiku_get_pixel (haiku, int, int); extern port_id port_application_to_emacs; extern port_id port_popup_menu_to_emacs; +extern port_id port_emacs_to_session_manager; extern void haiku_io_init (void); extern void haiku_io_init_in_app_thread (void); diff --git a/src/haikufns.c b/src/haikufns.c index ae0f442a21c..7ec6f576cfe 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -66,6 +66,8 @@ static Lisp_Object tip_last_parms; static void haiku_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); static void haiku_set_title (struct frame *, Lisp_Object, Lisp_Object); + +/* The number of references to an image cache. */ static ptrdiff_t image_cache_refcount; static Lisp_Object @@ -2604,7 +2606,7 @@ means that if both frames are visible and the display areas of these frames overlap, FRAME1 (partially) obscures FRAME2. Some window managers may refuse to restack windows. */) - (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above) + (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above) { struct frame *f1 = decode_window_system_frame (frame1); struct frame *f2 = decode_window_system_frame (frame2); @@ -2653,6 +2655,28 @@ Some window managers may refuse to restack windows. */) return Qnil; } +DEFUN ("haiku-save-session-reply", Fhaiku_save_session_reply, + Shaiku_save_session_reply, 1, 1, 0, + doc: /* Reply to a `save-session' event. +QUIT-REPLY means whether or not all files were saved and program +termination should proceed. + +Calls to this function must be balanced by the amount of +`save-session' events received. This is done automatically, so do not +call this function yourself. */) + (Lisp_Object quit_reply) +{ + struct haiku_session_manager_reply reply; + reply.quit_reply = !NILP (quit_reply); + + block_input (); + write_port (port_emacs_to_session_manager, 0, &reply, + sizeof reply); + unblock_input (); + + return Qnil; +} + frame_parm_handler haiku_frame_parm_handlers[] = { gui_set_autoraise, @@ -2750,6 +2774,7 @@ syms_of_haikufns (void) defsubr (&Shaiku_frame_list_z_order); defsubr (&Sx_display_save_under); defsubr (&Shaiku_frame_restack); + defsubr (&Shaiku_save_session_reply); tip_timer = Qnil; staticpro (&tip_timer); diff --git a/src/haikuterm.c b/src/haikuterm.c index 86266424c41..5d5e48c3915 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -3662,6 +3662,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) break; } case APP_QUIT_REQUESTED_EVENT: + inev.kind = SAVE_SESSION_EVENT; + inev.arg = Qt; + break; case KEY_UP: case DUMMY_EVENT: default: @@ -3962,15 +3965,14 @@ haiku_term_init (void) void *name_buffer; block_input (); - Fset_input_interrupt_mode (Qt); + Fset_input_interrupt_mode (Qt); baud_rate = 19200; - dpyinfo = xzalloc (sizeof *dpyinfo); - haiku_io_init (); - if (port_application_to_emacs < B_OK) + if (port_application_to_emacs < B_OK + || port_emacs_to_session_manager < B_OK) emacs_abort (); color_file = Fexpand_file_name (build_string ("rgb.txt"), -- 2.39.2