static void
FreeCursorBits(CursorBitsPtr bits)
{
    if (--bits->refcnt > 0)
	return;
    xfree(bits->source);
    xfree(bits->mask);
#ifdef ARGB_CURSOR
    xfree(bits->argb);
#endif
    dixFreePrivates(bits->devPrivates);
    bits->devPrivates = NULL;
    if (bits->refcnt == 0)
    {
	GlyphSharePtr *prev, this;

	for (prev = &sharedGlyphs;
	     (this = *prev) && (this->bits != bits);
	     prev = &this->next)
	    ;
	if (this)
	{
	    *prev = this->next;
	    CloseFont(this->font, (Font)0);
	    xfree(this);
	}
	xfree(bits);
    }
}
void
InitSelections(void)
{
    Selection *pSel, *pNextSel;

    pSel = CurrentSelections;
    while (pSel) {
	pNextSel = pSel->next;
	dixFreePrivates(pSel->devPrivates);
	xfree(pSel);
	pSel = pNextSel;
    }

    CurrentSelections = NULL;
}
Пример #3
0
void
CloseDownExtensions(void)
{
    int i, j;

    for (i = NumExtensions - 1; i >= 0; i--) {
        if (extensions[i]->CloseDown)
            extensions[i]->CloseDown(extensions[i]);
        NumExtensions = i;
        free(extensions[i]->name);
        for (j = extensions[i]->num_aliases; --j >= 0;)
            free(extensions[i]->aliases[j]);
        free(extensions[i]->aliases);
        dixFreePrivates(extensions[i]->devPrivates, PRIVATE_EXTENSION);
        free(extensions[i]);
    }
    free(extensions);
    extensions = (ExtensionEntry **) NULL;
    lastEvent = EXTENSION_EVENT_BASE;
    lastError = FirstExtensionError;
}
/**
 * To be called indirectly by DeleteResource; must use exactly two args.
 *
 *  \param value must conform to DeleteType
 */
