3
* Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
7
* Permission is hereby granted, free of charge, to any person obtaining
8
* a copy of this software and associated documentation files (the
9
* "Software"), to deal in the Software without restriction, including
10
* without limitation on the rights to use, copy, modify, merge,
11
* publish, distribute, sublicense, and/or sell copies of the Software,
12
* and to permit persons to whom the Software is furnished to do so,
13
* subject to the following conditions:
15
* The above copyright notice and this permission notice (including the
16
* next paragraph) shall be included in all copies or substantial
17
* portions of the Software.
19
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
* NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
23
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
* Kevin E. Martin <kem@redhat.com>
32
* David H. Dawes <dawes@xfree86.org>
37
* This file provides support for screen initialization. */
39
#ifdef HAVE_DMX_CONFIG_H
40
#include <dmx-config.h>
45
#include "dmxshadow.h"
46
#include "dmxscrinit.h"
47
#include "dmxcursor.h"
50
#include "dmxwindow.h"
51
#include "dmxpixmap.h"
62
#include "mipointer.h"
65
extern Bool dmxCloseScreen(int idx, ScreenPtr pScreen);
66
static Bool dmxSaveScreen(ScreenPtr pScreen, int what);
68
static unsigned long dmxGeneration;
69
static unsigned long *dmxCursorGeneration;
71
int dmxGCPrivateIndex; /**< Private index for GCs */
72
int dmxWinPrivateIndex; /**< Private index for Windows */
74
int dmxPixPrivateIndex; /**< Private index for Pixmaps */
76
int dmxFontPrivateIndex; /**< Private index for Fonts */
77
int dmxScreenPrivateIndex; /**< Private index for Screens */
78
int dmxColormapPrivateIndex; /**< Private index for Colormaps */
80
int dmxPictPrivateIndex; /**< Private index for Picts */
81
int dmxGlyphSetPrivateIndex; /**< Private index for GlyphSets */
84
/** Initialize the parts of screen \a idx that require access to the
86
void dmxBEScreenInit(int idx, ScreenPtr pScreen)
88
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
89
XSetWindowAttributes attribs;
94
/* FIXME: The dmxScreenInit() code currently assumes that it will
95
* not be called if the Xdmx server is started with this screen
96
* detached -- i.e., it assumes that dmxScreen->beDisplay is always
97
* valid. This is not necessarily a valid assumption when full
98
* addition/removal of screens is implemented, but when this code is
99
* broken out for screen reattachment, then we will reevaluate this
103
pScreen->mmWidth = DisplayWidthMM(dmxScreen->beDisplay,
104
DefaultScreen(dmxScreen->beDisplay));
105
pScreen->mmHeight = DisplayHeightMM(dmxScreen->beDisplay,
106
DefaultScreen(dmxScreen->beDisplay));
108
pScreen->whitePixel = dmxScreen->beWhitePixel;
109
pScreen->blackPixel = dmxScreen->beBlackPixel;
111
/* Handle screen savers and DPMS on the backend */
112
dmxDPMSInit(dmxScreen);
114
/* Create root window for screen */
115
mask = CWBackPixel | CWEventMask | CWColormap | CWOverrideRedirect;
116
attribs.background_pixel = dmxScreen->beBlackPixel;
117
attribs.event_mask = (KeyPressMask
126
attribs.colormap = dmxScreen->beDefColormaps[dmxScreen->beDefVisualIndex];
127
attribs.override_redirect = True;
130
XCreateWindow(dmxScreen->beDisplay,
131
DefaultRootWindow(dmxScreen->beDisplay),
134
dmxScreen->scrnWidth,
135
dmxScreen->scrnHeight,
139
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
142
dmxPropertyWindow(dmxScreen);
145
* This turns off the cursor by defining a cursor with no visible
149
char noCursorData[] = {0, 0, 0, 0,
154
pixmap = XCreateBitmapFromData(dmxScreen->beDisplay, dmxScreen->scrnWin,
156
XAllocNamedColor(dmxScreen->beDisplay, dmxScreen->beDefColormaps[0],
157
"black", &color, &tmp);
158
dmxScreen->noCursor = XCreatePixmapCursor(dmxScreen->beDisplay,
160
&color, &color, 0, 0);
161
XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
162
dmxScreen->noCursor);
164
XFreePixmap(dmxScreen->beDisplay, pixmap);
167
XMapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
173
gcvals.function = GXcopy;
174
gcvals.plane_mask = AllPlanes;
175
gcvals.clip_mask = None;
177
dmxScreen->shadowGC = XCreateGC(dmxScreen->beDisplay,
181
dmxScreen->shadowFBImage =
182
XCreateImage(dmxScreen->beDisplay,
183
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
187
(char *)dmxScreen->shadow,
188
dmxScreen->scrnWidth, dmxScreen->scrnHeight,
190
PixmapBytePad(dmxScreen->scrnWidth,
193
/* Create default drawables (used during GC creation) */
194
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++)
195
for (j = 0; j < dmxScreen->beNumDepths; j++)
196
if ((dmxScreen->bePixmapFormats[i].depth == 1) ||
197
(dmxScreen->bePixmapFormats[i].depth ==
198
dmxScreen->beDepths[j])) {
199
dmxScreen->scrnDefDrawables[i] = (Drawable)
200
XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
201
1, 1, dmxScreen->bePixmapFormats[i].depth);
207
/** Initialize screen number \a idx. */
208
Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
210
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
213
if (dmxGeneration != serverGeneration) {
215
/* Allocate picture private index */
216
dmxPictPrivateIndex = AllocatePicturePrivateIndex();
217
if (dmxPictPrivateIndex == -1)
220
/* Allocate glyph set private index */
221
dmxGlyphSetPrivateIndex = AllocateGlyphSetPrivateIndex();
222
if (dmxGlyphSetPrivateIndex == -1)
226
/* Allocate GC private index */
227
dmxGCPrivateIndex = AllocateGCPrivateIndex();
228
if (dmxGCPrivateIndex == -1)
231
/* Allocate window private index */
232
dmxWinPrivateIndex = AllocateWindowPrivateIndex();
233
if (dmxWinPrivateIndex == -1)
237
/* Allocate pixmap private index */
238
dmxPixPrivateIndex = AllocatePixmapPrivateIndex();
239
if (dmxPixPrivateIndex == -1)
242
#error Must define PIXPRIV to compile DMX X server
245
/* Allocate font private index */
246
dmxFontPrivateIndex = AllocateFontPrivateIndex();
247
if (dmxFontPrivateIndex == -1)
250
/* Allocate screen private index */
251
dmxScreenPrivateIndex = AllocateScreenPrivateIndex();
252
if (dmxScreenPrivateIndex == -1)
255
dmxGeneration = serverGeneration;
259
dmxScreen->shadow = shadowAlloc(dmxScreen->scrnWidth,
260
dmxScreen->scrnHeight,
263
if (!dmxInitGC(pScreen)) return FALSE;
264
if (!dmxInitWindow(pScreen)) return FALSE;
265
if (!dmxInitPixmap(pScreen)) return FALSE;
269
* Initalise the visual types. miSetVisualTypesAndMasks() requires
270
* that all of the types for each depth be collected together. It's
271
* intended for slightly different usage to what we would like here.
272
* Maybe a miAddVisualTypeAndMask() function will be added to make
273
* things easier here.
275
for (i = 0; i < dmxScreen->beNumDepths; i++) {
279
int preferredClass = -1;
284
depth = dmxScreen->beDepths[i];
285
for (j = 0; j < dmxScreen->beNumVisuals; j++) {
288
vi = &dmxScreen->beVisuals[j];
289
if (vi->depth == depth) {
290
/* Assume the masks are all the same. */
291
visuals |= (1 << vi->class);
292
bitsPerRgb = vi->bits_per_rgb;
293
redMask = vi->red_mask;
294
greenMask = vi->green_mask;
295
blueMask = vi->blue_mask;
296
if (j == dmxScreen->beDefVisualIndex) {
297
preferredClass = vi->class;
301
miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb, preferredClass,
302
redMask, greenMask, blueMask);
305
fbScreenInit(pScreen,
306
dmxShadowFB ? dmxScreen->shadow : NULL,
307
dmxScreen->scrnWidth,
308
dmxScreen->scrnHeight,
311
dmxScreen->scrnWidth,
314
(void)dmxPictureInit(pScreen, 0, 0);
317
if (dmxShadowFB && !shadowInit(pScreen, dmxShadowUpdateProc, NULL))
320
miInitializeBackingStore(pScreen);
323
miDCInitialize(pScreen, &dmxPointerCursorFuncs);
325
MAXSCREENSALLOC(dmxCursorGeneration);
326
if (dmxCursorGeneration[idx] != serverGeneration) {
327
if (!(miPointerInitialize(pScreen,
328
&dmxPointerSpriteFuncs,
329
&dmxPointerCursorFuncs,
333
dmxCursorGeneration[idx] = serverGeneration;
337
DMX_WRAP(CloseScreen, dmxCloseScreen, dmxScreen, pScreen);
338
DMX_WRAP(SaveScreen, dmxSaveScreen, dmxScreen, pScreen);
340
dmxBEScreenInit(idx, pScreen);
343
/* Wrap GC functions */
344
DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
346
/* Wrap Window functions */
347
DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
348
DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen);
349
DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen);
350
DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen,
352
DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen);
353
DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen);
354
DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen);
355
DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen);
356
DMX_WRAP(PaintWindowBackground, dmxPaintWindowBackground, dmxScreen,
358
DMX_WRAP(PaintWindowBorder, dmxPaintWindowBorder, dmxScreen, pScreen);
359
DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
361
DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
362
DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
364
DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
366
/* Wrap Image functions */
367
DMX_WRAP(GetImage, dmxGetImage, dmxScreen, pScreen);
368
DMX_WRAP(GetSpans, dmxGetSpans, dmxScreen, pScreen);
370
/* Wrap Pixmap functions */
371
DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen);
372
DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
373
DMX_WRAP(BitmapToRegion, dmxBitmapToRegion, dmxScreen, pScreen);
375
/* Wrap Font functions */
376
DMX_WRAP(RealizeFont, dmxRealizeFont, dmxScreen, pScreen);
377
DMX_WRAP(UnrealizeFont, dmxUnrealizeFont, dmxScreen, pScreen);
379
/* Wrap Colormap functions */
380
DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
381
DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
382
DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
383
DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
386
/* Wrap Shape functions */
387
DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
391
if (!dmxCreateDefColormap(pScreen))
397
/** Close the \a pScreen resources on the back-end server. */
398
void dmxBECloseScreen(ScreenPtr pScreen)
400
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
403
/* Restore the back-end screen-saver and DPMS state. */
404
dmxDPMSTerm(dmxScreen);
406
/* Free the screen resources */
408
XFreeCursor(dmxScreen->beDisplay, dmxScreen->noCursor);
409
dmxScreen->noCursor = (Cursor)0;
411
XUnmapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
412
XDestroyWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
413
dmxScreen->scrnWin = (Window)0;
416
/* Free the shadow GC and image assocated with the back-end server */
417
XFreeGC(dmxScreen->beDisplay, dmxScreen->shadowGC);
418
dmxScreen->shadowGC = NULL;
419
XFree(dmxScreen->shadowFBImage);
420
dmxScreen->shadowFBImage = NULL;
422
/* Free the default drawables */
423
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
424
XFreePixmap(dmxScreen->beDisplay, dmxScreen->scrnDefDrawables[i]);
425
dmxScreen->scrnDefDrawables[i] = (Drawable)0;
429
/* Free resources allocated during initialization (in dmxinit.c) */
430
for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
431
XFreeColormap(dmxScreen->beDisplay, dmxScreen->beDefColormaps[i]);
432
xfree(dmxScreen->beDefColormaps);
433
dmxScreen->beDefColormaps = NULL;
436
/* Do not free visuals, depths and pixmap formats here. Free them
437
* in dmxCloseScreen() instead -- see comment below. */
438
XFree(dmxScreen->beVisuals);
439
dmxScreen->beVisuals = NULL;
441
XFree(dmxScreen->beDepths);
442
dmxScreen->beDepths = NULL;
444
XFree(dmxScreen->bePixmapFormats);
445
dmxScreen->bePixmapFormats = NULL;
449
if (dmxScreen->glxVisuals) {
450
XFree(dmxScreen->glxVisuals);
451
dmxScreen->glxVisuals = NULL;
452
dmxScreen->numGlxVisuals = 0;
457
XCloseDisplay(dmxScreen->beDisplay);
458
dmxScreen->beDisplay = NULL;
461
/** Close screen number \a idx. */
462
Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
464
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
466
/* Reset the proc vectors */
475
/* Free the shadow framebuffer */
476
xfree(dmxScreen->shadow);
480
/* Unwrap Shape functions */
481
DMX_UNWRAP(SetShape, dmxScreen, pScreen);
484
/* Unwrap the pScreen functions */
485
DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
487
DMX_UNWRAP(CreateWindow, dmxScreen, pScreen);
488
DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen);
489
DMX_UNWRAP(PositionWindow, dmxScreen, pScreen);
490
DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen);
491
DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen);
492
DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen);
493
DMX_UNWRAP(RestackWindow, dmxScreen, pScreen);
494
DMX_UNWRAP(WindowExposures, dmxScreen, pScreen);
495
DMX_UNWRAP(PaintWindowBackground, dmxScreen, pScreen);
496
DMX_UNWRAP(PaintWindowBorder, dmxScreen, pScreen);
497
DMX_UNWRAP(CopyWindow, dmxScreen, pScreen);
499
DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
500
DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
502
DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
504
DMX_UNWRAP(GetImage, dmxScreen, pScreen);
505
DMX_UNWRAP(GetSpans, dmxScreen, pScreen);
507
DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
508
DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
509
DMX_UNWRAP(BitmapToRegion, dmxScreen, pScreen);
511
DMX_UNWRAP(RealizeFont, dmxScreen, pScreen);
512
DMX_UNWRAP(UnrealizeFont, dmxScreen, pScreen);
514
DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
515
DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
516
DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
517
DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
520
DMX_UNWRAP(SaveScreen, dmxScreen, pScreen);
522
if (dmxScreen->beDisplay) {
523
dmxBECloseScreen(pScreen);
526
/* Free visuals, depths and pixmap formats here so that they
527
* won't be freed when a screen is detached, thereby allowing
528
* the screen to be reattached to be compared to the one
529
* previously removed.
531
XFree(dmxScreen->beVisuals);
532
dmxScreen->beVisuals = NULL;
534
XFree(dmxScreen->beDepths);
535
dmxScreen->beDepths = NULL;
537
XFree(dmxScreen->bePixmapFormats);
538
dmxScreen->bePixmapFormats = NULL;
542
DMX_UNWRAP(CloseScreen, dmxScreen, pScreen);
543
return pScreen->CloseScreen(idx, pScreen);
546
static Bool dmxSaveScreen(ScreenPtr pScreen, int what)
548
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
550
if (dmxScreen->beDisplay) {
552
case SCREEN_SAVER_OFF:
553
case SCREEN_SAVER_FORCER:
554
XResetScreenSaver(dmxScreen->beDisplay);
555
dmxSync(dmxScreen, FALSE);
557
case SCREEN_SAVER_ON:
558
case SCREEN_SAVER_CYCLE:
559
XActivateScreenSaver(dmxScreen->beDisplay);
560
dmxSync(dmxScreen, FALSE);