diff options
| author | Po Lu | 2022-03-29 06:35:09 +0000 |
|---|---|---|
| committer | Po Lu | 2022-03-29 06:35:09 +0000 |
| commit | 080d29d52ecc6919517b7ee45cbdcc7444d8d025 (patch) | |
| tree | 69a0716a449426f78dcce4364531a2fc7d0a9e05 /src | |
| parent | 55932a65ed719d4277e0e781ca5e323b189d7f63 (diff) | |
| download | emacs-080d29d52ecc6919517b7ee45cbdcc7444d8d025.tar.gz emacs-080d29d52ecc6919517b7ee45cbdcc7444d8d025.zip | |
Specially decode more selection types on Haiku
* src/haiku_select.cc (be_get_point_data, be_add_point_data):
New functions.
* src/haikuselect.c (haiku_message_to_lisp, lisp_to_type_code)
(haiku_lisp_to_message): Accept new types `size_t', `ssize_t'
and `point'.
(Fhaiku_drag_message): Update doc string.
(syms_of_haikuselect): New defsyms.
* src/haikuselect.h: Update prototypes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/haiku_select.cc | 30 | ||||
| -rw-r--r-- | src/haikuselect.c | 149 | ||||
| -rw-r--r-- | src/haikuselect.h | 4 |
3 files changed, 160 insertions, 23 deletions
diff --git a/src/haiku_select.cc b/src/haiku_select.cc index e047b9b5139..be8026b6a16 100644 --- a/src/haiku_select.cc +++ b/src/haiku_select.cc | |||
| @@ -28,7 +28,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 28 | 28 | ||
| 29 | #include "haikuselect.h" | 29 | #include "haikuselect.h" |
| 30 | 30 | ||
| 31 | |||
| 32 | static BClipboard *primary = NULL; | 31 | static BClipboard *primary = NULL; |
| 33 | static BClipboard *secondary = NULL; | 32 | static BClipboard *secondary = NULL; |
| 34 | static BClipboard *system_clipboard = NULL; | 33 | static BClipboard *system_clipboard = NULL; |
| @@ -319,6 +318,26 @@ be_get_refs_data (void *message, const char *name, | |||
| 319 | } | 318 | } |
| 320 | 319 | ||
| 321 | int | 320 | int |
| 321 | be_get_point_data (void *message, const char *name, | ||
| 322 | int32 index, float *x, float *y) | ||
| 323 | { | ||
| 324 | status_t rc; | ||
| 325 | BMessage *msg; | ||
| 326 | BPoint point; | ||
| 327 | |||
| 328 | msg = (BMessage *) message; | ||
| 329 | rc = msg->FindPoint (name, index, &point); | ||
| 330 | |||
| 331 | if (rc != B_OK) | ||
| 332 | return 1; | ||
| 333 | |||
| 334 | *x = point.x; | ||
| 335 | *y = point.y; | ||
| 336 | |||
| 337 | return 0; | ||
| 338 | } | ||
| 339 | |||
| 340 | int | ||
| 322 | be_get_message_data (void *message, const char *name, | 341 | be_get_message_data (void *message, const char *name, |
| 323 | int32 type_code, int32 index, | 342 | int32 type_code, int32 index, |
| 324 | const void **buf_return, | 343 | const void **buf_return, |
| @@ -399,6 +418,15 @@ be_add_refs_data (void *message, const char *name, | |||
| 399 | } | 418 | } |
| 400 | 419 | ||
| 401 | int | 420 | int |
| 421 | be_add_point_data (void *message, const char *name, | ||
| 422 | float x, float y) | ||
| 423 | { | ||
| 424 | BMessage *msg = (BMessage *) message; | ||
| 425 | |||
| 426 | return msg->AddPoint (name, BPoint (x, y)) != B_OK; | ||
| 427 | } | ||
| 428 | |||
| 429 | int | ||
| 402 | be_add_message_message (void *message, const char *name, | 430 | be_add_message_message (void *message, const char *name, |
| 403 | void *data) | 431 | void *data) |
| 404 | { | 432 | { |
diff --git a/src/haikuselect.c b/src/haikuselect.c index c1c619ee8c4..38d4933948f 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c | |||
| @@ -213,25 +213,8 @@ same as `SECONDARY'. */) | |||
| 213 | return value ? Qt : Qnil; | 213 | return value ? Qt : Qnil; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | /* Return the Lisp representation of MESSAGE. | 216 | /* Return the Lisp representation of MESSAGE. See Fhaiku_drag_message |
| 217 | 217 | for the format of the object returned. */ | |
| 218 | It is an alist of strings, denoting message field names, to a list | ||
| 219 | of the form (TYPE DATA ...), where TYPE is an integer denoting the | ||
| 220 | system data type of DATA, and DATA is in the general case a unibyte | ||
| 221 | string. | ||
| 222 | |||
| 223 | If TYPE is a symbol instead of an integer, then DATA was specially | ||
| 224 | decoded. If TYPE is `ref', then DATA is the absolute file name of | ||
| 225 | a file, or nil if decoding the file name failed. If TYPE is | ||
| 226 | `string', then DATA is a unibyte string. If TYPE is `short', then | ||
| 227 | DATA is a 16-bit signed integer. If TYPE is `long', then DATA is a | ||
| 228 | 32-bit signed integer. If TYPE is `llong', then DATA is a 64-bit | ||
| 229 | signed integer. If TYPE is `byte' or `char', then DATA is an 8-bit | ||
| 230 | signed integer. If TYPE is `bool', then DATA is a boolean. | ||
| 231 | |||
| 232 | If the field name is not a string but the symbol `type', then it | ||
| 233 | associates to a 32-bit unsigned integer describing the type of the | ||
| 234 | system message. */ | ||
| 235 | Lisp_Object | 218 | Lisp_Object |
| 236 | haiku_message_to_lisp (void *message) | 219 | haiku_message_to_lisp (void *message) |
| 237 | { | 220 | { |
| @@ -243,6 +226,7 @@ haiku_message_to_lisp (void *message) | |||
| 243 | int32 i, j, count, type_code; | 226 | int32 i, j, count, type_code; |
| 244 | int rc; | 227 | int rc; |
| 245 | void *msg; | 228 | void *msg; |
| 229 | float point_x, point_y; | ||
| 246 | 230 | ||
| 247 | for (i = 0; !be_enum_message (message, &type_code, i, | 231 | for (i = 0; !be_enum_message (message, &type_code, i, |
| 248 | &count, &name); ++i) | 232 | &count, &name); ++i) |
| @@ -287,9 +271,22 @@ haiku_message_to_lisp (void *message) | |||
| 287 | 271 | ||
| 288 | t1 = build_string (pbuf); | 272 | t1 = build_string (pbuf); |
| 289 | 273 | ||
| 290 | block_input (); | ||
| 291 | free (pbuf); | 274 | free (pbuf); |
| 292 | unblock_input (); | 275 | break; |
| 276 | |||
| 277 | case 'BPNT': | ||
| 278 | rc = be_get_point_data (message, name, | ||
| 279 | j, &point_x, | ||
| 280 | &point_y); | ||
| 281 | |||
| 282 | if (rc) | ||
| 283 | { | ||
| 284 | t1 = Qnil; | ||
| 285 | break; | ||
| 286 | } | ||
| 287 | |||
| 288 | t1 = Fcons (make_float (point_x), | ||
| 289 | make_float (point_y)); | ||
| 293 | break; | 290 | break; |
| 294 | 291 | ||
| 295 | case 'SHRT': | 292 | case 'SHRT': |
| @@ -309,6 +306,14 @@ haiku_message_to_lisp (void *message) | |||
| 309 | t1 = make_fixnum (*(int8 *) buf); | 306 | t1 = make_fixnum (*(int8 *) buf); |
| 310 | break; | 307 | break; |
| 311 | 308 | ||
| 309 | case 'SIZT': | ||
| 310 | t1 = make_uint ((uintmax_t) *(size_t *) buf); | ||
| 311 | break; | ||
| 312 | |||
| 313 | case 'SSZT': | ||
| 314 | t1 = make_int ((intmax_t) *(ssize_t *) buf); | ||
| 315 | break; | ||
| 316 | |||
| 312 | default: | 317 | default: |
| 313 | t1 = make_uninit_string (buf_size); | 318 | t1 = make_uninit_string (buf_size); |
| 314 | memcpy (SDATA (t1), buf, buf_size); | 319 | memcpy (SDATA (t1), buf, buf_size); |
| @@ -355,6 +360,18 @@ haiku_message_to_lisp (void *message) | |||
| 355 | t2 = Qmessage; | 360 | t2 = Qmessage; |
| 356 | break; | 361 | break; |
| 357 | 362 | ||
| 363 | case 'SIZT': | ||
| 364 | t2 = Qsize_t; | ||
| 365 | break; | ||
| 366 | |||
| 367 | case 'SSZT': | ||
| 368 | t2 = Qssize_t; | ||
| 369 | break; | ||
| 370 | |||
| 371 | case 'BPNT': | ||
| 372 | t2 = Qpoint; | ||
| 373 | break; | ||
| 374 | |||
| 358 | default: | 375 | default: |
| 359 | t2 = make_int (type_code); | 376 | t2 = make_int (type_code); |
| 360 | } | 377 | } |
| @@ -394,6 +411,12 @@ lisp_to_type_code (Lisp_Object obj) | |||
| 394 | return 'BOOL'; | 411 | return 'BOOL'; |
| 395 | else if (EQ (obj, Qmessage)) | 412 | else if (EQ (obj, Qmessage)) |
| 396 | return 'MSGG'; | 413 | return 'MSGG'; |
| 414 | else if (EQ (obj, Qsize_t)) | ||
| 415 | return 'SIZT'; | ||
| 416 | else if (EQ (obj, Qssize_t)) | ||
| 417 | return 'SSZT'; | ||
| 418 | else if (EQ (obj, Qpoint)) | ||
| 419 | return 'BPNT'; | ||
| 397 | else | 420 | else |
| 398 | return -1; | 421 | return -1; |
| 399 | } | 422 | } |
| @@ -408,8 +431,11 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 408 | int8 char_data; | 431 | int8 char_data; |
| 409 | bool bool_data; | 432 | bool bool_data; |
| 410 | void *msg_data; | 433 | void *msg_data; |
| 434 | size_t sizet_data; | ||
| 435 | ssize_t ssizet_data; | ||
| 411 | intmax_t t4; | 436 | intmax_t t4; |
| 412 | uintmax_t t5; | 437 | uintmax_t t5; |
| 438 | float t6, t7; | ||
| 413 | int rc; | 439 | int rc; |
| 414 | specpdl_ref ref; | 440 | specpdl_ref ref; |
| 415 | 441 | ||
| @@ -498,6 +524,19 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 498 | signal_error ("Invalid file name", data); | 524 | signal_error ("Invalid file name", data); |
| 499 | break; | 525 | break; |
| 500 | 526 | ||
| 527 | case 'BPNT': | ||
| 528 | CHECK_CONS (data); | ||
| 529 | CHECK_NUMBER (XCAR (data)); | ||
| 530 | CHECK_NUMBER (XCDR (data)); | ||
| 531 | |||
| 532 | t6 = XFLOATINT (XCAR (data)); | ||
| 533 | t7 = XFLOATINT (XCDR (data)); | ||
| 534 | |||
| 535 | if (be_add_point_data (message, SSDATA (name), | ||
| 536 | t6, t7)) | ||
| 537 | signal_error ("Invalid point", data); | ||
| 538 | break; | ||
| 539 | |||
| 501 | case 'SHRT': | 540 | case 'SHRT': |
| 502 | if (!TYPE_RANGED_FIXNUMP (int16, data)) | 541 | if (!TYPE_RANGED_FIXNUMP (int16, data)) |
| 503 | signal_error ("Invalid value", data); | 542 | signal_error ("Invalid value", data); |
| @@ -572,6 +611,63 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 572 | signal_error ("Failed to add llong", data); | 611 | signal_error ("Failed to add llong", data); |
| 573 | break; | 612 | break; |
| 574 | 613 | ||
| 614 | case 'SIZT': | ||
| 615 | if (BIGNUMP (data)) | ||
| 616 | { | ||
| 617 | t4 = bignum_to_intmax (data); | ||
| 618 | |||
| 619 | if (!t4 || t4 > TYPE_MAXIMUM (size_t)) | ||
| 620 | signal_error ("Value too large", data); | ||
| 621 | |||
| 622 | sizet_data = (size_t) t4; | ||
| 623 | } | ||
| 624 | else | ||
| 625 | { | ||
| 626 | if (!TYPE_RANGED_FIXNUMP (size_t, data)) | ||
| 627 | signal_error ("Invalid value", data); | ||
| 628 | |||
| 629 | sizet_data = (int64) XFIXNUM (data); | ||
| 630 | } | ||
| 631 | |||
| 632 | block_input (); | ||
| 633 | rc = be_add_message_data (message, SSDATA (name), | ||
| 634 | type_code, &sizet_data, | ||
| 635 | sizeof sizet_data); | ||
| 636 | unblock_input (); | ||
| 637 | |||
| 638 | if (rc) | ||
| 639 | signal_error ("Failed to add sizet", data); | ||
| 640 | break; | ||
| 641 | |||
| 642 | case 'SSZT': | ||
| 643 | if (BIGNUMP (data)) | ||
| 644 | { | ||
| 645 | t4 = bignum_to_intmax (data); | ||
| 646 | |||
| 647 | if (!t4 || t4 > TYPE_MINIMUM (ssize_t) | ||
| 648 | || t4 < TYPE_MAXIMUM (ssize_t)) | ||
| 649 | signal_error ("Value too large", data); | ||
| 650 | |||
| 651 | ssizet_data = (ssize_t) t4; | ||
| 652 | } | ||
| 653 | else | ||
| 654 | { | ||
| 655 | if (!TYPE_RANGED_FIXNUMP (ssize_t, data)) | ||
| 656 | signal_error ("Invalid value", data); | ||
| 657 | |||
| 658 | ssizet_data = (int64) XFIXNUM (data); | ||
| 659 | } | ||
| 660 | |||
| 661 | block_input (); | ||
| 662 | rc = be_add_message_data (message, SSDATA (name), | ||
| 663 | type_code, &ssizet_data, | ||
| 664 | sizeof ssizet_data); | ||
| 665 | unblock_input (); | ||
| 666 | |||
| 667 | if (rc) | ||
| 668 | signal_error ("Failed to add ssizet", data); | ||
| 669 | break; | ||
| 670 | |||
| 575 | case 'CHAR': | 671 | case 'CHAR': |
| 576 | case 'BYTE': | 672 | case 'BYTE': |
| 577 | if (!TYPE_RANGED_FIXNUMP (int8, data)) | 673 | if (!TYPE_RANGED_FIXNUMP (int8, data)) |
| @@ -641,7 +737,13 @@ then DATA is a unibyte string. If TYPE is `short', then DATA is a | |||
| 641 | 16-bit signed integer. If TYPE is `long', then DATA is a 32-bit | 737 | 16-bit signed integer. If TYPE is `long', then DATA is a 32-bit |
| 642 | signed integer. If TYPE is `llong', then DATA is a 64-bit signed | 738 | signed integer. If TYPE is `llong', then DATA is a 64-bit signed |
| 643 | integer. If TYPE is `byte' or `char', then DATA is an 8-bit signed | 739 | integer. If TYPE is `byte' or `char', then DATA is an 8-bit signed |
| 644 | integer. If TYPE is `bool', then DATA is a boolean. | 740 | integer. If TYPE is `bool', then DATA is a boolean. If TYPE is |
| 741 | `size_t', then DATA is an integer that can hold between 0 and the | ||
| 742 | maximum value returned by the `sizeof' C operator on the current | ||
| 743 | system. If TYPE is `ssize_t', then DATA is an integer that can hold | ||
| 744 | values from -1 to the maximum value of the C data type `ssize_t' on | ||
| 745 | the current system. If TYPE is `point', then DATA is a cons of float | ||
| 746 | values describing the X and Y coordinates of an on-screen location. | ||
| 645 | 747 | ||
| 646 | If the field name is not a string but the symbol `type', then it | 748 | If the field name is not a string but the symbol `type', then it |
| 647 | associates to a 32-bit unsigned integer describing the type of the | 749 | associates to a 32-bit unsigned integer describing the type of the |
| @@ -701,6 +803,9 @@ syms_of_haikuselect (void) | |||
| 701 | DEFSYM (Qchar, "char"); | 803 | DEFSYM (Qchar, "char"); |
| 702 | DEFSYM (Qbool, "bool"); | 804 | DEFSYM (Qbool, "bool"); |
| 703 | DEFSYM (Qtype, "type"); | 805 | DEFSYM (Qtype, "type"); |
| 806 | DEFSYM (Qsize_t, "size_t"); | ||
| 807 | DEFSYM (Qssize_t, "ssize_t"); | ||
| 808 | DEFSYM (Qpoint, "point"); | ||
| 704 | 809 | ||
| 705 | defsubr (&Shaiku_selection_data); | 810 | defsubr (&Shaiku_selection_data); |
| 706 | defsubr (&Shaiku_selection_put); | 811 | defsubr (&Shaiku_selection_put); |
diff --git a/src/haikuselect.h b/src/haikuselect.h index 5d1dd33c8c4..bac9663c702 100644 --- a/src/haikuselect.h +++ b/src/haikuselect.h | |||
| @@ -94,6 +94,8 @@ extern "C" | |||
| 94 | ssize_t *size_return); | 94 | ssize_t *size_return); |
| 95 | extern int be_get_refs_data (void *message, const char *name, | 95 | extern int be_get_refs_data (void *message, const char *name, |
| 96 | int32 index, char **path_buffer); | 96 | int32 index, char **path_buffer); |
| 97 | extern int be_get_point_data (void *message, const char *name, | ||
| 98 | int32 index, float *x, float *y); | ||
| 97 | extern uint32 be_get_message_type (void *message); | 99 | extern uint32 be_get_message_type (void *message); |
| 98 | extern void be_set_message_type (void *message, uint32 what); | 100 | extern void be_set_message_type (void *message, uint32 what); |
| 99 | extern void *be_get_message_message (void *message, const char *name, | 101 | extern void *be_get_message_message (void *message, const char *name, |
| @@ -104,6 +106,8 @@ extern "C" | |||
| 104 | ssize_t buf_size); | 106 | ssize_t buf_size); |
| 105 | extern int be_add_refs_data (void *message, const char *name, | 107 | extern int be_add_refs_data (void *message, const char *name, |
| 106 | const char *filename); | 108 | const char *filename); |
| 109 | extern int be_add_point_data (void *message, const char *name, | ||
| 110 | float x, float y); | ||
| 107 | extern int be_add_message_message (void *message, const char *name, | 111 | extern int be_add_message_message (void *message, const char *name, |
| 108 | void *data); | 112 | void *data); |
| 109 | extern int be_lock_clipboard_message (enum haiku_clipboard clipboard, | 113 | extern int be_lock_clipboard_message (enum haiku_clipboard clipboard, |