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_DIX_CONFIG_H
24 #include <dix-config.h>
25 #endif
26 #include "kdrive.h"
27 #include <mivalidate.h>
28 #include <dixstruct.h>
29 #include "privates.h"
30 #ifdef RANDR
31 #include <randrstr.h>
32 #endif
33 #include "glx_extinit.h"
34
35 #ifdef XV
36 #include "kxv.h"
37 #endif
38
39 #ifdef DPMSExtension
40 #include "dpmsproc.h"
41 #endif
42
43 #ifdef HAVE_EXECINFO_H
44 #include <execinfo.h>
45 #endif
46
47 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
48 #include <hotplug.h>
49 #endif
50
51 /* This stub can be safely removed once we can
52 * split input and GPU parts in hotplug.h et al. */
53 #include <systemd-logind.h>
54
55 typedef struct _kdDepths {
56 CARD8 depth;
57 CARD8 bpp;
58 } KdDepths;
59
60 KdDepths kdDepths[] = {
61 {1, 1},
62 {4, 4},
63 {8, 8},
64 {15, 16},
65 {16, 16},
66 {24, 32},
67 {32, 32}
68 };
69
70 #define KD_DEFAULT_BUTTONS 5
71
72 DevPrivateKeyRec kdScreenPrivateKeyRec;
73 static unsigned long kdGeneration;
74
75 Bool kdEmulateMiddleButton;
76 Bool kdRawPointerCoordinates;
77 Bool kdDisableZaphod;
78 static Bool kdEnabled;
79 static int kdSubpixelOrder;
80 static char *kdSwitchCmd;
81 static DDXPointRec kdOrigin;
82 Bool kdHasPointer = FALSE;
83 Bool kdHasKbd = FALSE;
84 const char *kdGlobalXkbRules = NULL;
85 const char *kdGlobalXkbModel = NULL;
86 const char *kdGlobalXkbLayout = NULL;
87 const char *kdGlobalXkbVariant = NULL;
88 const char *kdGlobalXkbOptions = NULL;
89
90 void
KdDisableScreen(ScreenPtr pScreen)91 KdDisableScreen(ScreenPtr pScreen)
92 {
93 KdScreenPriv(pScreen);
94
95 if (!pScreenPriv->enabled)
96 return;
97 if (!pScreenPriv->closed)
98 SetRootClip(pScreen, ROOT_CLIP_NONE);
99 KdDisableColormap(pScreen);
100 if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel)
101 (*pScreenPriv->card->cfuncs->disableAccel) (pScreen);
102 pScreenPriv->enabled = FALSE;
103 }
104
105 static void
KdDoSwitchCmd(const char * reason)106 KdDoSwitchCmd(const char *reason)
107 {
108 if (kdSwitchCmd) {
109 char *command;
110 int ret;
111
112 if (asprintf(&command, "%s %s", kdSwitchCmd, reason) == -1)
113 return;
114
115 /* Ignore the return value from system; I'm not sure
116 * there's anything more useful to be done when
117 * it fails
118 */
119 ret = system(command);
120 (void) ret;
121 free(command);
122 }
123 }
124
125 static void
KdSuspend(void)126 KdSuspend(void)
127 {
128 KdCardInfo *card;
129 KdScreenInfo *screen;
130
131 if (kdEnabled) {
132 for (card = kdCardInfo; card; card = card->next) {
133 for (screen = card->screenList; screen; screen = screen->next)
134 if (screen->mynum == card->selected && screen->pScreen)
135 KdDisableScreen(screen->pScreen);
136 }
137 KdDisableInput();
138 KdDoSwitchCmd("suspend");
139 }
140 }
141
142 static void
KdDisableScreens(void)143 KdDisableScreens(void)
144 {
145 KdSuspend();
146 kdEnabled = FALSE;
147 }
148
149 Bool
KdEnableScreen(ScreenPtr pScreen)150 KdEnableScreen(ScreenPtr pScreen)
151 {
152 KdScreenPriv(pScreen);
153
154 if (pScreenPriv->enabled)
155 return TRUE;
156 pScreenPriv->enabled = TRUE;
157 pScreenPriv->dpmsState = KD_DPMS_NORMAL;
158 pScreenPriv->card->selected = pScreenPriv->screen->mynum;
159 if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel)
160 (*pScreenPriv->card->cfuncs->enableAccel) (pScreen);
161 KdEnableColormap(pScreen);
162 SetRootClip(pScreen, ROOT_CLIP_FULL);
163 return TRUE;
164 }
165
166 void
AbortDDX(enum ExitCode error)167 AbortDDX(enum ExitCode error)
168 {
169 KdDisableScreens();
170 }
171
172 void
ddxGiveUp(enum ExitCode error)173 ddxGiveUp(enum ExitCode error)
174 {
175 AbortDDX(error);
176 }
177
178 static Bool kdDumbDriver;
179 static Bool kdSoftCursor;
180
181 const char *
KdParseFindNext(const char * cur,const char * delim,char * save,char * last)182 KdParseFindNext(const char *cur, const char *delim, char *save, char *last)
183 {
184 while (*cur && !strchr(delim, *cur)) {
185 *save++ = *cur++;
186 }
187 *save = 0;
188 *last = *cur;
189 if (*cur)
190 cur++;
191 return cur;
192 }
193
194 Rotation
KdAddRotation(Rotation a,Rotation b)195 KdAddRotation(Rotation a, Rotation b)
196 {
197 Rotation rotate = (a & RR_Rotate_All) * (b & RR_Rotate_All);
198 Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All);
199
200 if (rotate > RR_Rotate_270)
201 rotate /= (RR_Rotate_270 * RR_Rotate_90);
202 return reflect | rotate;
203 }
204
205 Rotation
KdSubRotation(Rotation a,Rotation b)206 KdSubRotation(Rotation a, Rotation b)
207 {
208 Rotation rotate = (a & RR_Rotate_All) * 16 / (b & RR_Rotate_All);
209 Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All);
210
211 if (rotate > RR_Rotate_270)
212 rotate /= (RR_Rotate_270 * RR_Rotate_90);
213 return reflect | rotate;
214 }
215
216 void
KdParseScreen(KdScreenInfo * screen,const char * arg)217 KdParseScreen(KdScreenInfo * screen, const char *arg)
218 {
219 char delim;
220 char save[1024];
221 int i;
222 int pixels, mm;
223
224 screen->dumb = kdDumbDriver;
225 screen->softCursor = kdSoftCursor;
226 screen->origin = kdOrigin;
227 screen->randr = RR_Rotate_0;
228 screen->x = 0;
229 screen->y = 0;
230 screen->width = 0;
231 screen->height = 0;
232 screen->width_mm = 0;
233 screen->height_mm = 0;
234 screen->subpixel_order = kdSubpixelOrder;
235 screen->rate = 0;
236 screen->fb.depth = 0;
237 if (!arg)
238 return;
239 if (strlen(arg) >= sizeof(save))
240 return;
241
242 for (i = 0; i < 2; i++) {
243 arg = KdParseFindNext(arg, "x/+@XY", save, &delim);
244 if (!save[0])
245 return;
246
247 pixels = atoi(save);
248 mm = 0;
249
250 if (delim == '/') {
251 arg = KdParseFindNext(arg, "x+@XY", save, &delim);
252 if (!save[0])
253 return;
254 mm = atoi(save);
255 }
256
257 if (i == 0) {
258 screen->width = pixels;
259 screen->width_mm = mm;
260 }
261 else {
262 screen->height = pixels;
263 screen->height_mm = mm;
264 }
265 if (delim != 'x' && delim != '+' && delim != '@' &&
266 delim != 'X' && delim != 'Y' &&
267 (delim != '\0' || i == 0))
268 return;
269 }
270
271 kdOrigin.x += screen->width;
272 kdOrigin.y = 0;
273 kdDumbDriver = FALSE;
274 kdSoftCursor = FALSE;
275 kdSubpixelOrder = SubPixelUnknown;
276
277 if (delim == '+') {
278 arg = KdParseFindNext(arg, "+@xXY", save, &delim);
279 if (save[0])
280 screen->x = atoi(save);
281 }
282
283 if (delim == '+') {
284 arg = KdParseFindNext(arg, "@xXY", save, &delim);
285 if (save[0])
286 screen->y = atoi(save);
287 }
288
289 if (delim == '@') {
290 arg = KdParseFindNext(arg, "xXY", save, &delim);
291 if (save[0]) {
292 int rotate = atoi(save);
293
294 if (rotate < 45)
295 screen->randr = RR_Rotate_0;
296 else if (rotate < 135)
297 screen->randr = RR_Rotate_90;
298 else if (rotate < 225)
299 screen->randr = RR_Rotate_180;
300 else if (rotate < 315)
301 screen->randr = RR_Rotate_270;
302 else
303 screen->randr = RR_Rotate_0;
304 }
305 }
306 if (delim == 'X') {
307 arg = KdParseFindNext(arg, "xY", save, &delim);
308 screen->randr |= RR_Reflect_X;
309 }
310
311 if (delim == 'Y') {
312 arg = KdParseFindNext(arg, "xY", save, &delim);
313 screen->randr |= RR_Reflect_Y;
314 }
315
316 arg = KdParseFindNext(arg, "x/,", save, &delim);
317 if (save[0]) {
318 screen->fb.depth = atoi(save);
319 if (delim == '/') {
320 arg = KdParseFindNext(arg, "x,", save, &delim);
321 if (save[0])
322 screen->fb.bitsPerPixel = atoi(save);
323 }
324 else
325 screen->fb.bitsPerPixel = 0;
326 }
327
328 if (delim == 'x') {
329 arg = KdParseFindNext(arg, "x", save, &delim);
330 if (save[0])
331 screen->rate = atoi(save);
332 }
333 }
334
335 static void
KdParseRgba(char * rgba)336 KdParseRgba(char *rgba)
337 {
338 if (!strcmp(rgba, "rgb"))
339 kdSubpixelOrder = SubPixelHorizontalRGB;
340 else if (!strcmp(rgba, "bgr"))
341 kdSubpixelOrder = SubPixelHorizontalBGR;
342 else if (!strcmp(rgba, "vrgb"))
343 kdSubpixelOrder = SubPixelVerticalRGB;
344 else if (!strcmp(rgba, "vbgr"))
345 kdSubpixelOrder = SubPixelVerticalBGR;
346 else if (!strcmp(rgba, "none"))
347 kdSubpixelOrder = SubPixelNone;
348 else
349 kdSubpixelOrder = SubPixelUnknown;
350 }
351
352 void
KdUseMsg(void)353 KdUseMsg(void)
354 {
355 ErrorF("\nTinyX Device Dependent Usage:\n");
356 ErrorF
357 ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][+[-]XOFFSET][+[-]YOFFSET][@ROTATION][X][Y][xDEPTH/BPP[xFREQ]] Specify screen characteristics\n");
358 ErrorF
359 ("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n");
360 ErrorF
361 ("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n");
362 ErrorF
363 ("-keybd driver [,,options] Specify the keyboard driver and its options\n");
364 ErrorF("-xkb-rules Set default XkbRules value (can be overriden by -keybd options)\n");
365 ErrorF("-xkb-model Set default XkbModel value (can be overriden by -keybd options)\n");
366 ErrorF("-xkb-layout Set default XkbLayout value (can be overriden by -keybd options)\n");
367 ErrorF("-xkb-variant Set default XkbVariant value (can be overriden by -keybd options)\n");
368 ErrorF("-xkb-options Set default XkbOptions value (can be overriden by -keybd options)\n");
369 ErrorF("-zaphod Disable cursor screen switching\n");
370 ErrorF("-2button Emulate 3 button mouse\n");
371 ErrorF("-3button Disable 3 button mouse emulation\n");
372 ErrorF
373 ("-rawcoord Don't transform pointer coordinates on rotation\n");
374 ErrorF("-dumb Disable hardware acceleration\n");
375 ErrorF("-softCursor Force software cursor\n");
376 ErrorF("-videoTest Start the server, pause momentarily and exit\n");
377 ErrorF
378 ("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n");
379 ErrorF("-switchCmd Command to execute on vt switch\n");
380 ErrorF
381 ("vtxx Use virtual terminal xx instead of the next available\n");
382 }
383
384 int
KdProcessArgument(int argc,char ** argv,int i)385 KdProcessArgument(int argc, char **argv, int i)
386 {
387 KdCardInfo *card;
388 KdScreenInfo *screen;
389
390 if (!strcmp(argv[i], "-screen")) {
391 if ((i + 1) < argc) {
392 card = KdCardInfoLast();
393 if (!card) {
394 InitCard(0);
395 card = KdCardInfoLast();
396 }
397 if (card) {
398 screen = KdScreenInfoAdd(card);
399 KdParseScreen(screen, argv[i + 1]);
400 }
401 else
402 ErrorF("No matching card found!\n");
403 }
404 else
405 UseMsg();
406 return 2;
407 }
408 if (!strcmp(argv[i], "-zaphod")) {
409 kdDisableZaphod = TRUE;
410 return 1;
411 }
412 if (!strcmp(argv[i], "-3button")) {
413 kdEmulateMiddleButton = FALSE;
414 return 1;
415 }
416 if (!strcmp(argv[i], "-2button")) {
417 kdEmulateMiddleButton = TRUE;
418 return 1;
419 }
420 if (!strcmp(argv[i], "-rawcoord")) {
421 kdRawPointerCoordinates = 1;
422 return 1;
423 }
424 if (!strcmp(argv[i], "-dumb")) {
425 kdDumbDriver = TRUE;
426 return 1;
427 }
428 if (!strcmp(argv[i], "-softCursor")) {
429 kdSoftCursor = TRUE;
430 return 1;
431 }
432 if (!strcmp(argv[i], "-origin")) {
433 if ((i + 1) < argc) {
434 char *x = argv[i + 1];
435 char *y = strchr(x, ',');
436
437 if (x)
438 kdOrigin.x = atoi(x);
439 else
440 kdOrigin.x = 0;
441 if (y)
442 kdOrigin.y = atoi(y + 1);
443 else
444 kdOrigin.y = 0;
445 }
446 else
447 UseMsg();
448 return 2;
449 }
450 if (!strcmp(argv[i], "-rgba")) {
451 if ((i + 1) < argc)
452 KdParseRgba(argv[i + 1]);
453 else
454 UseMsg();
455 return 2;
456 }
457 if (!strcmp(argv[i], "-switchCmd")) {
458 if ((i + 1) < argc)
459 kdSwitchCmd = argv[i + 1];
460 else
461 UseMsg();
462 return 2;
463 }
464 if (!strcmp(argv[i], "-xkb-rules")) {
465 if (i + 1 >= argc) {
466 UseMsg();
467 FatalError("Missing argument for option -xkb-rules.\n");
468 }
469 kdGlobalXkbRules = argv[i + 1];
470 return 2;
471 }
472 if (!strcmp(argv[i], "-xkb-model")) {
473 if (i + 1 >= argc) {
474 UseMsg();
475 FatalError("Missing argument for option -xkb-model.\n");
476 }
477 kdGlobalXkbModel = argv[i + 1];
478 return 2;
479 }
480 if (!strcmp(argv[i], "-xkb-layout")) {
481 if (i + 1 >= argc) {
482 UseMsg();
483 FatalError("Missing argument for option -xkb-layout.\n");
484 }
485 kdGlobalXkbLayout = argv[i + 1];
486 return 2;
487 }
488 if (!strcmp(argv[i], "-xkb-variant")) {
489 if (i + 1 >= argc) {
490 UseMsg();
491 FatalError("Missing argument for option -xkb-variant.\n");
492 }
493 kdGlobalXkbVariant = argv[i + 1];
494 return 2;
495 }
496 if (!strcmp(argv[i], "-xkb-options")) {
497 if (i + 1 >= argc) {
498 UseMsg();
499 FatalError("Missing argument for option -xkb-options.\n");
500 }
501 kdGlobalXkbOptions = argv[i + 1];
502 return 2;
503 }
504 if (!strcmp(argv[i], "-mouse") || !strcmp(argv[i], "-pointer")) {
505 if (i + 1 >= argc)
506 UseMsg();
507 KdAddConfigPointer(argv[i + 1]);
508 kdHasPointer = TRUE;
509 return 2;
510 }
511 if (!strcmp(argv[i], "-keybd")) {
512 if (i + 1 >= argc)
513 UseMsg();
514 KdAddConfigKeyboard(argv[i + 1]);
515 kdHasKbd = TRUE;
516 return 2;
517 }
518
519 return 0;
520 }
521
522 static Bool
KdAllocatePrivates(ScreenPtr pScreen)523 KdAllocatePrivates(ScreenPtr pScreen)
524 {
525 KdPrivScreenPtr pScreenPriv;
526
527 if (kdGeneration != serverGeneration)
528 kdGeneration = serverGeneration;
529
530 if (!dixRegisterPrivateKey(&kdScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
531 return FALSE;
532
533 pScreenPriv = calloc(1, sizeof(*pScreenPriv));
534 if (!pScreenPriv)
535 return FALSE;
536 KdSetScreenPriv(pScreen, pScreenPriv);
537 return TRUE;
538 }
539
540 static Bool
KdCreateScreenResources(ScreenPtr pScreen)541 KdCreateScreenResources(ScreenPtr pScreen)
542 {
543 KdScreenPriv(pScreen);
544 KdCardInfo *card = pScreenPriv->card;
545 Bool ret;
546
547 pScreen->CreateScreenResources = pScreenPriv->CreateScreenResources;
548 if (pScreen->CreateScreenResources)
549 ret = (*pScreen->CreateScreenResources) (pScreen);
550 else
551 ret = -1;
552 pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources;
553 pScreen->CreateScreenResources = KdCreateScreenResources;
554 if (ret && card->cfuncs->createRes)
555 ret = (*card->cfuncs->createRes) (pScreen);
556 return ret;
557 }
558
559 static Bool
KdCloseScreen(ScreenPtr pScreen)560 KdCloseScreen(ScreenPtr pScreen)
561 {
562 KdScreenPriv(pScreen);
563 KdScreenInfo *screen = pScreenPriv->screen;
564 KdCardInfo *card = pScreenPriv->card;
565 Bool ret;
566
567 if (card->cfuncs->closeScreen)
568 (*card->cfuncs->closeScreen)(pScreen);
569
570 pScreenPriv->closed = TRUE;
571 pScreen->CloseScreen = pScreenPriv->CloseScreen;
572
573 if (pScreen->CloseScreen)
574 ret = (*pScreen->CloseScreen) (pScreen);
575 else
576 ret = TRUE;
577
578 if (screen->mynum == card->selected)
579 KdDisableScreen(pScreen);
580
581 if (!pScreenPriv->screen->dumb && card->cfuncs->finiAccel)
582 (*card->cfuncs->finiAccel) (pScreen);
583
584 if (card->cfuncs->scrfini)
585 (*card->cfuncs->scrfini) (screen);
586
587 /*
588 * Clean up card when last screen is closed, DIX closes them in
589 * reverse order, thus we check for when the first in the list is closed
590 */
591 if (screen == card->screenList) {
592 if (card->cfuncs->cardfini)
593 (*card->cfuncs->cardfini) (card);
594 /*
595 * Clean up OS when last card is closed
596 */
597 if (card == kdCardInfo) {
598 kdEnabled = FALSE;
599 }
600 }
601
602 pScreenPriv->screen->pScreen = 0;
603
604 free((void *) pScreenPriv);
605 return ret;
606 }
607
608 static Bool
KdSaveScreen(ScreenPtr pScreen,int on)609 KdSaveScreen(ScreenPtr pScreen, int on)
610 {
611 return FALSE;
612 }
613
614 static Bool
KdCreateWindow(WindowPtr pWin)615 KdCreateWindow(WindowPtr pWin)
616 {
617 #ifndef PHOENIX
618 if (!pWin->parent) {
619 KdScreenPriv(pWin->drawable.pScreen);
620
621 if (!pScreenPriv->enabled) {
622 RegionEmpty(&pWin->borderClip);
623 RegionBreak(&pWin->clipList);
624 }
625 }
626 #endif
627 return fbCreateWindow(pWin);
628 }
629
630 void
KdSetSubpixelOrder(ScreenPtr pScreen,Rotation randr)631 KdSetSubpixelOrder(ScreenPtr pScreen, Rotation randr)
632 {
633 KdScreenPriv(pScreen);
634 KdScreenInfo *screen = pScreenPriv->screen;
635 int subpixel_order = screen->subpixel_order;
636 Rotation subpixel_dir;
637 int i;
638
639 static struct {
640 int subpixel_order;
641 Rotation direction;
642 } orders[] = {
643 {SubPixelHorizontalRGB, RR_Rotate_0},
644 {SubPixelHorizontalBGR, RR_Rotate_180},
645 {SubPixelVerticalRGB, RR_Rotate_270},
646 {SubPixelVerticalBGR, RR_Rotate_90},
647 };
648
649 static struct {
650 int bit;
651 int normal;
652 int reflect;
653 } reflects[] = {
654 {RR_Reflect_X, SubPixelHorizontalRGB, SubPixelHorizontalBGR},
655 {RR_Reflect_X, SubPixelHorizontalBGR, SubPixelHorizontalRGB},
656 {RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalBGR},
657 {RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalRGB},
658 };
659
660 /* map subpixel to direction */
661 for (i = 0; i < 4; i++)
662 if (orders[i].subpixel_order == subpixel_order)
663 break;
664 if (i < 4) {
665 subpixel_dir =
666 KdAddRotation(randr & RR_Rotate_All, orders[i].direction);
667
668 /* map back to subpixel order */
669 for (i = 0; i < 4; i++)
670 if (orders[i].direction & subpixel_dir) {
671 subpixel_order = orders[i].subpixel_order;
672 break;
673 }
674 /* reflect */
675 for (i = 0; i < 4; i++)
676 if ((randr & reflects[i].bit) &&
677 reflects[i].normal == subpixel_order) {
678 subpixel_order = reflects[i].reflect;
679 break;
680 }
681 }
682 PictureSetSubpixelOrder(pScreen, subpixel_order);
683 }
684
685 /* Pass through AddScreen, which doesn't take any closure */
686 static KdScreenInfo *kdCurrentScreen;
687
688 static Bool
KdScreenInit(ScreenPtr pScreen,int argc,char ** argv)689 KdScreenInit(ScreenPtr pScreen, int argc, char **argv)
690 {
691 KdScreenInfo *screen = kdCurrentScreen;
692 KdCardInfo *card = screen->card;
693 KdPrivScreenPtr pScreenPriv;
694
695 /*
696 * note that screen->fb is set up for the nominal orientation
697 * of the screen; that means if randr is rotated, the values
698 * there should reflect a rotated frame buffer (or shadow).
699 */
700 Bool rotated = (screen->randr & (RR_Rotate_90 | RR_Rotate_270)) != 0;
701 int width, height, *width_mmp, *height_mmp;
702
703 KdAllocatePrivates(pScreen);
704
705 pScreenPriv = KdGetScreenPriv(pScreen);
706
707 if (!rotated) {
708 width = screen->width;
709 height = screen->height;
710 width_mmp = &screen->width_mm;
711 height_mmp = &screen->height_mm;
712 }
713 else {
714 width = screen->height;
715 height = screen->width;
716 width_mmp = &screen->height_mm;
717 height_mmp = &screen->width_mm;
718 }
719 screen->pScreen = pScreen;
720 pScreenPriv->screen = screen;
721 pScreenPriv->card = card;
722 pScreenPriv->bytesPerPixel = screen->fb.bitsPerPixel >> 3;
723 pScreenPriv->dpmsState = KD_DPMS_NORMAL;
724 pScreen->x = screen->origin.x;
725 pScreen->y = screen->origin.y;
726
727 if (!monitorResolution)
728 monitorResolution = 75;
729 /*
730 * This is done in this order so that backing store wraps
731 * our GC functions; fbFinishScreenInit initializes MI
732 * backing store
733 */
734 if (!fbSetupScreen(pScreen,
735 screen->fb.frameBuffer,
736 width, height,
737 monitorResolution, monitorResolution,
738 screen->fb.pixelStride, screen->fb.bitsPerPixel)) {
739 return FALSE;
740 }
741
742 /*
743 * Set colormap functions
744 */
745 pScreen->InstallColormap = KdInstallColormap;
746 pScreen->UninstallColormap = KdUninstallColormap;
747 pScreen->ListInstalledColormaps = KdListInstalledColormaps;
748 pScreen->StoreColors = KdStoreColors;
749
750 pScreen->SaveScreen = KdSaveScreen;
751 pScreen->CreateWindow = KdCreateWindow;
752
753 if (!fbFinishScreenInit(pScreen,
754 screen->fb.frameBuffer,
755 width, height,
756 monitorResolution, monitorResolution,
757 screen->fb.pixelStride, screen->fb.bitsPerPixel)) {
758 return FALSE;
759 }
760
761 /*
762 * Fix screen sizes; for some reason mi takes dpi instead of mm.
763 * Rounding errors are annoying
764 */
765 if (*width_mmp)
766 pScreen->mmWidth = *width_mmp;
767 else
768 *width_mmp = pScreen->mmWidth;
769 if (*height_mmp)
770 pScreen->mmHeight = *height_mmp;
771 else
772 *height_mmp = pScreen->mmHeight;
773
774 /*
775 * Plug in our own block/wakeup handlers.
776 * miScreenInit installs NoopDDA in both places
777 */
778 pScreen->BlockHandler = KdBlockHandler;
779 pScreen->WakeupHandler = KdWakeupHandler;
780
781 if (!fbPictureInit(pScreen, 0, 0))
782 return FALSE;
783 if (card->cfuncs->initScreen)
784 if (!(*card->cfuncs->initScreen) (pScreen))
785 return FALSE;
786
787 if (!screen->dumb && card->cfuncs->initAccel)
788 if (!(*card->cfuncs->initAccel) (pScreen))
789 screen->dumb = TRUE;
790
791 if (card->cfuncs->finishInitScreen)
792 if (!(*card->cfuncs->finishInitScreen) (pScreen))
793 return FALSE;
794
795 /*
796 * Wrap CloseScreen, the order now is:
797 * KdCloseScreen
798 * fbCloseScreen
799 */
800 pScreenPriv->CloseScreen = pScreen->CloseScreen;
801 pScreen->CloseScreen = KdCloseScreen;
802
803 pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources;
804 pScreen->CreateScreenResources = KdCreateScreenResources;
805
806 if (screen->softCursor ||
807 !card->cfuncs->initCursor || !(*card->cfuncs->initCursor) (pScreen)) {
808 /* Use MI for cursor display and event queueing. */
809 screen->softCursor = TRUE;
810 miDCInitialize(pScreen, &kdPointerScreenFuncs);
811 }
812
813 if (!fbCreateDefColormap(pScreen)) {
814 return FALSE;
815 }
816
817 KdSetSubpixelOrder(pScreen, screen->randr);
818
819 /*
820 * Enable the hardware
821 */
822 kdEnabled = TRUE;
823
824 if (screen->mynum == card->selected) {
825 pScreenPriv->enabled = TRUE;
826 KdEnableColormap(pScreen);
827 if (!screen->dumb && card->cfuncs->enableAccel)
828 (*card->cfuncs->enableAccel) (pScreen);
829 }
830
831 return TRUE;
832 }
833
834 static void
KdInitScreen(ScreenInfo * pScreenInfo,KdScreenInfo * screen,int argc,char ** argv)835 KdInitScreen(ScreenInfo * pScreenInfo,
836 KdScreenInfo * screen, int argc, char **argv)
837 {
838 KdCardInfo *card = screen->card;
839
840 if (!(*card->cfuncs->scrinit) (screen))
841 FatalError("Screen initialization failed!\n");
842
843 if (!card->cfuncs->initAccel)
844 screen->dumb = TRUE;
845 if (!card->cfuncs->initCursor)
846 screen->softCursor = TRUE;
847 }
848
849 static Bool
KdSetPixmapFormats(ScreenInfo * pScreenInfo)850 KdSetPixmapFormats(ScreenInfo * pScreenInfo)
851 {
852 CARD8 depthToBpp[33]; /* depth -> bpp map */
853 KdCardInfo *card;
854 KdScreenInfo *screen;
855 int i;
856 int bpp;
857 PixmapFormatRec *format;
858
859 for (i = 1; i <= 32; i++)
860 depthToBpp[i] = 0;
861
862 /*
863 * Generate mappings between bitsPerPixel and depth,
864 * also ensure that all screens comply with protocol
865 * restrictions on equivalent formats for the same
866 * depth on different screens
867 */
868 for (card = kdCardInfo; card; card = card->next) {
869 for (screen = card->screenList; screen; screen = screen->next) {
870 bpp = screen->fb.bitsPerPixel;
871 if (bpp == 24)
872 bpp = 32;
873 if (!depthToBpp[screen->fb.depth])
874 depthToBpp[screen->fb.depth] = bpp;
875 else if (depthToBpp[screen->fb.depth] != bpp)
876 return FALSE;
877 }
878 }
879
880 /*
881 * Fill in additional formats
882 */
883 for (i = 0; i < ARRAY_SIZE(kdDepths); i++)
884 if (!depthToBpp[kdDepths[i].depth])
885 depthToBpp[kdDepths[i].depth] = kdDepths[i].bpp;
886
887 pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
888 pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
889 pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
890 pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
891
892 pScreenInfo->numPixmapFormats = 0;
893
894 for (i = 1; i <= 32; i++) {
895 if (depthToBpp[i]) {
896 format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++];
897 format->depth = i;
898 format->bitsPerPixel = depthToBpp[i];
899 format->scanlinePad = BITMAP_SCANLINE_PAD;
900 }
901 }
902
903 return TRUE;
904 }
905
906 static void
KdAddScreen(ScreenInfo * pScreenInfo,KdScreenInfo * screen,int argc,char ** argv)907 KdAddScreen(ScreenInfo * pScreenInfo,
908 KdScreenInfo * screen, int argc, char **argv)
909 {
910 int i;
911
912 /*
913 * Fill in fb visual type masks for this screen
914 */
915 for (i = 0; i < pScreenInfo->numPixmapFormats; i++) {
916 unsigned long visuals;
917 Pixel rm, gm, bm;
918
919 visuals = 0;
920 rm = gm = bm = 0;
921 if (pScreenInfo->formats[i].depth == screen->fb.depth) {
922 visuals = screen->fb.visuals;
923 rm = screen->fb.redMask;
924 gm = screen->fb.greenMask;
925 bm = screen->fb.blueMask;
926 }
927 fbSetVisualTypesAndMasks(pScreenInfo->formats[i].depth,
928 visuals, 8, rm, gm, bm);
929 }
930
931 kdCurrentScreen = screen;
932
933 AddScreen(KdScreenInit, argc, argv);
934 }
935
936 void
KdInitOutput(ScreenInfo * pScreenInfo,int argc,char ** argv)937 KdInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
938 {
939 KdCardInfo *card;
940 KdScreenInfo *screen;
941
942 if (!kdCardInfo) {
943 InitCard(0);
944 if (!(card = KdCardInfoLast()))
945 FatalError("No matching cards found!\n");
946 screen = KdScreenInfoAdd(card);
947 KdParseScreen(screen, 0);
948 }
949 /*
950 * Initialize all of the screens for all of the cards
951 */
952 for (card = kdCardInfo; card; card = card->next) {
953 int ret = 1;
954
955 if (card->cfuncs->cardinit)
956 ret = (*card->cfuncs->cardinit) (card);
957 if (ret) {
958 for (screen = card->screenList; screen; screen = screen->next)
959 KdInitScreen(pScreenInfo, screen, argc, argv);
960 }
961 }
962
963 /*
964 * Merge the various pixmap formats together, this can fail
965 * when two screens share depth but not bitsPerPixel
966 */
967 if (!KdSetPixmapFormats(pScreenInfo))
968 return;
969
970 /*
971 * Add all of the screens
972 */
973 for (card = kdCardInfo; card; card = card->next)
974 for (screen = card->screenList; screen; screen = screen->next)
975 KdAddScreen(pScreenInfo, screen, argc, argv);
976
977 xorgGlxCreateVendor();
978
979 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
980 if (SeatId) /* Enable input hot-plugging */
981 config_pre_init();
982 #endif
983 }
984
985 void
OsVendorFatalError(const char * f,va_list args)986 OsVendorFatalError(const char *f, va_list args)
987 {
988 }
989
990 /* These stubs can be safely removed once we can
991 * split input and GPU parts in hotplug.h et al. */
992 #ifdef CONFIG_UDEV_KMS
993 void
NewGPUDeviceRequest(struct OdevAttributes * attribs)994 NewGPUDeviceRequest(struct OdevAttributes *attribs)
995 {
996 }
997
998 void
DeleteGPUDeviceRequest(struct OdevAttributes * attribs)999 DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
1000 {
1001 }
1002 #endif
1003
1004 struct xf86_platform_device *
xf86_find_platform_device_by_devnum(int major,int minor)1005 xf86_find_platform_device_by_devnum(int major, int minor)
1006 {
1007 return NULL;
1008 }
1009
1010 #ifdef SYSTEMD_LOGIND
1011 void
systemd_logind_vtenter(void)1012 systemd_logind_vtenter(void)
1013 {
1014 }
1015
1016 void
systemd_logind_release_fd(int major,int minor,int fd)1017 systemd_logind_release_fd(int major, int minor, int fd)
1018 {
1019 close(fd);
1020 }
1021 #endif
1022