105b261ecSmrg/* 205b261ecSmrg * Copyright © 1999 Keith Packard 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Keith Packard not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Keith Packard makes no 1105b261ecSmrg * representations about the suitability of this software for any purpose. It 1205b261ecSmrg * is provided "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg */ 2205b261ecSmrg 231b5d61b8Smrg#ifdef HAVE_DIX_CONFIG_H 241b5d61b8Smrg#include <dix-config.h> 2505b261ecSmrg#endif 2605b261ecSmrg#include "kdrive.h" 2705b261ecSmrg#include <mivalidate.h> 2805b261ecSmrg#include <dixstruct.h> 294642e01fSmrg#include "privates.h" 3005b261ecSmrg#ifdef RANDR 3105b261ecSmrg#include <randrstr.h> 3205b261ecSmrg#endif 331b5d61b8Smrg#include "glx_extinit.h" 3405b261ecSmrg 3505b261ecSmrg#ifdef XV 3605b261ecSmrg#include "kxv.h" 3705b261ecSmrg#endif 3805b261ecSmrg 3905b261ecSmrg#ifdef DPMSExtension 4005b261ecSmrg#include "dpmsproc.h" 4105b261ecSmrg#endif 4205b261ecSmrg 4305b261ecSmrg#ifdef HAVE_EXECINFO_H 4405b261ecSmrg#include <execinfo.h> 4505b261ecSmrg#endif 4605b261ecSmrg 471b5d61b8Smrg#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 481b5d61b8Smrg#include <hotplug.h> 491b5d61b8Smrg#endif 501b5d61b8Smrg 511b5d61b8Smrg/* This stub can be safely removed once we can 521b5d61b8Smrg * split input and GPU parts in hotplug.h et al. */ 531b5d61b8Smrg#include <systemd-logind.h> 5405b261ecSmrg 5505b261ecSmrgtypedef struct _kdDepths { 5635c4bbdfSmrg CARD8 depth; 5735c4bbdfSmrg CARD8 bpp; 5805b261ecSmrg} KdDepths; 5905b261ecSmrg 6035c4bbdfSmrgKdDepths kdDepths[] = { 6135c4bbdfSmrg {1, 1}, 6235c4bbdfSmrg {4, 4}, 6335c4bbdfSmrg {8, 8}, 6435c4bbdfSmrg {15, 16}, 6535c4bbdfSmrg {16, 16}, 6635c4bbdfSmrg {24, 32}, 6735c4bbdfSmrg {32, 32} 6805b261ecSmrg}; 6905b261ecSmrg 7005b261ecSmrg#define KD_DEFAULT_BUTTONS 5 7105b261ecSmrg 7235c4bbdfSmrgDevPrivateKeyRec kdScreenPrivateKeyRec; 731b5d61b8Smrgstatic unsigned long kdGeneration; 7435c4bbdfSmrg 7535c4bbdfSmrgBool kdEmulateMiddleButton; 7635c4bbdfSmrgBool kdRawPointerCoordinates; 7735c4bbdfSmrgBool kdDisableZaphod; 781b5d61b8Smrgstatic Bool kdEnabled; 791b5d61b8Smrgstatic int kdSubpixelOrder; 801b5d61b8Smrgstatic char *kdSwitchCmd; 811b5d61b8Smrgstatic DDXPointRec kdOrigin; 8235c4bbdfSmrgBool kdHasPointer = FALSE; 8335c4bbdfSmrgBool kdHasKbd = FALSE; 841b5d61b8Smrgconst char *kdGlobalXkbRules = NULL; 851b5d61b8Smrgconst char *kdGlobalXkbModel = NULL; 861b5d61b8Smrgconst char *kdGlobalXkbLayout = NULL; 871b5d61b8Smrgconst char *kdGlobalXkbVariant = NULL; 881b5d61b8Smrgconst char *kdGlobalXkbOptions = NULL; 8905b261ecSmrg 9005b261ecSmrgvoid 9135c4bbdfSmrgKdDisableScreen(ScreenPtr pScreen) 9205b261ecSmrg{ 9305b261ecSmrg KdScreenPriv(pScreen); 946747b715Smrg 9505b261ecSmrg if (!pScreenPriv->enabled) 9635c4bbdfSmrg return; 9705b261ecSmrg if (!pScreenPriv->closed) 9835c4bbdfSmrg SetRootClip(pScreen, ROOT_CLIP_NONE); 9935c4bbdfSmrg KdDisableColormap(pScreen); 10005b261ecSmrg if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel) 10135c4bbdfSmrg (*pScreenPriv->card->cfuncs->disableAccel) (pScreen); 10205b261ecSmrg pScreenPriv->enabled = FALSE; 10305b261ecSmrg} 10405b261ecSmrg 10505b261ecSmrgstatic void 10635c4bbdfSmrgKdDoSwitchCmd(const char *reason) 10705b261ecSmrg{ 10835c4bbdfSmrg if (kdSwitchCmd) { 10935c4bbdfSmrg char *command; 11035c4bbdfSmrg int ret; 11135c4bbdfSmrg 11235c4bbdfSmrg if (asprintf(&command, "%s %s", kdSwitchCmd, reason) == -1) 11335c4bbdfSmrg return; 11435c4bbdfSmrg 11535c4bbdfSmrg /* Ignore the return value from system; I'm not sure 11635c4bbdfSmrg * there's anything more useful to be done when 11735c4bbdfSmrg * it fails 11835c4bbdfSmrg */ 11935c4bbdfSmrg ret = system(command); 12035c4bbdfSmrg (void) ret; 12135c4bbdfSmrg free(command); 12205b261ecSmrg } 12305b261ecSmrg} 12405b261ecSmrg 1251b5d61b8Smrgstatic void 12635c4bbdfSmrgKdSuspend(void) 12705b261ecSmrg{ 12835c4bbdfSmrg KdCardInfo *card; 12935c4bbdfSmrg KdScreenInfo *screen; 13035c4bbdfSmrg 13135c4bbdfSmrg if (kdEnabled) { 13235c4bbdfSmrg for (card = kdCardInfo; card; card = card->next) { 13335c4bbdfSmrg for (screen = card->screenList; screen; screen = screen->next) 13435c4bbdfSmrg if (screen->mynum == card->selected && screen->pScreen) 13535c4bbdfSmrg KdDisableScreen(screen->pScreen); 13635c4bbdfSmrg } 13735c4bbdfSmrg KdDisableInput(); 13835c4bbdfSmrg KdDoSwitchCmd("suspend"); 13905b261ecSmrg } 14005b261ecSmrg} 14105b261ecSmrg 1421b5d61b8Smrgstatic void 14335c4bbdfSmrgKdDisableScreens(void) 14405b261ecSmrg{ 14535c4bbdfSmrg KdSuspend(); 1461b5d61b8Smrg kdEnabled = FALSE; 14705b261ecSmrg} 14805b261ecSmrg 14905b261ecSmrgBool 15035c4bbdfSmrgKdEnableScreen(ScreenPtr pScreen) 15105b261ecSmrg{ 15235c4bbdfSmrg KdScreenPriv(pScreen); 15305b261ecSmrg 15405b261ecSmrg if (pScreenPriv->enabled) 15535c4bbdfSmrg return TRUE; 15605b261ecSmrg pScreenPriv->enabled = TRUE; 15705b261ecSmrg pScreenPriv->dpmsState = KD_DPMS_NORMAL; 15805b261ecSmrg pScreenPriv->card->selected = pScreenPriv->screen->mynum; 15905b261ecSmrg if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel) 16035c4bbdfSmrg (*pScreenPriv->card->cfuncs->enableAccel) (pScreen); 16135c4bbdfSmrg KdEnableColormap(pScreen); 16235c4bbdfSmrg SetRootClip(pScreen, ROOT_CLIP_FULL); 16305b261ecSmrg return TRUE; 16405b261ecSmrg} 16505b261ecSmrg 16605b261ecSmrgvoid 16735c4bbdfSmrgddxGiveUp(enum ExitCode error) 16805b261ecSmrg{ 169ed6184dfSmrg KdDisableScreens(); 17005b261ecSmrg} 17105b261ecSmrg 1721b5d61b8Smrgstatic Bool kdDumbDriver; 1731b5d61b8Smrgstatic Bool kdSoftCursor; 17405b261ecSmrg 17535c4bbdfSmrgconst char * 17635c4bbdfSmrgKdParseFindNext(const char *cur, const char *delim, char *save, char *last) 17705b261ecSmrg{ 17835c4bbdfSmrg while (*cur && !strchr(delim, *cur)) { 17935c4bbdfSmrg *save++ = *cur++; 18005b261ecSmrg } 18105b261ecSmrg *save = 0; 18205b261ecSmrg *last = *cur; 18305b261ecSmrg if (*cur) 18435c4bbdfSmrg cur++; 18505b261ecSmrg return cur; 18605b261ecSmrg} 18705b261ecSmrg 18805b261ecSmrgRotation 18935c4bbdfSmrgKdAddRotation(Rotation a, Rotation b) 19005b261ecSmrg{ 19135c4bbdfSmrg Rotation rotate = (a & RR_Rotate_All) * (b & RR_Rotate_All); 19235c4bbdfSmrg Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All); 19305b261ecSmrg 19405b261ecSmrg if (rotate > RR_Rotate_270) 19535c4bbdfSmrg rotate /= (RR_Rotate_270 * RR_Rotate_90); 19605b261ecSmrg return reflect | rotate; 19705b261ecSmrg} 19805b261ecSmrg 19905b261ecSmrgRotation 20035c4bbdfSmrgKdSubRotation(Rotation a, Rotation b) 20105b261ecSmrg{ 20235c4bbdfSmrg Rotation rotate = (a & RR_Rotate_All) * 16 / (b & RR_Rotate_All); 20335c4bbdfSmrg Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All); 20405b261ecSmrg 20505b261ecSmrg if (rotate > RR_Rotate_270) 20635c4bbdfSmrg rotate /= (RR_Rotate_270 * RR_Rotate_90); 20705b261ecSmrg return reflect | rotate; 20805b261ecSmrg} 20905b261ecSmrg 21005b261ecSmrgvoid 21135c4bbdfSmrgKdParseScreen(KdScreenInfo * screen, const char *arg) 21205b261ecSmrg{ 21335c4bbdfSmrg char delim; 21435c4bbdfSmrg char save[1024]; 21535c4bbdfSmrg int i; 21635c4bbdfSmrg int pixels, mm; 2176747b715Smrg 21805b261ecSmrg screen->dumb = kdDumbDriver; 21905b261ecSmrg screen->softCursor = kdSoftCursor; 22005b261ecSmrg screen->origin = kdOrigin; 22105b261ecSmrg screen->randr = RR_Rotate_0; 22235c4bbdfSmrg screen->x = 0; 22335c4bbdfSmrg screen->y = 0; 22405b261ecSmrg screen->width = 0; 22505b261ecSmrg screen->height = 0; 22605b261ecSmrg screen->width_mm = 0; 22705b261ecSmrg screen->height_mm = 0; 22805b261ecSmrg screen->subpixel_order = kdSubpixelOrder; 22905b261ecSmrg screen->rate = 0; 2306747b715Smrg screen->fb.depth = 0; 23105b261ecSmrg if (!arg) 23235c4bbdfSmrg return; 23335c4bbdfSmrg if (strlen(arg) >= sizeof(save)) 23435c4bbdfSmrg return; 23535c4bbdfSmrg 23635c4bbdfSmrg for (i = 0; i < 2; i++) { 23735c4bbdfSmrg arg = KdParseFindNext(arg, "x/+@XY", save, &delim); 23835c4bbdfSmrg if (!save[0]) 23935c4bbdfSmrg return; 24035c4bbdfSmrg 24135c4bbdfSmrg pixels = atoi(save); 24235c4bbdfSmrg mm = 0; 24335c4bbdfSmrg 24435c4bbdfSmrg if (delim == '/') { 24535c4bbdfSmrg arg = KdParseFindNext(arg, "x+@XY", save, &delim); 24635c4bbdfSmrg if (!save[0]) 24735c4bbdfSmrg return; 24835c4bbdfSmrg mm = atoi(save); 24935c4bbdfSmrg } 25035c4bbdfSmrg 25135c4bbdfSmrg if (i == 0) { 25235c4bbdfSmrg screen->width = pixels; 25335c4bbdfSmrg screen->width_mm = mm; 25435c4bbdfSmrg } 25535c4bbdfSmrg else { 25635c4bbdfSmrg screen->height = pixels; 25735c4bbdfSmrg screen->height_mm = mm; 25835c4bbdfSmrg } 25935c4bbdfSmrg if (delim != 'x' && delim != '+' && delim != '@' && 26035c4bbdfSmrg delim != 'X' && delim != 'Y' && 26135c4bbdfSmrg (delim != '\0' || i == 0)) 26235c4bbdfSmrg return; 26305b261ecSmrg } 26405b261ecSmrg 26505b261ecSmrg kdOrigin.x += screen->width; 26605b261ecSmrg kdOrigin.y = 0; 26705b261ecSmrg kdDumbDriver = FALSE; 26805b261ecSmrg kdSoftCursor = FALSE; 26905b261ecSmrg kdSubpixelOrder = SubPixelUnknown; 27005b261ecSmrg 27135c4bbdfSmrg if (delim == '+') { 27235c4bbdfSmrg arg = KdParseFindNext(arg, "+@xXY", save, &delim); 27335c4bbdfSmrg if (save[0]) 27435c4bbdfSmrg screen->x = atoi(save); 27535c4bbdfSmrg } 27635c4bbdfSmrg 27735c4bbdfSmrg if (delim == '+') { 27835c4bbdfSmrg arg = KdParseFindNext(arg, "@xXY", save, &delim); 27935c4bbdfSmrg if (save[0]) 28035c4bbdfSmrg screen->y = atoi(save); 28105b261ecSmrg } 28235c4bbdfSmrg 28335c4bbdfSmrg if (delim == '@') { 28435c4bbdfSmrg arg = KdParseFindNext(arg, "xXY", save, &delim); 28535c4bbdfSmrg if (save[0]) { 28635c4bbdfSmrg int rotate = atoi(save); 28735c4bbdfSmrg 28835c4bbdfSmrg if (rotate < 45) 28935c4bbdfSmrg screen->randr = RR_Rotate_0; 29035c4bbdfSmrg else if (rotate < 135) 29135c4bbdfSmrg screen->randr = RR_Rotate_90; 29235c4bbdfSmrg else if (rotate < 225) 29335c4bbdfSmrg screen->randr = RR_Rotate_180; 29435c4bbdfSmrg else if (rotate < 315) 29535c4bbdfSmrg screen->randr = RR_Rotate_270; 29635c4bbdfSmrg else 29735c4bbdfSmrg screen->randr = RR_Rotate_0; 29835c4bbdfSmrg } 29935c4bbdfSmrg } 30035c4bbdfSmrg if (delim == 'X') { 30135c4bbdfSmrg arg = KdParseFindNext(arg, "xY", save, &delim); 30235c4bbdfSmrg screen->randr |= RR_Reflect_X; 30305b261ecSmrg } 30405b261ecSmrg 30535c4bbdfSmrg if (delim == 'Y') { 30635c4bbdfSmrg arg = KdParseFindNext(arg, "xY", save, &delim); 30735c4bbdfSmrg screen->randr |= RR_Reflect_Y; 30805b261ecSmrg } 3096747b715Smrg 31035c4bbdfSmrg arg = KdParseFindNext(arg, "x/,", save, &delim); 31135c4bbdfSmrg if (save[0]) { 31235c4bbdfSmrg screen->fb.depth = atoi(save); 31335c4bbdfSmrg if (delim == '/') { 31435c4bbdfSmrg arg = KdParseFindNext(arg, "x,", save, &delim); 31535c4bbdfSmrg if (save[0]) 31635c4bbdfSmrg screen->fb.bitsPerPixel = atoi(save); 31735c4bbdfSmrg } 31835c4bbdfSmrg else 31935c4bbdfSmrg screen->fb.bitsPerPixel = 0; 32005b261ecSmrg } 32105b261ecSmrg 32235c4bbdfSmrg if (delim == 'x') { 32335c4bbdfSmrg arg = KdParseFindNext(arg, "x", save, &delim); 32435c4bbdfSmrg if (save[0]) 32535c4bbdfSmrg screen->rate = atoi(save); 32605b261ecSmrg } 32705b261ecSmrg} 32805b261ecSmrg 3291b5d61b8Smrgstatic void 33035c4bbdfSmrgKdParseRgba(char *rgba) 33105b261ecSmrg{ 33235c4bbdfSmrg if (!strcmp(rgba, "rgb")) 33335c4bbdfSmrg kdSubpixelOrder = SubPixelHorizontalRGB; 33435c4bbdfSmrg else if (!strcmp(rgba, "bgr")) 33535c4bbdfSmrg kdSubpixelOrder = SubPixelHorizontalBGR; 33635c4bbdfSmrg else if (!strcmp(rgba, "vrgb")) 33735c4bbdfSmrg kdSubpixelOrder = SubPixelVerticalRGB; 33835c4bbdfSmrg else if (!strcmp(rgba, "vbgr")) 33935c4bbdfSmrg kdSubpixelOrder = SubPixelVerticalBGR; 34035c4bbdfSmrg else if (!strcmp(rgba, "none")) 34135c4bbdfSmrg kdSubpixelOrder = SubPixelNone; 34205b261ecSmrg else 34335c4bbdfSmrg kdSubpixelOrder = SubPixelUnknown; 34405b261ecSmrg} 34505b261ecSmrg 34605b261ecSmrgvoid 34735c4bbdfSmrgKdUseMsg(void) 34805b261ecSmrg{ 34905b261ecSmrg ErrorF("\nTinyX Device Dependent Usage:\n"); 35035c4bbdfSmrg ErrorF 35135c4bbdfSmrg ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][+[-]XOFFSET][+[-]YOFFSET][@ROTATION][X][Y][xDEPTH/BPP[xFREQ]] Specify screen characteristics\n"); 35235c4bbdfSmrg ErrorF 35335c4bbdfSmrg ("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n"); 35435c4bbdfSmrg ErrorF 35535c4bbdfSmrg ("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n"); 35635c4bbdfSmrg ErrorF 35735c4bbdfSmrg ("-keybd driver [,,options] Specify the keyboard driver and its options\n"); 358ed6184dfSmrg ErrorF("-xkb-rules Set default XkbRules value (can be overridden by -keybd options)\n"); 359ed6184dfSmrg ErrorF("-xkb-model Set default XkbModel value (can be overridden by -keybd options)\n"); 360ed6184dfSmrg ErrorF("-xkb-layout Set default XkbLayout value (can be overridden by -keybd options)\n"); 361ed6184dfSmrg ErrorF("-xkb-variant Set default XkbVariant value (can be overridden by -keybd options)\n"); 362ed6184dfSmrg ErrorF("-xkb-options Set default XkbOptions value (can be overridden by -keybd options)\n"); 36305b261ecSmrg ErrorF("-zaphod Disable cursor screen switching\n"); 36405b261ecSmrg ErrorF("-2button Emulate 3 button mouse\n"); 36505b261ecSmrg ErrorF("-3button Disable 3 button mouse emulation\n"); 36635c4bbdfSmrg ErrorF 36735c4bbdfSmrg ("-rawcoord Don't transform pointer coordinates on rotation\n"); 36805b261ecSmrg ErrorF("-dumb Disable hardware acceleration\n"); 36905b261ecSmrg ErrorF("-softCursor Force software cursor\n"); 37005b261ecSmrg ErrorF("-videoTest Start the server, pause momentarily and exit\n"); 37135c4bbdfSmrg ErrorF 37235c4bbdfSmrg ("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n"); 37305b261ecSmrg ErrorF("-switchCmd Command to execute on vt switch\n"); 37435c4bbdfSmrg ErrorF 37535c4bbdfSmrg ("vtxx Use virtual terminal xx instead of the next available\n"); 37605b261ecSmrg} 37705b261ecSmrg 37805b261ecSmrgint 37935c4bbdfSmrgKdProcessArgument(int argc, char **argv, int i) 38005b261ecSmrg{ 38135c4bbdfSmrg KdCardInfo *card; 38235c4bbdfSmrg KdScreenInfo *screen; 38335c4bbdfSmrg 38435c4bbdfSmrg if (!strcmp(argv[i], "-screen")) { 38535c4bbdfSmrg if ((i + 1) < argc) { 38635c4bbdfSmrg card = KdCardInfoLast(); 38735c4bbdfSmrg if (!card) { 38835c4bbdfSmrg InitCard(0); 38935c4bbdfSmrg card = KdCardInfoLast(); 39035c4bbdfSmrg } 39135c4bbdfSmrg if (card) { 39235c4bbdfSmrg screen = KdScreenInfoAdd(card); 39335c4bbdfSmrg KdParseScreen(screen, argv[i + 1]); 39435c4bbdfSmrg } 39535c4bbdfSmrg else 39635c4bbdfSmrg ErrorF("No matching card found!\n"); 39735c4bbdfSmrg } 39835c4bbdfSmrg else 39935c4bbdfSmrg UseMsg(); 40035c4bbdfSmrg return 2; 40105b261ecSmrg } 40235c4bbdfSmrg if (!strcmp(argv[i], "-zaphod")) { 40335c4bbdfSmrg kdDisableZaphod = TRUE; 40435c4bbdfSmrg return 1; 40505b261ecSmrg } 40635c4bbdfSmrg if (!strcmp(argv[i], "-3button")) { 40735c4bbdfSmrg kdEmulateMiddleButton = FALSE; 40835c4bbdfSmrg return 1; 40905b261ecSmrg } 41035c4bbdfSmrg if (!strcmp(argv[i], "-2button")) { 41135c4bbdfSmrg kdEmulateMiddleButton = TRUE; 41235c4bbdfSmrg return 1; 41305b261ecSmrg } 41435c4bbdfSmrg if (!strcmp(argv[i], "-rawcoord")) { 41535c4bbdfSmrg kdRawPointerCoordinates = 1; 41635c4bbdfSmrg return 1; 41705b261ecSmrg } 41835c4bbdfSmrg if (!strcmp(argv[i], "-dumb")) { 41935c4bbdfSmrg kdDumbDriver = TRUE; 42035c4bbdfSmrg return 1; 42105b261ecSmrg } 42235c4bbdfSmrg if (!strcmp(argv[i], "-softCursor")) { 42335c4bbdfSmrg kdSoftCursor = TRUE; 42435c4bbdfSmrg return 1; 42505b261ecSmrg } 42635c4bbdfSmrg if (!strcmp(argv[i], "-origin")) { 42735c4bbdfSmrg if ((i + 1) < argc) { 42835c4bbdfSmrg char *x = argv[i + 1]; 42935c4bbdfSmrg char *y = strchr(x, ','); 43035c4bbdfSmrg 43135c4bbdfSmrg if (x) 43235c4bbdfSmrg kdOrigin.x = atoi(x); 43335c4bbdfSmrg else 43435c4bbdfSmrg kdOrigin.x = 0; 43535c4bbdfSmrg if (y) 43635c4bbdfSmrg kdOrigin.y = atoi(y + 1); 43735c4bbdfSmrg else 43835c4bbdfSmrg kdOrigin.y = 0; 43935c4bbdfSmrg } 44035c4bbdfSmrg else 44135c4bbdfSmrg UseMsg(); 44235c4bbdfSmrg return 2; 44305b261ecSmrg } 44435c4bbdfSmrg if (!strcmp(argv[i], "-rgba")) { 44535c4bbdfSmrg if ((i + 1) < argc) 44635c4bbdfSmrg KdParseRgba(argv[i + 1]); 44735c4bbdfSmrg else 44835c4bbdfSmrg UseMsg(); 44935c4bbdfSmrg return 2; 45005b261ecSmrg } 45135c4bbdfSmrg if (!strcmp(argv[i], "-switchCmd")) { 45235c4bbdfSmrg if ((i + 1) < argc) 45335c4bbdfSmrg kdSwitchCmd = argv[i + 1]; 45435c4bbdfSmrg else 45535c4bbdfSmrg UseMsg(); 45635c4bbdfSmrg return 2; 45705b261ecSmrg } 4581b5d61b8Smrg if (!strcmp(argv[i], "-xkb-rules")) { 4591b5d61b8Smrg if (i + 1 >= argc) { 4601b5d61b8Smrg UseMsg(); 4611b5d61b8Smrg FatalError("Missing argument for option -xkb-rules.\n"); 4621b5d61b8Smrg } 4631b5d61b8Smrg kdGlobalXkbRules = argv[i + 1]; 4641b5d61b8Smrg return 2; 4651b5d61b8Smrg } 4661b5d61b8Smrg if (!strcmp(argv[i], "-xkb-model")) { 4671b5d61b8Smrg if (i + 1 >= argc) { 4681b5d61b8Smrg UseMsg(); 4691b5d61b8Smrg FatalError("Missing argument for option -xkb-model.\n"); 4701b5d61b8Smrg } 4711b5d61b8Smrg kdGlobalXkbModel = argv[i + 1]; 4721b5d61b8Smrg return 2; 4731b5d61b8Smrg } 4741b5d61b8Smrg if (!strcmp(argv[i], "-xkb-layout")) { 4751b5d61b8Smrg if (i + 1 >= argc) { 4761b5d61b8Smrg UseMsg(); 4771b5d61b8Smrg FatalError("Missing argument for option -xkb-layout.\n"); 4781b5d61b8Smrg } 4791b5d61b8Smrg kdGlobalXkbLayout = argv[i + 1]; 4801b5d61b8Smrg return 2; 4811b5d61b8Smrg } 4821b5d61b8Smrg if (!strcmp(argv[i], "-xkb-variant")) { 4831b5d61b8Smrg if (i + 1 >= argc) { 4841b5d61b8Smrg UseMsg(); 4851b5d61b8Smrg FatalError("Missing argument for option -xkb-variant.\n"); 4861b5d61b8Smrg } 4871b5d61b8Smrg kdGlobalXkbVariant = argv[i + 1]; 4881b5d61b8Smrg return 2; 4891b5d61b8Smrg } 4901b5d61b8Smrg if (!strcmp(argv[i], "-xkb-options")) { 4911b5d61b8Smrg if (i + 1 >= argc) { 4921b5d61b8Smrg UseMsg(); 4931b5d61b8Smrg FatalError("Missing argument for option -xkb-options.\n"); 4941b5d61b8Smrg } 4951b5d61b8Smrg kdGlobalXkbOptions = argv[i + 1]; 4961b5d61b8Smrg return 2; 49705b261ecSmrg } 49835c4bbdfSmrg if (!strcmp(argv[i], "-mouse") || !strcmp(argv[i], "-pointer")) { 49905b261ecSmrg if (i + 1 >= argc) 50005b261ecSmrg UseMsg(); 50105b261ecSmrg KdAddConfigPointer(argv[i + 1]); 50235c4bbdfSmrg kdHasPointer = TRUE; 50305b261ecSmrg return 2; 50405b261ecSmrg } 50535c4bbdfSmrg if (!strcmp(argv[i], "-keybd")) { 50605b261ecSmrg if (i + 1 >= argc) 50705b261ecSmrg UseMsg(); 50805b261ecSmrg KdAddConfigKeyboard(argv[i + 1]); 50935c4bbdfSmrg kdHasKbd = TRUE; 51005b261ecSmrg return 2; 51105b261ecSmrg } 51205b261ecSmrg 51305b261ecSmrg return 0; 51405b261ecSmrg} 51505b261ecSmrg 5161b5d61b8Smrgstatic Bool 51735c4bbdfSmrgKdAllocatePrivates(ScreenPtr pScreen) 51805b261ecSmrg{ 51935c4bbdfSmrg KdPrivScreenPtr pScreenPriv; 5206747b715Smrg 52105b261ecSmrg if (kdGeneration != serverGeneration) 52235c4bbdfSmrg kdGeneration = serverGeneration; 5234642e01fSmrg 5246747b715Smrg if (!dixRegisterPrivateKey(&kdScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 52535c4bbdfSmrg return FALSE; 5266747b715Smrg 52735c4bbdfSmrg pScreenPriv = calloc(1, sizeof(*pScreenPriv)); 52805b261ecSmrg if (!pScreenPriv) 52935c4bbdfSmrg return FALSE; 53035c4bbdfSmrg KdSetScreenPriv(pScreen, pScreenPriv); 53105b261ecSmrg return TRUE; 53205b261ecSmrg} 53305b261ecSmrg 5341b5d61b8Smrgstatic Bool 53535c4bbdfSmrgKdCreateScreenResources(ScreenPtr pScreen) 53605b261ecSmrg{ 53705b261ecSmrg KdScreenPriv(pScreen); 53835c4bbdfSmrg KdCardInfo *card = pScreenPriv->card; 53905b261ecSmrg Bool ret; 54005b261ecSmrg 54105b261ecSmrg pScreen->CreateScreenResources = pScreenPriv->CreateScreenResources; 54235c4bbdfSmrg if (pScreen->CreateScreenResources) 54335c4bbdfSmrg ret = (*pScreen->CreateScreenResources) (pScreen); 54405b261ecSmrg else 54535c4bbdfSmrg ret = -1; 54605b261ecSmrg pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; 54705b261ecSmrg pScreen->CreateScreenResources = KdCreateScreenResources; 54805b261ecSmrg if (ret && card->cfuncs->createRes) 54935c4bbdfSmrg ret = (*card->cfuncs->createRes) (pScreen); 55005b261ecSmrg return ret; 55105b261ecSmrg} 55205b261ecSmrg 5531b5d61b8Smrgstatic Bool 55435c4bbdfSmrgKdCloseScreen(ScreenPtr pScreen) 55505b261ecSmrg{ 55605b261ecSmrg KdScreenPriv(pScreen); 55735c4bbdfSmrg KdScreenInfo *screen = pScreenPriv->screen; 55835c4bbdfSmrg KdCardInfo *card = pScreenPriv->card; 55935c4bbdfSmrg Bool ret; 56035c4bbdfSmrg 56135c4bbdfSmrg if (card->cfuncs->closeScreen) 56235c4bbdfSmrg (*card->cfuncs->closeScreen)(pScreen); 5636747b715Smrg 56405b261ecSmrg pScreenPriv->closed = TRUE; 56505b261ecSmrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 56635c4bbdfSmrg 56735c4bbdfSmrg if (pScreen->CloseScreen) 56835c4bbdfSmrg ret = (*pScreen->CloseScreen) (pScreen); 56905b261ecSmrg else 57035c4bbdfSmrg ret = TRUE; 5716747b715Smrg 57205b261ecSmrg if (screen->mynum == card->selected) 57335c4bbdfSmrg KdDisableScreen(pScreen); 5746747b715Smrg 57505b261ecSmrg if (!pScreenPriv->screen->dumb && card->cfuncs->finiAccel) 57635c4bbdfSmrg (*card->cfuncs->finiAccel) (pScreen); 57705b261ecSmrg 57835c4bbdfSmrg if (card->cfuncs->scrfini) 57905b261ecSmrg (*card->cfuncs->scrfini) (screen); 58005b261ecSmrg 58105b261ecSmrg /* 58205b261ecSmrg * Clean up card when last screen is closed, DIX closes them in 58305b261ecSmrg * reverse order, thus we check for when the first in the list is closed 58405b261ecSmrg */ 58535c4bbdfSmrg if (screen == card->screenList) { 58635c4bbdfSmrg if (card->cfuncs->cardfini) 58735c4bbdfSmrg (*card->cfuncs->cardfini) (card); 58835c4bbdfSmrg /* 58935c4bbdfSmrg * Clean up OS when last card is closed 59035c4bbdfSmrg */ 59135c4bbdfSmrg if (card == kdCardInfo) { 5921b5d61b8Smrg kdEnabled = FALSE; 59335c4bbdfSmrg } 59405b261ecSmrg } 5956747b715Smrg 59605b261ecSmrg pScreenPriv->screen->pScreen = 0; 5976747b715Smrg 59835c4bbdfSmrg free((void *) pScreenPriv); 59905b261ecSmrg return ret; 60005b261ecSmrg} 60105b261ecSmrg 6021b5d61b8Smrgstatic Bool 60335c4bbdfSmrgKdSaveScreen(ScreenPtr pScreen, int on) 60405b261ecSmrg{ 6051b5d61b8Smrg return FALSE; 60605b261ecSmrg} 60705b261ecSmrg 60805b261ecSmrgstatic Bool 60935c4bbdfSmrgKdCreateWindow(WindowPtr pWin) 61005b261ecSmrg{ 61105b261ecSmrg#ifndef PHOENIX 61235c4bbdfSmrg if (!pWin->parent) { 61335c4bbdfSmrg KdScreenPriv(pWin->drawable.pScreen); 61435c4bbdfSmrg 61535c4bbdfSmrg if (!pScreenPriv->enabled) { 61635c4bbdfSmrg RegionEmpty(&pWin->borderClip); 61735c4bbdfSmrg RegionBreak(&pWin->clipList); 61835c4bbdfSmrg } 61905b261ecSmrg } 62005b261ecSmrg#endif 62135c4bbdfSmrg return fbCreateWindow(pWin); 62205b261ecSmrg} 62305b261ecSmrg 62405b261ecSmrgvoid 62535c4bbdfSmrgKdSetSubpixelOrder(ScreenPtr pScreen, Rotation randr) 62605b261ecSmrg{ 62705b261ecSmrg KdScreenPriv(pScreen); 62835c4bbdfSmrg KdScreenInfo *screen = pScreenPriv->screen; 62935c4bbdfSmrg int subpixel_order = screen->subpixel_order; 63035c4bbdfSmrg Rotation subpixel_dir; 63135c4bbdfSmrg int i; 6326747b715Smrg 63305b261ecSmrg static struct { 63435c4bbdfSmrg int subpixel_order; 63535c4bbdfSmrg Rotation direction; 63605b261ecSmrg } orders[] = { 63735c4bbdfSmrg {SubPixelHorizontalRGB, RR_Rotate_0}, 63835c4bbdfSmrg {SubPixelHorizontalBGR, RR_Rotate_180}, 63935c4bbdfSmrg {SubPixelVerticalRGB, RR_Rotate_270}, 64035c4bbdfSmrg {SubPixelVerticalBGR, RR_Rotate_90}, 64105b261ecSmrg }; 64205b261ecSmrg 64305b261ecSmrg static struct { 64435c4bbdfSmrg int bit; 64535c4bbdfSmrg int normal; 64635c4bbdfSmrg int reflect; 64705b261ecSmrg } reflects[] = { 64835c4bbdfSmrg {RR_Reflect_X, SubPixelHorizontalRGB, SubPixelHorizontalBGR}, 64935c4bbdfSmrg {RR_Reflect_X, SubPixelHorizontalBGR, SubPixelHorizontalRGB}, 65035c4bbdfSmrg {RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalBGR}, 65135c4bbdfSmrg {RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalRGB}, 65205b261ecSmrg }; 6536747b715Smrg 65405b261ecSmrg /* map subpixel to direction */ 65505b261ecSmrg for (i = 0; i < 4; i++) 65635c4bbdfSmrg if (orders[i].subpixel_order == subpixel_order) 65735c4bbdfSmrg break; 65835c4bbdfSmrg if (i < 4) { 65935c4bbdfSmrg subpixel_dir = 66035c4bbdfSmrg KdAddRotation(randr & RR_Rotate_All, orders[i].direction); 66135c4bbdfSmrg 66235c4bbdfSmrg /* map back to subpixel order */ 66335c4bbdfSmrg for (i = 0; i < 4; i++) 66435c4bbdfSmrg if (orders[i].direction & subpixel_dir) { 66535c4bbdfSmrg subpixel_order = orders[i].subpixel_order; 66635c4bbdfSmrg break; 66735c4bbdfSmrg } 66835c4bbdfSmrg /* reflect */ 66935c4bbdfSmrg for (i = 0; i < 4; i++) 67035c4bbdfSmrg if ((randr & reflects[i].bit) && 67135c4bbdfSmrg reflects[i].normal == subpixel_order) { 67235c4bbdfSmrg subpixel_order = reflects[i].reflect; 67335c4bbdfSmrg break; 67435c4bbdfSmrg } 67505b261ecSmrg } 67635c4bbdfSmrg PictureSetSubpixelOrder(pScreen, subpixel_order); 67705b261ecSmrg} 67805b261ecSmrg 67905b261ecSmrg/* Pass through AddScreen, which doesn't take any closure */ 68005b261ecSmrgstatic KdScreenInfo *kdCurrentScreen; 68105b261ecSmrg 6821b5d61b8Smrgstatic Bool 68335c4bbdfSmrgKdScreenInit(ScreenPtr pScreen, int argc, char **argv) 68405b261ecSmrg{ 68535c4bbdfSmrg KdScreenInfo *screen = kdCurrentScreen; 68635c4bbdfSmrg KdCardInfo *card = screen->card; 68735c4bbdfSmrg KdPrivScreenPtr pScreenPriv; 68835c4bbdfSmrg 68905b261ecSmrg /* 69005b261ecSmrg * note that screen->fb is set up for the nominal orientation 69105b261ecSmrg * of the screen; that means if randr is rotated, the values 69205b261ecSmrg * there should reflect a rotated frame buffer (or shadow). 69305b261ecSmrg */ 69435c4bbdfSmrg Bool rotated = (screen->randr & (RR_Rotate_90 | RR_Rotate_270)) != 0; 69535c4bbdfSmrg int width, height, *width_mmp, *height_mmp; 69605b261ecSmrg 69735c4bbdfSmrg KdAllocatePrivates(pScreen); 69805b261ecSmrg 69905b261ecSmrg pScreenPriv = KdGetScreenPriv(pScreen); 7006747b715Smrg 70135c4bbdfSmrg if (!rotated) { 70235c4bbdfSmrg width = screen->width; 70335c4bbdfSmrg height = screen->height; 70435c4bbdfSmrg width_mmp = &screen->width_mm; 70535c4bbdfSmrg height_mmp = &screen->height_mm; 70605b261ecSmrg } 70735c4bbdfSmrg else { 70835c4bbdfSmrg width = screen->height; 70935c4bbdfSmrg height = screen->width; 71035c4bbdfSmrg width_mmp = &screen->height_mm; 71135c4bbdfSmrg height_mmp = &screen->width_mm; 71205b261ecSmrg } 71305b261ecSmrg screen->pScreen = pScreen; 71405b261ecSmrg pScreenPriv->screen = screen; 71505b261ecSmrg pScreenPriv->card = card; 7166747b715Smrg pScreenPriv->bytesPerPixel = screen->fb.bitsPerPixel >> 3; 71705b261ecSmrg pScreenPriv->dpmsState = KD_DPMS_NORMAL; 7186747b715Smrg pScreen->x = screen->origin.x; 7196747b715Smrg pScreen->y = screen->origin.y; 72005b261ecSmrg 72105b261ecSmrg if (!monitorResolution) 72235c4bbdfSmrg monitorResolution = 75; 72305b261ecSmrg /* 72405b261ecSmrg * This is done in this order so that backing store wraps 72505b261ecSmrg * our GC functions; fbFinishScreenInit initializes MI 72605b261ecSmrg * backing store 72705b261ecSmrg */ 72835c4bbdfSmrg if (!fbSetupScreen(pScreen, 72935c4bbdfSmrg screen->fb.frameBuffer, 73035c4bbdfSmrg width, height, 73135c4bbdfSmrg monitorResolution, monitorResolution, 73235c4bbdfSmrg screen->fb.pixelStride, screen->fb.bitsPerPixel)) { 73335c4bbdfSmrg return FALSE; 73405b261ecSmrg } 73505b261ecSmrg 73605b261ecSmrg /* 73705b261ecSmrg * Set colormap functions 73805b261ecSmrg */ 73935c4bbdfSmrg pScreen->InstallColormap = KdInstallColormap; 74035c4bbdfSmrg pScreen->UninstallColormap = KdUninstallColormap; 74105b261ecSmrg pScreen->ListInstalledColormaps = KdListInstalledColormaps; 74235c4bbdfSmrg pScreen->StoreColors = KdStoreColors; 74335c4bbdfSmrg 74435c4bbdfSmrg pScreen->SaveScreen = KdSaveScreen; 74535c4bbdfSmrg pScreen->CreateWindow = KdCreateWindow; 74635c4bbdfSmrg 74735c4bbdfSmrg if (!fbFinishScreenInit(pScreen, 74835c4bbdfSmrg screen->fb.frameBuffer, 74935c4bbdfSmrg width, height, 75035c4bbdfSmrg monitorResolution, monitorResolution, 75135c4bbdfSmrg screen->fb.pixelStride, screen->fb.bitsPerPixel)) { 75235c4bbdfSmrg return FALSE; 75305b261ecSmrg } 7546747b715Smrg 75505b261ecSmrg /* 75605b261ecSmrg * Fix screen sizes; for some reason mi takes dpi instead of mm. 75705b261ecSmrg * Rounding errors are annoying 75805b261ecSmrg */ 75905b261ecSmrg if (*width_mmp) 76035c4bbdfSmrg pScreen->mmWidth = *width_mmp; 76105b261ecSmrg else 76235c4bbdfSmrg *width_mmp = pScreen->mmWidth; 76305b261ecSmrg if (*height_mmp) 76435c4bbdfSmrg pScreen->mmHeight = *height_mmp; 76505b261ecSmrg else 76635c4bbdfSmrg *height_mmp = pScreen->mmHeight; 7676747b715Smrg 76805b261ecSmrg /* 76905b261ecSmrg * Plug in our own block/wakeup handlers. 77005b261ecSmrg * miScreenInit installs NoopDDA in both places 77105b261ecSmrg */ 77235c4bbdfSmrg pScreen->BlockHandler = KdBlockHandler; 77335c4bbdfSmrg pScreen->WakeupHandler = KdWakeupHandler; 7746747b715Smrg 77535c4bbdfSmrg if (!fbPictureInit(pScreen, 0, 0)) 77635c4bbdfSmrg return FALSE; 77705b261ecSmrg if (card->cfuncs->initScreen) 77835c4bbdfSmrg if (!(*card->cfuncs->initScreen) (pScreen)) 77935c4bbdfSmrg return FALSE; 7806747b715Smrg 78105b261ecSmrg if (!screen->dumb && card->cfuncs->initAccel) 78235c4bbdfSmrg if (!(*card->cfuncs->initAccel) (pScreen)) 78335c4bbdfSmrg screen->dumb = TRUE; 7846747b715Smrg 78505b261ecSmrg if (card->cfuncs->finishInitScreen) 78635c4bbdfSmrg if (!(*card->cfuncs->finishInitScreen) (pScreen)) 78735c4bbdfSmrg return FALSE; 7886747b715Smrg 7896747b715Smrg /* 79005b261ecSmrg * Wrap CloseScreen, the order now is: 79135c4bbdfSmrg * KdCloseScreen 79235c4bbdfSmrg * fbCloseScreen 79305b261ecSmrg */ 79405b261ecSmrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 79505b261ecSmrg pScreen->CloseScreen = KdCloseScreen; 79605b261ecSmrg 79705b261ecSmrg pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; 79805b261ecSmrg pScreen->CreateScreenResources = KdCreateScreenResources; 7996747b715Smrg 80005b261ecSmrg if (screen->softCursor || 80135c4bbdfSmrg !card->cfuncs->initCursor || !(*card->cfuncs->initCursor) (pScreen)) { 80235c4bbdfSmrg /* Use MI for cursor display and event queueing. */ 80335c4bbdfSmrg screen->softCursor = TRUE; 80435c4bbdfSmrg miDCInitialize(pScreen, &kdPointerScreenFuncs); 80505b261ecSmrg } 80605b261ecSmrg 80735c4bbdfSmrg if (!fbCreateDefColormap(pScreen)) { 80835c4bbdfSmrg return FALSE; 80905b261ecSmrg } 81005b261ecSmrg 81135c4bbdfSmrg KdSetSubpixelOrder(pScreen, screen->randr); 81205b261ecSmrg 81305b261ecSmrg /* 81405b261ecSmrg * Enable the hardware 81505b261ecSmrg */ 8161b5d61b8Smrg kdEnabled = TRUE; 8176747b715Smrg 81835c4bbdfSmrg if (screen->mynum == card->selected) { 81935c4bbdfSmrg pScreenPriv->enabled = TRUE; 82035c4bbdfSmrg KdEnableColormap(pScreen); 82135c4bbdfSmrg if (!screen->dumb && card->cfuncs->enableAccel) 82235c4bbdfSmrg (*card->cfuncs->enableAccel) (pScreen); 82305b261ecSmrg } 8246747b715Smrg 82505b261ecSmrg return TRUE; 82605b261ecSmrg} 82705b261ecSmrg 8281b5d61b8Smrgstatic void 82935c4bbdfSmrgKdInitScreen(ScreenInfo * pScreenInfo, 83035c4bbdfSmrg KdScreenInfo * screen, int argc, char **argv) 83105b261ecSmrg{ 83235c4bbdfSmrg KdCardInfo *card = screen->card; 8336747b715Smrg 83435c4bbdfSmrg if (!(*card->cfuncs->scrinit) (screen)) 83535c4bbdfSmrg FatalError("Screen initialization failed!\n"); 8366747b715Smrg 83705b261ecSmrg if (!card->cfuncs->initAccel) 83835c4bbdfSmrg screen->dumb = TRUE; 83905b261ecSmrg if (!card->cfuncs->initCursor) 84035c4bbdfSmrg screen->softCursor = TRUE; 84105b261ecSmrg} 84205b261ecSmrg 84305b261ecSmrgstatic Bool 84435c4bbdfSmrgKdSetPixmapFormats(ScreenInfo * pScreenInfo) 84505b261ecSmrg{ 84635c4bbdfSmrg CARD8 depthToBpp[33]; /* depth -> bpp map */ 84735c4bbdfSmrg KdCardInfo *card; 84835c4bbdfSmrg KdScreenInfo *screen; 84935c4bbdfSmrg int i; 85035c4bbdfSmrg int bpp; 85105b261ecSmrg PixmapFormatRec *format; 85205b261ecSmrg 85305b261ecSmrg for (i = 1; i <= 32; i++) 85435c4bbdfSmrg depthToBpp[i] = 0; 85505b261ecSmrg 85605b261ecSmrg /* 85705b261ecSmrg * Generate mappings between bitsPerPixel and depth, 85805b261ecSmrg * also ensure that all screens comply with protocol 85905b261ecSmrg * restrictions on equivalent formats for the same 86005b261ecSmrg * depth on different screens 86105b261ecSmrg */ 86235c4bbdfSmrg for (card = kdCardInfo; card; card = card->next) { 86335c4bbdfSmrg for (screen = card->screenList; screen; screen = screen->next) { 86435c4bbdfSmrg bpp = screen->fb.bitsPerPixel; 86535c4bbdfSmrg if (bpp == 24) 86635c4bbdfSmrg bpp = 32; 86735c4bbdfSmrg if (!depthToBpp[screen->fb.depth]) 86835c4bbdfSmrg depthToBpp[screen->fb.depth] = bpp; 86935c4bbdfSmrg else if (depthToBpp[screen->fb.depth] != bpp) 87035c4bbdfSmrg return FALSE; 87135c4bbdfSmrg } 87205b261ecSmrg } 8736747b715Smrg 87405b261ecSmrg /* 87505b261ecSmrg * Fill in additional formats 87605b261ecSmrg */ 8771b5d61b8Smrg for (i = 0; i < ARRAY_SIZE(kdDepths); i++) 87835c4bbdfSmrg if (!depthToBpp[kdDepths[i].depth]) 87935c4bbdfSmrg depthToBpp[kdDepths[i].depth] = kdDepths[i].bpp; 8806747b715Smrg 88135c4bbdfSmrg pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; 88205b261ecSmrg pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; 88335c4bbdfSmrg pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; 88435c4bbdfSmrg pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; 8856747b715Smrg 88605b261ecSmrg pScreenInfo->numPixmapFormats = 0; 8876747b715Smrg 88835c4bbdfSmrg for (i = 1; i <= 32; i++) { 88935c4bbdfSmrg if (depthToBpp[i]) { 89035c4bbdfSmrg format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++]; 89135c4bbdfSmrg format->depth = i; 89235c4bbdfSmrg format->bitsPerPixel = depthToBpp[i]; 89335c4bbdfSmrg format->scanlinePad = BITMAP_SCANLINE_PAD; 89435c4bbdfSmrg } 89505b261ecSmrg } 8966747b715Smrg 89705b261ecSmrg return TRUE; 89805b261ecSmrg} 89905b261ecSmrg 90005b261ecSmrgstatic void 90135c4bbdfSmrgKdAddScreen(ScreenInfo * pScreenInfo, 90235c4bbdfSmrg KdScreenInfo * screen, int argc, char **argv) 90305b261ecSmrg{ 90435c4bbdfSmrg int i; 90535c4bbdfSmrg 90605b261ecSmrg /* 90705b261ecSmrg * Fill in fb visual type masks for this screen 90805b261ecSmrg */ 90935c4bbdfSmrg for (i = 0; i < pScreenInfo->numPixmapFormats; i++) { 91035c4bbdfSmrg unsigned long visuals; 91135c4bbdfSmrg Pixel rm, gm, bm; 91235c4bbdfSmrg 91335c4bbdfSmrg visuals = 0; 91435c4bbdfSmrg rm = gm = bm = 0; 91535c4bbdfSmrg if (pScreenInfo->formats[i].depth == screen->fb.depth) { 91635c4bbdfSmrg visuals = screen->fb.visuals; 91735c4bbdfSmrg rm = screen->fb.redMask; 91835c4bbdfSmrg gm = screen->fb.greenMask; 91935c4bbdfSmrg bm = screen->fb.blueMask; 92035c4bbdfSmrg } 92135c4bbdfSmrg fbSetVisualTypesAndMasks(pScreenInfo->formats[i].depth, 92235c4bbdfSmrg visuals, 8, rm, gm, bm); 92305b261ecSmrg } 92405b261ecSmrg 92505b261ecSmrg kdCurrentScreen = screen; 9266747b715Smrg 92735c4bbdfSmrg AddScreen(KdScreenInit, argc, argv); 92805b261ecSmrg} 92905b261ecSmrg 93005b261ecSmrgvoid 93135c4bbdfSmrgKdInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) 93205b261ecSmrg{ 93335c4bbdfSmrg KdCardInfo *card; 93435c4bbdfSmrg KdScreenInfo *screen; 93535c4bbdfSmrg 93635c4bbdfSmrg if (!kdCardInfo) { 93735c4bbdfSmrg InitCard(0); 93835c4bbdfSmrg if (!(card = KdCardInfoLast())) 93935c4bbdfSmrg FatalError("No matching cards found!\n"); 94035c4bbdfSmrg screen = KdScreenInfoAdd(card); 94135c4bbdfSmrg KdParseScreen(screen, 0); 94205b261ecSmrg } 94305b261ecSmrg /* 94405b261ecSmrg * Initialize all of the screens for all of the cards 94505b261ecSmrg */ 94635c4bbdfSmrg for (card = kdCardInfo; card; card = card->next) { 94735c4bbdfSmrg int ret = 1; 94835c4bbdfSmrg 94935c4bbdfSmrg if (card->cfuncs->cardinit) 95035c4bbdfSmrg ret = (*card->cfuncs->cardinit) (card); 95135c4bbdfSmrg if (ret) { 95235c4bbdfSmrg for (screen = card->screenList; screen; screen = screen->next) 95335c4bbdfSmrg KdInitScreen(pScreenInfo, screen, argc, argv); 95435c4bbdfSmrg } 95505b261ecSmrg } 9566747b715Smrg 95705b261ecSmrg /* 95805b261ecSmrg * Merge the various pixmap formats together, this can fail 95905b261ecSmrg * when two screens share depth but not bitsPerPixel 96005b261ecSmrg */ 96135c4bbdfSmrg if (!KdSetPixmapFormats(pScreenInfo)) 96235c4bbdfSmrg return; 9636747b715Smrg 96405b261ecSmrg /* 96505b261ecSmrg * Add all of the screens 96605b261ecSmrg */ 96705b261ecSmrg for (card = kdCardInfo; card; card = card->next) 96835c4bbdfSmrg for (screen = card->screenList; screen; screen = screen->next) 96935c4bbdfSmrg KdAddScreen(pScreenInfo, screen, argc, argv); 97005b261ecSmrg 9711b5d61b8Smrg xorgGlxCreateVendor(); 9721b5d61b8Smrg 9731b5d61b8Smrg#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 9741b5d61b8Smrg if (SeatId) /* Enable input hot-plugging */ 9751b5d61b8Smrg config_pre_init(); 9761b5d61b8Smrg#endif 97705b261ecSmrg} 97805b261ecSmrg 97905b261ecSmrgvoid 98035c4bbdfSmrgOsVendorFatalError(const char *f, va_list args) 9814642e01fSmrg{ 9824642e01fSmrg} 9834642e01fSmrg 9841b5d61b8Smrg/* These stubs can be safely removed once we can 9851b5d61b8Smrg * split input and GPU parts in hotplug.h et al. */ 9861b5d61b8Smrg#ifdef CONFIG_UDEV_KMS 9871b5d61b8Smrgvoid 9881b5d61b8SmrgNewGPUDeviceRequest(struct OdevAttributes *attribs) 98905b261ecSmrg{ 99005b261ecSmrg} 99105b261ecSmrg 9921b5d61b8Smrgvoid 9931b5d61b8SmrgDeleteGPUDeviceRequest(struct OdevAttributes *attribs) 99405b261ecSmrg{ 99505b261ecSmrg} 9961b5d61b8Smrg#endif 9971b5d61b8Smrg 998ed6184dfSmrg#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 9991b5d61b8Smrgstruct xf86_platform_device * 10001b5d61b8Smrgxf86_find_platform_device_by_devnum(int major, int minor) 10011b5d61b8Smrg{ 10021b5d61b8Smrg return NULL; 10031b5d61b8Smrg} 1004ed6184dfSmrg#endif 10051b5d61b8Smrg 10061b5d61b8Smrg#ifdef SYSTEMD_LOGIND 10071b5d61b8Smrgvoid 10081b5d61b8Smrgsystemd_logind_vtenter(void) 10091b5d61b8Smrg{ 10101b5d61b8Smrg} 10111b5d61b8Smrg 10121b5d61b8Smrgvoid 10131b5d61b8Smrgsystemd_logind_release_fd(int major, int minor, int fd) 10141b5d61b8Smrg{ 10151b5d61b8Smrg close(fd); 10161b5d61b8Smrg} 10171b5d61b8Smrg#endif 1018