diff options
author | Po Lu <luangruo@yahoo.com> | 2022-05-04 03:23:11 +0000 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2022-05-04 03:23:11 +0000 |
commit | b5cf6c1ab6cc5ca3d7a4b5d1e2b775d7d59a5866 (patch) | |
tree | c0728c027deb2b081d5df57c2a1fe54cfb3cfb4b | |
parent | 7dfb068c13205df9e58d289c3fb4ddafd8625600 (diff) | |
download | emacs-b5cf6c1ab6cc5ca3d7a4b5d1e2b775d7d59a5866.tar.gz |
Clean up Haiku file panel code
* lisp/term/haiku-win.el (x-file-dialog): Fix nil values of
`default-filename'.
* src/haiku_io.c (haiku_len): Remove `FILE_PANEL_EVENT'.
(record_c_unwind_protect_from_cxx, c_specpdl_idx_from_cxx)
(c_unbind_to_nil_from_cxx): Delete functions.
* src/haiku_support.cc (MessageReceived): Write pointer to
buffer to file panel port instead.
(struct popup_file_dialog_data): Delete strict.
(unwind_popup_file_dialog): Delete functions.
(be_popup_file_dialog): Accept a pointer to
`process_pending_signals' and run nested event loop as usual.
* src/haiku_support.h (enum haiku_event_type): Remove
`FILE_PANEL_EVENT'.
(struct haiku_file_panel_event): Delete struct.
* src/haikufns.c (unwind_popup): Delete function.
(Fhaiku_read_file_name): Update and quit on invalid filename.
* src/haikuterm.c (struct unhandled_event): Delete struct.
(haiku_read_socket): Remove "unhandled events".
-rw-r--r-- | lisp/term/haiku-win.el | 3 | ||||
-rw-r--r-- | src/haiku_io.c | 23 | ||||
-rw-r--r-- | src/haiku_support.cc | 176 | ||||
-rw-r--r-- | src/haiku_support.h | 13 | ||||
-rw-r--r-- | src/haikufns.c | 64 | ||||
-rw-r--r-- | src/haikuterm.c | 30 |
6 files changed, 116 insertions, 193 deletions
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index 09210792468..5f020877325 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el @@ -273,7 +273,8 @@ or a pair of markers) and turns it into a file system reference." (or dir (and default-filename (file-name-directory default-filename))) mustmatch only-dir-p - (file-name-nondirectory default-filename)) + (and default-filename + (file-name-nondirectory default-filename))) (error "x-file-dialog on a tty frame"))) (defun haiku-drag-and-drop (event) diff --git a/src/haiku_io.c b/src/haiku_io.c index 0db5d26314b..5d0031ef712 100644 --- a/src/haiku_io.c +++ b/src/haiku_io.c @@ -91,8 +91,6 @@ haiku_len (enum haiku_event_type type) return sizeof (struct haiku_menu_bar_state_event); case MENU_BAR_SELECT_EVENT: return sizeof (struct haiku_menu_bar_select_event); - case FILE_PANEL_EVENT: - return sizeof (struct haiku_file_panel_event); case MENU_BAR_HELP_EVENT: return sizeof (struct haiku_menu_bar_help_event); case ZOOM_EVENT: @@ -209,24 +207,3 @@ haiku_io_init_in_app_thread (void) if (pthread_sigmask (SIG_BLOCK, &set, NULL)) perror ("pthread_sigmask"); } - -/* Record an unwind protect from C++ code. */ -void -record_c_unwind_protect_from_cxx (void (*fn) (void *), void *r) -{ - record_unwind_protect_ptr (fn, r); -} - -/* SPECPDL_IDX that is safe from C++ code. */ -specpdl_ref -c_specpdl_idx_from_cxx (void) -{ - return SPECPDL_INDEX (); -} - -/* unbind_to (IDX, Qnil), but safe from C++ code. */ -void -c_unbind_to_nil_from_cxx (specpdl_ref idx) -{ - unbind_to (idx, Qnil); -} diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 80c3ba3331d..1280a77b22a 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -100,6 +100,7 @@ enum REPLAY_MENU_BAR = 3007, FONT_FAMILY_SELECTED = 3008, FONT_STYLE_SELECTED = 3009, + FILE_PANEL_SELECTION = 3010, }; /* X11 keysyms that we use. */ @@ -188,6 +189,10 @@ static void *grab_view = NULL; static BLocker grab_view_locker; static bool drag_and_drop_in_progress; +/* Port used to send data to the main thread while a file panel is + active. */ +static port_id volatile current_file_panel_port; + /* Many places require us to lock the child frame data, and then lock the locker of some random window. Unfortunately, locking such a window might be delayed due to an arriving message, which then @@ -875,46 +880,48 @@ public: haiku_write (MENU_BAR_SELECT_EVENT, &rq); } - else if (msg->what == 'FPSE' + else if (msg->what == FILE_PANEL_SELECTION || ((msg->FindInt32 ("old_what", &old_what) == B_OK - && old_what == 'FPSE'))) + && old_what == FILE_PANEL_SELECTION))) { - struct haiku_file_panel_event rq; + const char *str_path, *name; + char *file_name, *str_buf; BEntry entry; BPath path; entry_ref ref; - rq.ptr = NULL; + file_name = NULL; if (msg->FindRef ("refs", &ref) == B_OK && entry.SetTo (&ref, 0) == B_OK && entry.GetPath (&path) == B_OK) { - const char *str_path = path.Path (); + str_path = path.Path (); + if (str_path) - rq.ptr = strdup (str_path); + file_name = strdup (str_path); } if (msg->FindRef ("directory", &ref), entry.SetTo (&ref, 0) == B_OK && entry.GetPath (&path) == B_OK) { - const char *name = msg->GetString ("name"); - const char *str_path = path.Path (); + name = msg->GetString ("name"); + str_path = path.Path (); if (name) { - char str_buf[std::strlen (str_path) - + std::strlen (name) + 2]; - snprintf ((char *) &str_buf, - std::strlen (str_path) + str_buf = (char *) alloca (std::strlen (str_path) + + std::strlen (name) + 2); + snprintf (str_buf, std::strlen (str_path) + std::strlen (name) + 2, "%s/%s", str_path, name); - rq.ptr = strdup (str_buf); + file_name = strdup (str_buf); } } - haiku_write (FILE_PANEL_EVENT, &rq); + write_port (current_file_panel_port, 0, + &file_name, sizeof file_name); } else BWindow::MessageReceived (msg); @@ -1117,12 +1124,13 @@ public: void Minimize (bool minimized_p) { - BWindow::Minimize (minimized_p); struct haiku_iconification_event rq; + rq.window = this; rq.iconified_p = !parent && minimized_p; - haiku_write (ICONIFICATION, &rq); + + BWindow::Minimize (minimized_p); } void @@ -4121,100 +4129,92 @@ EmacsView_double_buffered_p (void *vw) return db_p; } -struct popup_file_dialog_data -{ - BMessage *msg; - BFilePanel *panel; - BEntry *entry; -}; - -static void -unwind_popup_file_dialog (void *ptr) -{ - struct popup_file_dialog_data *data - = (struct popup_file_dialog_data *) ptr; - BFilePanel *panel = data->panel; - - delete panel; - delete data->entry; - delete data->msg; -} - /* Popup a file dialog. */ char * be_popup_file_dialog (int open_p, const char *default_dir, int must_match_p, int dir_only_p, void *window, const char *save_text, - const char *prompt, void (*block_input_function) (void), - void (*unblock_input_function) (void), - void (*maybe_quit_function) (void)) -{ - specpdl_ref idx = c_specpdl_idx_from_cxx (); - /* setjmp/longjmp is UB with automatic objects. */ - BWindow *w = (BWindow *) window; - uint32_t mode = (dir_only_p - ? B_DIRECTORY_NODE - : B_FILE_NODE | B_DIRECTORY_NODE); - BEntry *path = new BEntry; - BMessage *msg = new BMessage ('FPSE'); - BFilePanel *panel = new BFilePanel (open_p ? B_OPEN_PANEL : B_SAVE_PANEL, - NULL, NULL, mode); - void *buf; - enum haiku_event_type type; - char *ptr; - struct popup_file_dialog_data dat; - ssize_t b_s; - - dat.entry = path; - dat.msg = msg; - dat.panel = panel; - - record_c_unwind_protect_from_cxx (unwind_popup_file_dialog, &dat); + const char *prompt, + void (*process_pending_signals_function) (void)) +{ + BWindow *w, *panel_window; + BEntry path; + BMessage msg (FILE_PANEL_SELECTION); + BFilePanel panel (open_p ? B_OPEN_PANEL : B_SAVE_PANEL, + NULL, NULL, (dir_only_p + ? B_DIRECTORY_NODE + : B_FILE_NODE | B_DIRECTORY_NODE)); + object_wait_info infos[2]; + ssize_t status; + int32 reply_type; + char *file_name; + + current_file_panel_port = create_port (1, "file panel port"); + file_name = NULL; + + if (current_file_panel_port < B_OK) + return NULL; if (default_dir) { - if (path->SetTo (default_dir, 0) != B_OK) + if (path.SetTo (default_dir, 0) != B_OK) default_dir = NULL; } - panel->SetMessage (msg); + w = (BWindow *) window; + panel_window = panel.Window (); + + panel.SetMessage (&msg); if (default_dir) - panel->SetPanelDirectory (path); + panel.SetPanelDirectory (&path); + if (save_text) - panel->SetSaveText (save_text); + panel.SetSaveText (save_text); - panel->SetHideWhenDone (0); - panel->Window ()->SetTitle (prompt); - panel->SetTarget (BMessenger (w)); - panel->Show (); + panel_window->SetTitle (prompt); + panel_window->SetFeel (B_MODAL_APP_WINDOW_FEEL); - buf = alloca (200); - while (1) + panel.SetHideWhenDone (false); + panel.SetTarget (BMessenger (w)); + panel.Show (); + + infos[0].object = port_application_to_emacs; + infos[0].type = B_OBJECT_TYPE_PORT; + infos[0].events = B_EVENT_READ; + + infos[1].object = current_file_panel_port; + infos[1].type = B_OBJECT_TYPE_PORT; + infos[1].events = B_EVENT_READ; + + while (true) { - ptr = NULL; + status = wait_for_objects (infos, 2); - if (!haiku_read_with_timeout (&type, buf, 200, 1000000, false)) - { - block_input_function (); - if (type != FILE_PANEL_EVENT) - haiku_write (type, buf); - else if (!ptr) - ptr = (char *) ((struct haiku_file_panel_event *) buf)->ptr; - unblock_input_function (); + if (status == B_INTERRUPTED || status == B_WOULD_BLOCK) + continue; - maybe_quit_function (); - } + if (infos[0].events & B_EVENT_READ) + process_pending_signals_function (); - block_input_function (); - haiku_read_size (&b_s, false); - if (!b_s || ptr || panel->Window ()->IsHidden ()) + if (infos[1].events & B_EVENT_READ) { - c_unbind_to_nil_from_cxx (idx); - unblock_input_function (); - return ptr; + status = read_port (current_file_panel_port, + &reply_type, &file_name, + sizeof file_name); + + if (status < B_OK) + file_name = NULL; + + goto out; } - unblock_input_function (); + + infos[0].events = B_EVENT_READ; + infos[1].events = B_EVENT_READ; } + + out: + delete_port (current_file_panel_port); + return file_name; } /* Zoom WINDOW. */ diff --git a/src/haiku_support.h b/src/haiku_support.h index 056063864e1..722c05511cf 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -91,7 +91,6 @@ enum haiku_event_type MENU_BAR_OPEN, MENU_BAR_SELECT_EVENT, MENU_BAR_CLOSE, - FILE_PANEL_EVENT, MENU_BAR_HELP_EVENT, ZOOM_EVENT, DRAG_AND_DROP_EVENT, @@ -222,11 +221,6 @@ struct haiku_menu_bar_select_event void *ptr; }; -struct haiku_file_panel_event -{ - void *ptr; -}; - struct haiku_menu_bar_help_event { void *window; @@ -612,12 +606,7 @@ extern int EmacsView_double_buffered_p (void *); extern char *be_popup_file_dialog (int, const char *, int, int, void *, const char *, - const char *, void (*) (void), - void (*) (void), void (*) (void)); - -extern void record_c_unwind_protect_from_cxx (void (*) (void *), void *); -extern specpdl_ref c_specpdl_idx_from_cxx (void); -extern void c_unbind_to_nil_from_cxx (specpdl_ref); + const char *, void (*) (void)); #ifdef HAVE_NATIVE_IMAGE_API extern int be_can_translate_type_to_bitmap_p (const char *); diff --git a/src/haikufns.c b/src/haikufns.c index 78014c50886..3e3104193e0 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -617,14 +617,6 @@ haiku_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval } } -static void -unwind_popup (void) -{ - if (!popup_activated_p) - emacs_abort (); - --popup_activated_p; -} - static Lisp_Object haiku_create_frame (Lisp_Object parms) { @@ -2479,12 +2471,15 @@ Optional arg MUSTMATCH, if non-nil, means the returned file or directory must exist. Optional arg DIR_ONLY_P, if non-nil, means choose only directories. Optional arg SAVE_TEXT, if non-nil, specifies some text to show in the entry field. */) - (Lisp_Object prompt, Lisp_Object frame, - Lisp_Object dir, Lisp_Object mustmatch, - Lisp_Object dir_only_p, Lisp_Object save_text) + (Lisp_Object prompt, Lisp_Object frame, Lisp_Object dir, + Lisp_Object mustmatch, Lisp_Object dir_only_p, Lisp_Object save_text) { - if (!x_display_list) - error ("Haiku windowing not initialized"); + struct frame *f; + char *file_name; + Lisp_Object value; + + if (popup_activated_p) + error ("Trying to use a menu from within a menu-entry"); if (!NILP (dir)) CHECK_STRING (dir); @@ -2497,37 +2492,28 @@ Optional arg SAVE_TEXT, if non-nil, specifies some text to show in the entry fie CHECK_STRING (prompt); - CHECK_LIVE_FRAME (frame); - check_window_system (XFRAME (frame)); - - specpdl_ref idx = SPECPDL_INDEX (); - record_unwind_protect_void (unwind_popup); - - struct frame *f = XFRAME (frame); - - FRAME_DISPLAY_INFO (f)->focus_event_frame = f; + f = decode_window_system_frame (frame); ++popup_activated_p; - char *fn = be_popup_file_dialog (!NILP (mustmatch) || !NILP (dir_only_p), - !NILP (dir) ? SSDATA (ENCODE_UTF_8 (dir)) : NULL, - !NILP (mustmatch), !NILP (dir_only_p), - FRAME_HAIKU_WINDOW (f), - !NILP (save_text) ? SSDATA (ENCODE_UTF_8 (save_text)) : NULL, - SSDATA (ENCODE_UTF_8 (prompt)), - block_input, unblock_input, maybe_quit); - - unbind_to (idx, Qnil); + unrequest_sigio (); + file_name = be_popup_file_dialog (!NILP (mustmatch) || !NILP (dir_only_p), + !NILP (dir) ? SSDATA (dir) : NULL, + !NILP (mustmatch), !NILP (dir_only_p), + FRAME_HAIKU_WINDOW (f), + (!NILP (save_text) + ? SSDATA (ENCODE_UTF_8 (save_text)) : NULL), + SSDATA (ENCODE_UTF_8 (prompt)), + process_pending_signals); + request_sigio (); + --popup_activated_p; - block_input (); - BWindow_activate (FRAME_HAIKU_WINDOW (f)); - unblock_input (); + if (!file_name) + quit (); - if (!fn) - return Qnil; + value = build_string (file_name); + free (file_name); - Lisp_Object p = build_string_from_utf8 (fn); - free (fn); - return p; + return value; } DEFUN ("haiku-put-resource", Fhaiku_put_resource, Shaiku_put_resource, diff --git a/src/haikuterm.c b/src/haikuterm.c index 80c945c7724..341288133e8 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -54,14 +54,6 @@ static void **fringe_bmps; static int max_fringe_bmp = 0; static Lisp_Object rdb; - -struct unhandled_event -{ - struct unhandled_event *next; - enum haiku_event_type type; - uint8_t buffer[200]; -}; - static bool any_help_event_p; char * @@ -2824,7 +2816,6 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) int message_count; static void *buf; ssize_t b_size; - struct unhandled_event *unhandled_events = NULL; int button_or_motion_p, do_help; enum haiku_event_type type; struct input_event inev, inev2; @@ -3583,19 +3574,6 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) f->menu_bar_vector, b->ptr); break; } - case FILE_PANEL_EVENT: - { - if (!popup_activated_p) - continue; - - struct unhandled_event *ev = xmalloc (sizeof *ev); - ev->next = unhandled_events; - ev->type = type; - memcpy (&ev->buffer, buf, 200); - - unhandled_events = ev; - break; - } case MENU_BAR_HELP_EVENT: { struct haiku_menu_bar_help_event *b = buf; @@ -3678,14 +3656,6 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) } } - for (struct unhandled_event *ev = unhandled_events; ev;) - { - haiku_write_without_signal (ev->type, &ev->buffer, false); - struct unhandled_event *old = ev; - ev = old->next; - xfree (old); - } - if (do_help && !(hold_quit && hold_quit->kind != NO_EVENT)) { Lisp_Object help_frame = Qnil; |