int
FreeCursor(pointer value, XID cid)
{
    int		nscr;
    CursorPtr 	pCurs = (CursorPtr)value;

    ScreenPtr	pscr;
    DeviceIntPtr pDev = NULL; /* unused anyway */

    if ( --pCurs->refcnt != 0)
	return(Success);

    for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
    {
	pscr = screenInfo.screens[nscr];
        (void)( *pscr->UnrealizeCursor)(pDev, pscr, pCurs);
    }
    dixFreePrivates(pCurs->devPrivates);
    FreeCursorBits(pCurs->bits);
    xfree( pCurs);
    return(Success);
}
Пример #5
0
int
AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor, ClientPtr client, XID cid)
{
    CursorPtr	pCursor;
    int		rc, i;
    AnimCurPtr	ac;

    for (i = 0; i < screenInfo.numScreens; i++)
	if (!GetAnimCurScreenIfSet (screenInfo.screens[i]))
	    return BadImplementation;

    for (i = 0; i < ncursor; i++)
	if (IsAnimCur (cursors[i]))
	    return BadMatch;
	
    pCursor = (CursorPtr) xalloc (sizeof (CursorRec) +
				  sizeof (AnimCurRec) +
				  ncursor * sizeof (AnimCurElt));
    if (!pCursor)
	return BadAlloc;
    pCursor->bits = &animCursorBits;
    pCursor->refcnt = 1;
    
    pCursor->foreRed = cursors[0]->foreRed;
    pCursor->foreGreen = cursors[0]->foreGreen;
    pCursor->foreBlue = cursors[0]->foreBlue;
    
    pCursor->backRed = cursors[0]->backRed;
    pCursor->backGreen = cursors[0]->backGreen;
    pCursor->backBlue = cursors[0]->backBlue;

    pCursor->id = cid;
    pCursor->devPrivates = NULL;

    /* security creation/labeling check */
    rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCursor,
		  RT_NONE, NULL, DixCreateAccess);
    if (rc != Success) {
	dixFreePrivates(pCursor->devPrivates);
	xfree(pCursor);
	return rc;
    }
	
    /*
     * Fill in the AnimCurRec
     */
    animCursorBits.refcnt++;
    ac = GetAnimCur (pCursor);
    ac->nelt = ncursor;
    ac->elts = (AnimCurElt *) (ac + 1);
    
    for (i = 0; i < ncursor; i++)
    {
	cursors[i]->refcnt++;
	ac->elts[i].pCursor = cursors[i];
	ac->elts[i].delay = deltas[i];
    }
    
    *ppCursor = pCursor;
    return Success;
}
Пример #6
0
int
main(int argc, char *argv[], char *envp[])
#endif
{
    int i;
    HWEventQueueType alwaysCheckForInput[2];

    display = "0";

    InitRegions();

    CheckUserParameters(argc, argv, envp);

    CheckUserAuthorization();

    InitConnectionLimits();

    ProcessCommandLine(argc, argv);

    alwaysCheckForInput[0] = 0;
    alwaysCheckForInput[1] = 1;
    while (1) {
        serverGeneration++;
        ScreenSaverTime = defaultScreenSaverTime;
        ScreenSaverInterval = defaultScreenSaverInterval;
        ScreenSaverBlanking = defaultScreenSaverBlanking;
        ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
#ifdef DPMSExtension
        DPMSStandbyTime = DPMSSuspendTime = DPMSOffTime = ScreenSaverTime;
        DPMSEnabled = TRUE;
        DPMSPowerLevel = 0;
#endif
        InitBlockAndWakeupHandlers();
        /* Perform any operating system dependent initializations you'd like */
        OsInit();
        if (serverGeneration == 1) {
            CreateWellKnownSockets();
            for (i = 1; i < MAXCLIENTS; i++)
                clients[i] = NullClient;
            serverClient = calloc(sizeof(ClientRec), 1);
            if (!serverClient)
                FatalError("couldn't create server client");
            InitClient(serverClient, 0, (pointer) NULL);
        }
        else
            ResetWellKnownSockets();
        clients[0] = serverClient;
        currentMaxClients = 1;

        /* Initialize privates before first allocation */
        dixResetPrivates();

        /* Initialize server client devPrivates, to be reallocated as
         * more client privates are registered
         */
        if (!dixAllocatePrivates(&serverClient->devPrivates, PRIVATE_CLIENT))
            FatalError("failed to create server client privates");

        if (!InitClientResources(serverClient)) /* for root resources */
            FatalError("couldn't init server resources");

        SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
        screenInfo.numScreens = 0;

        InitAtoms();
        InitEvents();
        InitSelections();
        InitGlyphCaching();
        dixResetRegistry();
        ResetFontPrivateIndex();
        InitCallbackManager();
        InitOutput(&screenInfo, argc, argv);

        if (screenInfo.numScreens < 1)
            FatalError("no screens found");
        InitExtensions(argc, argv);

        for (i = 0; i < screenInfo.numGPUScreens; i++) {
            ScreenPtr pScreen = screenInfo.gpuscreens[i];
            if (!CreateScratchPixmapsForScreen(pScreen))
                FatalError("failed to create scratch pixmaps");
        }

        for (i = 0; i < screenInfo.numScreens; i++) {
            ScreenPtr pScreen = screenInfo.screens[i];

            if (!CreateScratchPixmapsForScreen(pScreen))
                FatalError("failed to create scratch pixmaps");
            if (pScreen->CreateScreenResources &&
                !(*pScreen->CreateScreenResources) (pScreen))
                FatalError("failed to create screen resources");
            if (!CreateGCperDepth(i))
                FatalError("failed to create scratch GCs");
            if (!CreateDefaultStipple(i))
                FatalError("failed to create default stipple");
            if (!CreateRootWindow(pScreen))
                FatalError("failed to create root window");
        }

        InitFonts();
        if (SetDefaultFontPath(defaultFontPath) != Success) {
            ErrorF("[dix] failed to set default font path '%s'",
                   defaultFontPath);
        }
        if (!SetDefaultFont(defaultTextFont)) {
            FatalError("could not open default font '%s'", defaultTextFont);
        }

        if (!(rootCursor = CreateRootCursor(NULL, 0))) {
            FatalError("could not open default cursor font '%s'",
                       defaultCursorFont);
        }

#ifdef DPMSExtension
        /* check all screens, looking for DPMS Capabilities */
        DPMSCapableFlag = DPMSSupported();
        if (!DPMSCapableFlag)
            DPMSEnabled = FALSE;
#endif

#ifdef PANORAMIX
        /*
         * Consolidate window and colourmap information for each screen
         */
        if (!noPanoramiXExtension)
            PanoramiXConsolidate();
#endif

        for (i = 0; i < screenInfo.numScreens; i++)
            InitRootWindow(screenInfo.screens[i]->root);

        InitCoreDevices();
        InitInput(argc, argv);
        InitAndStartDevices();
        ReserveClientIds(serverClient);

        dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);

#ifdef PANORAMIX
        if (!noPanoramiXExtension) {
            if (!PanoramiXCreateConnectionBlock()) {
                FatalError("could not create connection block info");
            }
        }
        else
#endif
        {
            if (!CreateConnectionBlock()) {
                FatalError("could not create connection block info");
            }
        }

#ifdef XQUARTZ
        /* Let the other threads know the server is done with its init */
        pthread_mutex_lock(&serverRunningMutex);
        serverRunning = TRUE;
        pthread_cond_broadcast(&serverRunningCond);
        pthread_mutex_unlock(&serverRunningMutex);
#endif

        NotifyParentProcess();

        Dispatch();

#ifdef XQUARTZ
        /* Let the other threads know the server is no longer running */
        pthread_mutex_lock(&serverRunningMutex);
        serverRunning = FALSE;
        pthread_mutex_unlock(&serverRunningMutex);
#endif

        UndisplayDevices();
        DisableAllDevices();

        /* Now free up whatever must be freed */
        if (screenIsSaved == SCREEN_SAVER_ON)
            dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
        FreeScreenSaverTimer();
        CloseDownExtensions();

#ifdef PANORAMIX
        {
            Bool remember_it = noPanoramiXExtension;

            noPanoramiXExtension = TRUE;
            FreeAllResources();
            noPanoramiXExtension = remember_it;
        }
#else
        FreeAllResources();
#endif

        CloseInput();

        for (i = 0; i < screenInfo.numScreens; i++)
            screenInfo.screens[i]->root = NullWindow;

        CloseDownDevices();

        CloseDownEvents();

        for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) {
            ScreenPtr pScreen = screenInfo.gpuscreens[i];
            FreeScratchPixmapsForScreen(pScreen);
            (*pScreen->CloseScreen) (pScreen);
            dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
            free(pScreen);
            screenInfo.numGPUScreens = i;
        }

        for (i = screenInfo.numScreens - 1; i >= 0; i--) {
            FreeScratchPixmapsForScreen(screenInfo.screens[i]);
            FreeGCperDepth(i);
            FreeDefaultStipple(i);
            dixFreeScreenSpecificPrivates(screenInfo.screens[i]);
            (*screenInfo.screens[i]->CloseScreen) (screenInfo.screens[i]);
            dixFreePrivates(screenInfo.screens[i]->devPrivates, PRIVATE_SCREEN);
            free(screenInfo.screens[i]);
            screenInfo.numScreens = i;
        }

        ReleaseClientIds(serverClient);
        dixFreePrivates(serverClient->devPrivates, PRIVATE_CLIENT);
        serverClient->devPrivates = NULL;

        FreeFonts();

        FreeAuditTimer();

        if (dispatchException & DE_TERMINATE) {
            CloseWellKnownConnections();
        }

        OsCleanup((dispatchException & DE_TERMINATE) != 0);

        if (dispatchException & DE_TERMINATE) {
            ddxGiveUp(EXIT_NO_ERROR);
            break;
        }

        free(ConnectionInfo);
        ConnectionInfo = NULL;
    }
    return 0;
}
Пример #7
0
ExtensionEntry *
AddExtension(const char *name, int NumEvents, int NumErrors,
	     int (*MainProc)(ClientPtr c1), 
	     int (*SwappedMainProc)(ClientPtr c2), 
	     void (*CloseDownProc)(ExtensionEntry *e), 
	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
{
    int i;
    ExtensionEntry *ext, **newexts;

    if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
        return((ExtensionEntry *) NULL);
    if ((lastEvent + NumEvents > MAXEVENTS) || 
	        (unsigned)(lastError + NumErrors > LAST_ERROR)) {
        LogMessage(X_ERROR, "Not enabling extension %s: maximum number of "
                   "events or errors exceeded.\n", name);
        return((ExtensionEntry *) NULL);
    }

    ext = calloc(sizeof (ExtensionEntry), 1);
    if (!ext)
	return NULL;
    if (!dixAllocatePrivates(&ext->devPrivates, PRIVATE_EXTENSION)) {
	free(ext);
	return NULL;
    }
    ext->name = strdup(name);
    ext->num_aliases = 0;
    ext->aliases = (char **)NULL;
    if (!ext->name)
    {
	dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
	free(ext);
	return((ExtensionEntry *) NULL);
    }
    i = NumExtensions;
    newexts = (ExtensionEntry **) realloc(extensions,
					   (i + 1) * sizeof(ExtensionEntry *));
    if (!newexts)
    {
	free(ext->name);
	dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
	free(ext);
	return((ExtensionEntry *) NULL);
    }
    NumExtensions++;
    extensions = newexts;
    extensions[i] = ext;
    ext->index = i;
    ext->base = i + EXTENSION_BASE;
    ext->CloseDown = CloseDownProc;
    ext->MinorOpcode = MinorOpcodeProc;
    ProcVector[i + EXTENSION_BASE] = MainProc;
    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
    if (NumEvents)
    {
        ext->eventBase = lastEvent;
	ext->eventLast = lastEvent + NumEvents;
	lastEvent += NumEvents;
    }
    else
    {
        ext->eventBase = 0;
        ext->eventLast = 0;
    }
    if (NumErrors)
    {
        ext->errorBase = lastError;
	ext->errorLast = lastError + NumErrors;
	lastError += NumErrors;
    }
    else
    {
        ext->errorBase = 0;
        ext->errorLast = 0;
    }

    RegisterExtensionNames(ext);
    return ext;
}
Пример #8
0
int
dix_main(int argc, char *argv[], char *envp[])
{
    int i;
    HWEventQueueType alwaysCheckForInput[2];
    #ifdef _DEBUG
    //int TmpFlag=_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG);
    
    //TmpFlag|=_CRTDBG_ALLOC_MEM_DF;
    //TmpFlag|=_CRTDBG_DELAY_FREE_MEM_DF;
    //TmpFlag|=_CRTDBG_CHECK_ALWAYS_DF;
    //TmpFlag|=_CRTDBG_CHECK_CRT_DF;
    //TmpFlag|=_CRTDBG_LEAK_CHECK_DF;
    
    //_CrtSetDbgFlag(TmpFlag);
    #endif

    ptw32_processInitialize();
    display = "0";

    #ifdef WIN32

    if (InitWSA()<0)
    {
      printf("Error initialising WSA\n");
      return -1;
    }
    /* In Win32 we have different threads call Xlib functions (depending
       on the commandline options given).
       XInitThreads has to be called before
       any xlib function is called (aoccording to the man page) */
    XInitThreads();
    /* change the current directory to the directory where the vcxsrv.exe executable is installed.
       This is needed because the font directories are relative to the current directory.
     */
     {
       char ModuleFilename[MAX_PATH];
       char *pSlash;
       GetModuleFileName(NULL,ModuleFilename,sizeof(ModuleFilename));
       pSlash=strrchr(ModuleFilename,'\\');
       if (pSlash)
       {
         *pSlash='\0';
         chdir(ModuleFilename);
       }
     }
    OsVendorPreInit(argc, argv);
    #endif

    InitRegions();

    CheckUserParameters(argc, argv, envp);

    CheckUserAuthorization();

    InitConnectionLimits();

    ProcessCommandLine(argc, argv);

    alwaysCheckForInput[0] = 0;
    alwaysCheckForInput[1] = 1;
    while (1) {
        serverGeneration++;
        ScreenSaverTime = defaultScreenSaverTime;
        ScreenSaverInterval = defaultScreenSaverInterval;
        ScreenSaverBlanking = defaultScreenSaverBlanking;
        ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
#ifdef DPMSExtension
        DPMSStandbyTime = DPMSSuspendTime = DPMSOffTime = ScreenSaverTime;
        DPMSEnabled = TRUE;
        DPMSPowerLevel = 0;
#endif
        InitBlockAndWakeupHandlers();
        /* Perform any operating system dependent initializations you'd like */
        if (serverGeneration == 1) {
            CreateWellKnownSockets();
            for (i = 1; i < MAXCLIENTS; i++)
                clients[i] = NullClient;
            serverClient = calloc(sizeof(ClientRec), 1);
            if (!serverClient)
                FatalError("couldn't create server client");
            InitClient(serverClient, 0, (void *) NULL);
        }
        else
            ResetWellKnownSockets();
        clients[0] = serverClient;
        currentMaxClients = 1;
        OsInit();

        /* clear any existing selections */
        InitSelections();

        /* Initialize privates before first allocation */
        dixResetPrivates();

        /* Initialize server client devPrivates, to be reallocated as
         * more client privates are registered
         */
        if (!dixAllocatePrivates(&serverClient->devPrivates, PRIVATE_CLIENT))
            FatalError("failed to create server client privates");

        if (!InitClientResources(serverClient)) /* for root resources */
            FatalError("couldn't init server resources");

        SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
        screenInfo.numScreens = 0;

        InitAtoms();
        InitEvents();
        InitGlyphCaching();
        dixResetRegistry();
        ResetFontPrivateIndex();
        InitCallbackManager();
        InitOutput(&screenInfo, argc, argv);

        if (screenInfo.numScreens < 1)
            FatalError("no screens found");
        InitExtensions(argc, argv);

        for (i = 0; i < screenInfo.numGPUScreens; i++) {
            ScreenPtr pScreen = screenInfo.gpuscreens[i];
            if (!CreateScratchPixmapsForScreen(pScreen))
                FatalError("failed to create scratch pixmaps");
            if (pScreen->CreateScreenResources &&
                !(*pScreen->CreateScreenResources) (pScreen))
                FatalError("failed to create screen resources");
        }

        for (i = 0; i < screenInfo.numScreens; i++) {
            ScreenPtr pScreen = screenInfo.screens[i];

            if (!CreateScratchPixmapsForScreen(pScreen))
                FatalError("failed to create scratch pixmaps");
            if (pScreen->CreateScreenResources &&
                !(*pScreen->CreateScreenResources) (pScreen))
                FatalError("failed to create screen resources");
            if (!CreateGCperDepth(i))
                FatalError("failed to create scratch GCs");
            if (!CreateDefaultStipple(i))
                FatalError("failed to create default stipple");
            if (!CreateRootWindow(pScreen))
                FatalError("failed to create root window");
        }

        InitFonts();
        if (SetDefaultFontPath(defaultFontPath) != Success) {
            ErrorF("[dix] failed to set default font path '%s'",
                   defaultFontPath);
        }
        if (!SetDefaultFont(defaultTextFont)) {
            FatalError("could not open default font '%s'", defaultTextFont);
        }

        if (!(rootCursor = CreateRootCursor(NULL, 0))) {
            FatalError("could not open default cursor font '%s'",
                       defaultCursorFont);
        }

#ifdef DPMSExtension
        /* check all screens, looking for DPMS Capabilities */
        DPMSCapableFlag = DPMSSupported();
        if (!DPMSCapableFlag)
            DPMSEnabled = FALSE;
#endif

#ifdef PANORAMIX
        /*
         * Consolidate window and colourmap information for each screen
         */
        if (!noPanoramiXExtension)
            PanoramiXConsolidate();
#endif

        for (i = 0; i < screenInfo.numScreens; i++)
            InitRootWindow(screenInfo.screens[i]->root);

        InitCoreDevices();
        InitInput(argc, argv);
        InitAndStartDevices();
        ReserveClientIds(serverClient);

        dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);

        dixCloseRegistry();

#ifdef PANORAMIX
        if (!noPanoramiXExtension) {
            if (!PanoramiXCreateConnectionBlock()) {
                FatalError("could not create connection block info");
            }
        }
        else
#endif
        {
            if (!CreateConnectionBlock()) {
                FatalError("could not create connection block info");
            }
        }

#ifdef XQUARTZ
        /* Let the other threads know the server is done with its init */
        pthread_mutex_lock(&serverRunningMutex);
        serverRunning = TRUE;
        pthread_cond_broadcast(&serverRunningCond);
        pthread_mutex_unlock(&serverRunningMutex);
#endif

        NotifyParentProcess();

        #ifdef _MSC_VER
        // initialise here because doing it in InitInput failes because keyboard device is not started yet then
        winInitializeModeKeyStates ();
        #endif

        Dispatch();

#ifdef XQUARTZ
        /* Let the other threads know the server is no longer running */
        pthread_mutex_lock(&serverRunningMutex);
        serverRunning = FALSE;
        pthread_mutex_unlock(&serverRunningMutex);
#endif

        UndisplayDevices();
        DisableAllDevices();

        /* Now free up whatever must be freed */
        if (screenIsSaved == SCREEN_SAVER_ON)
            dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
        FreeScreenSaverTimer();
        CloseDownExtensions();

#ifdef PANORAMIX
        {
            Bool remember_it = noPanoramiXExtension;

            noPanoramiXExtension = TRUE;
            FreeAllResources();
            noPanoramiXExtension = remember_it;
        }
#else
        FreeAllResources();
#endif

        CloseInput();

        for (i = 0; i < screenInfo.numScreens; i++)
            screenInfo.screens[i]->root = NullWindow;

        CloseDownDevices();

        CloseDownEvents();

        for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) {
            ScreenPtr pScreen = screenInfo.gpuscreens[i];
            FreeScratchPixmapsForScreen(pScreen);
            (*pScreen->CloseScreen) (pScreen);
            dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
            free(pScreen);
            screenInfo.numGPUScreens = i;
        }

        for (i = screenInfo.numScreens - 1; i >= 0; i--) {
            FreeScratchPixmapsForScreen(screenInfo.screens[i]);
            FreeGCperDepth(i);
            FreeDefaultStipple(i);
            dixFreeScreenSpecificPrivates(screenInfo.screens[i]);
            (*screenInfo.screens[i]->CloseScreen) (screenInfo.screens[i]);
            dixFreePrivates(screenInfo.screens[i]->devPrivates, PRIVATE_SCREEN);
            free(screenInfo.screens[i]);
            screenInfo.numScreens = i;
        }

        ReleaseClientIds(serverClient);
        dixFreePrivates(serverClient->devPrivates, PRIVATE_CLIENT);
        serverClient->devPrivates = NULL;

	dixFreeRegistry();

        FreeFonts();

        FreeAllAtoms();

        FreeAuditTimer();

        DeleteCallbackManager();

        if (dispatchException & DE_TERMINATE) {
            CloseWellKnownConnections();
        }

        OsCleanup((dispatchException & DE_TERMINATE) != 0);

        if (dispatchException & DE_TERMINATE) {
            ddxGiveUp(EXIT_NO_ERROR);
            break;
        }

        free(ConnectionInfo);
        ConnectionInfo = NULL;
    }
    return 0;
}
int
AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
                unsigned foreRed, unsigned foreGreen, unsigned foreBlue, 
                unsigned backRed, unsigned backGreen, unsigned backBlue,
		CursorPtr *ppCurs, ClientPtr client, XID cid)
{
    FontPtr  sourcefont, maskfont;
    unsigned char   *srcbits;
    unsigned char   *mskbits;
    CursorMetricRec cm;
    int rc;
    CursorBitsPtr  bits;
    CursorPtr 	pCurs;
    GlyphSharePtr pShare;

    rc = dixLookupResourceByType((pointer *)&sourcefont, source, RT_FONT, client,
				 DixUseAccess);
    if (rc != Success)
    {
	client->errorValue = source;
	return (rc == BadValue) ? BadFont : rc;
    }
    rc = dixLookupResourceByType((pointer *)&maskfont, mask, RT_FONT, client,
				 DixUseAccess);
    if (rc != Success && mask != None)
    {
	client->errorValue = mask;
	return (rc == BadValue) ? BadFont : rc;
    }
    if (sourcefont != maskfont)
	pShare = (GlyphSharePtr)NULL;
    else
    {
	for (pShare = sharedGlyphs;
	     pShare &&
	     ((pShare->font != sourcefont) ||
	      (pShare->sourceChar != sourceChar) ||
	      (pShare->maskChar != maskChar));
	     pShare = pShare->next)
	    ;
    }
    if (pShare)
    {
	pCurs = (CursorPtr)xcalloc(sizeof(CursorRec), 1);
	if (!pCurs)
	    return BadAlloc;
	bits = pShare->bits;
	bits->refcnt++;
    }
    else
    {
	if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm))
	{
	    client->errorValue = sourceChar;
	    return BadValue;
	}
	if (!maskfont)
	{
	    long n;
	    unsigned char *mskptr;

	    n = BitmapBytePad(cm.width)*(long)cm.height;
	    mskptr = mskbits = xalloc(n);
	    if (!mskptr)
		return BadAlloc;
	    while (--n >= 0)
		*mskptr++ = ~0;
	}
	else
	{
	    if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm))
	    {
		client->errorValue = maskChar;
		return BadValue;
	    }
	    if ((rc = ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits)))
		return rc;
	}
	if ((rc = ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits)))
	{
	    xfree(mskbits);
	    return rc;
	}
	if (sourcefont != maskfont)
	{
	    pCurs = 
                (CursorPtr)xcalloc(sizeof(CursorRec) + sizeof(CursorBits), 1);
	    if (pCurs)
		bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
	    else
		bits = (CursorBitsPtr)NULL;
	}
	else
	{
	    pCurs = (CursorPtr)xcalloc(sizeof(CursorRec), 1);
	    if (pCurs)
		bits = (CursorBitsPtr)xcalloc(sizeof(CursorBits), 1);
	    else
		bits = (CursorBitsPtr)NULL;
	}
	if (!bits)
	{
	    xfree(pCurs);
	    xfree(mskbits);
	    xfree(srcbits);
	    return BadAlloc;
	}
	bits->source = srcbits;
	bits->mask = mskbits;
