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