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