|
182 | 182 | '(member :rotate-0 :rotate-90 :rotate-180 :rotate-270 :reflect-x :reflect-y)) |
183 | 183 |
|
184 | 184 | (deftype rotation-mask () |
185 | | - '(or mask16 (clx-list event-mask-class))) |
| 185 | + '(or mask16 (clx-list rotation-mask-class))) |
186 | 186 |
|
187 | 187 | ;; Select |
188 | 188 |
|
|
435 | 435 | (boolean state) |
436 | 436 | ) |
437 | 437 |
|
438 | | -;; x-requests |
| 438 | +;;; Helpers |
439 | 439 |
|
| 440 | +(declaim (ftype (function (card32 card32) (values boolean &optional)) |
| 441 | + rr-has-rates)) |
| 442 | +(defun rr-has-rates (major minor) |
| 443 | + (or (> major 1) |
| 444 | + (and (= major 1) (>= minor 1)))) |
| 445 | + |
| 446 | +;;; Requests |
| 447 | + |
| 448 | +(declaim (ftype (function (display) (values card32 card32 &optional)) |
| 449 | + rr-query-version)) |
440 | 450 | (defun rr-query-version (display) |
441 | | -"Returns version MAJOR and MINOR from server." |
442 | | - (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (32)) |
| 451 | + "Execute the RRQueryVersion request and return its result as multiple |
| 452 | +values consisting of the server's major and minor protocol versions." |
| 453 | + (with-buffer-request-and-reply (display (randr-opcode display) nil |
| 454 | + :sizes (32)) |
443 | 455 | ((data +rr-QueryVersion+) |
444 | 456 | (card32 +rr-major+) |
445 | 457 | (card32 +rr-minor+)) |
446 | 458 | (values |
447 | 459 | (card32-get 8) |
448 | 460 | (card32-get 12)))) |
449 | 461 |
|
| 462 | +;; Unexported |
| 463 | +(declaim (ftype (function (display (or null card32) (or null card32)) |
| 464 | + (values card32 card32 &optional)) |
| 465 | + rr-maybe-query-version)) |
| 466 | +(defun rr-maybe-query-version (display major minor) |
| 467 | + "Return MAJOR and MINOR as multiple values, substituting 0 for NIL, |
| 468 | +unless they are both NIL, in which case call RR-QUERY-VERSION and return |
| 469 | +its values. |
| 470 | +
|
| 471 | +Some requests (e.g., RRGetScreenInfo) behave differently after a version |
| 472 | +query (only the first query has any effect on these requests). |
| 473 | +In order that the functions executing such requests be able to skip |
| 474 | +subsequent (redundant) queries, have them accept MAJOR and MINOR keyword |
| 475 | +arguments and call this function with those arguments instead of calling |
| 476 | +RR-QUERY-VERSION." |
| 477 | + (if (or major minor) |
| 478 | + (values (or major 0) (or minor 0)) |
| 479 | + (rr-query-version display))) |
| 480 | + |
450 | 481 | (defun rr-set-screen-config (window timestamp conf-timestamp size-id rotation refresh) |
451 | 482 | "Sets the current screen to which the given window belongs. Timestamps are obtained from rr-get-screen-info. Rotation can be a list of rotation keys or a rotation mask. Returns timestamp, config timestamp, the root window of the screen and sub-pixel order." |
452 | 483 | (let ((display (window-display window)) |
|
487 | 518 | (card16 select-mask) |
488 | 519 | (pad16)))) |
489 | 520 |
|
490 | | -(defun rr-get-screen-info (window &optional (result-type 'list)) |
491 | | -"Returns rotations, root-window, timestamp, config-timestamp, current-size-id, current rotation, current rate, a list of screen-size structures, and last a sequence of refresh-rates" |
| 521 | +(declaim (ftype (function (window &key |
| 522 | + (:major (or null card32)) |
| 523 | + (:minor (or null card32)) |
| 524 | + (:result-type t)) |
| 525 | + (values (clx-list rotation-mask-class) |
| 526 | + window |
| 527 | + timestamp |
| 528 | + timestamp |
| 529 | + size-id |
| 530 | + (clx-list rotation-mask-class) |
| 531 | + (clx-list screen-size) |
| 532 | + (or null card16) |
| 533 | + (clx-sequence card16) |
| 534 | + &optional)) |
| 535 | + rr-get-screen-info)) |
| 536 | +(defun rr-get-screen-info (window &key major minor (result-type 'list)) |
| 537 | + "Execute the RRGetScreenInfo request and return its result as multiple |
| 538 | +values consisting of: |
| 539 | +
|
| 540 | +1. List of possible rotations and reflections |
| 541 | +2. Root window |
| 542 | +3. Timestamp |
| 543 | +4. Configuration timestamp |
| 544 | +5. Current screen size index (in the list of possible screen sizes) |
| 545 | +6. Current rotation and reflection |
| 546 | +7. List of possible screen sizes |
| 547 | +8. Current refresh rate (non-NIL only if server's protocol version is |
| 548 | + 1.1 or later) |
| 549 | +9. Sequence of refresh rate information (non-NIL only if server's |
| 550 | + protocol version is 1.1 or later) |
| 551 | +
|
| 552 | +Each screen size has in the refresh rate information sequence a |
| 553 | +corresponding refresh rate count followed by that number of possible |
| 554 | +refresh rates. |
| 555 | +For example, '(2 120 60 1 60) means that the first screen size has the |
| 556 | +two refresh rates 120 and 60, and that the second screen size has the |
| 557 | +single refresh rate 60. |
| 558 | +
|
| 559 | +If MAJOR and MINOR, which comprise the server's protocol version, are |
| 560 | +missing, this function executes the RRQueryVersion request before |
| 561 | +RRGetScreenInfo in order to, first, potentially ask the server to |
| 562 | +include, if it can, the current refresh rate and the refresh rate |
| 563 | +information sequence in its reply to the latter request, and second, |
| 564 | +determine whether this information is forthcoming. |
| 565 | +Otherwise, this function assumes MAJOR and MINOR are the result of |
| 566 | +RR-QUERY-VERSION -- failing which it will behave unreliably -- and it |
| 567 | +skips executing the RRQueryVersion request." |
492 | 568 | (let ((display (window-display window))) |
493 | | - (declare (type display display) |
494 | | - (type window window)) |
495 | | - (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (8 16 32)) |
496 | | - ((data +rr-GetScreenInfo+ ) |
497 | | - (window window)) |
498 | | - (let ((num-screens (card16-get 20)) |
499 | | - (num-rates (card16-get 28)) |
500 | | - (rates-location 0)) |
501 | | - (declare (type fixnum rates-location num-rates)) |
| 569 | + (declare (type display display)) |
| 570 | + (multiple-value-bind (major minor) |
| 571 | + (rr-maybe-query-version display major minor) |
| 572 | + (with-buffer-request-and-reply (display (randr-opcode display) nil |
| 573 | + :sizes (8 16 32)) |
| 574 | + ((data +rr-GetScreenInfo+) |
| 575 | + (window window)) |
| 576 | + (let* ((num-screens (card16-get 20)) |
| 577 | + (rate-info-length (card16-get 28)) |
| 578 | + (screen-start +replysize+) |
| 579 | + (rate-info-start (index+ screen-start (index* num-screens 8))) |
| 580 | + (has-rates (rr-has-rates major minor))) |
502 | 581 | (values |
503 | | - (make-rotation-keys (card16-get 1)) ; possible rotations, using card16, not card8 from spec. |
504 | | - (window-get 8) ;root window |
505 | | - (card32-get 12) ;timestamp |
506 | | - (card32-get 16) ;config-timestamp |
507 | | - (card16-get 22) ;size-id |
508 | | - (make-rotation-keys (card16-get 24)) ;current rotation |
509 | | - (card16-get 26) ; current rate |
510 | | - (loop :for x fixnum :from 1 :to num-screens |
511 | | - :for offset fixnum := 32 :then (+ offset 8) |
512 | | - :collect (make-screen-size (card16-get offset) |
513 | | - (card16-get (index+ offset 2)) |
514 | | - (card16-get (index+ offset 4)) |
515 | | - (card16-get (index+ offset 6))) |
516 | | - :finally (setf rates-location (+ offset 8 2))) |
517 | | - (sequence-get :format card16 :length num-rates :index rates-location :result-type result-type)))))) |
518 | | - |
| 582 | + ;; Possible rotations and reflections |
| 583 | + (make-rotation-keys (card16-get 1)) |
| 584 | + (window-get 8) ; Root window |
| 585 | + (card32-get 12) ; Timestamp |
| 586 | + (card32-get 16) ; Configuration timestamp |
| 587 | + (card16-get 22) ; Current screen size index |
| 588 | + ;; Current rotation and reflection |
| 589 | + (make-rotation-keys (card16-get 24)) |
| 590 | + (loop for i fixnum from 1 to num-screens |
| 591 | + for offset fixnum = screen-start then (+ offset 8) |
| 592 | + collect (make-screen-size (card16-get offset) |
| 593 | + (card16-get (index+ offset 2)) |
| 594 | + (card16-get (index+ offset 4)) |
| 595 | + (card16-get (index+ offset 6)))) |
| 596 | + ;; Some servers (e.g., X.Org) always reply with the current |
| 597 | + ;; refresh rate if they support it, even before receiving any |
| 598 | + ;; version query. |
| 599 | + ;; However, the refresh rate information is available only |
| 600 | + ;; after querying the version (when providing an appropriate |
| 601 | + ;; client version). |
| 602 | + (when has-rates (card16-get 26)) ; Current refresh rate |
| 603 | + (when has-rates (sequence-get :result-type result-type |
| 604 | + :format card16 |
| 605 | + :length rate-info-length |
| 606 | + :index rate-info-start)))))))) |
519 | 607 |
|
520 | 608 | ;; Version 1.2 |
521 | 609 |
|
522 | | -(defun rr-get-screen-size-range (window &optional (result-type 'list)) |
| 610 | +(defun rr-get-screen-size-range (window &key (result-type 'list)) |
523 | 611 | "Returns a sequence of minimum width, minimum height, max width, max height." |
524 | 612 | (let ((display (window-display window))) |
525 | 613 | (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (16)) |
|
546 | 634 | (card32 width-mm) |
547 | 635 | (card32 height-mm)))) |
548 | 636 |
|
549 | | -(defun rr-get-screen-resources (window &optional (result-type 'list)) |
| 637 | +(defun rr-get-screen-resources (window &key (result-type 'list)) |
550 | 638 | "" |
551 | 639 | (let ((display (window-display window))) |
552 | 640 | (declare (type display display) |
|
574 | 662 |
|
575 | 663 |
|
576 | 664 |
|
577 | | -(defun rr-get-output-info (display output config-timestamp &optional (result-type 'list)) |
| 665 | +(defun rr-get-output-info (display output config-timestamp &key (result-type 'list)) |
578 | 666 | "FIXME: indexes might be off, name not decoded properly" |
579 | 667 | (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (8 16 32)) |
580 | 668 | ((data +rr-getoutputinfo+) |
|
604 | 692 | (sequence-get :result-type 'string :format card16 :length name-length :index name-start :transform #'code-char)) |
605 | 693 | ))) |
606 | 694 |
|
607 | | -(defun rr-list-output-properties (display output &optional (result-type 'list)) |
| 695 | +(defun rr-list-output-properties (display output &key (result-type 'list)) |
608 | 696 | "Returns a list of atom properties for given display. ?keep it simple and return id's or atom-names?" |
609 | 697 | (declare (type display display) |
610 | 698 | (type card32 output)) |
|
615 | 703 | (values |
616 | 704 | (sequence-get :format card32 :result-type result-type :length num-atoms :index +replysize+ :transform #'(lambda (id) (atom-name display id))))))) |
617 | 705 |
|
618 | | -(defun rr-query-output-property (display output atom &optional (result-type 'list)) |
| 706 | +(defun rr-query-output-property (display output atom &key (result-type 'list)) |
619 | 707 | "Querys the current properties of an atom. Atom may be referenced by either id or keyword" |
620 | 708 | (let ((atom (if (typep atom 'keyword) (find-atom display atom) atom))) |
621 | 709 | (declare (type display display) |
|
630 | 718 | (boolean-get 10) ; immutable |
631 | 719 | (sequence-get :result-type result-type :index +replysize+ :length (card32-get 4)))))) |
632 | 720 |
|
633 | | -(defun rr-configure-output-property (display output atom value-list &optional (pending nil) (range nil)) |
| 721 | +(defun rr-configure-output-property (display output atom value-list &key pending range) |
634 | 722 | "Atom can be specified by either id or keyword" |
635 | 723 | (let ((atom (if (typep atom 'keyword) (find-atom display atom) atom)) |
636 | 724 | (seq (coerce value-list 'vector))) |
|
647 | 735 | ;; Spec says type is not interpreted, what use? shit, are certain property types tied to certain formats? change if necessary after get-output-property |
648 | 736 |
|
649 | 737 | ;; FIXME asynchronous match error |
650 | | -(defun rr-change-output-property (display output atom mode data &optional (atom-type 0) ) |
| 738 | +(defun rr-change-output-property (display output atom mode data &key (atom-type 0)) |
651 | 739 | "Mode may be 0-replace 1-prepend 2-append. atom-type is obtained by calling rr-get-output-property " |
652 | 740 | (let ((atom (if (typep atom 'keyword) (find-atom display atom) atom)) |
653 | 741 | (data-length (length data)) |
|
672 | 760 | (card32 output) |
673 | 761 | (card32 atom)))) |
674 | 762 |
|
675 | | -(defun rr-get-output-property (display output property &optional (type 0) (delete 0) (pending 0) (result-type 'list)) |
| 763 | +(defun rr-get-output-property (display output property &key (type 0) (delete 0) (pending 0) (result-type 'list)) |
676 | 764 | "" |
677 | 765 | (let ((atom (if (typep property 'keyword) (find-atom display property) property))) |
678 | 766 | (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (8 16 32)) |
|
744 | 832 | (card32 output) |
745 | 833 | (card32 mode))) |
746 | 834 |
|
747 | | -(defun rr-get-crtc-info (display crtc config-timestamp &optional (result-type 'list)) |
| 835 | +(defun rr-get-crtc-info (display crtc config-timestamp &key (result-type 'list)) |
748 | 836 | "" |
749 | 837 | (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (8 16 32)) |
750 | 838 | ((data +rr-getcrtcinfo+) |
|
794 | 882 | (values |
795 | 883 | (card16-get 8)))) |
796 | 884 |
|
797 | | -(defun rr-get-crtc-gamma (display crtc &optional (result-type 'list)) |
| 885 | +(defun rr-get-crtc-gamma (display crtc &key (result-type 'list)) |
798 | 886 | "Get current gamma ramps, returns 3 sequences for red, green, blue." |
799 | 887 | (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (8 16 32)) |
800 | 888 | ((data +rr-getcrtcgamma+) |
|
825 | 913 | ;; version 1.3 |
826 | 914 |
|
827 | 915 |
|
828 | | - (defun rr-get-screen-resources-current (window &optional (result-type 'list )) |
| 916 | + (defun rr-get-screen-resources-current (window &key (result-type 'list)) |
829 | 917 | "Unlike RRGetScreenResources, this merely returns the current configuration, and does not poll for hardware changes." |
830 | 918 | (let ((display (window-display window))) |
831 | 919 | (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (8 16 32)) |
|
849 | 937 | (string-get name-bytes name-start)))))) |
850 | 938 |
|
851 | 939 |
|
852 | | -;; (defun rr-set-crtc-transform (display crtc transform &optional ( filter-name nil) ( filter-parameters nil)) |
| 940 | +;; (defun rr-set-crtc-transform (display crtc transform &key filter-name filter-parameters) |
853 | 941 | ;; "FIXME:Transfrom may be a list or vector of length 9. ?perhaps allow length 6?" |
854 | 942 | ;; (let ((seq (if filter-parameters (coerce filter-parameters 'vector) nil )) |
855 | 943 | ;; (param-length (length filter-parameters)) |
|
874 | 962 | ;; ))) |
875 | 963 |
|
876 | 964 |
|
877 | | -(defun rr-get-crtc-transform (display crtc &optional (result-type 'list)) |
| 965 | +(defun rr-get-crtc-transform (display crtc &key (result-type 'list)) |
878 | 966 | "" |
879 | 967 | (with-buffer-request-and-reply (display (randr-opcode display) nil :sizes (8 16 32)) |
880 | 968 | ((data +rr-getcrtctransform+) |
|
0 commit comments