xserver-multidpi/hw/kdrive/src/kdrive.c
Peter Hutterer f51e42f583 Terminate the log with one last message.
Instead of just closing the log when everything is done, put one more
message in stating that we're actually terminating. Users or scripts that
look at the Xorg.log will then know that a) the server has terminated
properly and b) why the server terminated (to some degree, given that most
real-world errors will be caused by AbortServer()).

Acked-by: Gaetan Nadon <memsize@videotron.ca>
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
Tested-by: Jeremy Huddleston <jeremyhu@apple.com>
Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
Tested-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Reviewed-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2011-07-27 09:31:02 +10:00

1190 lines
27 KiB
C

/*
* Copyright © 1999 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include "kdrive.h"
#include <mivalidate.h>
#include <dixstruct.h>
#include "privates.h"
#ifdef RANDR
#include <randrstr.h>
#endif
#ifdef XV
#include "kxv.h"
#endif
#ifdef DPMSExtension
#include "dpmsproc.h"
#endif
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif
#include <signal.h>
typedef struct _kdDepths {
CARD8 depth;
CARD8 bpp;
} KdDepths;
KdDepths kdDepths[] = {
{ 1, 1 },
{ 4, 4 },
{ 8, 8 },
{ 15, 16 },
{ 16, 16 },
{ 24, 32 },
{ 32, 32 }
};
#define NUM_KD_DEPTHS (sizeof (kdDepths) / sizeof (kdDepths[0]))
#define KD_DEFAULT_BUTTONS 5
DevPrivateKeyRec kdScreenPrivateKeyRec;
unsigned long kdGeneration;
Bool kdVideoTest;
unsigned long kdVideoTestTime;
Bool kdEmulateMiddleButton;
Bool kdRawPointerCoordinates;
Bool kdDisableZaphod;
Bool kdAllowZap;
Bool kdEnabled;
int kdSubpixelOrder;
int kdVirtualTerminal = -1;
Bool kdSwitchPending;
char *kdSwitchCmd;
DDXPointRec kdOrigin;
Bool kdHasPointer = FALSE;
Bool kdHasKbd = FALSE;
static Bool kdCaughtSignal = FALSE;
/*
* Carry arguments from InitOutput through driver initialization
* to KdScreenInit
*/
KdOsFuncs *kdOsFuncs;
void
KdDisableScreen (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
if (!pScreenPriv->enabled)
return;
if (!pScreenPriv->closed)
SetRootClip (pScreen, FALSE);
KdDisableColormap (pScreen);
if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel)
(*pScreenPriv->card->cfuncs->disableAccel) (pScreen);
if (!pScreenPriv->screen->softCursor && pScreenPriv->card->cfuncs->disableCursor)
(*pScreenPriv->card->cfuncs->disableCursor) (pScreen);
if (pScreenPriv->card->cfuncs->dpms)
(*pScreenPriv->card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
pScreenPriv->enabled = FALSE;
if(pScreenPriv->card->cfuncs->disable)
(*pScreenPriv->card->cfuncs->disable) (pScreen);
}
static void
KdDoSwitchCmd (char *reason)
{
if (kdSwitchCmd)
{
char *command = malloc(strlen (kdSwitchCmd) +
1 +
strlen (reason) +
1);
if (!command)
return;
strcpy (command, kdSwitchCmd);
strcat (command, " ");
strcat (command, reason);
system (command);
free(command);
}
}
void
KdSuspend (void)
{
KdCardInfo *card;
KdScreenInfo *screen;
if (kdEnabled)
{
for (card = kdCardInfo; card; card = card->next)
{
for (screen = card->screenList; screen; screen = screen->next)
if (screen->mynum == card->selected && screen->pScreen)
KdDisableScreen (screen->pScreen);
if (card->driver && card->cfuncs->restore)
(*card->cfuncs->restore) (card);
}
KdDisableInput ();
KdDoSwitchCmd ("suspend");
}
}
void
KdDisableScreens (void)
{
KdSuspend ();
if (kdEnabled)
{
if (kdOsFuncs->Disable)
(*kdOsFuncs->Disable) ();
kdEnabled = FALSE;
}
}
Bool
KdEnableScreen (ScreenPtr pScreen)
{
KdScreenPriv (pScreen);
if (pScreenPriv->enabled)
return TRUE;
if(pScreenPriv->card->cfuncs->enable)
if (!(*pScreenPriv->card->cfuncs->enable) (pScreen))
return FALSE;
pScreenPriv->enabled = TRUE;
pScreenPriv->dpmsState = KD_DPMS_NORMAL;
pScreenPriv->card->selected = pScreenPriv->screen->mynum;
if (!pScreenPriv->screen->softCursor && pScreenPriv->card->cfuncs->enableCursor)
(*pScreenPriv->card->cfuncs->enableCursor) (pScreen);
if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel)
(*pScreenPriv->card->cfuncs->enableAccel) (pScreen);
KdEnableColormap (pScreen);
SetRootClip (pScreen, TRUE);
if (pScreenPriv->card->cfuncs->dpms)
(*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState);
return TRUE;
}
void
KdResume (void)
{
KdCardInfo *card;
KdScreenInfo *screen;
if (kdEnabled)
{
KdDoSwitchCmd ("resume");
for (card = kdCardInfo; card; card = card->next)
{
if(card->cfuncs->preserve)
(*card->cfuncs->preserve) (card);
for (screen = card->screenList; screen; screen = screen->next)
if (screen->mynum == card->selected && screen->pScreen)
KdEnableScreen (screen->pScreen);
}
KdEnableInput ();
KdReleaseAllKeys ();
}
}
void
KdEnableScreens (void)
{
if (!kdEnabled)
{
kdEnabled = TRUE;
if (kdOsFuncs->Enable)
(*kdOsFuncs->Enable) ();
}
KdResume ();
}
void
KdProcessSwitch (void)
{
if (kdEnabled)
KdDisableScreens ();
else
KdEnableScreens ();
}
void
AbortDDX(enum ExitCode error)
{
KdDisableScreens ();
if (kdOsFuncs)
{
if (kdEnabled && kdOsFuncs->Disable)
(*kdOsFuncs->Disable) ();
if (kdOsFuncs->Fini)
(*kdOsFuncs->Fini) ();
KdDoSwitchCmd ("stop");
}
if (kdCaughtSignal)
OsAbort();
}
void
ddxGiveUp (enum ExitCode error)
{
AbortDDX (error);
}
Bool kdDumbDriver;
Bool kdSoftCursor;
char *
KdParseFindNext (char *cur, char *delim, char *save, char *last)
{
while (*cur && !strchr (delim, *cur))
{
*save++ = *cur++;
}
*save = 0;
*last = *cur;
if (*cur)
cur++;
return cur;
}
Rotation
KdAddRotation (Rotation a, Rotation b)
{
Rotation rotate = (a & RR_Rotate_All) * (b & RR_Rotate_All);
Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All);
if (rotate > RR_Rotate_270)
rotate /= (RR_Rotate_270 * RR_Rotate_90);
return reflect | rotate;
}
Rotation
KdSubRotation (Rotation a, Rotation b)
{
Rotation rotate = (a & RR_Rotate_All) * 16 / (b & RR_Rotate_All);
Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All);
if (rotate > RR_Rotate_270)
rotate /= (RR_Rotate_270 * RR_Rotate_90);
return reflect | rotate;
}
void
KdParseScreen (KdScreenInfo *screen,
char *arg)
{
char delim;
char save[1024];
int i;
int pixels, mm;
screen->dumb = kdDumbDriver;
screen->softCursor = kdSoftCursor;
screen->origin = kdOrigin;
screen->randr = RR_Rotate_0;
screen->width = 0;
screen->height = 0;
screen->width_mm = 0;
screen->height_mm = 0;
screen->subpixel_order = kdSubpixelOrder;
screen->rate = 0;
screen->fb.depth = 0;
if (!arg)
return;
if (strlen (arg) >= sizeof (save))
return;
for (i = 0; i < 2; i++)
{
arg = KdParseFindNext (arg, "x/@XY", save, &delim);
if (!save[0])
return;
pixels = atoi(save);
mm = 0;
if (delim == '/')
{
arg = KdParseFindNext (arg, "x@XY", save, &delim);
if (!save[0])
return;
mm = atoi(save);
}
if (i == 0)
{
screen->width = pixels;
screen->width_mm = mm;
}
else
{
screen->height = pixels;
screen->height_mm = mm;
}
if (delim != 'x' && delim != '@' && delim != 'X' && delim != 'Y')
return;
}
kdOrigin.x += screen->width;
kdOrigin.y = 0;
kdDumbDriver = FALSE;
kdSoftCursor = FALSE;
kdSubpixelOrder = SubPixelUnknown;
if (delim == '@')
{
arg = KdParseFindNext (arg, "xXY", save, &delim);
if (save[0])
{
int rotate = atoi (save);
if (rotate < 45)
screen->randr = RR_Rotate_0;
else if (rotate < 135)
screen->randr = RR_Rotate_90;
else if (rotate < 225)
screen->randr = RR_Rotate_180;
else if (rotate < 315)
screen->randr = RR_Rotate_270;
else
screen->randr = RR_Rotate_0;
}
}
if (delim == 'X')
{
arg = KdParseFindNext (arg, "xY", save, &delim);
screen->randr |= RR_Reflect_X;
}
if (delim == 'Y')
{
arg = KdParseFindNext (arg, "xY", save, &delim);
screen->randr |= RR_Reflect_Y;
}
arg = KdParseFindNext (arg, "x/,", save, &delim);
if (save[0])
{
screen->fb.depth = atoi(save);
if (delim == '/')
{
arg = KdParseFindNext (arg, "x,", save, &delim);
if (save[0])
screen->fb.bitsPerPixel = atoi (save);
}
else
screen->fb.bitsPerPixel = 0;
}
if (delim == 'x')
{
arg = KdParseFindNext (arg, "x", save, &delim);
if (save[0])
screen->rate = atoi(save);
}
}
/*
* Mouse argument syntax:
*
* device,protocol,options...
*
* Options are any of:
* 1-5 n button mouse
* 2button emulate middle button
* {NMO} Reorder buttons
*/
void
KdParseRgba (char *rgba)
{
if (!strcmp (rgba, "rgb"))
kdSubpixelOrder = SubPixelHorizontalRGB;
else if (!strcmp (rgba, "bgr"))
kdSubpixelOrder = SubPixelHorizontalBGR;
else if (!strcmp (rgba, "vrgb"))
kdSubpixelOrder = SubPixelVerticalRGB;
else if (!strcmp (rgba, "vbgr"))
kdSubpixelOrder = SubPixelVerticalBGR;
else if (!strcmp (rgba, "none"))
kdSubpixelOrder = SubPixelNone;
else
kdSubpixelOrder = SubPixelUnknown;
}
void
KdUseMsg (void)
{
ErrorF("\nTinyX Device Dependent Usage:\n");
ErrorF("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][@ROTATION][X][Y][xDEPTH/BPP[xFREQ]] Specify screen characteristics\n");
ErrorF("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n");
ErrorF("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n");
ErrorF("-keybd driver [,,options] Specify the keyboard driver and its options\n");
ErrorF("-zaphod Disable cursor screen switching\n");
ErrorF("-2button Emulate 3 button mouse\n");
ErrorF("-3button Disable 3 button mouse emulation\n");
ErrorF("-rawcoord Don't transform pointer coordinates on rotation\n");
ErrorF("-dumb Disable hardware acceleration\n");
ErrorF("-softCursor Force software cursor\n");
ErrorF("-videoTest Start the server, pause momentarily and exit\n");
ErrorF("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n");
ErrorF("-switchCmd Command to execute on vt switch\n");
ErrorF("-zap Terminate server on Ctrl+Alt+Backspace\n");
ErrorF("vtxx Use virtual terminal xx instead of the next available\n");
}
int
KdProcessArgument (int argc, char **argv, int i)
{
KdCardInfo *card;
KdScreenInfo *screen;
if (!strcmp (argv[i], "-screen"))
{
if ((i+1) < argc)
{
card = KdCardInfoLast ();
if (!card)
{
InitCard (0);
card = KdCardInfoLast ();
}
if (card) {
screen = KdScreenInfoAdd (card);
KdParseScreen (screen, argv[i+1]);
} else
ErrorF("No matching card found!\n");
}
else
UseMsg ();
return 2;
}
if (!strcmp (argv[i], "-zaphod"))
{
kdDisableZaphod = TRUE;
return 1;
}
if (!strcmp (argv[i], "-zap"))
{
kdAllowZap = TRUE;
return 1;
}
if (!strcmp (argv[i], "-3button"))
{
kdEmulateMiddleButton = FALSE;
return 1;
}
if (!strcmp (argv[i], "-2button"))
{
kdEmulateMiddleButton = TRUE;
return 1;
}
if (!strcmp (argv[i], "-rawcoord"))
{
kdRawPointerCoordinates = 1;
return 1;
}
if (!strcmp (argv[i], "-dumb"))
{
kdDumbDriver = TRUE;
return 1;
}
if (!strcmp (argv[i], "-softCursor"))
{
kdSoftCursor = TRUE;
return 1;
}
if (!strcmp (argv[i], "-videoTest"))
{
kdVideoTest = TRUE;
return 1;
}
if (!strcmp (argv[i], "-origin"))
{
if ((i+1) < argc)
{
char *x = argv[i+1];
char *y = strchr (x, ',');
if (x)
kdOrigin.x = atoi (x);
else
kdOrigin.x = 0;
if (y)
kdOrigin.y = atoi(y+1);
else
kdOrigin.y = 0;
}
else
UseMsg ();
return 2;
}
if (!strcmp (argv[i], "-rgba"))
{
if ((i+1) < argc)
KdParseRgba (argv[i+1]);
else
UseMsg ();
return 2;
}
if (!strcmp (argv[i], "-switchCmd"))
{
if ((i+1) < argc)
kdSwitchCmd = argv[i+1];
else
UseMsg ();
return 2;
}
if (!strncmp (argv[i], "vt", 2) &&
sscanf (argv[i], "vt%2d", &kdVirtualTerminal) == 1)
{
return 1;
}
if (!strcmp (argv[i], "-mouse") ||
!strcmp (argv[i], "-pointer")) {
if (i + 1 >= argc)
UseMsg();
KdAddConfigPointer(argv[i + 1]);
kdHasPointer = TRUE;
return 2;
}
if (!strcmp (argv[i], "-keybd")) {
if (i + 1 >= argc)
UseMsg();
KdAddConfigKeyboard(argv[i + 1]);
kdHasKbd = TRUE;
return 2;
}
return 0;
}
/*
* These are getting tossed in here until I can think of where
* they really belong
*/
void
KdOsInit (KdOsFuncs *pOsFuncs)
{
kdOsFuncs = pOsFuncs;
if (pOsFuncs)
{
if (serverGeneration == 1)
{
KdDoSwitchCmd ("start");
if (pOsFuncs->Init)
(*pOsFuncs->Init) ();
}
}
}
Bool
KdAllocatePrivates (ScreenPtr pScreen)
{
KdPrivScreenPtr pScreenPriv;
if (kdGeneration != serverGeneration)
kdGeneration = serverGeneration;
if (!dixRegisterPrivateKey(&kdScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
return FALSE;
pScreenPriv = calloc(1, sizeof (*pScreenPriv));
if (!pScreenPriv)
return FALSE;
KdSetScreenPriv (pScreen, pScreenPriv);
return TRUE;
}
Bool
KdCreateScreenResources (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
KdCardInfo *card = pScreenPriv->card;
Bool ret;
pScreen->CreateScreenResources = pScreenPriv->CreateScreenResources;
if(pScreen->CreateScreenResources)
ret = (*pScreen->CreateScreenResources) (pScreen);
else
ret= -1;
pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = KdCreateScreenResources;
if (ret && card->cfuncs->createRes)
ret = (*card->cfuncs->createRes) (pScreen);
return ret;
}
Bool
KdCloseScreen (int index, ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
KdCardInfo *card = pScreenPriv->card;
Bool ret;
pScreenPriv->closed = TRUE;
pScreen->CloseScreen = pScreenPriv->CloseScreen;
if(pScreen->CloseScreen)
ret = (*pScreen->CloseScreen) (index, pScreen);
else
ret = TRUE;
if (pScreenPriv->dpmsState != KD_DPMS_NORMAL)
(*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
if (screen->mynum == card->selected)
KdDisableScreen (pScreen);
/*
* Restore video hardware when last screen is closed
*/
if (screen == card->screenList)
{
if (kdEnabled && card->cfuncs->restore)
(*card->cfuncs->restore) (card);
}
if (!pScreenPriv->screen->dumb && card->cfuncs->finiAccel)
(*card->cfuncs->finiAccel) (pScreen);
if (!pScreenPriv->screen->softCursor && card->cfuncs->finiCursor)
(*card->cfuncs->finiCursor) (pScreen);
if(card->cfuncs->scrfini)
(*card->cfuncs->scrfini) (screen);
/*
* Clean up card when last screen is closed, DIX closes them in
* reverse order, thus we check for when the first in the list is closed
*/
if (screen == card->screenList)
{
if(card->cfuncs->cardfini)
(*card->cfuncs->cardfini) (card);
/*
* Clean up OS when last card is closed
*/
if (card == kdCardInfo)
{
if (kdEnabled)
{
kdEnabled = FALSE;
if(kdOsFuncs->Disable)
(*kdOsFuncs->Disable) ();
}
}
}
pScreenPriv->screen->pScreen = 0;
free((pointer) pScreenPriv);
return ret;
}
Bool
KdSaveScreen (ScreenPtr pScreen, int on)
{
KdScreenPriv(pScreen);
int dpmsState;
if (!pScreenPriv->card->cfuncs->dpms)
return FALSE;
dpmsState = pScreenPriv->dpmsState;
switch (on) {
case SCREEN_SAVER_OFF:
dpmsState = KD_DPMS_NORMAL;
break;
case SCREEN_SAVER_ON:
if (dpmsState == KD_DPMS_NORMAL)
dpmsState = KD_DPMS_NORMAL+1;
break;
case SCREEN_SAVER_CYCLE:
if (dpmsState < KD_DPMS_MAX)
dpmsState++;
break;
case SCREEN_SAVER_FORCER:
break;
}
if (dpmsState != pScreenPriv->dpmsState)
{
if (pScreenPriv->enabled)
(*pScreenPriv->card->cfuncs->dpms) (pScreen, dpmsState);
pScreenPriv->dpmsState = dpmsState;
}
return TRUE;
}
static Bool
KdCreateWindow (WindowPtr pWin)
{
#ifndef PHOENIX
if (!pWin->parent)
{
KdScreenPriv(pWin->drawable.pScreen);
if (!pScreenPriv->enabled)
{
RegionEmpty(&pWin->borderClip);
RegionBreak(&pWin->clipList);
}
}
#endif
return fbCreateWindow (pWin);
}
void
KdSetSubpixelOrder (ScreenPtr pScreen, Rotation randr)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
int subpixel_order = screen->subpixel_order;
Rotation subpixel_dir;
int i;
static struct {
int subpixel_order;
Rotation direction;
} orders[] = {
{ SubPixelHorizontalRGB, RR_Rotate_0 },
{ SubPixelHorizontalBGR, RR_Rotate_180 },
{ SubPixelVerticalRGB, RR_Rotate_270 },
{ SubPixelVerticalBGR, RR_Rotate_90 },
};
static struct {
int bit;
int normal;
int reflect;
} reflects[] = {
{ RR_Reflect_X, SubPixelHorizontalRGB, SubPixelHorizontalBGR },
{ RR_Reflect_X, SubPixelHorizontalBGR, SubPixelHorizontalRGB },
{ RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalBGR },
{ RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalRGB },
};
/* map subpixel to direction */
for (i = 0; i < 4; i++)
if (orders[i].subpixel_order == subpixel_order)
break;
if (i < 4)
{
subpixel_dir = KdAddRotation (randr & RR_Rotate_All, orders[i].direction);
/* map back to subpixel order */
for (i = 0; i < 4; i++)
if (orders[i].direction & subpixel_dir)
{
subpixel_order = orders[i].subpixel_order;
break;
}
/* reflect */
for (i = 0; i < 4; i++)
if ((randr & reflects[i].bit) &&
reflects[i].normal == subpixel_order)
{
subpixel_order = reflects[i].reflect;
break;
}
}
PictureSetSubpixelOrder (pScreen, subpixel_order);
}
/* Pass through AddScreen, which doesn't take any closure */
static KdScreenInfo *kdCurrentScreen;
Bool
KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
{
KdScreenInfo *screen = kdCurrentScreen;
KdCardInfo *card = screen->card;
KdPrivScreenPtr pScreenPriv;
/*
* note that screen->fb is set up for the nominal orientation
* of the screen; that means if randr is rotated, the values
* there should reflect a rotated frame buffer (or shadow).
*/
Bool rotated = (screen->randr & (RR_Rotate_90|RR_Rotate_270)) != 0;
int width, height, *width_mmp, *height_mmp;
KdAllocatePrivates (pScreen);
pScreenPriv = KdGetScreenPriv(pScreen);
if (!rotated)
{
width = screen->width;
height = screen->height;
width_mmp = &screen->width_mm;
height_mmp = &screen->height_mm;
}
else
{
width = screen->height;
height = screen->width;
width_mmp = &screen->height_mm;
height_mmp = &screen->width_mm;
}
screen->pScreen = pScreen;
pScreenPriv->screen = screen;
pScreenPriv->card = card;
pScreenPriv->bytesPerPixel = screen->fb.bitsPerPixel >> 3;
pScreenPriv->dpmsState = KD_DPMS_NORMAL;
pScreen->x = screen->origin.x;
pScreen->y = screen->origin.y;
if (!monitorResolution)
monitorResolution = 75;
/*
* This is done in this order so that backing store wraps
* our GC functions; fbFinishScreenInit initializes MI
* backing store
*/
if (!fbSetupScreen (pScreen,
screen->fb.frameBuffer,
width, height,
monitorResolution, monitorResolution,
screen->fb.pixelStride,
screen->fb.bitsPerPixel))
{
return FALSE;
}
/*
* Set colormap functions
*/
pScreen->InstallColormap = KdInstallColormap;
pScreen->UninstallColormap = KdUninstallColormap;
pScreen->ListInstalledColormaps = KdListInstalledColormaps;
pScreen->StoreColors = KdStoreColors;
pScreen->SaveScreen = KdSaveScreen;
pScreen->CreateWindow = KdCreateWindow;
if (!fbFinishScreenInit (pScreen,
screen->fb.frameBuffer,
width, height,
monitorResolution, monitorResolution,
screen->fb.pixelStride,
screen->fb.bitsPerPixel))
{
return FALSE;
}
/*
* Fix screen sizes; for some reason mi takes dpi instead of mm.
* Rounding errors are annoying
*/
if (*width_mmp)
pScreen->mmWidth = *width_mmp;
else
*width_mmp = pScreen->mmWidth;
if (*height_mmp)
pScreen->mmHeight = *height_mmp;
else
*height_mmp = pScreen->mmHeight;
/*
* Plug in our own block/wakeup handlers.
* miScreenInit installs NoopDDA in both places
*/
pScreen->BlockHandler = KdBlockHandler;
pScreen->WakeupHandler = KdWakeupHandler;
if (!fbPictureInit (pScreen, 0, 0))
return FALSE;
if (card->cfuncs->initScreen)
if (!(*card->cfuncs->initScreen) (pScreen))
return FALSE;
if (!screen->dumb && card->cfuncs->initAccel)
if (!(*card->cfuncs->initAccel) (pScreen))
screen->dumb = TRUE;
if (card->cfuncs->finishInitScreen)
if (!(*card->cfuncs->finishInitScreen) (pScreen))
return FALSE;
#if 0
fbInitValidateTree (pScreen);
#endif
/*
* Wrap CloseScreen, the order now is:
* KdCloseScreen
* miBSCloseScreen
* fbCloseScreen
*/
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = KdCloseScreen;
pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = KdCreateScreenResources;
if (screen->softCursor ||
!card->cfuncs->initCursor ||
!(*card->cfuncs->initCursor) (pScreen))
{
/* Use MI for cursor display and event queueing. */
screen->softCursor = TRUE;
miDCInitialize(pScreen, &kdPointerScreenFuncs);
}
if (!fbCreateDefColormap (pScreen))
{
return FALSE;
}
KdSetSubpixelOrder (pScreen, screen->randr);
/*
* Enable the hardware
*/
if (!kdEnabled)
{
kdEnabled = TRUE;
if(kdOsFuncs->Enable)
(*kdOsFuncs->Enable) ();
}
if (screen->mynum == card->selected)
{
if(card->cfuncs->preserve)
(*card->cfuncs->preserve) (card);
if(card->cfuncs->enable)
if (!(*card->cfuncs->enable) (pScreen))
return FALSE;
pScreenPriv->enabled = TRUE;
if (!screen->softCursor && card->cfuncs->enableCursor)
(*card->cfuncs->enableCursor) (pScreen);
KdEnableColormap (pScreen);
if (!screen->dumb && card->cfuncs->enableAccel)
(*card->cfuncs->enableAccel) (pScreen);
}
return TRUE;
}
void
KdInitScreen (ScreenInfo *pScreenInfo,
KdScreenInfo *screen,
int argc,
char **argv)
{
KdCardInfo *card = screen->card;
(*card->cfuncs->scrinit) (screen);
if (!card->cfuncs->initAccel)
screen->dumb = TRUE;
if (!card->cfuncs->initCursor)
screen->softCursor = TRUE;
}
static Bool
KdSetPixmapFormats (ScreenInfo *pScreenInfo)
{
CARD8 depthToBpp[33]; /* depth -> bpp map */
KdCardInfo *card;
KdScreenInfo *screen;
int i;
int bpp;
PixmapFormatRec *format;
for (i = 1; i <= 32; i++)
depthToBpp[i] = 0;
/*
* Generate mappings between bitsPerPixel and depth,
* also ensure that all screens comply with protocol
* restrictions on equivalent formats for the same
* depth on different screens
*/
for (card = kdCardInfo; card; card = card->next)
{
for (screen = card->screenList; screen; screen = screen->next)
{
bpp = screen->fb.bitsPerPixel;
if (bpp == 24)
bpp = 32;
if (!depthToBpp[screen->fb.depth])
depthToBpp[screen->fb.depth] = bpp;
else if (depthToBpp[screen->fb.depth] != bpp)
return FALSE;
}
}
/*
* Fill in additional formats
*/
for (i = 0; i < NUM_KD_DEPTHS; i++)
if (!depthToBpp[kdDepths[i].depth])
depthToBpp[kdDepths[i].depth] = kdDepths[i].bpp;
pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
pScreenInfo->numPixmapFormats = 0;
for (i = 1; i <= 32; i++)
{
if (depthToBpp[i])
{
format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++];
format->depth = i;
format->bitsPerPixel = depthToBpp[i];
format->scanlinePad = BITMAP_SCANLINE_PAD;
}
}
return TRUE;
}
static void
KdAddScreen (ScreenInfo *pScreenInfo,
KdScreenInfo *screen,
int argc,
char **argv)
{
int i;
/*
* Fill in fb visual type masks for this screen
*/
for (i = 0; i < pScreenInfo->numPixmapFormats; i++)
{
unsigned long visuals;
Pixel rm, gm, bm;
visuals = 0;
rm = gm = bm = 0;
if (pScreenInfo->formats[i].depth == screen->fb.depth)
{
visuals = screen->fb.visuals;
rm = screen->fb.redMask;
gm = screen->fb.greenMask;
bm = screen->fb.blueMask;
}
fbSetVisualTypesAndMasks (pScreenInfo->formats[i].depth,
visuals,
8,
rm, gm, bm);
}
kdCurrentScreen = screen;
AddScreen (KdScreenInit, argc, argv);
}
#if 0 /* This function is not used currently */
int
KdDepthToFb (ScreenPtr pScreen, int depth)
{
KdScreenPriv(pScreen);
for (fb = 0; fb <= KD_MAX_FB && pScreenPriv->screen->fb.frameBuffer; fb++)
if (pScreenPriv->screen->fb.depth == depth)
return fb;
}
#endif
static int
KdSignalWrapper (int signum)
{
kdCaughtSignal = TRUE;
return 1; /* use generic OS layer cleanup & abort */
}
void
KdInitOutput (ScreenInfo *pScreenInfo,
int argc,
char **argv)
{
KdCardInfo *card;
KdScreenInfo *screen;
if (!kdCardInfo)
{
InitCard (0);
if (!(card = KdCardInfoLast ()))
FatalError("No matching cards found!\n");
screen = KdScreenInfoAdd (card);
KdParseScreen (screen, 0);
}
/*
* Initialize all of the screens for all of the cards
*/
for (card = kdCardInfo; card; card = card->next)
{
int ret=1;
if(card->cfuncs->cardinit)
ret=(*card->cfuncs->cardinit) (card);
if (ret)
{
for (screen = card->screenList; screen; screen = screen->next)
KdInitScreen (pScreenInfo, screen, argc, argv);
}
}
/*
* Merge the various pixmap formats together, this can fail
* when two screens share depth but not bitsPerPixel
*/
if (!KdSetPixmapFormats (pScreenInfo))
return;
/*
* Add all of the screens
*/
for (card = kdCardInfo; card; card = card->next)
for (screen = card->screenList; screen; screen = screen->next)
KdAddScreen (pScreenInfo, screen, argc, argv);
OsRegisterSigWrapper(KdSignalWrapper);
}
void
OsVendorFatalError(void)
{
}
int
DPMSSet(ClientPtr client, int level)
{
return Success;
}
Bool
DPMSSupported (void)
{
return FALSE;
}