~ubuntu-branches/ubuntu/intrepid/ecl/intrepid

« back to all changes in this revision

Viewing changes to src/clx/xvidmode.lisp

  • Committer: Bazaar Package Importer
  • Author(s): Peter Van Eynde
  • Date: 2006-05-17 02:46:26 UTC
  • Revision ID: james.westby@ubuntu.com-20060517024626-lljr08ftv9g9vefl
Tags: upstream-0.9h-20060510
ImportĀ upstreamĀ versionĀ 0.9h-20060510

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;; -*- Mode: Lisp; Syntax: Common-Lisp; Package: XLIB; -*-
 
2
;;; ---------------------------------------------------------------------------
 
3
;;;     Title: XFree86 video mode extension
 
4
;;;   Created: 2003 03 28 15:28
 
5
;;;    Author: Iban Hatchondo <hatchond@labri.fr>
 
6
;;; ---------------------------------------------------------------------------
 
7
;;;  (c) copyright 2003 by Iban Hatchondo
 
8
 
 
9
;;;
 
10
;;; Permission is granted to any individual or institution to use,
 
11
;;; copy, modify, and distribute this software, provided that this
 
12
;;; complete copyright and permission notice is maintained, intact, in
 
13
;;; all copies and supporting documentation.
 
14
;;;
 
15
;;; This program is distributed in the hope that it will be useful,
 
16
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
18
;;;
 
19
 
 
20
;;; THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION
 
21
 
 
22
;;; DESCRIPTION
 
23
;;;
 
24
;;; These functions provide an interface to the server extension 
 
25
;;; XFree86-VidModeExtension which allows the video modes to be 
 
26
;;; queried, adjusted dynamically and the mode switching to be 
 
27
;;; controlled.
 
28
 
 
29
;;; [ personal notes ]
 
30
;;;
 
31
;;; The documentation on this extension is very poor, probably,
 
32
;;; because it is not an X standard nor an X project team spec.
 
33
;;; Because of that, it need to be tested on some XFree 3.3.6,
 
34
;;; and XFree 4.3.x to ensure that all request are correctly 
 
35
;;; constructed as well as to indentify any obsolete/wrong 
 
36
;;; functions I made.
 
37
 
 
38
(in-package :xlib)
 
39
 
 
40
(export '(mode-info
 
41
          mode-info-dotclock
 
42
          mode-info-hdisplay
 
43
          mode-info-hsyncstart
 
44
          mode-info-hsyncend
 
45
          mode-info-htotal
 
46
          mode-info-hskew
 
47
          mode-info-vdisplay
 
48
          mode-info-vsyncstart
 
49
          mode-info-vsyncend
 
50
          mode-info-vtotal
 
51
          mode-info-flags
 
52
          mode-info-privsize
 
53
          mode-info-private
 
54
          make-mode-info
 
55
 
 
56
          xfree86-vidmode-query-version
 
57
          xfree86-vidmode-set-client-version
 
58
          xfree86-vidmode-get-permissions
 
59
          xfree86-vidmode-mod-mode-line 
 
60
          xfree86-vidmode-get-mode-line 
 
61
          xfree86-vidmode-get-all-mode-lines
 
62
          xfree86-vidmode-add-mode-line
 
63
          xfree86-vidmode-delete-mode-line
 
64
          xfree86-vidmode-validate-mode-line
 
65
          xfree86-vidmode-get-gamma
 
66
          xfree86-vidmode-set-gamma
 
67
          xfree86-vidmode-get-gamma-ramp
 
68
          xfree86-vidmode-set-gamma-ramp     
 
69
          xfree86-vidmode-get-gamma-ramp-size
 
70
          xfree86-vidmode-lock-mode-switch
 
71
          xfree86-vidmode-switch-to-mode
 
72
          xfree86-vidmode-switch-mode
 
73
          xfree86-vidmode-select-next-mode
 
74
          xfree86-vidmode-select-prev-mode
 
75
          xfree86-vidmode-get-monitor
 
76
          xfree86-vidmode-get-viewport
 
77
          xfree86-vidmode-set-viewport
 
78
          xfree86-vidmode-get-dotclocks)
 
79
        :xlib)
 
80
 
 
81
;; current version numbers
 
82
;;
 
83
;; major 0 == uses parameter-to-wire functions in XFree86 libXxf86vm.
 
84
;; major 1 == uses parameter-to-wire functions hard-coded in xvidtune client.
 
85
;; major 2 == uses new protocol version in XFree86 4.0.
 
86
(defconstant +xf86vidmode-major-version+ 2)
 
87
(defconstant +xf86vidmode-minor-version+ 2)
 
88
 
 
89
;; requests number.
 
90
(defconstant +query-version+        0)
 
91
(defconstant +get-mode-line+        1)
 
92
(defconstant +mod-mode-line+        2)
 
93
(defconstant +switch-mode+          3)
 
94
(defconstant +get-monitor+          4)
 
95
(defconstant +lock-mode-switch+     5)
 
96
(defconstant +get-all-mode-lines+   6)
 
97
(defconstant +add-mode-line+        7)
 
98
(defconstant +delete-mode-line+     8)
 
99
(defconstant +validate-mode-line+   9)
 
100
(defconstant +switch-to-mode+      10)
 
101
(defconstant +get-viewport+        11)
 
102
(defconstant +set-viewport+        12)
 
103
 
 
104
;; new for version 2.x of this extension.
 
105
(defconstant +get-dot-clocks+      13)
 
106
(defconstant +set-client-version+  14)
 
107
(defconstant +set-gamma+           15)
 
108
(defconstant +get-gamma+           16)
 
109
(defconstant +get-gamma-ramp+      17)
 
110
(defconstant +set-gamma-ramp+      18)
 
111
(defconstant +get-gamma-ramp-size+ 19)
 
112
(defconstant +get-permisions+      20)
 
113
 
 
114
(define-extension "XFree86-VidModeExtension"
 
115
  :events (:xfree86-vidmode-notify) 
 
116
  :errors (xf86-vidmode-bad-clock 
 
117
           xf86-vidmode-bad-htimings 
 
118
           xf86-vidmode-bad-vtimings
 
119
           xf86-vidmode-mode-unsuitable
 
120
           xf86-vidmode-extension-disabled
 
121
           xf86-vidmode-client-not-local
 
122
           xf86-vidmode-zoom-locked))
 
123
 
 
124
(define-condition xf86-vidmode-bad-clock (request-error) ())
 
125
(define-condition xf86-vidmode-bad-htimings (request-error) ())
 
126
(define-condition xf86-vidmode-bad-vtimings (request-error) ())
 
127
(define-condition xf86-vidmode-mode-unsuitable (request-error) ())
 
128
(define-condition xf86-vidmode-extension-disabled (request-error) ())
 
129
(define-condition xf86-vidmode-client-not-local (request-error) ())
 
130
(define-condition xf86-vidmode-zoom-locked (request-error) ())
 
131
 
 
132
(define-error xf86-vidmode-bad-clock decode-core-error)
 
133
(define-error xf86-vidmode-bad-htimings decode-core-error)
 
134
(define-error xf86-vidmode-bad-vtimings decode-core-error)
 
135
(define-error xf86-vidmode-mode-unsuitable decode-core-error)
 
136
(define-error xf86-vidmode-extension-disabled decode-core-error)
 
137
(define-error xf86-vidmode-client-not-local decode-core-error)
 
138
(define-error xf86-vidmode-zoom-locked  decode-core-error)
 
139
 
 
140
(declare-event :XFree86-VidMode-notify
 
141
  (card16 sequence)
 
142
  (window (window event-window)) ; the root window of event screen
 
143
  (int16 state)                  ; what happend
 
144
  (int16 kind)                   ; what happend
 
145
  (boolean forced-p)             ; extents of a new region
 
146
  ((or null card32) time))       ; event timestamp
 
147
 
 
148
(defstruct mode-info
 
149
  (dotclock 0 :type card32)
 
150
  (hdisplay   0 :type card16)
 
151
  (hsyncstart 0 :type card16)
 
152
  (hsyncend   0 :type card16)
 
153
  (htotal     0 :type card16)
 
154
  (hskew      0 :type card32)
 
155
  (vdisplay   0 :type card16)
 
156
  (vsyncstart 0 :type card16)
 
157
  (vsyncend   0 :type card16)
 
158
  (vtotal     0 :type card16)
 
159
  (flags      0 :type card32)
 
160
  (privsize   0 :type card32)
 
161
  (private    nil :type sequence))
 
162
 
 
163
(defmacro vidmode-opcode (display)
 
164
  `(extension-opcode ,display "XFree86-VidModeExtension"))
 
165
 
 
166
(declaim (inline screen-position))
 
167
(defun screen-position (screen display)
 
168
  (declare (type display display)
 
169
           (type screen screen))
 
170
  (declare (clx-values position))
 
171
  (let ((position (position screen (xlib:display-roots display))))
 
172
    (if (not (numberp position))
 
173
        (error "screen ~A not found in display ~A" screen display)
 
174
        position)))
 
175
 
 
176
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
177
;;;;                                                                       ;;;;
 
178
;;;;              public XFree86-VidMode Extension routines                ;;;;
 
179
;;;;                                                                       ;;;;
 
180
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
181
 
 
182
(defun xfree86-vidmode-query-version (display)
 
183
  "Determine the version of the extension built into the server.
 
184
return two values major-version and minor-version in that order."
 
185
  (declare (type display display))
 
186
  (with-buffer-request-and-reply
 
187
      (display (vidmode-opcode display) nil :sizes 16)
 
188
    ((data +query-version+))
 
189
   (let ((major (card16-get 8))
 
190
         (minor (card16-get 10)))
 
191
     (declare (type card16 major minor))
 
192
     (when (>= major 2)
 
193
       (XFree86-VidMode-set-client-version display))
 
194
     (values major minor))))
 
195
 
 
196
(defun xfree86-vidmode-set-client-version (display)
 
197
  (declare (type display display))
 
198
  (with-buffer-request (display (vidmode-opcode display))
 
199
    (data +set-client-version+)
 
200
    (card16 +xf86vidmode-major-version+)
 
201
    (card16 +xf86vidmode-minor-version+)))
 
202
 
 
203
(defun xfree86-vidmode-get-permissions (dpy screen)
 
204
  (declare (type display dpy)
 
205
           (type screen screen))
 
206
  (with-buffer-request-and-reply
 
207
      (dpy (vidmode-opcode dpy) nil :sizes (8 16 32))
 
208
    ((data +get-permisions+)
 
209
     (card16 (screen-position screen dpy))
 
210
     (card16 0))
 
211
   (values 
 
212
    (card32-get 8))))
 
213
 
 
214
(defun xfree86-vidmode-mod-mode-line (display screen mode-line)
 
215
  "Change the settings of the current video mode provided the 
 
216
requested settings are valid (e.g. they don't exceed the 
 
217
capabilities of the monitor)."
 
218
  (declare (type display display)
 
219
           (type screen screen))
 
220
  (let* ((major (xfree86-vidmode-query-version display))
 
221
         (v (mode-info->v-card16 mode-line major)))
 
222
    (declare (type card16 major)
 
223
             (type simple-vector v))
 
224
    (with-buffer-request (display (vidmode-opcode display))
 
225
      (data +mod-mode-line+)
 
226
      (card32 (screen-position screen display))
 
227
      ((sequence :format card16 :start 2) v))))
 
228
 
 
229
(defun xfree86-vidmode-get-mode-line (display screen)
 
230
  "Query the settings for the currently selected video mode.
 
231
return a mode-info structure fields with the server answer.
 
232
If there are any server  private  values (currently  only 
 
233
applicable  to  the S3 server) the function will store it 
 
234
into the returned structure."
 
235
  (declare (clx-values mode-info)
 
236
           (type display display)
 
237
           (type screen screen))
 
238
  (let ((major (xfree86-vidmode-query-version display))
 
239
        (offset 8))
 
240
    (declare (type fixnum offset)
 
241
             (type card16 major))    
 
242
    (with-buffer-request-and-reply
 
243
        (display (vidmode-opcode display) nil :sizes (8 16 32))
 
244
      ((data +get-mode-line+)
 
245
       (card16 (screen-position screen display))
 
246
       (card16 0))
 
247
     (let ((mode-info 
 
248
            (make-mode-info
 
249
                :dotclock (card32-get offset)
 
250
                :hdisplay (card16-get (incf offset 4))
 
251
                :hsyncstart (card16-get (incf offset 2))
 
252
                :hsyncend (card16-get (incf offset 2))
 
253
                :htotal (card16-get (incf offset 2))
 
254
                :hskew (if (< major 2) 0 (card16-get (incf offset 2)))
 
255
                :vdisplay (card16-get (incf offset 2))
 
256
                :vsyncstart (card16-get (incf offset 2))
 
257
                :vsyncend (card16-get (incf offset 2))
 
258
                :vtotal (card16-get (incf offset 2))
 
259
                :flags (card32-get (incf offset (if (< major 2) 2 4)))))
 
260
           (size (card32-get (incf offset (if (< major 2) 4 16)))))
 
261
       (declare (type card32 size))
 
262
       (incf offset 4)
 
263
       (setf (mode-info-privsize mode-info) size
 
264
             (mode-info-private mode-info)
 
265
             (sequence-get :format card32 :index offset
 
266
                           :length size :result-type 'list))
 
267
       mode-info))))
 
268
 
 
269
(defun xfree86-vidmode-get-all-mode-lines (dpy screen)
 
270
  "Returns a list containing all video modes (as mode-info structure). 
 
271
The first element of the list corresponds to the current video mode."
 
272
  (declare (type display dpy)
 
273
           (type screen screen))
 
274
  (multiple-value-bind (major minor) (xfree86-vidmode-query-version dpy)
 
275
    (declare (type card16 major minor))
 
276
    (with-buffer-request-and-reply 
 
277
        (dpy (vidmode-opcode dpy) nil :sizes (8 16 32))
 
278
      ((data +get-all-mode-lines+)
 
279
       (card16 (screen-position screen dpy)))
 
280
     (values 
 
281
      ;; Note: There was a bug in the protocol implementation in versions
 
282
      ;; 0.x with x < 8 (the .private field wasn't being passed over the wire).
 
283
      ;; Check the server's version, and accept the old format if appropriate.
 
284
      (loop with bug-p = (and (= major 0) (< minor 8))
 
285
            with offset of-type fixnum = 32
 
286
            for i of-type card32 from 0 below (or (card32-get 8) 0)
 
287
            collect
 
288
             (let ((mode-info
 
289
                    (make-mode-info
 
290
                       :dotclock (card32-get offset)
 
291
                       :hdisplay (card16-get (incf offset 4))
 
292
                       :hsyncstart (card16-get (incf offset 2))
 
293
                       :hsyncend (card16-get (incf offset 2))
 
294
                       :htotal (card16-get (incf offset 2))
 
295
                       :hskew (if (< major 2) 0 (card32-get (incf offset 2)))
 
296
                       :vdisplay (card16-get (incf offset 4))
 
297
                       :vsyncstart (card16-get (incf offset 2))
 
298
                       :vsyncend (card16-get (incf offset 2))
 
299
                       :vtotal (card16-get (incf offset 2))
 
300
                       :flags (card32-get (incf offset (if (< major 2) 2 6)))))
 
301
                   (size (card32-get (incf offset (if (< major 2) 4 16)))))
 
302
                (declare (type card32 size))
 
303
                (incf offset 4)
 
304
                (when bug-p 
 
305
                  (setf size 0))
 
306
                (setf (mode-info-privsize mode-info) size
 
307
                      (mode-info-private mode-info)
 
308
                      (sequence-get :format card32 :index offset
 
309
                                    :length size :result-type 'list))
 
310
                (incf offset (* 4 size))
 
311
                mode-info))))))
 
312
 
 
313
(defun xfree86-vidmode-add-mode-line (dpy scr new &key (after (make-mode-info)))
 
314
  (declare (type display dpy)
 
315
           (type screen scr))
 
316
  (let* ((private (mode-info-private new))
 
317
         (privsize (mode-info-privsize new))
 
318
         (major (xfree86-vidmode-query-version dpy))
 
319
         (i (if (< major 2) 14 22))
 
320
         (v (make-array (- (+ (* 2 i) (* 2 privsize)) 2) :initial-element 0)))
 
321
    (declare (type card32 privsize)
 
322
             (type fixnum i)
 
323
             (type card16 major)
 
324
             (type simple-vector v))
 
325
    (mode-info->v-card16 new major :encode-private nil :data v)
 
326
    (mode-info->v-card16 after major :encode-private nil :data v :index i)
 
327
    (setf i (- (* 2 i) 2))
 
328
    ;; strore private info (sequence card32) according clx bytes order.
 
329
    (loop for card of-type card32 in private
 
330
          do (multiple-value-bind (w1 w2) (__card32->card16__ card)
 
331
               (setf (svref v (incf i)) w1
 
332
                     (svref v (incf i)) w2)))
 
333
    
 
334
    (with-buffer-request (dpy (vidmode-opcode dpy))
 
335
      (data +add-mode-line+)
 
336
      (card32 (screen-position scr dpy))
 
337
      ((sequence :format card16) v))))
 
338
 
 
339
(defun xfree86-vidmode-delete-mode-line (dpy scr mode-info)
 
340
  "Delete mode argument. The specified mode must match an existing mode. 
 
341
To be considered a match, all of the fields of the given mode-info 
 
342
structure must match, except the privsize and private fields. 
 
343
If the mode to be deleted is the current mode, a mode switch to the next 
 
344
mode will occur first. The last remaining mode can not be deleted."
 
345
  (declare (type display dpy)
 
346
           (type screen scr))
 
347
  (let* ((major (xfree86-vidmode-query-version dpy))
 
348
         (v (mode-info->v-card16 mode-info major)))
 
349
    (declare (type card16 major)
 
350
             (type simple-vector v))
 
351
    (with-buffer-request (dpy (vidmode-opcode dpy))
 
352
      (data +delete-mode-line+)
 
353
      (card32 (screen-position scr dpy))
 
354
      ((sequence :format card16) v))))
 
355
 
 
356
(defconstant +mode-status+
 
357
  '#(:MODE_BAD             ; unspecified reason 
 
358
     :MODE_ERROR           ; error condition 
 
359
     :MODE_OK              ; Mode OK 
 
360
     :MODE_HSYNC           ; hsync out of range 
 
361
     :MODE_VSYNC           ; vsync out of range 
 
362
     :MODE_H_ILLEGAL       ; mode has illegal horizontal timings 
 
363
     :MODE_V_ILLEGAL       ; mode has illegal horizontal timings 
 
364
     :MODE_BAD_WIDTH       ; requires an unsupported linepitch 
 
365
     :MODE_NO_MODE         ; no mode with a maching name 
 
366
     :MODE_NO_INTERLACE    ; interlaced mode not supported 
 
367
     :MODE_NO_DBLESCAN     ; doublescan mode not supported 
 
368
     :MODE_NO_VSCAN        ; multiscan mode not supported 
 
369
     :MODE_MEM             ; insufficient video memory 
 
370
     :MODE_VIRTUAL_X       ; mode width too large for specified virtual size 
 
371
     :MODE_VIRTUAL_Y       ; mode height too large for specified virtual size 
 
372
     :MODE_MEM_VIRT        ; insufficient video memory given virtual size 
 
373
     :MODE_NOCLOCK         ; no fixed clock available 
 
374
     :MODE_CLOCK_HIGH      ; clock required is too high 
 
375
     :MODE_CLOCK_LOW       ; clock required is too low 
 
376
     :MODE_CLOCK_RANGE     ; clock/mode isn't in a ClockRange 
 
377
     :MODE_BAD_HVALUE      ; horizontal timing was out of range 
 
378
     :MODE_BAD_VVALUE      ; vertical timing was out of range 
 
379
     :MODE_BAD_VSCAN       ; VScan value out of range 
 
380
     :MODE_HSYNC_NARROW    ; horizontal sync too narrow 
 
381
     :MODE_HSYNC_WIDE      ; horizontal sync too wide 
 
382
     :MODE_HBLANK_NARROW   ; horizontal blanking too narrow 
 
383
     :MODE_HBLANK_WIDE     ; horizontal blanking too wide 
 
384
     :MODE_VSYNC_NARROW    ; vertical sync too narrow 
 
385
     :MODE_VSYNC_WIDE      ; vertical sync too wide 
 
386
     :MODE_VBLANK_NARROW   ; vertical blanking too narrow 
 
387
     :MODE_VBLANK_WIDE     ; vertical blanking too wide 
 
388
     :MODE_PANEL           ; exceeds panel dimensions 
 
389
     :MODE_INTERLACE_WIDTH ; width too large for interlaced mode 
 
390
     :MODE_ONE_WIDTH       ; only one width is supported 
 
391
     :MODE_ONE_HEIGHT      ; only one height is supported 
 
392
     :MODE_ONE_SIZE        ; only one resolution is supported 
 
393
     ))
 
394
 
 
395
(defun decode-status-mode (status)
 
396
  (declare (type int32 status))
 
397
  (svref +mode-status+ (+ status 2)))
 
398
 
 
399
(defun xfree86-vidmode-validate-mode-line (dpy scr mode-info)
 
400
  "Checked the validity of a mode-info argument. If the specified mode can be 
 
401
used by the server (i.e. meets all the constraints placed upon a mode by the 
 
402
combination of the server, card, and monitor) the function returns :mode_ok
 
403
otherwise it returns a keyword indicating  the  reason why the mode is 
 
404
invalid."
 
405
  (declare (type display dpy)
 
406
           (type screen scr))
 
407
  (let* ((major (xfree86-vidmode-query-version dpy))
 
408
         (v (mode-info->v-card16 mode-info major)))
 
409
    (declare (type card16 major)
 
410
             (type simple-vector v))
 
411
    (with-buffer-request-and-reply
 
412
        (dpy (vidmode-opcode dpy) nil :sizes (8 16 32))
 
413
      ((data +validate-mode-line+)
 
414
       (card32 (screen-position scr dpy))
 
415
       ((sequence :format card16) v))
 
416
     (let ((status (integer-get 8)))
 
417
       (declare (type int32 status))
 
418
       (when status (decode-status-mode status))))))
 
419
 
 
420
(defun xfree86-vidmode-get-gamma (display screen)
 
421
  (declare (type display display)
 
422
           (type screen screen))
 
423
  (with-buffer-request-and-reply 
 
424
      (display (vidmode-opcode display) nil :sizes (8 16 32))
 
425
    ((data +get-gamma+)
 
426
     (card16 (screen-position screen display))
 
427
     (card16 0)
 
428
     (card32 0) (card32 0)
 
429
     (card32 0) (card32 0)
 
430
     (card32 0) (card32 0))
 
431
   (values 
 
432
    (/ (the card32 (or (card32-get 8) 0)) 10000.0)
 
433
    (/ (the card32 (or (card32-get 12) 0)) 10000.0)
 
434
    (/ (the card32 (or (card32-get 16) 0)) 10000.0))))
 
435
 
 
436
(defun xfree86-vidmode-set-gamma (dpy scr &key (red 1.0) (green 1.0) (blue 1.0))
 
437
  (declare (type display dpy)
 
438
           (type screen scr)
 
439
           (type (single-float 0.100 10.000) red green blue))
 
440
  (with-buffer-request (dpy (vidmode-opcode dpy))
 
441
    (data +set-gamma+)
 
442
    (card16 (screen-position scr dpy))
 
443
    (card16 0)
 
444
    (card32 (truncate (* red 10000)))
 
445
    (card32 (truncate (* green 10000)))
 
446
    (card32 (truncate (* blue 10000)))
 
447
    (card32 0) 
 
448
    (card32 0)
 
449
    (card32 0)))
 
450
 
 
451
(defun xfree86-vidmode-get-gamma-ramp (dpy scr size)
 
452
  (declare (type display dpy)
 
453
           (type screen scr)
 
454
           (type card16 size))
 
455
  (with-buffer-request-and-reply (dpy (vidmode-opcode dpy) nil :sizes (8 16 32))
 
456
    ((data +get-gamma-ramp+)
 
457
     (card16 (screen-position scr dpy))
 
458
     (card16 size))
 
459
   (let ((rep-size (* (the card16 (or (card16-get 8) 0)) 2)))
 
460
     (declare (type fixnum rep-size))
 
461
     (unless (zerop rep-size)
 
462
       (let* ((off1 (+ 32 rep-size (* 2 (mod rep-size 2))))
 
463
              (off2 (+ off1 rep-size (* 2 (mod rep-size 2)))))
 
464
         (declare (type fixnum off1 off2))
 
465
         (values
 
466
          (sequence-get :format card16 :length (card16-get 8)
 
467
                        :index 32 :result-type 'list)
 
468
          (sequence-get :format card16 :length (card16-get 8)
 
469
                        :index off1 :result-type 'list)
 
470
          (sequence-get :format card16 :length (card16-get 8)
 
471
                        :index off2 :result-type 'list)))))))
 
472
 
 
473
(defun xfree86-vidmode-set-gamma-ramp (dpy scr size &key red green blue)
 
474
  (declare (type (or null simple-vector) red green blue)
 
475
           (type card16 size)
 
476
           (type display dpy)
 
477
           (type screen scr))
 
478
  (with-buffer-request (dpy (vidmode-opcode dpy))
 
479
    (data +set-gamma-ramp+)
 
480
    (card16 (screen-position scr dpy))
 
481
    (card16 size)
 
482
    ((sequence :format card16) 
 
483
     (if (zerop (mod size 2))
 
484
         (concatenate 'vector red green blue)
 
485
         (concatenate 'vector red '#(0) green '#(0) blue '#(0))))))
 
486
 
 
487
(defun xfree86-vidmode-get-gamma-ramp-size (dpy screen)
 
488
  (declare (type display dpy)
 
489
           (type screen screen))
 
490
  (with-buffer-request-and-reply 
 
491
      (dpy (vidmode-opcode dpy) nil :sizes (8 16 32))
 
492
    ((data +get-gamma-ramp-size+)
 
493
     (card16 (screen-position screen dpy))
 
494
     (card16 0))
 
495
    (card16-get 8)))
 
496
 
 
497
(defun xfree86-vidmode-lock-mode-switch (display screen lock-p)
 
498
  "Allow or disallow mode switching whether the request to switch
 
499
modes comes from a call to the mode switching functions or from one 
 
500
of the mode switch key sequences (e.g. Ctrl-Alt-+ Ctrl-Alt--)."
 
501
  (declare (type display display)
 
502
           (type screen screen)
 
503
           (type boolean lock-p))
 
504
  (with-buffer-request (display (vidmode-opcode display))
 
505
    (data +lock-mode-switch+)
 
506
    (card16 (screen-position screen display))
 
507
    (card16 (if lock-p 1 0))))
 
508
 
 
509
(defun xfree86-vidmode-switch-to-mode (display screen mode-info)
 
510
  "Switch directly to the specified mode. The specified mode must match 
 
511
an existing mode. Matching is as specified in the description of the 
 
512
xf86-vidmode-delete-mode-line function."
 
513
  (declare (type display display)
 
514
           (type screen screen))
 
515
  (multiple-value-bind (major minor) (xfree86-vidmode-query-version display)
 
516
    (declare (type card16 major minor))
 
517
    ;; Note: There was a bug in the protocol implementation in versions
 
518
    ;; 0.x with x < 8 (the .private field wasn't being passed over the wire).
 
519
    ;; Check the server's version, and accept the old format if appropriate.
 
520
    (let ((bug-p (and (= major 0) (< minor 8)))
 
521
          (privsize (mode-info-privsize mode-info)))
 
522
      (declare (type boolean bug-p))
 
523
      (and bug-p (setf (mode-info-privsize mode-info) 0))
 
524
      (let ((v (mode-info->v-card16 mode-info major :encode-private bug-p)))
 
525
        (declare (type simple-vector v))
 
526
        (and bug-p (setf (mode-info-privsize mode-info) privsize))
 
527
        (with-buffer-request (display (vidmode-opcode display))
 
528
          (data +switch-to-mode+)
 
529
          (card32 (screen-position screen display))
 
530
          ((sequence :format card16) v))))))
 
531
 
 
532
(defun xfree86-vidmode-switch-mode (display screen zoom)
 
533
  "Change the video mode to next (or previous) video mode, depending 
 
534
of zoom sign. If positive, switch to next mode, else switch to prev mode."
 
535
  (declare (type display display)
 
536
           (type screen screen)
 
537
           (type card16 zoom))
 
538
  (with-buffer-request (display (vidmode-opcode display))
 
539
    (data +switch-mode+)
 
540
    (card16 (screen-position screen display))
 
541
    (card16 zoom)))
 
542
 
 
543
(defun xfree86-vidmode-select-next-mode (display screen)
 
544
  "Change the video mode to next video mode"
 
545
  (declare (type display display)
 
546
           (type screen screen))
 
547
  (with-buffer-request (display (vidmode-opcode display))
 
548
    (data +switch-mode+)
 
549
    (card16 (screen-position screen display))
 
550
    (card16 1)))
 
551
 
 
552
(defun xfree86-vidmode-select-prev-mode (display screen)
 
553
  "Change the video mode to previous video mode"
 
554
  (declare (type display display)
 
555
           (type screen screen))
 
556
  (with-buffer-request (display (vidmode-opcode display))
 
557
    (data +switch-mode+)
 
558
    (card16 (screen-position screen display))
 
559
    (card16 #xFFFF)))
 
560
 
 
561
(defun xfree86-vidmode-get-monitor (dpy screen)
 
562
  "Information known to the server about the monitor is returned. 
 
563
Multiple value return:
 
564
 hsync (list of hi, low, ...)
 
565
 vsync (list of hi, low, ...)
 
566
 vendor name
 
567
 model name 
 
568
 
 
569
The hi and low values will be equal if a discreate value was given 
 
570
in the XF86Config file."
 
571
  (declare (type display dpy)
 
572
           (type screen screen))
 
573
  (with-buffer-request-and-reply
 
574
      (dpy (vidmode-opcode dpy) nil :sizes (8 16 32))
 
575
    ((data +get-monitor+)
 
576
     (card16 (screen-position screen dpy))
 
577
     (card16 0))
 
578
   (let* ((vendor-name-length (card8-get 8))
 
579
          (model-name-length (card8-get 9))
 
580
          (pad (- 4 (mod vendor-name-length 4)))
 
581
          (nhsync (card8-get 10))
 
582
          (nvsync (card8-get 11))
 
583
          (vindex (+ 32 (* 4 (+ nhsync nvsync))))
 
584
          (mindex (+ vindex vendor-name-length pad))
 
585
          (hsync (sequence-get :length nhsync :index 32 :result-type 'list))
 
586
          (vsync (sequence-get :length nvsync :index (+ 32 (* nhsync 4))
 
587
                               :result-type 'list)))
 
588
     (declare (type card8 nhsync nvsync vendor-name-length model-name-length)
 
589
              (type fixnum pad vindex mindex))
 
590
     (values 
 
591
      (loop for i of-type card32 in hsync
 
592
            collect (/ (ldb (byte 16 0) i) 100.)
 
593
            collect (/ (ldb (byte 32 16) i) 100.))
 
594
      (loop for i of-type card32 in vsync
 
595
            collect (/ (ldb (byte 16 0) i) 100.)
 
596
            collect (/ (ldb (byte 32 16) i) 100.))
 
597
      (string-get vendor-name-length vindex)
 
598
      (string-get model-name-length mindex)))))
 
599
 
 
600
(defun xfree86-vidmode-get-viewport (dpy screen)
 
601
  "Query the location of the upper left corner of the viewport into 
 
602
the virtual screen. The upper left coordinates will be returned as 
 
603
a multiple value."
 
604
  (declare (type display dpy)
 
605
           (type screen screen))
 
606
  (multiple-value-bind (major minor) (xfree86-vidmode-query-version dpy)
 
607
    (declare (type card16 major minor))
 
608
    ;; Note: There was a bug in the protocol implementation in versions
 
609
    ;; 0.x with x < 8 (no reply was sent, so the client would hang)
 
610
    ;; Check the server's version, and don't wait for a reply with older
 
611
    ;; versions.
 
612
    (when (and (= major 0) (< minor 8))
 
613
      (format cl:*error-output* 
 
614
              "running an old version ~a ~a~%"
 
615
              major minor)
 
616
      (return-from xfree86-vidmode-get-viewport nil))
 
617
    (with-buffer-request-and-reply 
 
618
        (dpy (vidmode-opcode dpy) nil :sizes (8 16 32))
 
619
      ((data +get-viewport+)
 
620
       (card16 (screen-position screen dpy))
 
621
       (card16 0))
 
622
     (values
 
623
      (card32-get 8)
 
624
      (card32-get 12)))))
 
625
       
 
626
(defun xfree86-vidmode-set-viewport (dpy screen &key (x 0) (y 0))
 
627
  "Set upper left corner of the viewport into the virtual screen to the 
 
628
x and y keyword parameters value (zero will be theire default value)."
 
629
  (declare (type display dpy)
 
630
           (type screen screen)
 
631
           (type card32 x y))
 
632
  (with-buffer-request (dpy (vidmode-opcode dpy))
 
633
    (data +set-viewport+)
 
634
    (card16 (screen-position screen dpy))
 
635
    (card16 0)
 
636
    (card32 x)
 
637
    (card32 y)))
 
638
 
 
639
(defun xfree86-vidmode-get-dotclocks (dpy screen)
 
640
  "Returns as a multiple value return the server dotclock informations:
 
641
 flags
 
642
 maxclocks
 
643
 clock list"
 
644
  (declare (type display dpy)
 
645
           (type screen screen))
 
646
  (with-buffer-request-and-reply 
 
647
      (dpy (vidmode-opcode dpy) nil :sizes (8 16 32))
 
648
    ((data +get-dot-clocks+)
 
649
     (card16 (screen-position screen dpy))
 
650
     (card16 0))
 
651
   (values
 
652
    (card32-get 8)  ; flags
 
653
    (card32-get 16) ; max clocks
 
654
    (sequence-get :length (card32-get 12) :format card32
 
655
                  :index 32 :result-type 'list))))
 
656
 
 
657
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
658
;;;;                                                                       ;;;;
 
659
;;;;                       private utility routines                        ;;;;
 
660
;;;;                                                                       ;;;;
 
661
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
662
 
 
663
(defun mode-info->v-card16
 
664
    (mode-info major &key (encode-private t) (index 0) data)
 
665
  (declare (type integer index)
 
666
           (type card16 major)
 
667
           (type boolean encode-private)
 
668
           (type (or null simple-vector) data))
 
669
  (let ((dotclock (mode-info-dotclock mode-info))
 
670
        (hdisplay (mode-info-hdisplay mode-info))
 
671
        (hsyncstart (mode-info-hsyncstart mode-info))
 
672
        (hsyncend (mode-info-hsyncend mode-info))
 
673
        (htotal (mode-info-htotal mode-info))
 
674
        (hskew (mode-info-hskew mode-info))
 
675
        (vdisplay (mode-info-vdisplay mode-info))
 
676
        (vsyncstart (mode-info-vsyncstart mode-info))
 
677
        (vsyncend (mode-info-vsyncend mode-info))
 
678
        (vtotal (mode-info-vtotal mode-info))
 
679
        (flags (mode-info-flags mode-info))
 
680
        (privsize (mode-info-privsize mode-info))
 
681
        (private (mode-info-private mode-info)))
 
682
    (declare (type card16 hdisplay hsyncstart hsyncend htotal hskew)
 
683
             (type card16 vdisplay vsyncstart vsyncend vtotal)
 
684
             (type card32 dotclock flags privsize)
 
685
             (type (or null sequence) private))
 
686
    (let* ((size (+ (if (< major 2) 14 22) (* privsize 2)))
 
687
           (v (or data (make-array size :initial-element 0))))      
 
688
      (declare (type fixnum size)
 
689
               (type simple-vector v))
 
690
      ;; store dotclock (card32) according clx bytes order.
 
691
      (multiple-value-bind (w1 w2) (__card32->card16__ dotclock)
 
692
        (setf (svref v index) w1
 
693
              (svref v (incf index)) w2))
 
694
      (setf (svref v (incf index)) hdisplay
 
695
            (svref v (incf index)) hsyncstart
 
696
            (svref v (incf index)) hsyncend
 
697
            (svref v (incf index)) htotal)
 
698
      (unless (< major 2)
 
699
        (setf (svref v (incf index)) hskew))
 
700
      (setf (svref v (incf index)) vdisplay
 
701
            (svref v (incf index)) vsyncstart
 
702
            (svref v (incf index)) vsyncend
 
703
            (svref v (incf index)) vtotal)
 
704
      (unless (< major 2)
 
705
        (incf index))
 
706
      ;; strore flags (card32) according clx bytes order.
 
707
      (multiple-value-bind (w1 w2) (__card32->card16__ flags)
 
708
        (setf (svref v (incf index)) w1
 
709
              (svref v (incf index)) w2))
 
710
      ;; strore privsize (card32) according clx bytes order.
 
711
      (multiple-value-bind (w1 w2) (__card32->card16__ privsize)
 
712
        (setf (svref v (incf index)) w1
 
713
              (svref v (incf index)) w2))
 
714
      ;; reserverd byte32 1 2 3
 
715
      (unless (< major 2) (incf index 6))
 
716
      ;; strore private info (sequence card32) according clx bytes order.
 
717
      (when encode-private
 
718
        (loop for i of-type int32 in private
 
719
              do (multiple-value-bind (w1 w2) (__card32->card16__ i)
 
720
                   (setf (svref v (incf index)) w1
 
721
                         (svref v (incf index)) w2))))
 
722
      v)))
 
723
 
 
724
(declaim (inline __card32->card16__))
 
725
(defun __card32->card16__ (i)
 
726
  (declare (type card32 i))
 
727
  #+clx-little-endian
 
728
  (progn (values (ldb (byte 16 0) i) (ldb (byte 32 16) i)))
 
729
  #-clx-little-endian
 
730
  (progn (values (ldb (byte 32 16) i) (ldb (byte 16 0) i))))