Bug Summary

File:hw/kdrive/src/kdrive.c
Location:line 404, column 9
Description:Value stored to 'arg' is never read

Annotated Source Code

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
48typedef struct _kdDepths {
49 CARD8 depth;
50 CARD8 bpp;
51} KdDepths;
52
53KdDepths 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
67DevPrivateKeyRec kdScreenPrivateKeyRec;
68unsigned long kdGeneration;
69
70Bool kdVideoTest;
71unsigned long kdVideoTestTime;
72Bool kdEmulateMiddleButton;
73Bool kdRawPointerCoordinates;
74Bool kdDisableZaphod;
75Bool kdAllowZap;
76Bool kdEnabled;
77int kdSubpixelOrder;
78int kdVirtualTerminal = -1;
79Bool kdSwitchPending;
80char *kdSwitchCmd;
81DDXPointRec kdOrigin;
82Bool kdHasPointer = FALSE0;
83Bool kdHasKbd = FALSE0;
84
85static Bool kdCaughtSignal = FALSE0;
86
87/*
88 * Carry arguments from InitOutput through driver initialization
89 * to KdScreenInit
90 */
91
92KdOsFuncs *kdOsFuncs;
93
94void
95KdDisableScreen(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, FALSE0);
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
116static void
117KdDoSwitchCmd(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
136void
137KdSuspend(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
155void
156KdDisableScreens(void)
157{
158 KdSuspend();
159 if (kdEnabled) {
160 if (kdOsFuncs->Disable)
161 (*kdOsFuncs->Disable) ();
162 kdEnabled = FALSE0;
163 }
164}
165
166Bool
167KdEnableScreen(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, TRUE1);
186 if (pScreenPriv->card->cfuncs->dpms)
187 (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState);
188 return TRUE1;
189}
190
191void
192KdResume(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
211void
212KdEnableScreens(void)
213{
214 if (!kdEnabled) {
215 kdEnabled = TRUE1;
216 if (kdOsFuncs->Enable)
217 (*kdOsFuncs->Enable) ();
218 }
219 KdResume();
220}
221
222void
223KdProcessSwitch(void)
224{
225 if (kdEnabled)
226 KdDisableScreens();
227 else
228 KdEnableScreens();
229}
230
231void
232AbortDDX(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
247void
248ddxGiveUp(enum ExitCode error)
249{
250 AbortDDX(error);
251}
252
253Bool kdDumbDriver;
254Bool kdSoftCursor;
255
256const char *
257KdParseFindNext(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
269Rotation
270KdAddRotation(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
280Rotation
281KdSubRotation(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
291void
292KdParseScreen(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
421void
422KdParseRgba(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
438void
439KdUseMsg(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
466int
467KdProcessArgument(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
581void
582KdOsInit(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
594Bool
595KdAllocatePrivates(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
612Bool
613KdCreateScreenResources(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
631Bool
632KdCloseScreen(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
698Bool
699KdSaveScreen(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
731static Bool
732KdCreateWindow(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
747void
748KdSetSubpixelOrder(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 */
803static KdScreenInfo *kdCurrentScreen;
804
805Bool
806KdScreenInit(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
963void
964KdInitScreen(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
978static Bool
979KdSetPixmapFormats(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
1035static void
1036KdAddScreen(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
1067int
1068KdDepthToFb(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
1079static int
1080KdSignalWrapper(int signum)
1081{
1082 kdCaughtSignal = TRUE1;
1083 return 1; /* use generic OS layer cleanup & abort */
1084}
1085
1086void
1087KdInitOutput(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
1130void
1131OsVendorFatalError(const char *f, va_list args)
1132{
1133}
1134
1135int
1136DPMSSet(ClientPtr client, int level)
1137{
1138 return Success0;
1139}
1140
1141Bool
1142DPMSSupported(void)
1143{
1144 return FALSE0;
1145}