diff options
| author | Po Lu | 2022-09-14 06:24:49 +0000 |
|---|---|---|
| committer | Po Lu | 2022-09-14 06:25:11 +0000 |
| commit | b9ca1a8e4fbd3f8ef0d384d402ec5721ddcad28c (patch) | |
| tree | b7ed77f1c3091a68229779e9edef3a7b14ea70b7 /src | |
| parent | f0798ac13dcb4c01a883f165e03c3cd7f208667c (diff) | |
| download | emacs-b9ca1a8e4fbd3f8ef0d384d402ec5721ddcad28c.tar.gz emacs-b9ca1a8e4fbd3f8ef0d384d402ec5721ddcad28c.zip | |
Implement wallpaper.el support for Haiku
* lisp/image/wallpaper.el (haiku-set-wallpaper, wallpaper-set):
Use `haiku-set-wallpaper' on Haiku.
* lisp/term/haiku-win.el (haiku-write-node-attribute)
(haiku-send-message, haiku-set-wallpaper): New function.
* src/haiku_support.cc (be_write_node_message, be_send_message):
New functions.
* src/haiku_support.h: Update prototypes.
* src/haikuselect.c (haiku_message_to_lisp)
(haiku_lisp_to_message): Fix CSTR type handling to include NULL
byte.
(haiku_report_system_error, Fhaiku_write_node_attribute)
(Fhaiku_send_message): New functions.
(syms_of_haikuselect): Add defsubrs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/haiku_support.cc | 53 | ||||
| -rw-r--r-- | src/haiku_support.h | 3 | ||||
| -rw-r--r-- | src/haikuselect.c | 129 |
3 files changed, 185 insertions, 0 deletions
diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 983928442a1..0f8e26d0db4 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc | |||
| @@ -54,12 +54,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 54 | #include <game/WindowScreen.h> | 54 | #include <game/WindowScreen.h> |
| 55 | #include <game/DirectWindow.h> | 55 | #include <game/DirectWindow.h> |
| 56 | 56 | ||
| 57 | #include <storage/FindDirectory.h> | ||
| 57 | #include <storage/Entry.h> | 58 | #include <storage/Entry.h> |
| 58 | #include <storage/Path.h> | 59 | #include <storage/Path.h> |
| 59 | #include <storage/FilePanel.h> | 60 | #include <storage/FilePanel.h> |
| 60 | #include <storage/AppFileInfo.h> | 61 | #include <storage/AppFileInfo.h> |
| 61 | #include <storage/Path.h> | 62 | #include <storage/Path.h> |
| 62 | #include <storage/PathFinder.h> | 63 | #include <storage/PathFinder.h> |
| 64 | #include <storage/Node.h> | ||
| 63 | 65 | ||
| 64 | #include <support/Beep.h> | 66 | #include <support/Beep.h> |
| 65 | #include <support/DataIO.h> | 67 | #include <support/DataIO.h> |
| @@ -5501,3 +5503,54 @@ be_set_use_frame_synchronization (void *view, bool sync) | |||
| 5501 | vw = (EmacsView *) view; | 5503 | vw = (EmacsView *) view; |
| 5502 | vw->SetFrameSynchronization (sync); | 5504 | vw->SetFrameSynchronization (sync); |
| 5503 | } | 5505 | } |
| 5506 | |||
| 5507 | status_t | ||
| 5508 | be_write_node_message (const char *path, const char *name, void *message) | ||
| 5509 | { | ||
| 5510 | BNode node (path); | ||
| 5511 | status_t rc; | ||
| 5512 | ssize_t flat, result; | ||
| 5513 | char *buffer; | ||
| 5514 | BMessage *msg; | ||
| 5515 | |||
| 5516 | rc = node.InitCheck (); | ||
| 5517 | msg = (BMessage *) message; | ||
| 5518 | |||
| 5519 | if (rc < B_OK) | ||
| 5520 | return rc; | ||
| 5521 | |||
| 5522 | flat = msg->FlattenedSize (); | ||
| 5523 | if (flat < B_OK) | ||
| 5524 | return flat; | ||
| 5525 | |||
| 5526 | buffer = new (std::nothrow) char[flat]; | ||
| 5527 | if (!buffer) | ||
| 5528 | return B_NO_MEMORY; | ||
| 5529 | |||
| 5530 | rc = msg->Flatten (buffer, flat); | ||
| 5531 | if (rc < B_OK) | ||
| 5532 | { | ||
| 5533 | delete[] buffer; | ||
| 5534 | return rc; | ||
| 5535 | } | ||
| 5536 | |||
| 5537 | result = node.WriteAttr (name, B_MIME_TYPE, 0, | ||
| 5538 | buffer, flat); | ||
| 5539 | delete[] buffer; | ||
| 5540 | |||
| 5541 | if (result < B_OK) | ||
| 5542 | return result; | ||
| 5543 | |||
| 5544 | if (result != flat) | ||
| 5545 | return B_ERROR; | ||
| 5546 | |||
| 5547 | return B_OK; | ||
| 5548 | } | ||
| 5549 | |||
| 5550 | void | ||
| 5551 | be_send_message (const char *app_id, void *message) | ||
| 5552 | { | ||
| 5553 | BMessenger messenger (app_id); | ||
| 5554 | |||
| 5555 | messenger.SendMessage ((BMessage *) message); | ||
| 5556 | } | ||
diff --git a/src/haiku_support.h b/src/haiku_support.h index ca1808556a4..d66dbc5fa60 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h | |||
| @@ -724,6 +724,9 @@ extern void be_get_window_decorator_frame (void *, int *, int *, int *, int *); | |||
| 724 | extern void be_send_move_frame_event (void *); | 724 | extern void be_send_move_frame_event (void *); |
| 725 | extern void be_set_window_fullscreen_mode (void *, enum haiku_fullscreen_mode); | 725 | extern void be_set_window_fullscreen_mode (void *, enum haiku_fullscreen_mode); |
| 726 | 726 | ||
| 727 | extern status_t be_write_node_message (const char *, const char *, void *); | ||
| 728 | extern void be_send_message (const char *, void *); | ||
| 729 | |||
| 727 | extern void be_lock_window (void *); | 730 | extern void be_lock_window (void *); |
| 728 | extern void be_unlock_window (void *); | 731 | extern void be_unlock_window (void *); |
| 729 | extern bool be_get_explicit_workarea (int *, int *, int *, int *); | 732 | extern bool be_get_explicit_workarea (int *, int *, int *, int *); |
diff --git a/src/haikuselect.c b/src/haikuselect.c index 7eb93a2754d..bd004f4900a 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c | |||
| @@ -325,6 +325,15 @@ haiku_message_to_lisp (void *message) | |||
| 325 | t1 = make_float (*(float *) buf); | 325 | t1 = make_float (*(float *) buf); |
| 326 | break; | 326 | break; |
| 327 | 327 | ||
| 328 | case 'CSTR': | ||
| 329 | /* Is this even possible? */ | ||
| 330 | if (!buf_size) | ||
| 331 | buf_size = 1; | ||
| 332 | |||
| 333 | t1 = make_uninit_string (buf_size - 1); | ||
| 334 | memcpy (SDATA (t1), buf, buf_size - 1); | ||
| 335 | break; | ||
| 336 | |||
| 328 | default: | 337 | default: |
| 329 | t1 = make_uninit_string (buf_size); | 338 | t1 = make_uninit_string (buf_size); |
| 330 | memcpy (SDATA (t1), buf, buf_size); | 339 | memcpy (SDATA (t1), buf, buf_size); |
| @@ -747,6 +756,21 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 747 | signal_error ("Failed to add bool", data); | 756 | signal_error ("Failed to add bool", data); |
| 748 | break; | 757 | break; |
| 749 | 758 | ||
| 759 | case 'CSTR': | ||
| 760 | /* C strings must be handled specially, since they | ||
| 761 | include a trailing NULL byte. */ | ||
| 762 | CHECK_STRING (data); | ||
| 763 | |||
| 764 | block_input (); | ||
| 765 | rc = be_add_message_data (message, SSDATA (name), | ||
| 766 | type_code, SDATA (data), | ||
| 767 | SBYTES (data) + 1); | ||
| 768 | unblock_input (); | ||
| 769 | |||
| 770 | if (rc) | ||
| 771 | signal_error ("Failed to add", data); | ||
| 772 | break; | ||
| 773 | |||
| 750 | default: | 774 | default: |
| 751 | decode_normally: | 775 | decode_normally: |
| 752 | CHECK_STRING (data); | 776 | CHECK_STRING (data); |
| @@ -779,6 +803,49 @@ haiku_unwind_drag_message (void *message) | |||
| 779 | BMessage_delete (message); | 803 | BMessage_delete (message); |
| 780 | } | 804 | } |
| 781 | 805 | ||
| 806 | static void | ||
| 807 | haiku_report_system_error (status_t code, const char *format) | ||
| 808 | { | ||
| 809 | switch (code) | ||
| 810 | { | ||
| 811 | case B_BAD_VALUE: | ||
| 812 | error (format, "Bad value"); | ||
| 813 | break; | ||
| 814 | |||
| 815 | case B_ENTRY_NOT_FOUND: | ||
| 816 | error (format, "File not found"); | ||
| 817 | break; | ||
| 818 | |||
| 819 | case B_PERMISSION_DENIED: | ||
| 820 | error (format, "Permission denied"); | ||
| 821 | break; | ||
| 822 | |||
| 823 | case B_LINK_LIMIT: | ||
| 824 | error (format, "Link limit reached"); | ||
| 825 | break; | ||
| 826 | |||
| 827 | case B_BUSY: | ||
| 828 | error (format, "Device busy"); | ||
| 829 | break; | ||
| 830 | |||
| 831 | case B_NO_MORE_FDS: | ||
| 832 | error (format, "No more file descriptors"); | ||
| 833 | break; | ||
| 834 | |||
| 835 | case B_FILE_ERROR: | ||
| 836 | error (format, "File error"); | ||
| 837 | break; | ||
| 838 | |||
| 839 | case B_NO_MEMORY: | ||
| 840 | memory_full (SIZE_MAX); | ||
| 841 | break; | ||
| 842 | |||
| 843 | default: | ||
| 844 | error (format, "Unknown error"); | ||
| 845 | break; | ||
| 846 | } | ||
| 847 | } | ||
| 848 | |||
| 782 | DEFUN ("haiku-drag-message", Fhaiku_drag_message, Shaiku_drag_message, | 849 | DEFUN ("haiku-drag-message", Fhaiku_drag_message, Shaiku_drag_message, |
| 783 | 2, 4, 0, | 850 | 2, 4, 0, |
| 784 | doc: /* Begin dragging MESSAGE from FRAME. | 851 | doc: /* Begin dragging MESSAGE from FRAME. |
| @@ -958,6 +1025,66 @@ after it starts. */) | |||
| 958 | return SAFE_FREE_UNBIND_TO (depth, Qnil); | 1025 | return SAFE_FREE_UNBIND_TO (depth, Qnil); |
| 959 | } | 1026 | } |
| 960 | 1027 | ||
| 1028 | DEFUN ("haiku-write-node-attribute", Fhaiku_write_node_attribute, | ||
| 1029 | Shaiku_write_node_attribute, 3, 3, 0, | ||
| 1030 | doc: /* Write a message as a file-system attribute of NODE. | ||
| 1031 | FILE should be a file name of a file on a Be File System volume, NAME | ||
| 1032 | should be a string describing the name of the attribute that will be | ||
| 1033 | written, and MESSAGE will be the attribute written to FILE, as a | ||
| 1034 | system message in the format accepted by `haiku-drag-message', which | ||
| 1035 | see. */) | ||
| 1036 | (Lisp_Object file, Lisp_Object name, Lisp_Object message) | ||
| 1037 | { | ||
| 1038 | void *be_message; | ||
| 1039 | status_t rc; | ||
| 1040 | specpdl_ref count; | ||
| 1041 | |||
| 1042 | CHECK_STRING (file); | ||
| 1043 | CHECK_STRING (name); | ||
| 1044 | |||
| 1045 | file = ENCODE_FILE (file); | ||
| 1046 | name = ENCODE_SYSTEM (name); | ||
| 1047 | |||
| 1048 | be_message = be_create_simple_message (); | ||
| 1049 | count = SPECPDL_INDEX (); | ||
| 1050 | |||
| 1051 | record_unwind_protect_ptr (BMessage_delete, be_message); | ||
| 1052 | haiku_lisp_to_message (message, be_message); | ||
| 1053 | rc = be_write_node_message (SSDATA (file), SSDATA (name), | ||
| 1054 | be_message); | ||
| 1055 | |||
| 1056 | if (rc < B_OK) | ||
| 1057 | haiku_report_system_error (rc, "Failed to set attribute: %s"); | ||
| 1058 | |||
| 1059 | return unbind_to (count, Qnil); | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | DEFUN ("haiku-send-message", Fhaiku_send_message, Shaiku_send_message, | ||
| 1063 | 2, 2, 0, | ||
| 1064 | doc: /* Send a system message to PROGRAM. | ||
| 1065 | PROGRAM must be the name of the application to which the message will | ||
| 1066 | be sent. MESSAGE is the system message, serialized in the format | ||
| 1067 | accepted by `haiku-drag-message', that will be sent to the application | ||
| 1068 | specified by PROGRAM. There is no guarantee that the message will | ||
| 1069 | arrive after this function is called. */) | ||
| 1070 | (Lisp_Object program, Lisp_Object message) | ||
| 1071 | { | ||
| 1072 | specpdl_ref count; | ||
| 1073 | void *be_message; | ||
| 1074 | |||
| 1075 | CHECK_STRING (program); | ||
| 1076 | program = ENCODE_SYSTEM (program); | ||
| 1077 | |||
| 1078 | be_message = be_create_simple_message (); | ||
| 1079 | count = SPECPDL_INDEX (); | ||
| 1080 | |||
| 1081 | record_unwind_protect_ptr (BMessage_delete, be_message); | ||
| 1082 | haiku_lisp_to_message (message, be_message); | ||
| 1083 | be_send_message (SSDATA (program), be_message); | ||
| 1084 | |||
| 1085 | return unbind_to (count, Qnil); | ||
| 1086 | } | ||
| 1087 | |||
| 961 | static void | 1088 | static void |
| 962 | haiku_dnd_compute_tip_xy (int *root_x, int *root_y) | 1089 | haiku_dnd_compute_tip_xy (int *root_x, int *root_y) |
| 963 | { | 1090 | { |
| @@ -1191,6 +1318,8 @@ keyboard modifiers currently held down. */); | |||
| 1191 | defsubr (&Shaiku_selection_owner_p); | 1318 | defsubr (&Shaiku_selection_owner_p); |
| 1192 | defsubr (&Shaiku_drag_message); | 1319 | defsubr (&Shaiku_drag_message); |
| 1193 | defsubr (&Shaiku_roster_launch); | 1320 | defsubr (&Shaiku_roster_launch); |
| 1321 | defsubr (&Shaiku_write_node_attribute); | ||
| 1322 | defsubr (&Shaiku_send_message); | ||
| 1194 | 1323 | ||
| 1195 | haiku_dnd_frame = NULL; | 1324 | haiku_dnd_frame = NULL; |
| 1196 | } | 1325 | } |