diff options
| -rw-r--r-- | lisp/term/haiku-win.el | 8 | ||||
| -rw-r--r-- | src/haiku_select.cc | 92 | ||||
| -rw-r--r-- | src/haikuselect.c | 60 | ||||
| -rw-r--r-- | src/haikuselect.h | 16 |
4 files changed, 155 insertions, 21 deletions
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index 36af10d2c70..7861cfb9003 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el | |||
| @@ -86,15 +86,19 @@ If TYPE is nil, return \"text/plain\"." | |||
| 86 | (cond | 86 | (cond |
| 87 | ((memq type '(TEXT COMPOUND_TEXT STRING UTF8_STRING)) "text/plain") | 87 | ((memq type '(TEXT COMPOUND_TEXT STRING UTF8_STRING)) "text/plain") |
| 88 | ((stringp type) type) | 88 | ((stringp type) type) |
| 89 | ((symbolp type) (symbol-name type)) | ||
| 89 | (t "text/plain"))) | 90 | (t "text/plain"))) |
| 90 | 91 | ||
| 91 | (cl-defmethod gui-backend-get-selection (type data-type | 92 | (cl-defmethod gui-backend-get-selection (type data-type |
| 92 | &context (window-system haiku)) | 93 | &context (window-system haiku)) |
| 93 | (haiku-selection-data type (haiku--selection-type-to-mime data-type))) | 94 | (if (eq data-type 'TARGETS) |
| 95 | (apply #'vector (mapcar #'intern | ||
| 96 | (haiku-selection-targets type))) | ||
| 97 | (haiku-selection-data type (haiku--selection-type-to-mime data-type)))) | ||
| 94 | 98 | ||
| 95 | (cl-defmethod gui-backend-set-selection (type value | 99 | (cl-defmethod gui-backend-set-selection (type value |
| 96 | &context (window-system haiku)) | 100 | &context (window-system haiku)) |
| 97 | (haiku-selection-put type "text/plain" value)) | 101 | (haiku-selection-put type "text/plain" value t)) |
| 98 | 102 | ||
| 99 | (cl-defmethod gui-backend-selection-exists-p (selection | 103 | (cl-defmethod gui-backend-selection-exists-p (selection |
| 100 | &context (window-system haiku)) | 104 | &context (window-system haiku)) |
diff --git a/src/haiku_select.cc b/src/haiku_select.cc index 8d345ca6617..6cd6ee879e5 100644 --- a/src/haiku_select.cc +++ b/src/haiku_select.cc | |||
| @@ -64,12 +64,62 @@ BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len) | |||
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | static void | 66 | static void |
| 67 | BClipboard_get_targets (BClipboard *cb, char **buf, int buf_size) | ||
| 68 | { | ||
| 69 | BMessage *data; | ||
| 70 | char *name; | ||
| 71 | int32 count_found; | ||
| 72 | type_code type; | ||
| 73 | int32 i; | ||
| 74 | int index; | ||
| 75 | |||
| 76 | if (!cb->Lock ()) | ||
| 77 | { | ||
| 78 | buf[0] = NULL; | ||
| 79 | return; | ||
| 80 | } | ||
| 81 | |||
| 82 | data = cb->Data (); | ||
| 83 | index = 0; | ||
| 84 | |||
| 85 | if (!data) | ||
| 86 | { | ||
| 87 | buf[0] = NULL; | ||
| 88 | cb->Unlock (); | ||
| 89 | return; | ||
| 90 | } | ||
| 91 | |||
| 92 | for (i = 0; (data->GetInfo (B_ANY_TYPE, i, &name, | ||
| 93 | &type, &count_found) | ||
| 94 | == B_OK); ++i) | ||
| 95 | { | ||
| 96 | if (type == B_MIME_TYPE) | ||
| 97 | { | ||
| 98 | if (index < (buf_size - 1)) | ||
| 99 | { | ||
| 100 | buf[index++] = strdup (name); | ||
| 101 | |||
| 102 | if (!buf[index - 1]) | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | buf[index] = NULL; | ||
| 109 | |||
| 110 | cb->Unlock (); | ||
| 111 | } | ||
| 112 | |||
| 113 | static void | ||
| 67 | BClipboard_set_data (BClipboard *cb, const char *type, const char *dat, | 114 | BClipboard_set_data (BClipboard *cb, const char *type, const char *dat, |
| 68 | ssize_t len) | 115 | ssize_t len, bool clear) |
| 69 | { | 116 | { |
| 70 | if (!cb->Lock ()) | 117 | if (!cb->Lock ()) |
| 71 | return; | 118 | return; |
| 72 | cb->Clear (); | 119 | |
| 120 | if (clear) | ||
| 121 | cb->Clear (); | ||
| 122 | |||
| 73 | BMessage *mdat = cb->Data (); | 123 | BMessage *mdat = cb->Data (); |
| 74 | if (!mdat) | 124 | if (!mdat) |
| 75 | { | 125 | { |
| @@ -78,7 +128,13 @@ BClipboard_set_data (BClipboard *cb, const char *type, const char *dat, | |||
| 78 | } | 128 | } |
| 79 | 129 | ||
| 80 | if (dat) | 130 | if (dat) |
| 81 | mdat->AddData (type, B_MIME_TYPE, dat, len); | 131 | { |
| 132 | if (mdat->ReplaceData (type, B_MIME_TYPE, dat, len) | ||
| 133 | == B_NAME_NOT_FOUND) | ||
| 134 | mdat->AddData (type, B_MIME_TYPE, dat, len); | ||
| 135 | } | ||
| 136 | else | ||
| 137 | mdat->RemoveName (type); | ||
| 82 | cb->Commit (); | 138 | cb->Commit (); |
| 83 | cb->Unlock (); | 139 | cb->Unlock (); |
| 84 | } | 140 | } |
| @@ -112,32 +168,32 @@ BClipboard_find_secondary_selection_data (const char *type, ssize_t *len) | |||
| 112 | 168 | ||
| 113 | void | 169 | void |
| 114 | BClipboard_set_system_data (const char *type, const char *data, | 170 | BClipboard_set_system_data (const char *type, const char *data, |
| 115 | ssize_t len) | 171 | ssize_t len, bool clear) |
| 116 | { | 172 | { |
| 117 | if (!system_clipboard) | 173 | if (!system_clipboard) |
| 118 | return; | 174 | return; |
| 119 | 175 | ||
| 120 | BClipboard_set_data (system_clipboard, type, data, len); | 176 | BClipboard_set_data (system_clipboard, type, data, len, clear); |
| 121 | } | 177 | } |
| 122 | 178 | ||
| 123 | void | 179 | void |
| 124 | BClipboard_set_primary_selection_data (const char *type, const char *data, | 180 | BClipboard_set_primary_selection_data (const char *type, const char *data, |
| 125 | ssize_t len) | 181 | ssize_t len, bool clear) |
| 126 | { | 182 | { |
| 127 | if (!primary) | 183 | if (!primary) |
| 128 | return; | 184 | return; |
| 129 | 185 | ||
| 130 | BClipboard_set_data (primary, type, data, len); | 186 | BClipboard_set_data (primary, type, data, len, clear); |
| 131 | } | 187 | } |
| 132 | 188 | ||
| 133 | void | 189 | void |
| 134 | BClipboard_set_secondary_selection_data (const char *type, const char *data, | 190 | BClipboard_set_secondary_selection_data (const char *type, const char *data, |
| 135 | ssize_t len) | 191 | ssize_t len, bool clear) |
| 136 | { | 192 | { |
| 137 | if (!secondary) | 193 | if (!secondary) |
| 138 | return; | 194 | return; |
| 139 | 195 | ||
| 140 | BClipboard_set_data (secondary, type, data, len); | 196 | BClipboard_set_data (secondary, type, data, len, clear); |
| 141 | } | 197 | } |
| 142 | 198 | ||
| 143 | void | 199 | void |
| @@ -147,6 +203,24 @@ BClipboard_free_data (void *ptr) | |||
| 147 | } | 203 | } |
| 148 | 204 | ||
| 149 | void | 205 | void |
| 206 | BClipboard_system_targets (char **buf, int len) | ||
| 207 | { | ||
| 208 | BClipboard_get_targets (system_clipboard, buf, len); | ||
| 209 | } | ||
| 210 | |||
| 211 | void | ||
| 212 | BClipboard_primary_targets (char **buf, int len) | ||
| 213 | { | ||
| 214 | BClipboard_get_targets (primary, buf, len); | ||
| 215 | } | ||
| 216 | |||
| 217 | void | ||
| 218 | BClipboard_secondary_targets (char **buf, int len) | ||
| 219 | { | ||
| 220 | BClipboard_get_targets (secondary, buf, len); | ||
| 221 | } | ||
| 222 | |||
| 223 | void | ||
| 150 | init_haiku_select (void) | 224 | init_haiku_select (void) |
| 151 | { | 225 | { |
| 152 | system_clipboard = new BClipboard ("system"); | 226 | system_clipboard = new BClipboard ("system"); |
diff --git a/src/haikuselect.c b/src/haikuselect.c index 3f0441e0779..38cceb1de74 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c | |||
| @@ -24,6 +24,46 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 24 | #include "haikuselect.h" | 24 | #include "haikuselect.h" |
| 25 | #include "haikuterm.h" | 25 | #include "haikuterm.h" |
| 26 | 26 | ||
| 27 | static Lisp_Object | ||
| 28 | haiku_selection_data_1 (Lisp_Object clipboard) | ||
| 29 | { | ||
| 30 | Lisp_Object result = Qnil; | ||
| 31 | char *targets[256]; | ||
| 32 | |||
| 33 | block_input (); | ||
| 34 | if (EQ (clipboard, QPRIMARY)) | ||
| 35 | BClipboard_primary_targets ((char **) &targets, 256); | ||
| 36 | else if (EQ (clipboard, QSECONDARY)) | ||
| 37 | BClipboard_secondary_targets ((char **) &targets, 256); | ||
| 38 | else if (EQ (clipboard, QCLIPBOARD)) | ||
| 39 | BClipboard_system_targets ((char **) &targets, 256); | ||
| 40 | else | ||
| 41 | { | ||
| 42 | unblock_input (); | ||
| 43 | signal_error ("Bad clipboard", clipboard); | ||
| 44 | } | ||
| 45 | |||
| 46 | for (int i = 0; targets[i]; ++i) | ||
| 47 | { | ||
| 48 | result = Fcons (build_unibyte_string (targets[i]), | ||
| 49 | result); | ||
| 50 | free (targets[i]); | ||
| 51 | } | ||
| 52 | unblock_input (); | ||
| 53 | |||
| 54 | return result; | ||
| 55 | } | ||
| 56 | |||
| 57 | DEFUN ("haiku-selection-targets", Fhaiku_selection_targets, | ||
| 58 | Shaiku_selection_targets, 1, 1, 0, | ||
| 59 | doc: /* Find the types of data available from CLIPBOARD. | ||
| 60 | CLIPBOARD should be the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'. | ||
| 61 | Return the available types as a list of strings. */) | ||
| 62 | (Lisp_Object clipboard) | ||
| 63 | { | ||
| 64 | return haiku_selection_data_1 (clipboard); | ||
| 65 | } | ||
| 66 | |||
| 27 | DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data, | 67 | DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data, |
| 28 | 2, 2, 0, | 68 | 2, 2, 0, |
| 29 | doc: /* Retrieve content typed as NAME from the clipboard | 69 | doc: /* Retrieve content typed as NAME from the clipboard |
| @@ -78,15 +118,17 @@ fetch. */) | |||
| 78 | } | 118 | } |
| 79 | 119 | ||
| 80 | DEFUN ("haiku-selection-put", Fhaiku_selection_put, Shaiku_selection_put, | 120 | DEFUN ("haiku-selection-put", Fhaiku_selection_put, Shaiku_selection_put, |
| 81 | 3, 3, 0, | 121 | 3, 4, 0, |
| 82 | doc: /* Add or remove content from the clipboard CLIPBOARD. | 122 | doc: /* Add or remove content from the clipboard CLIPBOARD. |
| 83 | CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'. NAME | 123 | CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'. NAME |
| 84 | is a MIME type denoting the type of the data to add. DATA is the | 124 | is a MIME type denoting the type of the data to add. DATA is the |
| 85 | string that will be placed in the clipboard, or nil if the content is | 125 | string that will be placed in the clipboard, or nil if the content is |
| 86 | to be removed. If NAME is the string `text/utf-8' or the string | 126 | to be removed. If NAME is the string "text/utf-8" or the string |
| 87 | `text/plain', encode it as UTF-8 before storing it into the | 127 | "text/plain", encode it as UTF-8 before storing it into the clipboard. |
| 128 | CLEAR, if non-nil, means to erase all the previous contents of the | ||
| 88 | clipboard. */) | 129 | clipboard. */) |
| 89 | (Lisp_Object clipboard, Lisp_Object name, Lisp_Object data) | 130 | (Lisp_Object clipboard, Lisp_Object name, Lisp_Object data, |
| 131 | Lisp_Object clear) | ||
| 90 | { | 132 | { |
| 91 | CHECK_SYMBOL (clipboard); | 133 | CHECK_SYMBOL (clipboard); |
| 92 | CHECK_STRING (name); | 134 | CHECK_STRING (name); |
| @@ -105,11 +147,13 @@ clipboard. */) | |||
| 105 | ptrdiff_t len = !NILP (data) ? SBYTES (data) : 0; | 147 | ptrdiff_t len = !NILP (data) ? SBYTES (data) : 0; |
| 106 | 148 | ||
| 107 | if (EQ (clipboard, QPRIMARY)) | 149 | if (EQ (clipboard, QPRIMARY)) |
| 108 | BClipboard_set_primary_selection_data (SSDATA (name), dat, len); | 150 | BClipboard_set_primary_selection_data (SSDATA (name), dat, len, |
| 151 | !NILP (clear)); | ||
| 109 | else if (EQ (clipboard, QSECONDARY)) | 152 | else if (EQ (clipboard, QSECONDARY)) |
| 110 | BClipboard_set_secondary_selection_data (SSDATA (name), dat, len); | 153 | BClipboard_set_secondary_selection_data (SSDATA (name), dat, len, |
| 154 | !NILP (clear)); | ||
| 111 | else if (EQ (clipboard, QCLIPBOARD)) | 155 | else if (EQ (clipboard, QCLIPBOARD)) |
| 112 | BClipboard_set_system_data (SSDATA (name), dat, len); | 156 | BClipboard_set_system_data (SSDATA (name), dat, len, !NILP (clear)); |
| 113 | else | 157 | else |
| 114 | { | 158 | { |
| 115 | unblock_input (); | 159 | unblock_input (); |
| @@ -128,7 +172,9 @@ syms_of_haikuselect (void) | |||
| 128 | DEFSYM (QSTRING, "STRING"); | 172 | DEFSYM (QSTRING, "STRING"); |
| 129 | DEFSYM (QUTF8_STRING, "UTF8_STRING"); | 173 | DEFSYM (QUTF8_STRING, "UTF8_STRING"); |
| 130 | DEFSYM (Qforeign_selection, "foreign-selection"); | 174 | DEFSYM (Qforeign_selection, "foreign-selection"); |
| 175 | DEFSYM (QTARGETS, "TARGETS"); | ||
| 131 | 176 | ||
| 132 | defsubr (&Shaiku_selection_data); | 177 | defsubr (&Shaiku_selection_data); |
| 133 | defsubr (&Shaiku_selection_put); | 178 | defsubr (&Shaiku_selection_put); |
| 179 | defsubr (&Shaiku_selection_targets); | ||
| 134 | } | 180 | } |
diff --git a/src/haikuselect.h b/src/haikuselect.h index 542d550d64e..1a3a945f98d 100644 --- a/src/haikuselect.h +++ b/src/haikuselect.h | |||
| @@ -46,15 +46,25 @@ extern "C" | |||
| 46 | BClipboard_find_secondary_selection_data (const char *type, ssize_t *len); | 46 | BClipboard_find_secondary_selection_data (const char *type, ssize_t *len); |
| 47 | 47 | ||
| 48 | extern void | 48 | extern void |
| 49 | BClipboard_set_system_data (const char *type, const char *data, ssize_t len); | 49 | BClipboard_set_system_data (const char *type, const char *data, ssize_t len, |
| 50 | bool clear); | ||
| 50 | 51 | ||
| 51 | extern void | 52 | extern void |
| 52 | BClipboard_set_primary_selection_data (const char *type, const char *data, | 53 | BClipboard_set_primary_selection_data (const char *type, const char *data, |
| 53 | ssize_t len); | 54 | ssize_t len, bool clear); |
| 54 | 55 | ||
| 55 | extern void | 56 | extern void |
| 56 | BClipboard_set_secondary_selection_data (const char *type, const char *data, | 57 | BClipboard_set_secondary_selection_data (const char *type, const char *data, |
| 57 | ssize_t len); | 58 | ssize_t len, bool clear); |
| 59 | |||
| 60 | extern void | ||
| 61 | BClipboard_system_targets (char **buf, int len); | ||
| 62 | |||
| 63 | extern void | ||
| 64 | BClipboard_primary_targets (char **buf, int len); | ||
| 65 | |||
| 66 | extern void | ||
| 67 | BClipboard_secondary_targets (char **buf, int len); | ||
| 58 | 68 | ||
| 59 | /* Free the returned data. */ | 69 | /* Free the returned data. */ |
| 60 | extern void BClipboard_free_data (void *ptr); | 70 | extern void BClipboard_free_data (void *ptr); |