#ifdef ARGB_CURSOR
	bits->argb = 0;
#endif
	bits->width = cm.width;
	bits->height = cm.height;
	bits->xhot = cm.xhot;
	bits->yhot = cm.yhot;
	bits->devPrivates = NULL;
	if (sourcefont != maskfont)
	    bits->refcnt = -1;
	else
	{
	    bits->refcnt = 1;
	    pShare = xalloc(sizeof(GlyphShare));
	    if (!pShare)
	    {
		FreeCursorBits(bits);
		return BadAlloc;
	    }
	    pShare->font = sourcefont;
	    sourcefont->refcnt++;
	    pShare->sourceChar = sourceChar;
	    pShare->maskChar = maskChar;
	    pShare->bits = bits;
	    pShare->next = sharedGlyphs;
	    sharedGlyphs = pShare;
	}
    }

    CheckForEmptyMask(bits);
    pCurs->bits = bits;
    pCurs->refcnt = 1;
#ifdef XFIXES
    pCurs->serialNumber = ++cursorSerial;
    pCurs->name = None;
#endif

    pCurs->foreRed = foreRed;
    pCurs->foreGreen = foreGreen;
    pCurs->foreBlue = foreBlue;

    pCurs->backRed = backRed;
    pCurs->backGreen = backGreen;
    pCurs->backBlue = backBlue;

    pCurs->id = cid;
    pCurs->devPrivates = NULL;

    /* security creation/labeling check */
    rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR,
		  pCurs, RT_NONE, NULL, DixCreateAccess);
    if (rc != Success)
        goto error;

    rc = RealizeCursorAllScreens(pCurs);
    if (rc != Success)
        goto error;

    *ppCurs = pCurs;
    return Success;

