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