mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
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".
This commit is contained in:
parent
7dfb068c13
commit
b5cf6c1ab6
6 changed files with 113 additions and 190 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
const char *prompt,
|
||||
void (*process_pending_signals_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;
|
||||
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;
|
||||
|
||||
dat.entry = path;
|
||||
dat.msg = msg;
|
||||
dat.panel = panel;
|
||||
current_file_panel_port = create_port (1, "file panel port");
|
||||
file_name = NULL;
|
||||
|
||||
record_c_unwind_protect_from_cxx (unwind_popup_file_dialog, &dat);
|
||||
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))
|
||||
if (status == B_INTERRUPTED || status == B_WOULD_BLOCK)
|
||||
continue;
|
||||
|
||||
if (infos[0].events & B_EVENT_READ)
|
||||
process_pending_signals_function ();
|
||||
|
||||
if (infos[1].events & B_EVENT_READ)
|
||||
{
|
||||
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 ();
|
||||
status = read_port (current_file_panel_port,
|
||||
&reply_type, &file_name,
|
||||
sizeof file_name);
|
||||
|
||||
maybe_quit_function ();
|
||||
if (status < B_OK)
|
||||
file_name = NULL;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
block_input_function ();
|
||||
haiku_read_size (&b_s, false);
|
||||
if (!b_s || ptr || panel->Window ()->IsHidden ())
|
||||
{
|
||||
c_unbind_to_nil_from_cxx (idx);
|
||||
unblock_input_function ();
|
||||
return ptr;
|
||||
}
|
||||
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. */
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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;
|
||||
|
||||
unbind_to (idx, Qnil);
|
||||
if (!file_name)
|
||||
quit ();
|
||||
|
||||
block_input ();
|
||||
BWindow_activate (FRAME_HAIKU_WINDOW (f));
|
||||
unblock_input ();
|
||||
value = build_string (file_name);
|
||||
free (file_name);
|
||||
|
||||
if (!fn)
|
||||
return Qnil;
|
||||
|
||||
Lisp_Object p = build_string_from_utf8 (fn);
|
||||
free (fn);
|
||||
return p;
|
||||
return value;
|
||||
}
|
||||
|
||||
DEFUN ("haiku-put-resource", Fhaiku_put_resource, Shaiku_put_resource,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue