File: | hw/kdrive/src/kdrive.c |
Location: | line 404, column 9 |
Description: | Value stored to 'arg' is never read |
1 | /* |
2 | * Copyright © 1999 Keith Packard |
3 | * |
4 | * Permission to use, copy, modify, distribute, and sell this software and its |
5 | * documentation for any purpose is hereby granted without fee, provided that |
6 | * the above copyright notice appear in all copies and that both that |
7 | * copyright notice and this permission notice appear in supporting |
8 | * documentation, and that the name of Keith Packard not be used in |
9 | * advertising or publicity pertaining to distribution of the software without |
10 | * specific, written prior permission. Keith Packard makes no |
11 | * representations about the suitability of this software for any purpose. It |
12 | * is provided "as is" without express or implied warranty. |
13 | * |
14 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
16 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
20 | * PERFORMANCE OF THIS SOFTWARE. |
21 | */ |
22 | |
23 | #ifdef HAVE_CONFIG_H1 |
24 | #include <kdrive-config.h> |
25 | #endif |
26 | #include "kdrive.h" |
27 | #include <mivalidate.h> |
28 | #include <dixstruct.h> |
29 | #include "privates.h" |
30 | #ifdef RANDR1 |
31 | #include <randrstr.h> |
32 | #endif |
33 | |
34 | #ifdef XV1 |
35 | #include "kxv.h" |
36 | #endif |
37 | |
38 | #ifdef DPMSExtension1 |
39 | #include "dpmsproc.h" |
40 | #endif |
41 | |
42 | #ifdef HAVE_EXECINFO_H1 |
43 | #include <execinfo.h> |
44 | #endif |
45 | |
46 | #include <signal.h> |
47 | |
48 | typedef struct _kdDepths { |
49 | CARD8 depth; |
50 | CARD8 bpp; |
51 | } KdDepths; |
52 | |
53 | KdDepths kdDepths[] = { |
54 | {1, 1}, |
55 | {4, 4}, |
56 | {8, 8}, |
57 | {15, 16}, |
58 | {16, 16}, |
59 | {24, 32}, |
60 | {32, 32} |
61 | }; |
62 | |
63 | #define NUM_KD_DEPTHS(sizeof (kdDepths) / sizeof (kdDepths[0])) (sizeof (kdDepths) / sizeof (kdDepths[0])) |
64 | |
65 | #define KD_DEFAULT_BUTTONS5 5 |
66 | |
67 | DevPrivateKeyRec kdScreenPrivateKeyRec; |
68 | unsigned long kdGeneration; |
69 | |
70 | Bool kdVideoTest; |
71 | unsigned long kdVideoTestTime; |
72 | Bool kdEmulateMiddleButton; |
73 | Bool kdRawPointerCoordinates; |
74 | Bool kdDisableZaphod; |
75 | Bool kdAllowZap; |
76 | Bool kdEnabled; |
77 | int kdSubpixelOrder; |
78 | int kdVirtualTerminal = -1; |
79 | Bool kdSwitchPending; |
80 | char *kdSwitchCmd; |
81 | DDXPointRec kdOrigin; |
82 | Bool kdHasPointer = FALSE0; |
83 | Bool kdHasKbd = FALSE0; |
84 | |
85 | static Bool kdCaughtSignal = FALSE0; |
86 | |
87 | /* |
88 | * Carry arguments from InitOutput through driver initialization |
89 | * to KdScreenInit |
90 | */ |
91 | |
92 | KdOsFuncs *kdOsFuncs; |
93 | |
94 | void |
95 | KdDisableScreen(ScreenPtr pScreen) |
96 | { |
97 | KdScreenPriv(pScreen)KdPrivScreenPtr pScreenPriv = ((KdPrivScreenPtr) dixLookupPrivate (&(pScreen)->devPrivates, (&kdScreenPrivateKeyRec) )); |
98 | |
99 | if (!pScreenPriv->enabled) |
100 | return; |
101 | if (!pScreenPriv->closed) |
102 | SetRootClip(pScreen, ROOT_CLIP_NONE); |
103 | KdDisableColormap(pScreen); |
104 | if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel) |
105 | (*pScreenPriv->card->cfuncs->disableAccel) (pScreen); |
106 | if (!pScreenPriv->screen->softCursor && |
107 | pScreenPriv->card->cfuncs->disableCursor) |
108 | (*pScreenPriv->card->cfuncs->disableCursor) (pScreen); |
109 | if (pScreenPriv->card->cfuncs->dpms) |
110 | (*pScreenPriv->card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL0); |
111 | pScreenPriv->enabled = FALSE0; |
112 | if (pScreenPriv->card->cfuncs->disable) |
113 | (*pScreenPriv->card->cfuncs->disable) (pScreen); |
114 | } |
115 | |
116 | static void |
117 | KdDoSwitchCmd(const char *reason) |
118 | { |
119 | if (kdSwitchCmd) { |
120 | char *command; |
121 | int ret; |
122 | |
123 | if (asprintf(&command, "%s %s", kdSwitchCmd, reason) == -1) |
124 | return; |
125 | |
126 | /* Ignore the return value from system; I'm not sure |
127 | * there's anything more useful to be done when |
128 | * it fails |
129 | */ |
130 | ret = system(command); |
131 | (void) ret; |
132 | free(command); |
133 | } |
134 | } |
135 | |
136 | void |
137 | KdSuspend(void) |
138 | { |
139 | KdCardInfo *card; |
140 | KdScreenInfo *screen; |
141 | |
142 | if (kdEnabled) { |
143 | for (card = kdCardInfo; card; card = card->next) { |
144 | for (screen = card->screenList; screen; screen = screen->next) |
145 | if (screen->mynum == card->selected && screen->pScreen) |
146 | KdDisableScreen(screen->pScreen); |
147 | if (card->driver && card->cfuncs->restore) |
148 | (*card->cfuncs->restore) (card); |
149 | } |
150 | KdDisableInput(); |
151 | KdDoSwitchCmd("suspend"); |
152 | } |
153 | } |
154 | |
155 | void |
156 | KdDisableScreens(void) |
157 | { |
158 | KdSuspend(); |
159 | if (kdEnabled) { |
160 | if (kdOsFuncs->Disable) |
161 | (*kdOsFuncs->Disable) (); |
162 | kdEnabled = FALSE0; |
163 | } |
164 | } |
165 | |
166 | Bool |
167 | KdEnableScreen(ScreenPtr pScreen) |
168 | { |
169 | KdScreenPriv(pScreen)KdPrivScreenPtr pScreenPriv = ((KdPrivScreenPtr) dixLookupPrivate (&(pScreen)->devPrivates, (&kdScreenPrivateKeyRec) )); |
170 | |
171 | if (pScreenPriv->enabled) |
172 | return TRUE1; |
173 | if (pScreenPriv->card->cfuncs->enable) |
174 | if (!(*pScreenPriv->card->cfuncs->enable) (pScreen)) |
175 | return FALSE0; |
176 | pScreenPriv->enabled = TRUE1; |
177 | pScreenPriv->dpmsState = KD_DPMS_NORMAL0; |
178 | pScreenPriv->card->selected = pScreenPriv->screen->mynum; |
179 | if (!pScreenPriv->screen->softCursor && |
180 | pScreenPriv->card->cfuncs->enableCursor) |
181 | (*pScreenPriv->card->cfuncs->enableCursor) (pScreen); |
182 | if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel) |
183 | (*pScreenPriv->card->cfuncs->enableAccel) (pScreen); |
184 | KdEnableColormap(pScreen); |
185 | SetRootClip(pScreen, ROOT_CLIP_FULL); |
186 | if (pScreenPriv->card->cfuncs->dpms) |
187 | (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState); |
188 | return TRUE1; |
189 | } |
190 | |
191 | void |
192 | KdResume(void) |
193 | { |
194 | KdCardInfo *card; |
195 | KdScreenInfo *screen; |
196 | |
197 | if (kdEnabled) { |
198 | KdDoSwitchCmd("resume"); |
199 | for (card = kdCardInfo; card; card = card->next) { |
200 | if (card->cfuncs->preserve) |
201 | (*card->cfuncs->preserve) (card); |
202 | for (screen = card->screenList; screen; screen = screen->next) |
203 | if (screen->mynum == card->selected && screen->pScreen) |
204 | KdEnableScreen(screen->pScreen); |
205 | } |
206 | KdEnableInput(); |
207 | KdReleaseAllKeys(); |
208 | } |
209 | } |
210 | |
211 | void |
212 | KdEnableScreens(void) |
213 | { |
214 | if (!kdEnabled) { |
215 | kdEnabled = TRUE1; |
216 | if (kdOsFuncs->Enable) |
217 | (*kdOsFuncs->Enable) (); |
218 | } |
219 | KdResume(); |
220 | } |
221 | |
222 | void |
223 | KdProcessSwitch(void) |
224 | { |
225 | if (kdEnabled) |
226 | KdDisableScreens(); |
227 | else |
228 | KdEnableScreens(); |
229 | } |
230 | |
231 | void |
232 | AbortDDX(enum ExitCode error) |
233 | { |
234 | KdDisableScreens(); |
235 | if (kdOsFuncs) { |
236 | if (kdEnabled && kdOsFuncs->Disable) |
237 | (*kdOsFuncs->Disable) (); |
238 | if (kdOsFuncs->Fini) |
239 | (*kdOsFuncs->Fini) (); |
240 | KdDoSwitchCmd("stop"); |
241 | } |
242 | |
243 | if (kdCaughtSignal) |
244 | OsAbort(); |
245 | } |
246 | |
247 | void |
248 | ddxGiveUp(enum ExitCode error) |
249 | { |
250 | AbortDDX(error); |
251 | } |
252 | |
253 | Bool kdDumbDriver; |
254 | Bool kdSoftCursor; |
255 | |
256 | const char * |
257 | KdParseFindNext(const char *cur, const char *delim, char *save, char *last) |
258 | { |
259 | while (*cur && !strchr(delim, *cur)) { |
260 | *save++ = *cur++; |
261 | } |
262 | *save = 0; |
263 | *last = *cur; |
264 | if (*cur) |
265 | cur++; |
266 | return cur; |
267 | } |
268 | |
269 | Rotation |
270 | KdAddRotation(Rotation a, Rotation b) |
271 | { |
272 | Rotation rotate = (a & RR_Rotate_All(1|2|4|8)) * (b & RR_Rotate_All(1|2|4|8)); |
273 | Rotation reflect = (a & RR_Reflect_All(16|32)) ^ (b & RR_Reflect_All(16|32)); |
274 | |
275 | if (rotate > RR_Rotate_2708) |
276 | rotate /= (RR_Rotate_2708 * RR_Rotate_902); |
277 | return reflect | rotate; |
278 | } |
279 | |
280 | Rotation |
281 | KdSubRotation(Rotation a, Rotation b) |
282 | { |
283 | Rotation rotate = (a & RR_Rotate_All(1|2|4|8)) * 16 / (b & RR_Rotate_All(1|2|4|8)); |
284 | Rotation reflect = (a & RR_Reflect_All(16|32)) ^ (b & RR_Reflect_All(16|32)); |
285 | |
286 | if (rotate > RR_Rotate_2708) |
287 | rotate /= (RR_Rotate_2708 * RR_Rotate_902); |
288 | return reflect | rotate; |
289 | } |
290 | |
291 | void |
292 | KdParseScreen(KdScreenInfo * screen, const char *arg) |
293 | { |
294 | char delim; |
295 | char save[1024]; |
296 | int i; |
297 | int pixels, mm; |
298 | |
299 | screen->dumb = kdDumbDriver; |
300 | screen->softCursor = kdSoftCursor; |
301 | screen->origin = kdOrigin; |
302 | screen->randr = RR_Rotate_01; |
303 | screen->x = 0; |
304 | screen->y = 0; |
305 | screen->width = 0; |
306 | screen->height = 0; |
307 | screen->width_mm = 0; |
308 | screen->height_mm = 0; |
309 | screen->subpixel_order = kdSubpixelOrder; |
310 | screen->rate = 0; |
311 | screen->fb.depth = 0; |
312 | if (!arg) |
313 | return; |
314 | if (strlen(arg) >= sizeof(save)) |
315 | return; |
316 | |
317 | for (i = 0; i < 2; i++) { |
318 | arg = KdParseFindNext(arg, "x/+@XY", save, &delim); |
319 | if (!save[0]) |
320 | return; |
321 | |
322 | pixels = atoi(save); |
323 | mm = 0; |
324 | |
325 | if (delim == '/') { |
326 | arg = KdParseFindNext(arg, "x+@XY", save, &delim); |
327 | if (!save[0]) |
328 | return; |
329 | mm = atoi(save); |
330 | } |
331 | |
332 | if (i == 0) { |
333 | screen->width = pixels; |
334 | screen->width_mm = mm; |
335 | } |
336 | else { |
337 | screen->height = pixels; |
338 | screen->height_mm = mm; |
339 | } |
340 | if (delim != 'x' && delim != '+' && delim != '@' && |
341 | delim != 'X' && delim != 'Y' && |
342 | (delim != '\0' || i == 0)) |
343 | return; |
344 | } |
345 | |
346 | kdOrigin.x += screen->width; |
347 | kdOrigin.y = 0; |
348 | kdDumbDriver = FALSE0; |
349 | kdSoftCursor = FALSE0; |
350 | kdSubpixelOrder = SubPixelUnknown0; |
351 | |
352 | if (delim == '+') { |
353 | arg = KdParseFindNext(arg, "+@xXY", save, &delim); |
354 | if (save[0]) |
355 | screen->x = atoi(save); |
356 | } |
357 | |
358 | if (delim == '+') { |
359 | arg = KdParseFindNext(arg, "@xXY", save, &delim); |
360 | if (save[0]) |
361 | screen->y = atoi(save); |
362 | } |
363 | |
364 | if (delim == '@') { |
365 | arg = KdParseFindNext(arg, "xXY", save, &delim); |
366 | if (save[0]) { |
367 | int rotate = atoi(save); |
368 | |
369 | if (rotate < 45) |
370 | screen->randr = RR_Rotate_01; |
371 | else if (rotate < 135) |
372 | screen->randr = RR_Rotate_902; |
373 | else if (rotate < 225) |
374 | screen->randr = RR_Rotate_1804; |
375 | else if (rotate < 315) |
376 | screen->randr = RR_Rotate_2708; |
377 | else |
378 | screen->randr = RR_Rotate_01; |
379 | } |
380 | } |
381 | if (delim == 'X') { |
382 | arg = KdParseFindNext(arg, "xY", save, &delim); |
383 | screen->randr |= RR_Reflect_X16; |
384 | } |
385 | |
386 | if (delim == 'Y') { |
387 | arg = KdParseFindNext(arg, "xY", save, &delim); |
388 | screen->randr |= RR_Reflect_Y32; |
389 | } |
390 | |
391 | arg = KdParseFindNext(arg, "x/,", save, &delim); |
392 | if (save[0]) { |
393 | screen->fb.depth = atoi(save); |
394 | if (delim == '/') { |
395 | arg = KdParseFindNext(arg, "x,", save, &delim); |
396 | if (save[0]) |
397 | screen->fb.bitsPerPixel = atoi(save); |
398 | } |
399 | else |
400 | screen->fb.bitsPerPixel = 0; |
401 | } |
402 | |
403 | if (delim == 'x') { |
404 | arg = KdParseFindNext(arg, "x", save, &delim); |
Value stored to 'arg' is never read | |
405 | if (save[0]) |
406 | screen->rate = atoi(save); |
407 | } |
408 | } |
409 | |
410 | /* |
411 | * Mouse argument syntax: |
412 | * |
413 | * device,protocol,options... |
414 | * |
415 | * Options are any of: |
416 | * 1-5 n button mouse |
417 | * 2button emulate middle button |
418 | * {NMO} Reorder buttons |
419 | */ |
420 | |
421 | void |
422 | KdParseRgba(char *rgba) |
423 | { |
424 | if (!strcmp(rgba, "rgb")) |
425 | kdSubpixelOrder = SubPixelHorizontalRGB1; |
426 | else if (!strcmp(rgba, "bgr")) |
427 | kdSubpixelOrder = SubPixelHorizontalBGR2; |
428 | else if (!strcmp(rgba, "vrgb")) |
429 | kdSubpixelOrder = SubPixelVerticalRGB3; |
430 | else if (!strcmp(rgba, "vbgr")) |
431 | kdSubpixelOrder = SubPixelVerticalBGR4; |
432 | else if (!strcmp(rgba, "none")) |
433 | kdSubpixelOrder = SubPixelNone5; |
434 | else |
435 | kdSubpixelOrder = SubPixelUnknown0; |
436 | } |
437 | |
438 | void |
439 | KdUseMsg(void) |
440 | { |
441 | ErrorF("\nTinyX Device Dependent Usage:\n"); |
442 | ErrorF |
443 | ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][+[-]XOFFSET][+[-]YOFFSET][@ROTATION][X][Y][xDEPTH/BPP[xFREQ]] Specify screen characteristics\n"); |
444 | ErrorF |
445 | ("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n"); |
446 | ErrorF |
447 | ("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n"); |
448 | ErrorF |
449 | ("-keybd driver [,,options] Specify the keyboard driver and its options\n"); |
450 | ErrorF("-zaphod Disable cursor screen switching\n"); |
451 | ErrorF("-2button Emulate 3 button mouse\n"); |
452 | ErrorF("-3button Disable 3 button mouse emulation\n"); |
453 | ErrorF |
454 | ("-rawcoord Don't transform pointer coordinates on rotation\n"); |
455 | ErrorF("-dumb Disable hardware acceleration\n"); |
456 | ErrorF("-softCursor Force software cursor\n"); |
457 | ErrorF("-videoTest Start the server, pause momentarily and exit\n"); |
458 | ErrorF |
459 | ("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n"); |
460 | ErrorF("-switchCmd Command to execute on vt switch\n"); |
461 | ErrorF("-zap Terminate server on Ctrl+Alt+Backspace\n"); |
462 | ErrorF |
463 | ("vtxx Use virtual terminal xx instead of the next available\n"); |
464 | } |
465 | |
466 | int |
467 | KdProcessArgument(int argc, char **argv, int i) |
468 | { |
469 | KdCardInfo *card; |
470 | KdScreenInfo *screen; |
471 | |
472 | if (!strcmp(argv[i], "-screen")) { |
473 | if ((i + 1) < argc) { |
474 | card = KdCardInfoLast(); |
475 | if (!card) { |
476 | InitCard(0); |
477 | card = KdCardInfoLast(); |
478 | } |
479 | if (card) { |
480 | screen = KdScreenInfoAdd(card); |
481 | KdParseScreen(screen, argv[i + 1]); |
482 | } |
483 | else |
484 | ErrorF("No matching card found!\n"); |
485 | } |
486 | else |
487 | UseMsg(); |
488 | return 2; |
489 | } |
490 | if (!strcmp(argv[i], "-zaphod")) { |
491 | kdDisableZaphod = TRUE1; |
492 | return 1; |
493 | } |
494 | if (!strcmp(argv[i], "-zap")) { |
495 | kdAllowZap = TRUE1; |
496 | return 1; |
497 | } |
498 | if (!strcmp(argv[i], "-3button")) { |
499 | kdEmulateMiddleButton = FALSE0; |
500 | return 1; |
501 | } |
502 | if (!strcmp(argv[i], "-2button")) { |
503 | kdEmulateMiddleButton = TRUE1; |
504 | return 1; |
505 | } |
506 | if (!strcmp(argv[i], "-rawcoord")) { |
507 | kdRawPointerCoordinates = 1; |
508 | return 1; |
509 | } |
510 | if (!strcmp(argv[i], "-dumb")) { |
511 | kdDumbDriver = TRUE1; |
512 | return 1; |
513 | } |
514 | if (!strcmp(argv[i], "-softCursor")) { |
515 | kdSoftCursor = TRUE1; |
516 | return 1; |
517 | } |
518 | if (!strcmp(argv[i], "-videoTest")) { |
519 | kdVideoTest = TRUE1; |
520 | return 1; |
521 | } |
522 | if (!strcmp(argv[i], "-origin")) { |
523 | if ((i + 1) < argc) { |
524 | char *x = argv[i + 1]; |
525 | char *y = strchr(x, ','); |
526 | |
527 | if (x) |
528 | kdOrigin.x = atoi(x); |
529 | else |
530 | kdOrigin.x = 0; |
531 | if (y) |
532 | kdOrigin.y = atoi(y + 1); |
533 | else |
534 | kdOrigin.y = 0; |
535 | } |
536 | else |
537 | UseMsg(); |
538 | return 2; |
539 | } |
540 | if (!strcmp(argv[i], "-rgba")) { |
541 | if ((i + 1) < argc) |
542 | KdParseRgba(argv[i + 1]); |
543 | else |
544 | UseMsg(); |
545 | return 2; |
546 | } |
547 | if (!strcmp(argv[i], "-switchCmd")) { |
548 | if ((i + 1) < argc) |
549 | kdSwitchCmd = argv[i + 1]; |
550 | else |
551 | UseMsg(); |
552 | return 2; |
553 | } |
554 | if (!strncmp(argv[i], "vt", 2) && |
555 | sscanf(argv[i], "vt%2d", &kdVirtualTerminal) == 1) { |
556 | return 1; |
557 | } |
558 | if (!strcmp(argv[i], "-mouse") || !strcmp(argv[i], "-pointer")) { |
559 | if (i + 1 >= argc) |
560 | UseMsg(); |
561 | KdAddConfigPointer(argv[i + 1]); |
562 | kdHasPointer = TRUE1; |
563 | return 2; |
564 | } |
565 | if (!strcmp(argv[i], "-keybd")) { |
566 | if (i + 1 >= argc) |
567 | UseMsg(); |
568 | KdAddConfigKeyboard(argv[i + 1]); |
569 | kdHasKbd = TRUE1; |
570 | return 2; |
571 | } |
572 | |
573 | return 0; |
574 | } |
575 | |
576 | /* |
577 | * These are getting tossed in here until I can think of where |
578 | * they really belong |
579 | */ |
580 | |
581 | void |
582 | KdOsInit(KdOsFuncs * pOsFuncs) |
583 | { |
584 | kdOsFuncs = pOsFuncs; |
585 | if (pOsFuncs) { |
586 | if (serverGeneration == 1) { |
587 | KdDoSwitchCmd("start"); |
588 | if (pOsFuncs->Init) |
589 | (*pOsFuncs->Init) (); |
590 | } |
591 | } |
592 | } |
593 | |
594 | Bool |
595 | KdAllocatePrivates(ScreenPtr pScreen) |
596 | { |
597 | KdPrivScreenPtr pScreenPriv; |
598 | |
599 | if (kdGeneration != serverGeneration) |
600 | kdGeneration = serverGeneration; |
601 | |
602 | if (!dixRegisterPrivateKey(&kdScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) |
603 | return FALSE0; |
604 | |
605 | pScreenPriv = calloc(1, sizeof(*pScreenPriv)); |
606 | if (!pScreenPriv) |
607 | return FALSE0; |
608 | KdSetScreenPriv(pScreen, pScreenPriv)dixSetPrivate(&(pScreen)->devPrivates, (&kdScreenPrivateKeyRec ), pScreenPriv); |
609 | return TRUE1; |
610 | } |
611 | |
612 | Bool |
613 | KdCreateScreenResources(ScreenPtr pScreen) |
614 | { |
615 | KdScreenPriv(pScreen)KdPrivScreenPtr pScreenPriv = ((KdPrivScreenPtr) dixLookupPrivate (&(pScreen)->devPrivates, (&kdScreenPrivateKeyRec) )); |
616 | KdCardInfo *card = pScreenPriv->card; |
617 | Bool ret; |
618 | |
619 | pScreen->CreateScreenResources = pScreenPriv->CreateScreenResources; |
620 | if (pScreen->CreateScreenResources) |
621 | ret = (*pScreen->CreateScreenResources) (pScreen); |
622 | else |
623 | ret = -1; |
624 | pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; |
625 | pScreen->CreateScreenResources = KdCreateScreenResources; |
626 | if (ret && card->cfuncs->createRes) |
627 | ret = (*card->cfuncs->createRes) (pScreen); |
628 | return ret; |
629 | } |
630 | |
631 | Bool |
632 | KdCloseScreen(ScreenPtr pScreen) |
633 | { |
634 | KdScreenPriv(pScreen)KdPrivScreenPtr pScreenPriv = ((KdPrivScreenPtr) dixLookupPrivate (&(pScreen)->devPrivates, (&kdScreenPrivateKeyRec) )); |
635 | KdScreenInfo *screen = pScreenPriv->screen; |
636 | KdCardInfo *card = pScreenPriv->card; |
637 | Bool ret; |
638 | |
639 | if (card->cfuncs->closeScreen) |
640 | (*card->cfuncs->closeScreen)(pScreen); |
641 | |
642 | pScreenPriv->closed = TRUE1; |
643 | pScreen->CloseScreen = pScreenPriv->CloseScreen; |
644 | |
645 | if (pScreen->CloseScreen) |
646 | ret = (*pScreen->CloseScreen) (pScreen); |
647 | else |
648 | ret = TRUE1; |
649 | |
650 | if (pScreenPriv->dpmsState != KD_DPMS_NORMAL0) |
651 | (*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL0); |
652 | |
653 | if (screen->mynum == card->selected) |
654 | KdDisableScreen(pScreen); |
655 | |
656 | /* |
657 | * Restore video hardware when last screen is closed |
658 | */ |
659 | if (screen == card->screenList) { |
660 | if (kdEnabled && card->cfuncs->restore) |
661 | (*card->cfuncs->restore) (card); |
662 | } |
663 | |
664 | if (!pScreenPriv->screen->dumb && card->cfuncs->finiAccel) |
665 | (*card->cfuncs->finiAccel) (pScreen); |
666 | |
667 | if (!pScreenPriv->screen->softCursor && card->cfuncs->finiCursor) |
668 | (*card->cfuncs->finiCursor) (pScreen); |
669 | |
670 | if (card->cfuncs->scrfini) |
671 | (*card->cfuncs->scrfini) (screen); |
672 | |
673 | /* |
674 | * Clean up card when last screen is closed, DIX closes them in |
675 | * reverse order, thus we check for when the first in the list is closed |
676 | */ |
677 | if (screen == card->screenList) { |
678 | if (card->cfuncs->cardfini) |
679 | (*card->cfuncs->cardfini) (card); |
680 | /* |
681 | * Clean up OS when last card is closed |
682 | */ |
683 | if (card == kdCardInfo) { |
684 | if (kdEnabled) { |
685 | kdEnabled = FALSE0; |
686 | if (kdOsFuncs->Disable) |
687 | (*kdOsFuncs->Disable) (); |
688 | } |
689 | } |
690 | } |
691 | |
692 | pScreenPriv->screen->pScreen = 0; |
693 | |
694 | free((void *) pScreenPriv); |
695 | return ret; |
696 | } |
697 | |
698 | Bool |
699 | KdSaveScreen(ScreenPtr pScreen, int on) |
700 | { |
701 | KdScreenPriv(pScreen)KdPrivScreenPtr pScreenPriv = ((KdPrivScreenPtr) dixLookupPrivate (&(pScreen)->devPrivates, (&kdScreenPrivateKeyRec) )); |
702 | int dpmsState; |
703 | |
704 | if (!pScreenPriv->card->cfuncs->dpms) |
705 | return FALSE0; |
706 | |
707 | dpmsState = pScreenPriv->dpmsState; |
708 | switch (on) { |
709 | case SCREEN_SAVER_OFF1: |
710 | dpmsState = KD_DPMS_NORMAL0; |
711 | break; |
712 | case SCREEN_SAVER_ON0: |
713 | if (dpmsState == KD_DPMS_NORMAL0) |
714 | dpmsState = KD_DPMS_NORMAL0 + 1; |
715 | break; |
716 | case SCREEN_SAVER_CYCLE3: |
717 | if (dpmsState < KD_DPMS_MAX3) |
718 | dpmsState++; |
719 | break; |
720 | case SCREEN_SAVER_FORCER2: |
721 | break; |
722 | } |
723 | if (dpmsState != pScreenPriv->dpmsState) { |
724 | if (pScreenPriv->enabled) |
725 | (*pScreenPriv->card->cfuncs->dpms) (pScreen, dpmsState); |
726 | pScreenPriv->dpmsState = dpmsState; |
727 | } |
728 | return TRUE1; |
729 | } |
730 | |
731 | static Bool |
732 | KdCreateWindow(WindowPtr pWin) |
733 | { |
734 | #ifndef PHOENIX |
735 | if (!pWin->parent) { |
736 | KdScreenPriv(pWin->drawable.pScreen)KdPrivScreenPtr pScreenPriv = ((KdPrivScreenPtr) dixLookupPrivate (&(pWin->drawable.pScreen)->devPrivates, (&kdScreenPrivateKeyRec ))); |
737 | |
738 | if (!pScreenPriv->enabled) { |
739 | RegionEmpty(&pWin->borderClip); |
740 | RegionBreak(&pWin->clipList); |
741 | } |
742 | } |
743 | #endif |
744 | return fbCreateWindow(pWin); |
745 | } |
746 | |
747 | void |
748 | KdSetSubpixelOrder(ScreenPtr pScreen, Rotation randr) |
749 | { |
750 | KdScreenPriv(pScreen)KdPrivScreenPtr pScreenPriv = ((KdPrivScreenPtr) dixLookupPrivate (&(pScreen)->devPrivates, (&kdScreenPrivateKeyRec) )); |
751 | KdScreenInfo *screen = pScreenPriv->screen; |
752 | int subpixel_order = screen->subpixel_order; |
753 | Rotation subpixel_dir; |
754 | int i; |
755 | |
756 | static struct { |
757 | int subpixel_order; |
758 | Rotation direction; |
759 | } orders[] = { |
760 | {SubPixelHorizontalRGB1, RR_Rotate_01}, |
761 | {SubPixelHorizontalBGR2, RR_Rotate_1804}, |
762 | {SubPixelVerticalRGB3, RR_Rotate_2708}, |
763 | {SubPixelVerticalBGR4, RR_Rotate_902}, |
764 | }; |
765 | |
766 | static struct { |
767 | int bit; |
768 | int normal; |
769 | int reflect; |
770 | } reflects[] = { |
771 | {RR_Reflect_X16, SubPixelHorizontalRGB1, SubPixelHorizontalBGR2}, |
772 | {RR_Reflect_X16, SubPixelHorizontalBGR2, SubPixelHorizontalRGB1}, |
773 | {RR_Reflect_Y32, SubPixelVerticalRGB3, SubPixelVerticalBGR4}, |
774 | {RR_Reflect_Y32, SubPixelVerticalRGB3, SubPixelVerticalRGB3}, |
775 | }; |
776 | |
777 | /* map subpixel to direction */ |
778 | for (i = 0; i < 4; i++) |
779 | if (orders[i].subpixel_order == subpixel_order) |
780 | break; |
781 | if (i < 4) { |
782 | subpixel_dir = |
783 | KdAddRotation(randr & RR_Rotate_All(1|2|4|8), orders[i].direction); |
784 | |
785 | /* map back to subpixel order */ |
786 | for (i = 0; i < 4; i++) |
787 | if (orders[i].direction & subpixel_dir) { |
788 | subpixel_order = orders[i].subpixel_order; |
789 | break; |
790 | } |
791 | /* reflect */ |
792 | for (i = 0; i < 4; i++) |
793 | if ((randr & reflects[i].bit) && |
794 | reflects[i].normal == subpixel_order) { |
795 | subpixel_order = reflects[i].reflect; |
796 | break; |
797 | } |
798 | } |
799 | PictureSetSubpixelOrder(pScreen, subpixel_order); |
800 | } |
801 | |
802 | /* Pass through AddScreen, which doesn't take any closure */ |
803 | static KdScreenInfo *kdCurrentScreen; |
804 | |
805 | Bool |
806 | KdScreenInit(ScreenPtr pScreen, int argc, char **argv) |
807 | { |
808 | KdScreenInfo *screen = kdCurrentScreen; |
809 | KdCardInfo *card = screen->card; |
810 | KdPrivScreenPtr pScreenPriv; |
811 | |
812 | /* |
813 | * note that screen->fb is set up for the nominal orientation |
814 | * of the screen; that means if randr is rotated, the values |
815 | * there should reflect a rotated frame buffer (or shadow). |
816 | */ |
817 | Bool rotated = (screen->randr & (RR_Rotate_902 | RR_Rotate_2708)) != 0; |
818 | int width, height, *width_mmp, *height_mmp; |
819 | |
820 | KdAllocatePrivates(pScreen); |
821 | |
822 | pScreenPriv = KdGetScreenPriv(pScreen)((KdPrivScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&kdScreenPrivateKeyRec))); |
823 | |
824 | if (!rotated) { |
825 | width = screen->width; |
826 | height = screen->height; |
827 | width_mmp = &screen->width_mm; |
828 | height_mmp = &screen->height_mm; |
829 | } |
830 | else { |
831 | width = screen->height; |
832 | height = screen->width; |
833 | width_mmp = &screen->height_mm; |
834 | height_mmp = &screen->width_mm; |
835 | } |
836 | screen->pScreen = pScreen; |
837 | pScreenPriv->screen = screen; |
838 | pScreenPriv->card = card; |
839 | pScreenPriv->bytesPerPixel = screen->fb.bitsPerPixel >> 3; |
840 | pScreenPriv->dpmsState = KD_DPMS_NORMAL0; |
841 | pScreen->x = screen->origin.x; |
842 | pScreen->y = screen->origin.y; |
843 | |
844 | if (!monitorResolution) |
845 | monitorResolution = 75; |
846 | /* |
847 | * This is done in this order so that backing store wraps |
848 | * our GC functions; fbFinishScreenInit initializes MI |
849 | * backing store |
850 | */ |
851 | if (!fbSetupScreen(pScreen, |
852 | screen->fb.frameBuffer, |
853 | width, height, |
854 | monitorResolution, monitorResolution, |
855 | screen->fb.pixelStride, screen->fb.bitsPerPixel)) { |
856 | return FALSE0; |
857 | } |
858 | |
859 | /* |
860 | * Set colormap functions |
861 | */ |
862 | pScreen->InstallColormap = KdInstallColormap; |
863 | pScreen->UninstallColormap = KdUninstallColormap; |
864 | pScreen->ListInstalledColormaps = KdListInstalledColormaps; |
865 | pScreen->StoreColors = KdStoreColors; |
866 | |
867 | pScreen->SaveScreen = KdSaveScreen; |
868 | pScreen->CreateWindow = KdCreateWindow; |
869 | |
870 | if (!fbFinishScreenInit(pScreen, |
871 | screen->fb.frameBuffer, |
872 | width, height, |
873 | monitorResolution, monitorResolution, |
874 | screen->fb.pixelStride, screen->fb.bitsPerPixel)) { |
875 | return FALSE0; |
876 | } |
877 | |
878 | /* |
879 | * Fix screen sizes; for some reason mi takes dpi instead of mm. |
880 | * Rounding errors are annoying |
881 | */ |
882 | if (*width_mmp) |
883 | pScreen->mmWidth = *width_mmp; |
884 | else |
885 | *width_mmp = pScreen->mmWidth; |
886 | if (*height_mmp) |
887 | pScreen->mmHeight = *height_mmp; |
888 | else |
889 | *height_mmp = pScreen->mmHeight; |
890 | |
891 | /* |
892 | * Plug in our own block/wakeup handlers. |
893 | * miScreenInit installs NoopDDA in both places |
894 | */ |
895 | pScreen->BlockHandler = KdBlockHandler; |
896 | pScreen->WakeupHandler = KdWakeupHandler; |
897 | |
898 | if (!fbPictureInit(pScreen, 0, 0)) |
899 | return FALSE0; |
900 | if (card->cfuncs->initScreen) |
901 | if (!(*card->cfuncs->initScreen) (pScreen)) |
902 | return FALSE0; |
903 | |
904 | if (!screen->dumb && card->cfuncs->initAccel) |
905 | if (!(*card->cfuncs->initAccel) (pScreen)) |
906 | screen->dumb = TRUE1; |
907 | |
908 | if (card->cfuncs->finishInitScreen) |
909 | if (!(*card->cfuncs->finishInitScreen) (pScreen)) |
910 | return FALSE0; |
911 | |
912 | /* |
913 | * Wrap CloseScreen, the order now is: |
914 | * KdCloseScreen |
915 | * miBSCloseScreen |
916 | * fbCloseScreen |
917 | */ |
918 | pScreenPriv->CloseScreen = pScreen->CloseScreen; |
919 | pScreen->CloseScreen = KdCloseScreen; |
920 | |
921 | pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; |
922 | pScreen->CreateScreenResources = KdCreateScreenResources; |
923 | |
924 | if (screen->softCursor || |
925 | !card->cfuncs->initCursor || !(*card->cfuncs->initCursor) (pScreen)) { |
926 | /* Use MI for cursor display and event queueing. */ |
927 | screen->softCursor = TRUE1; |
928 | miDCInitialize(pScreen, &kdPointerScreenFuncs); |
929 | } |
930 | |
931 | if (!fbCreateDefColormap(pScreen)) { |
932 | return FALSE0; |
933 | } |
934 | |
935 | KdSetSubpixelOrder(pScreen, screen->randr); |
936 | |
937 | /* |
938 | * Enable the hardware |
939 | */ |
940 | if (!kdEnabled) { |
941 | kdEnabled = TRUE1; |
942 | if (kdOsFuncs->Enable) |
943 | (*kdOsFuncs->Enable) (); |
944 | } |
945 | |
946 | if (screen->mynum == card->selected) { |
947 | if (card->cfuncs->preserve) |
948 | (*card->cfuncs->preserve) (card); |
949 | if (card->cfuncs->enable) |
950 | if (!(*card->cfuncs->enable) (pScreen)) |
951 | return FALSE0; |
952 | pScreenPriv->enabled = TRUE1; |
953 | if (!screen->softCursor && card->cfuncs->enableCursor) |
954 | (*card->cfuncs->enableCursor) (pScreen); |
955 | KdEnableColormap(pScreen); |
956 | if (!screen->dumb && card->cfuncs->enableAccel) |
957 | (*card->cfuncs->enableAccel) (pScreen); |
958 | } |
959 | |
960 | return TRUE1; |
961 | } |
962 | |
963 | void |
964 | KdInitScreen(ScreenInfo * pScreenInfo, |
965 | KdScreenInfo * screen, int argc, char **argv) |
966 | { |
967 | KdCardInfo *card = screen->card; |
968 | |
969 | if (!(*card->cfuncs->scrinit) (screen)) |
970 | FatalError("Screen initialization failed!\n"); |
971 | |
972 | if (!card->cfuncs->initAccel) |
973 | screen->dumb = TRUE1; |
974 | if (!card->cfuncs->initCursor) |
975 | screen->softCursor = TRUE1; |
976 | } |
977 | |
978 | static Bool |
979 | KdSetPixmapFormats(ScreenInfo * pScreenInfo) |
980 | { |
981 | CARD8 depthToBpp[33]; /* depth -> bpp map */ |
982 | KdCardInfo *card; |
983 | KdScreenInfo *screen; |
984 | int i; |
985 | int bpp; |
986 | PixmapFormatRec *format; |
987 | |
988 | for (i = 1; i <= 32; i++) |
989 | depthToBpp[i] = 0; |
990 | |
991 | /* |
992 | * Generate mappings between bitsPerPixel and depth, |
993 | * also ensure that all screens comply with protocol |
994 | * restrictions on equivalent formats for the same |
995 | * depth on different screens |
996 | */ |
997 | for (card = kdCardInfo; card; card = card->next) { |
998 | for (screen = card->screenList; screen; screen = screen->next) { |
999 | bpp = screen->fb.bitsPerPixel; |
1000 | if (bpp == 24) |
1001 | bpp = 32; |
1002 | if (!depthToBpp[screen->fb.depth]) |
1003 | depthToBpp[screen->fb.depth] = bpp; |
1004 | else if (depthToBpp[screen->fb.depth] != bpp) |
1005 | return FALSE0; |
1006 | } |
1007 | } |
1008 | |
1009 | /* |
1010 | * Fill in additional formats |
1011 | */ |
1012 | for (i = 0; i < NUM_KD_DEPTHS(sizeof (kdDepths) / sizeof (kdDepths[0])); i++) |
1013 | if (!depthToBpp[kdDepths[i].depth]) |
1014 | depthToBpp[kdDepths[i].depth] = kdDepths[i].bpp; |
1015 | |
1016 | pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER0; |
1017 | pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT32; |
1018 | pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD32; |
1019 | pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER0; |
1020 | |
1021 | pScreenInfo->numPixmapFormats = 0; |
1022 | |
1023 | for (i = 1; i <= 32; i++) { |
1024 | if (depthToBpp[i]) { |
1025 | format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++]; |
1026 | format->depth = i; |
1027 | format->bitsPerPixel = depthToBpp[i]; |
1028 | format->scanlinePad = BITMAP_SCANLINE_PAD32; |
1029 | } |
1030 | } |
1031 | |
1032 | return TRUE1; |
1033 | } |
1034 | |
1035 | static void |
1036 | KdAddScreen(ScreenInfo * pScreenInfo, |
1037 | KdScreenInfo * screen, int argc, char **argv) |
1038 | { |
1039 | int i; |
1040 | |
1041 | /* |
1042 | * Fill in fb visual type masks for this screen |
1043 | */ |
1044 | for (i = 0; i < pScreenInfo->numPixmapFormats; i++) { |
1045 | unsigned long visuals; |
1046 | Pixel rm, gm, bm; |
1047 | |
1048 | visuals = 0; |
1049 | rm = gm = bm = 0; |
1050 | if (pScreenInfo->formats[i].depth == screen->fb.depth) { |
1051 | visuals = screen->fb.visuals; |
1052 | rm = screen->fb.redMask; |
1053 | gm = screen->fb.greenMask; |
1054 | bm = screen->fb.blueMask; |
1055 | } |
1056 | fbSetVisualTypesAndMasks(pScreenInfo->formats[i].depth, |
1057 | visuals, 8, rm, gm, bm); |
1058 | } |
1059 | |
1060 | kdCurrentScreen = screen; |
1061 | |
1062 | AddScreen(KdScreenInit, argc, argv); |
1063 | } |
1064 | |
1065 | #if 0 /* This function is not used currently */ |
1066 | |
1067 | int |
1068 | KdDepthToFb(ScreenPtr pScreen, int depth) |
1069 | { |
1070 | KdScreenPriv(pScreen)KdPrivScreenPtr pScreenPriv = ((KdPrivScreenPtr) dixLookupPrivate (&(pScreen)->devPrivates, (&kdScreenPrivateKeyRec) )); |
1071 | |
1072 | for (fb = 0; fb <= KD_MAX_FB && pScreenPriv->screen->fb.frameBuffer; fb++) |
1073 | if (pScreenPriv->screen->fb.depth == depth) |
1074 | return fb; |
1075 | } |
1076 | |
1077 | #endif |
1078 | |
1079 | static int |
1080 | KdSignalWrapper(int signum) |
1081 | { |
1082 | kdCaughtSignal = TRUE1; |
1083 | return 1; /* use generic OS layer cleanup & abort */ |
1084 | } |
1085 | |
1086 | void |
1087 | KdInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) |
1088 | { |
1089 | KdCardInfo *card; |
1090 | KdScreenInfo *screen; |
1091 | |
1092 | if (!kdCardInfo) { |
1093 | InitCard(0); |
1094 | if (!(card = KdCardInfoLast())) |
1095 | FatalError("No matching cards found!\n"); |
1096 | screen = KdScreenInfoAdd(card); |
1097 | KdParseScreen(screen, 0); |
1098 | } |
1099 | /* |
1100 | * Initialize all of the screens for all of the cards |
1101 | */ |
1102 | for (card = kdCardInfo; card; card = card->next) { |
1103 | int ret = 1; |
1104 | |
1105 | if (card->cfuncs->cardinit) |
1106 | ret = (*card->cfuncs->cardinit) (card); |
1107 | if (ret) { |
1108 | for (screen = card->screenList; screen; screen = screen->next) |
1109 | KdInitScreen(pScreenInfo, screen, argc, argv); |
1110 | } |
1111 | } |
1112 | |
1113 | /* |
1114 | * Merge the various pixmap formats together, this can fail |
1115 | * when two screens share depth but not bitsPerPixel |
1116 | */ |
1117 | if (!KdSetPixmapFormats(pScreenInfo)) |
1118 | return; |
1119 | |
1120 | /* |
1121 | * Add all of the screens |
1122 | */ |
1123 | for (card = kdCardInfo; card; card = card->next) |
1124 | for (screen = card->screenList; screen; screen = screen->next) |
1125 | KdAddScreen(pScreenInfo, screen, argc, argv); |
1126 | |
1127 | OsRegisterSigWrapper(KdSignalWrapper); |
1128 | } |
1129 | |
1130 | void |
1131 | OsVendorFatalError(const char *f, va_list args) |
1132 | { |
1133 | } |
1134 | |
1135 | int |
1136 | DPMSSet(ClientPtr client, int level) |
1137 | { |
1138 | return Success0; |
1139 | } |
1140 | |
1141 | Bool |
1142 | DPMSSupported(void) |
1143 | { |
1144 | return FALSE0; |
1145 | } |