emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master b5cf6c1ab6: Clean up Haiku file panel code


From: Po Lu
Subject: master b5cf6c1ab6: Clean up Haiku file panel code
Date: Tue, 3 May 2022 23:23:39 -0400 (EDT)

branch: master
commit b5cf6c1ab6cc5ca3d7a4b5d1e2b775d7d59a5866
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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".
---
 lisp/term/haiku-win.el |   3 +-
 src/haiku_io.c         |  23 -------
 src/haiku_support.cc   | 176 ++++++++++++++++++++++++-------------------------
 src/haiku_support.h    |  13 +---
 src/haikufns.c         |  64 +++++++-----------
 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 0921079246..5f02087732 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 0db5d26314..5d0031ef71 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 80c3ba3331..1280a77b22 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 056063864e..722c05511c 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 78014c5088..3e3104193e 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 80c945c772..341288133e 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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]