2 * Copyright © 1999 Keith Packard
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.
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.
24 #include <kdrive-config.h>
27 #include <mivalidate.h>
28 #include <dixstruct.h>
42 #ifdef HAVE_EXECINFO_H
48 typedef struct _kdDepths
{
53 KdDepths kdDepths
[] = {
63 #define NUM_KD_DEPTHS (sizeof (kdDepths) / sizeof (kdDepths[0]))
65 #define KD_DEFAULT_BUTTONS 5
67 DevPrivateKeyRec kdScreenPrivateKeyRec
;
68 unsigned long kdGeneration
;
71 unsigned long kdVideoTestTime
;
72 Bool kdEmulateMiddleButton
;
73 Bool kdRawPointerCoordinates
;
78 int kdVirtualTerminal
= -1;
82 Bool kdHasPointer
= FALSE
;
83 Bool kdHasKbd
= FALSE
;
85 static Bool kdCaughtSignal
= FALSE
;
88 * Carry arguments from InitOutput through driver initialization
95 KdDisableScreen(ScreenPtr pScreen
)
97 KdScreenPriv(pScreen
);
99 if (!pScreenPriv
->enabled
)
101 if (!pScreenPriv
->closed
)
102 SetRootClip(pScreen
, FALSE
);
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_NORMAL
);
111 pScreenPriv
->enabled
= FALSE
;
112 if (pScreenPriv
->card
->cfuncs
->disable
)
113 (*pScreenPriv
->card
->cfuncs
->disable
) (pScreen
);
117 KdDoSwitchCmd(const char *reason
)
122 if (asprintf(&command
, "%s %s", kdSwitchCmd
, reason
) == -1)
133 KdScreenInfo
*screen
;
136 for (card
= kdCardInfo
; card
; card
= card
->next
) {
137 for (screen
= card
->screenList
; screen
; screen
= screen
->next
)
138 if (screen
->mynum
== card
->selected
&& screen
->pScreen
)
139 KdDisableScreen(screen
->pScreen
);
140 if (card
->driver
&& card
->cfuncs
->restore
)
141 (*card
->cfuncs
->restore
) (card
);
144 KdDoSwitchCmd("suspend");
149 KdDisableScreens(void)
153 if (kdOsFuncs
->Disable
)
154 (*kdOsFuncs
->Disable
) ();
160 KdEnableScreen(ScreenPtr pScreen
)
162 KdScreenPriv(pScreen
);
164 if (pScreenPriv
->enabled
)
166 if (pScreenPriv
->card
->cfuncs
->enable
)
167 if (!(*pScreenPriv
->card
->cfuncs
->enable
) (pScreen
))
169 pScreenPriv
->enabled
= TRUE
;
170 pScreenPriv
->dpmsState
= KD_DPMS_NORMAL
;
171 pScreenPriv
->card
->selected
= pScreenPriv
->screen
->mynum
;
172 if (!pScreenPriv
->screen
->softCursor
&&
173 pScreenPriv
->card
->cfuncs
->enableCursor
)
174 (*pScreenPriv
->card
->cfuncs
->enableCursor
) (pScreen
);
175 if (!pScreenPriv
->screen
->dumb
&& pScreenPriv
->card
->cfuncs
->enableAccel
)
176 (*pScreenPriv
->card
->cfuncs
->enableAccel
) (pScreen
);
177 KdEnableColormap(pScreen
);
178 SetRootClip(pScreen
, TRUE
);
179 if (pScreenPriv
->card
->cfuncs
->dpms
)
180 (*pScreenPriv
->card
->cfuncs
->dpms
) (pScreen
, pScreenPriv
->dpmsState
);
188 KdScreenInfo
*screen
;
191 KdDoSwitchCmd("resume");
192 for (card
= kdCardInfo
; card
; card
= card
->next
) {
193 if (card
->cfuncs
->preserve
)
194 (*card
->cfuncs
->preserve
) (card
);
195 for (screen
= card
->screenList
; screen
; screen
= screen
->next
)
196 if (screen
->mynum
== card
->selected
&& screen
->pScreen
)
197 KdEnableScreen(screen
->pScreen
);
205 KdEnableScreens(void)
209 if (kdOsFuncs
->Enable
)
210 (*kdOsFuncs
->Enable
) ();
216 KdProcessSwitch(void)
225 AbortDDX(enum ExitCode error
)
229 if (kdEnabled
&& kdOsFuncs
->Disable
)
230 (*kdOsFuncs
->Disable
) ();
232 (*kdOsFuncs
->Fini
) ();
233 KdDoSwitchCmd("stop");
241 ddxGiveUp(enum ExitCode error
)
250 KdParseFindNext(const char *cur
, const char *delim
, char *save
, char *last
)
252 while (*cur
&& !strchr(delim
, *cur
)) {
263 KdAddRotation(Rotation a
, Rotation b
)
265 Rotation rotate
= (a
& RR_Rotate_All
) * (b
& RR_Rotate_All
);
266 Rotation reflect
= (a
& RR_Reflect_All
) ^ (b
& RR_Reflect_All
);
268 if (rotate
> RR_Rotate_270
)
269 rotate
/= (RR_Rotate_270
* RR_Rotate_90
);
270 return reflect
| rotate
;
274 KdSubRotation(Rotation a
, Rotation b
)
276 Rotation rotate
= (a
& RR_Rotate_All
) * 16 / (b
& RR_Rotate_All
);
277 Rotation reflect
= (a
& RR_Reflect_All
) ^ (b
& RR_Reflect_All
);
279 if (rotate
> RR_Rotate_270
)
280 rotate
/= (RR_Rotate_270
* RR_Rotate_90
);
281 return reflect
| rotate
;
285 KdParseScreen(KdScreenInfo
* screen
, const char *arg
)
292 screen
->dumb
= kdDumbDriver
;
293 screen
->softCursor
= kdSoftCursor
;
294 screen
->origin
= kdOrigin
;
295 screen
->randr
= RR_Rotate_0
;
298 screen
->width_mm
= 0;
299 screen
->height_mm
= 0;
300 screen
->subpixel_order
= kdSubpixelOrder
;
302 screen
->fb
.depth
= 0;
305 if (strlen(arg
) >= sizeof(save
))
308 for (i
= 0; i
< 2; i
++) {
309 arg
= KdParseFindNext(arg
, "x/@XY", save
, &delim
);
317 arg
= KdParseFindNext(arg
, "x@XY", save
, &delim
);
324 screen
->width
= pixels
;
325 screen
->width_mm
= mm
;
328 screen
->height
= pixels
;
329 screen
->height_mm
= mm
;
331 if (delim
!= 'x' && delim
!= '@' && delim
!= 'X' && delim
!= 'Y' &&
332 (delim
!= '\0' || i
== 0))
336 kdOrigin
.x
+= screen
->width
;
338 kdDumbDriver
= FALSE
;
339 kdSoftCursor
= FALSE
;
340 kdSubpixelOrder
= SubPixelUnknown
;
343 arg
= KdParseFindNext(arg
, "xXY", save
, &delim
);
345 int rotate
= atoi(save
);
348 screen
->randr
= RR_Rotate_0
;
349 else if (rotate
< 135)
350 screen
->randr
= RR_Rotate_90
;
351 else if (rotate
< 225)
352 screen
->randr
= RR_Rotate_180
;
353 else if (rotate
< 315)
354 screen
->randr
= RR_Rotate_270
;
356 screen
->randr
= RR_Rotate_0
;
360 arg
= KdParseFindNext(arg
, "xY", save
, &delim
);
361 screen
->randr
|= RR_Reflect_X
;
365 arg
= KdParseFindNext(arg
, "xY", save
, &delim
);
366 screen
->randr
|= RR_Reflect_Y
;
369 arg
= KdParseFindNext(arg
, "x/,", save
, &delim
);
371 screen
->fb
.depth
= atoi(save
);
373 arg
= KdParseFindNext(arg
, "x,", save
, &delim
);
375 screen
->fb
.bitsPerPixel
= atoi(save
);
378 screen
->fb
.bitsPerPixel
= 0;
382 arg
= KdParseFindNext(arg
, "x", save
, &delim
);
384 screen
->rate
= atoi(save
);
389 * Mouse argument syntax:
391 * device,protocol,options...
393 * Options are any of:
395 * 2button emulate middle button
396 * {NMO} Reorder buttons
400 KdParseRgba(char *rgba
)
402 if (!strcmp(rgba
, "rgb"))
403 kdSubpixelOrder
= SubPixelHorizontalRGB
;
404 else if (!strcmp(rgba
, "bgr"))
405 kdSubpixelOrder
= SubPixelHorizontalBGR
;
406 else if (!strcmp(rgba
, "vrgb"))
407 kdSubpixelOrder
= SubPixelVerticalRGB
;
408 else if (!strcmp(rgba
, "vbgr"))
409 kdSubpixelOrder
= SubPixelVerticalBGR
;
410 else if (!strcmp(rgba
, "none"))
411 kdSubpixelOrder
= SubPixelNone
;
413 kdSubpixelOrder
= SubPixelUnknown
;
419 ErrorF("\nTinyX Device Dependent Usage:\n");
421 ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][@ROTATION][X][Y][xDEPTH/BPP[xFREQ]] Specify screen characteristics\n");
423 ("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n");
425 ("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n");
427 ("-keybd driver [,,options] Specify the keyboard driver and its options\n");
428 ErrorF("-zaphod Disable cursor screen switching\n");
429 ErrorF("-2button Emulate 3 button mouse\n");
430 ErrorF("-3button Disable 3 button mouse emulation\n");
432 ("-rawcoord Don't transform pointer coordinates on rotation\n");
433 ErrorF("-dumb Disable hardware acceleration\n");
434 ErrorF("-softCursor Force software cursor\n");
435 ErrorF("-videoTest Start the server, pause momentarily and exit\n");
437 ("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n");
438 ErrorF("-switchCmd Command to execute on vt switch\n");
439 ErrorF("-zap Terminate server on Ctrl+Alt+Backspace\n");
441 ("vtxx Use virtual terminal xx instead of the next available\n");
445 KdProcessArgument(int argc
, char **argv
, int i
)
448 KdScreenInfo
*screen
;
450 if (!strcmp(argv
[i
], "-screen")) {
451 if ((i
+ 1) < argc
) {
452 card
= KdCardInfoLast();
455 card
= KdCardInfoLast();
458 screen
= KdScreenInfoAdd(card
);
459 KdParseScreen(screen
, argv
[i
+ 1]);
462 ErrorF("No matching card found!\n");
468 if (!strcmp(argv
[i
], "-zaphod")) {
469 kdDisableZaphod
= TRUE
;
472 if (!strcmp(argv
[i
], "-zap")) {
476 if (!strcmp(argv
[i
], "-3button")) {
477 kdEmulateMiddleButton
= FALSE
;
480 if (!strcmp(argv
[i
], "-2button")) {
481 kdEmulateMiddleButton
= TRUE
;
484 if (!strcmp(argv
[i
], "-rawcoord")) {
485 kdRawPointerCoordinates
= 1;
488 if (!strcmp(argv
[i
], "-dumb")) {
492 if (!strcmp(argv
[i
], "-softCursor")) {
496 if (!strcmp(argv
[i
], "-videoTest")) {
500 if (!strcmp(argv
[i
], "-origin")) {
501 if ((i
+ 1) < argc
) {
502 char *x
= argv
[i
+ 1];
503 char *y
= strchr(x
, ',');
506 kdOrigin
.x
= atoi(x
);
510 kdOrigin
.y
= atoi(y
+ 1);
518 if (!strcmp(argv
[i
], "-rgba")) {
520 KdParseRgba(argv
[i
+ 1]);
525 if (!strcmp(argv
[i
], "-switchCmd")) {
527 kdSwitchCmd
= argv
[i
+ 1];
532 if (!strncmp(argv
[i
], "vt", 2) &&
533 sscanf(argv
[i
], "vt%2d", &kdVirtualTerminal
) == 1) {
536 if (!strcmp(argv
[i
], "-mouse") || !strcmp(argv
[i
], "-pointer")) {
539 KdAddConfigPointer(argv
[i
+ 1]);
543 if (!strcmp(argv
[i
], "-keybd")) {
546 KdAddConfigKeyboard(argv
[i
+ 1]);
555 * These are getting tossed in here until I can think of where
560 KdOsInit(KdOsFuncs
* pOsFuncs
)
562 kdOsFuncs
= pOsFuncs
;
564 if (serverGeneration
== 1) {
565 KdDoSwitchCmd("start");
567 (*pOsFuncs
->Init
) ();
573 KdAllocatePrivates(ScreenPtr pScreen
)
575 KdPrivScreenPtr pScreenPriv
;
577 if (kdGeneration
!= serverGeneration
)
578 kdGeneration
= serverGeneration
;
580 if (!dixRegisterPrivateKey(&kdScreenPrivateKeyRec
, PRIVATE_SCREEN
, 0))
583 pScreenPriv
= calloc(1, sizeof(*pScreenPriv
));
586 KdSetScreenPriv(pScreen
, pScreenPriv
);
591 KdCreateScreenResources(ScreenPtr pScreen
)
593 KdScreenPriv(pScreen
);
594 KdCardInfo
*card
= pScreenPriv
->card
;
597 pScreen
->CreateScreenResources
= pScreenPriv
->CreateScreenResources
;
598 if (pScreen
->CreateScreenResources
)
599 ret
= (*pScreen
->CreateScreenResources
) (pScreen
);
602 pScreenPriv
->CreateScreenResources
= pScreen
->CreateScreenResources
;
603 pScreen
->CreateScreenResources
= KdCreateScreenResources
;
604 if (ret
&& card
->cfuncs
->createRes
)
605 ret
= (*card
->cfuncs
->createRes
) (pScreen
);
610 KdCloseScreen(ScreenPtr pScreen
)
612 KdScreenPriv(pScreen
);
613 KdScreenInfo
*screen
= pScreenPriv
->screen
;
614 KdCardInfo
*card
= pScreenPriv
->card
;
617 pScreenPriv
->closed
= TRUE
;
618 pScreen
->CloseScreen
= pScreenPriv
->CloseScreen
;
619 if (pScreen
->CloseScreen
)
620 ret
= (*pScreen
->CloseScreen
) (pScreen
);
624 if (pScreenPriv
->dpmsState
!= KD_DPMS_NORMAL
)
625 (*card
->cfuncs
->dpms
) (pScreen
, KD_DPMS_NORMAL
);
627 if (screen
->mynum
== card
->selected
)
628 KdDisableScreen(pScreen
);
631 * Restore video hardware when last screen is closed
633 if (screen
== card
->screenList
) {
634 if (kdEnabled
&& card
->cfuncs
->restore
)
635 (*card
->cfuncs
->restore
) (card
);
638 if (!pScreenPriv
->screen
->dumb
&& card
->cfuncs
->finiAccel
)
639 (*card
->cfuncs
->finiAccel
) (pScreen
);
641 if (!pScreenPriv
->screen
->softCursor
&& card
->cfuncs
->finiCursor
)
642 (*card
->cfuncs
->finiCursor
) (pScreen
);
644 if (card
->cfuncs
->scrfini
)
645 (*card
->cfuncs
->scrfini
) (screen
);
648 * Clean up card when last screen is closed, DIX closes them in
649 * reverse order, thus we check for when the first in the list is closed
651 if (screen
== card
->screenList
) {
652 if (card
->cfuncs
->cardfini
)
653 (*card
->cfuncs
->cardfini
) (card
);
655 * Clean up OS when last card is closed
657 if (card
== kdCardInfo
) {
660 if (kdOsFuncs
->Disable
)
661 (*kdOsFuncs
->Disable
) ();
666 pScreenPriv
->screen
->pScreen
= 0;
668 free((pointer
) pScreenPriv
);
673 KdSaveScreen(ScreenPtr pScreen
, int on
)
675 KdScreenPriv(pScreen
);
678 if (!pScreenPriv
->card
->cfuncs
->dpms
)
681 dpmsState
= pScreenPriv
->dpmsState
;
683 case SCREEN_SAVER_OFF
:
684 dpmsState
= KD_DPMS_NORMAL
;
686 case SCREEN_SAVER_ON
:
687 if (dpmsState
== KD_DPMS_NORMAL
)
688 dpmsState
= KD_DPMS_NORMAL
+ 1;
690 case SCREEN_SAVER_CYCLE
:
691 if (dpmsState
< KD_DPMS_MAX
)
694 case SCREEN_SAVER_FORCER
:
697 if (dpmsState
!= pScreenPriv
->dpmsState
) {
698 if (pScreenPriv
->enabled
)
699 (*pScreenPriv
->card
->cfuncs
->dpms
) (pScreen
, dpmsState
);
700 pScreenPriv
->dpmsState
= dpmsState
;
706 KdCreateWindow(WindowPtr pWin
)
710 KdScreenPriv(pWin
->drawable
.pScreen
);
712 if (!pScreenPriv
->enabled
) {
713 RegionEmpty(&pWin
->borderClip
);
714 RegionBreak(&pWin
->clipList
);
718 return fbCreateWindow(pWin
);
722 KdSetSubpixelOrder(ScreenPtr pScreen
, Rotation randr
)
724 KdScreenPriv(pScreen
);
725 KdScreenInfo
*screen
= pScreenPriv
->screen
;
726 int subpixel_order
= screen
->subpixel_order
;
727 Rotation subpixel_dir
;
734 {SubPixelHorizontalRGB
, RR_Rotate_0
},
735 {SubPixelHorizontalBGR
, RR_Rotate_180
},
736 {SubPixelVerticalRGB
, RR_Rotate_270
},
737 {SubPixelVerticalBGR
, RR_Rotate_90
},
745 {RR_Reflect_X
, SubPixelHorizontalRGB
, SubPixelHorizontalBGR
},
746 {RR_Reflect_X
, SubPixelHorizontalBGR
, SubPixelHorizontalRGB
},
747 {RR_Reflect_Y
, SubPixelVerticalRGB
, SubPixelVerticalBGR
},
748 {RR_Reflect_Y
, SubPixelVerticalRGB
, SubPixelVerticalRGB
},
751 /* map subpixel to direction */
752 for (i
= 0; i
< 4; i
++)
753 if (orders
[i
].subpixel_order
== subpixel_order
)
757 KdAddRotation(randr
& RR_Rotate_All
, orders
[i
].direction
);
759 /* map back to subpixel order */
760 for (i
= 0; i
< 4; i
++)
761 if (orders
[i
].direction
& subpixel_dir
) {
762 subpixel_order
= orders
[i
].subpixel_order
;
766 for (i
= 0; i
< 4; i
++)
767 if ((randr
& reflects
[i
].bit
) &&
768 reflects
[i
].normal
== subpixel_order
) {
769 subpixel_order
= reflects
[i
].reflect
;
773 PictureSetSubpixelOrder(pScreen
, subpixel_order
);
776 /* Pass through AddScreen, which doesn't take any closure */
777 static KdScreenInfo
*kdCurrentScreen
;
780 KdScreenInit(ScreenPtr pScreen
, int argc
, char **argv
)
782 KdScreenInfo
*screen
= kdCurrentScreen
;
783 KdCardInfo
*card
= screen
->card
;
784 KdPrivScreenPtr pScreenPriv
;
787 * note that screen->fb is set up for the nominal orientation
788 * of the screen; that means if randr is rotated, the values
789 * there should reflect a rotated frame buffer (or shadow).
791 Bool rotated
= (screen
->randr
& (RR_Rotate_90
| RR_Rotate_270
)) != 0;
792 int width
, height
, *width_mmp
, *height_mmp
;
794 KdAllocatePrivates(pScreen
);
796 pScreenPriv
= KdGetScreenPriv(pScreen
);
799 width
= screen
->width
;
800 height
= screen
->height
;
801 width_mmp
= &screen
->width_mm
;
802 height_mmp
= &screen
->height_mm
;
805 width
= screen
->height
;
806 height
= screen
->width
;
807 width_mmp
= &screen
->height_mm
;
808 height_mmp
= &screen
->width_mm
;
810 screen
->pScreen
= pScreen
;
811 pScreenPriv
->screen
= screen
;
812 pScreenPriv
->card
= card
;
813 pScreenPriv
->bytesPerPixel
= screen
->fb
.bitsPerPixel
>> 3;
814 pScreenPriv
->dpmsState
= KD_DPMS_NORMAL
;
815 pScreen
->x
= screen
->origin
.x
;
816 pScreen
->y
= screen
->origin
.y
;
818 if (!monitorResolution
)
819 monitorResolution
= 75;
821 * This is done in this order so that backing store wraps
822 * our GC functions; fbFinishScreenInit initializes MI
825 if (!fbSetupScreen(pScreen
,
826 screen
->fb
.frameBuffer
,
828 monitorResolution
, monitorResolution
,
829 screen
->fb
.pixelStride
, screen
->fb
.bitsPerPixel
)) {
834 * Set colormap functions
836 pScreen
->InstallColormap
= KdInstallColormap
;
837 pScreen
->UninstallColormap
= KdUninstallColormap
;
838 pScreen
->ListInstalledColormaps
= KdListInstalledColormaps
;
839 pScreen
->StoreColors
= KdStoreColors
;
841 pScreen
->SaveScreen
= KdSaveScreen
;
842 pScreen
->CreateWindow
= KdCreateWindow
;
844 if (!fbFinishScreenInit(pScreen
,
845 screen
->fb
.frameBuffer
,
847 monitorResolution
, monitorResolution
,
848 screen
->fb
.pixelStride
, screen
->fb
.bitsPerPixel
)) {
853 * Fix screen sizes; for some reason mi takes dpi instead of mm.
854 * Rounding errors are annoying
857 pScreen
->mmWidth
= *width_mmp
;
859 *width_mmp
= pScreen
->mmWidth
;
861 pScreen
->mmHeight
= *height_mmp
;
863 *height_mmp
= pScreen
->mmHeight
;
866 * Plug in our own block/wakeup handlers.
867 * miScreenInit installs NoopDDA in both places
869 pScreen
->BlockHandler
= KdBlockHandler
;
870 pScreen
->WakeupHandler
= KdWakeupHandler
;
872 if (!fbPictureInit(pScreen
, 0, 0))
874 if (card
->cfuncs
->initScreen
)
875 if (!(*card
->cfuncs
->initScreen
) (pScreen
))
878 if (!screen
->dumb
&& card
->cfuncs
->initAccel
)
879 if (!(*card
->cfuncs
->initAccel
) (pScreen
))
882 if (card
->cfuncs
->finishInitScreen
)
883 if (!(*card
->cfuncs
->finishInitScreen
) (pScreen
))
887 fbInitValidateTree(pScreen
);
891 * Wrap CloseScreen, the order now is:
896 pScreenPriv
->CloseScreen
= pScreen
->CloseScreen
;
897 pScreen
->CloseScreen
= KdCloseScreen
;
899 pScreenPriv
->CreateScreenResources
= pScreen
->CreateScreenResources
;
900 pScreen
->CreateScreenResources
= KdCreateScreenResources
;
902 if (screen
->softCursor
||
903 !card
->cfuncs
->initCursor
|| !(*card
->cfuncs
->initCursor
) (pScreen
)) {
904 /* Use MI for cursor display and event queueing. */
905 screen
->softCursor
= TRUE
;
906 miDCInitialize(pScreen
, &kdPointerScreenFuncs
);
909 if (!fbCreateDefColormap(pScreen
)) {
913 KdSetSubpixelOrder(pScreen
, screen
->randr
);
916 * Enable the hardware
920 if (kdOsFuncs
->Enable
)
921 (*kdOsFuncs
->Enable
) ();
924 if (screen
->mynum
== card
->selected
) {
925 if (card
->cfuncs
->preserve
)
926 (*card
->cfuncs
->preserve
) (card
);
927 if (card
->cfuncs
->enable
)
928 if (!(*card
->cfuncs
->enable
) (pScreen
))
930 pScreenPriv
->enabled
= TRUE
;
931 if (!screen
->softCursor
&& card
->cfuncs
->enableCursor
)
932 (*card
->cfuncs
->enableCursor
) (pScreen
);
933 KdEnableColormap(pScreen
);
934 if (!screen
->dumb
&& card
->cfuncs
->enableAccel
)
935 (*card
->cfuncs
->enableAccel
) (pScreen
);
942 KdInitScreen(ScreenInfo
* pScreenInfo
,
943 KdScreenInfo
* screen
, int argc
, char **argv
)
945 KdCardInfo
*card
= screen
->card
;
947 if (!(*card
->cfuncs
->scrinit
) (screen
))
948 FatalError("Screen initialization failed!\n");
950 if (!card
->cfuncs
->initAccel
)
952 if (!card
->cfuncs
->initCursor
)
953 screen
->softCursor
= TRUE
;
957 KdSetPixmapFormats(ScreenInfo
* pScreenInfo
)
959 CARD8 depthToBpp
[33]; /* depth -> bpp map */
961 KdScreenInfo
*screen
;
964 PixmapFormatRec
*format
;
966 for (i
= 1; i
<= 32; i
++)
970 * Generate mappings between bitsPerPixel and depth,
971 * also ensure that all screens comply with protocol
972 * restrictions on equivalent formats for the same
973 * depth on different screens
975 for (card
= kdCardInfo
; card
; card
= card
->next
) {
976 for (screen
= card
->screenList
; screen
; screen
= screen
->next
) {
977 bpp
= screen
->fb
.bitsPerPixel
;
980 if (!depthToBpp
[screen
->fb
.depth
])
981 depthToBpp
[screen
->fb
.depth
] = bpp
;
982 else if (depthToBpp
[screen
->fb
.depth
] != bpp
)
988 * Fill in additional formats
990 for (i
= 0; i
< NUM_KD_DEPTHS
; i
++)
991 if (!depthToBpp
[kdDepths
[i
].depth
])
992 depthToBpp
[kdDepths
[i
].depth
] = kdDepths
[i
].bpp
;
994 pScreenInfo
->imageByteOrder
= IMAGE_BYTE_ORDER
;
995 pScreenInfo
->bitmapScanlineUnit
= BITMAP_SCANLINE_UNIT
;
996 pScreenInfo
->bitmapScanlinePad
= BITMAP_SCANLINE_PAD
;
997 pScreenInfo
->bitmapBitOrder
= BITMAP_BIT_ORDER
;
999 pScreenInfo
->numPixmapFormats
= 0;
1001 for (i
= 1; i
<= 32; i
++) {
1002 if (depthToBpp
[i
]) {
1003 format
= &pScreenInfo
->formats
[pScreenInfo
->numPixmapFormats
++];
1005 format
->bitsPerPixel
= depthToBpp
[i
];
1006 format
->scanlinePad
= BITMAP_SCANLINE_PAD
;
1014 KdAddScreen(ScreenInfo
* pScreenInfo
,
1015 KdScreenInfo
* screen
, int argc
, char **argv
)
1020 * Fill in fb visual type masks for this screen
1022 for (i
= 0; i
< pScreenInfo
->numPixmapFormats
; i
++) {
1023 unsigned long visuals
;
1028 if (pScreenInfo
->formats
[i
].depth
== screen
->fb
.depth
) {
1029 visuals
= screen
->fb
.visuals
;
1030 rm
= screen
->fb
.redMask
;
1031 gm
= screen
->fb
.greenMask
;
1032 bm
= screen
->fb
.blueMask
;
1034 fbSetVisualTypesAndMasks(pScreenInfo
->formats
[i
].depth
,
1035 visuals
, 8, rm
, gm
, bm
);
1038 kdCurrentScreen
= screen
;
1040 AddScreen(KdScreenInit
, argc
, argv
);
1043 #if 0 /* This function is not used currently */
1046 KdDepthToFb(ScreenPtr pScreen
, int depth
)
1048 KdScreenPriv(pScreen
);
1050 for (fb
= 0; fb
<= KD_MAX_FB
&& pScreenPriv
->screen
->fb
.frameBuffer
; fb
++)
1051 if (pScreenPriv
->screen
->fb
.depth
== depth
)
1058 KdSignalWrapper(int signum
)
1060 kdCaughtSignal
= TRUE
;
1061 return 1; /* use generic OS layer cleanup & abort */
1065 KdInitOutput(ScreenInfo
* pScreenInfo
, int argc
, char **argv
)
1068 KdScreenInfo
*screen
;
1072 if (!(card
= KdCardInfoLast()))
1073 FatalError("No matching cards found!\n");
1074 screen
= KdScreenInfoAdd(card
);
1075 KdParseScreen(screen
, 0);
1078 * Initialize all of the screens for all of the cards
1080 for (card
= kdCardInfo
; card
; card
= card
->next
) {
1083 if (card
->cfuncs
->cardinit
)
1084 ret
= (*card
->cfuncs
->cardinit
) (card
);
1086 for (screen
= card
->screenList
; screen
; screen
= screen
->next
)
1087 KdInitScreen(pScreenInfo
, screen
, argc
, argv
);
1092 * Merge the various pixmap formats together, this can fail
1093 * when two screens share depth but not bitsPerPixel
1095 if (!KdSetPixmapFormats(pScreenInfo
))
1099 * Add all of the screens
1101 for (card
= kdCardInfo
; card
; card
= card
->next
)
1102 for (screen
= card
->screenList
; screen
; screen
= screen
->next
)
1103 KdAddScreen(pScreenInfo
, screen
, argc
, argv
);
1105 OsRegisterSigWrapper(KdSignalWrapper
);
1109 OsVendorFatalError(const char *f
, va_list args
)
1114 DPMSSet(ClientPtr client
, int level
)