error:
    dixFreePrivates(pCurs->devPrivates);
    FreeCursorBits(bits);
    xfree(pCurs);

    return rc;
}
/**
 * does nothing about the resource table, just creates the data structure.
 * does not copy the src and mask bits
 *
 *  \param psrcbits  server-defined padding
 *  \param pmaskbits server-defined padding
 *  \param argb      no padding
 */
int
AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
		CARD32 *argb, CursorMetricPtr cm,
		unsigned foreRed, unsigned foreGreen, unsigned foreBlue, 
		unsigned backRed, unsigned backGreen, unsigned backBlue,
		CursorPtr *ppCurs, ClientPtr client, XID cid)
{
    CursorBitsPtr  bits;
    CursorPtr 	pCurs;
    int rc;

    *ppCurs = NULL;
    pCurs = (CursorPtr)xcalloc(sizeof(CursorRec) + sizeof(CursorBits), 1);
    if (!pCurs)
    {
	xfree(psrcbits);
	xfree(pmaskbits);
	return BadAlloc;
    }
    bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
    bits->source = psrcbits;
    bits->mask = pmaskbits;
#ifdef ARGB_CURSOR
    bits->argb = argb;
#endif
    bits->width = cm->width;
    bits->height = cm->height;
    bits->xhot = cm->xhot;
    bits->yhot = cm->yhot;
    pCurs->refcnt = 1;		
    bits->devPrivates = NULL;
    bits->refcnt = -1;
    CheckForEmptyMask(bits);
    pCurs->bits = bits;
#ifdef XFIXES
    pCurs->serialNumber = ++cursorSerial;
    pCurs->name = None;
#endif

    pCurs->foreRed = foreRed;
    pCurs->foreGreen = foreGreen;
    pCurs->foreBlue = foreBlue;

    pCurs->backRed = backRed;
    pCurs->backGreen = backGreen;
    pCurs->backBlue = backBlue;

    pCurs->id = cid;
    pCurs->devPrivates = NULL;

    /* security creation/labeling check */
    rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR,
		  pCurs, RT_NONE, NULL, DixCreateAccess);
    if (rc != Success)
        goto error;

    rc = RealizeCursorAllScreens(pCurs);
    if (rc != Success)
        goto error;

    *ppCurs = pCurs;
    return Success;

error:
    dixFreePrivates(pCurs->devPrivates);
    FreeCursorBits(bits);
    xfree(pCurs);

    return rc;
}