From 09866bb019d005ac5a8c475fe0b173fa35228d11 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 07:54:54 +0000 Subject: [PATCH] Use default external browser by default on Haiku * lisp/net/browse-url.el (browse-url-default-browser): Use that by default on Haiku. (browse-url-default-haiku-browser): New function. * src/haiku_support.cc (be_roster_launch): * src/haiku_support.h: New function. Update prototypes. * src/haikuselect.c (haiku_message_to_lisp): Encode and decode files correctly. (haiku_lisp_to_message): Encode and decode files correctly. (Fhaiku_roster_launch): New function. (syms_of_haikuselect): Update defsubrs. --- lisp/net/browse-url.el | 20 ++++++++++ src/haiku_support.cc | 34 +++++++++++++++++ src/haiku_support.h | 2 + src/haikuselect.c | 87 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 141 insertions(+), 2 deletions(-) diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 66898d77073..c563a27ac85 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -1019,6 +1019,8 @@ instead of `browse-url-new-window-flag'." 'browse-url-default-windows-browser) ((memq system-type '(darwin)) 'browse-url-default-macosx-browser) + ((featurep 'haiku) + 'browse-url-default-haiku-browser) ((browse-url-can-use-xdg-open) 'browse-url-xdg-open) ;;; ((executable-find browse-url-gnome-moz-program) 'browse-url-gnome-moz) ((executable-find browse-url-mozilla-program) 'browse-url-mozilla) @@ -1239,6 +1241,24 @@ The optional argument NEW-WINDOW is not used." (function-put 'browse-url-webpositive 'browse-url-browser-kind 'external) +(declare-function haiku-roster-launch "haikuselect.c") + +;;;###autoload +(defun browse-url-default-haiku-browser (url &optional _new-window) + "Browse URL with the system default browser. +Default to the URL around or before point." + (interactive (browse-url-interactive-arg "URL: ")) + (setq url (browse-url-encode-url url)) + (let* ((scheme (save-match-data + (if (string-match "\\(.+\\):/" url) + (match-string 1 url) + "http"))) + (mime (concat "application/x-vnd.Be.URL." scheme))) + (haiku-roster-launch mime (vector url)))) + +(function-put 'browse-url-default-haiku-browser + 'browse-url-browser-kind 'external) + ;;;###autoload (defun browse-url-emacs (url &optional same-window) "Ask Emacs to load URL into a buffer and show it in another window. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 27a676dd31c..6b4951e139a 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include #include #include @@ -5071,3 +5072,36 @@ BWindow_set_sticky (void *window, bool sticky) w->UnlockLooper (); } } + +status_t +be_roster_launch (const char *type, const char *file, char **cargs, + ptrdiff_t nargs, void *message, team_id *team_id) +{ + BEntry entry; + entry_ref ref; + + if (type) + { + if (message) + return be_roster->Launch (type, (BMessage *) message, + team_id); + + return be_roster->Launch (type, (nargs > INT_MAX + ? INT_MAX : nargs), + cargs, team_id); + } + + if (entry.SetTo (file) != B_OK) + return B_ERROR; + + if (entry.GetRef (&ref) != B_OK) + return B_ERROR; + + if (message) + return be_roster->Launch (&ref, (BMessage *) message, + team_id); + + return be_roster->Launch (&ref, (nargs > INT_MAX + ? INT_MAX : nargs), + cargs, team_id); +} diff --git a/src/haiku_support.h b/src/haiku_support.h index eaca7a9bad7..416c717546f 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -690,6 +690,8 @@ extern bool be_select_font (void (*) (void), bool (*) (void), int *, bool, int, int, int); extern int be_find_font_indices (struct haiku_font_pattern *, int *, int *); +extern status_t be_roster_launch (const char *, const char *, char **, + ptrdiff_t, void *, team_id *); #ifdef __cplusplus } diff --git a/src/haikuselect.c b/src/haikuselect.c index a186acc66ff..6d62f395c16 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -275,7 +275,7 @@ haiku_message_to_lisp (void *message) if (!pbuf) memory_full (SIZE_MAX); - t1 = build_string (pbuf); + t1 = DECODE_FILE (build_string (pbuf)); free (pbuf); break; @@ -526,7 +526,8 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) case 'RREF': CHECK_STRING (data); - if (be_add_refs_data (message, SSDATA (name), SSDATA (data)) + if (be_add_refs_data (message, SSDATA (name), + SSDATA (ENCODE_FILE (data))) && haiku_signal_invalid_refs) signal_error ("Invalid file name", data); break; @@ -799,6 +800,87 @@ ignored if it is dropped on top of FRAME. */) return unbind_to (idx, Qnil); } +DEFUN ("haiku-roster-launch", Fhaiku_roster_launch, Shaiku_roster_launch, + 2, 2, 0, + doc: /* Launch an application associated with FILE-OR-TYPE. +Return the process ID of the application, or nil if no application was +launched. + +FILE-OR-TYPE can either be a string denoting a MIME type, or a list +with one argument FILE, denoting a file whose associated application +will be launched. + +ARGS can either be a vector of strings containing the arguments that +will be passed to the application, or a system message in the form +accepted by `haiku-drag-message' that will be sent to the application +after it starts. */) + (Lisp_Object file_or_type, Lisp_Object args) +{ + char **cargs; + char *type, *file; + team_id team_id; + status_t rc; + ptrdiff_t i, nargs; + Lisp_Object tem; + void *message; + specpdl_ref depth; + + type = NULL; + file = NULL; + cargs = NULL; + message = NULL; + nargs = 0; + depth = SPECPDL_INDEX (); + + USE_SAFE_ALLOCA; + + if (STRINGP (file_or_type)) + SAFE_ALLOCA_STRING (type, file_or_type); + else + { + CHECK_LIST (file_or_type); + tem = XCAR (file_or_type); + + CHECK_STRING (tem); + SAFE_ALLOCA_STRING (file, ENCODE_FILE (tem)); + CHECK_LIST_END (XCDR (file_or_type), file_or_type); + } + + if (VECTORP (args)) + { + nargs = ASIZE (args); + cargs = SAFE_ALLOCA (nargs * sizeof *cargs); + + for (i = 0; i < nargs; ++i) + { + tem = AREF (args, i); + CHECK_STRING (tem); + maybe_quit (); + + cargs[i] = SAFE_ALLOCA (SBYTES (tem) + 1); + memcpy (cargs[i], SDATA (tem), SBYTES (tem) + 1); + } + } + else + { + message = be_create_simple_message (); + + record_unwind_protect_ptr (BMessage_delete, message); + haiku_lisp_to_message (args, message); + } + + block_input (); + rc = be_roster_launch (type, file, cargs, nargs, message, + &team_id); + unblock_input (); + + if (rc == B_OK) + return SAFE_FREE_UNBIND_TO (depth, + make_uint (team_id)); + + return SAFE_FREE_UNBIND_TO (depth, Qnil); +} + static Lisp_Object haiku_note_drag_motion_1 (void *data) { @@ -860,6 +942,7 @@ used to retrieve the current position of the mouse. */); defsubr (&Shaiku_selection_put); defsubr (&Shaiku_selection_owner_p); defsubr (&Shaiku_drag_message); + defsubr (&Shaiku_roster_launch); haiku_dnd_frame = NULL; } -- 2.39.2