2 * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * Kevin E. Martin <kem@redhat.com>
31 * David H. Dawes <dawes@xfree86.org>
36 * This file provides support for screen initialization. */
38 #ifdef HAVE_DMX_CONFIG_H
39 #include <dmx-config.h>
44 #include "dmxshadow.h"
45 #include "dmxscrinit.h"
46 #include "dmxcursor.h"
49 #include "dmxwindow.h"
50 #include "dmxpixmap.h"
61 #include "mipointer.h"
64 extern Bool
dmxCloseScreen(int idx
, ScreenPtr pScreen
);
65 static Bool
dmxSaveScreen(ScreenPtr pScreen
, int what
);
67 static unsigned long dmxGeneration
;
68 static unsigned long *dmxCursorGeneration
;
70 int dmxGCPrivateIndex
; /**< Private index for GCs */
71 int dmxWinPrivateIndex
; /**< Private index for Windows */
72 int dmxPixPrivateIndex
; /**< Private index for Pixmaps */
73 int dmxFontPrivateIndex
; /**< Private index for Fonts */
74 int dmxScreenPrivateIndex
; /**< Private index for Screens */
75 int dmxColormapPrivateIndex
; /**< Private index for Colormaps */
77 int dmxPictPrivateIndex
; /**< Private index for Picts */
78 int dmxGlyphSetPrivateIndex
; /**< Private index for GlyphSets */
81 /** Initialize the parts of screen \a idx that require access to the
83 void dmxBEScreenInit(int idx
, ScreenPtr pScreen
)
85 DMXScreenInfo
*dmxScreen
= &dmxScreens
[idx
];
86 XSetWindowAttributes attribs
;
91 /* FIXME: The dmxScreenInit() code currently assumes that it will
92 * not be called if the Xdmx server is started with this screen
93 * detached -- i.e., it assumes that dmxScreen->beDisplay is always
94 * valid. This is not necessarily a valid assumption when full
95 * addition/removal of screens is implemented, but when this code is
96 * broken out for screen reattachment, then we will reevaluate this
100 pScreen
->mmWidth
= DisplayWidthMM(dmxScreen
->beDisplay
,
101 DefaultScreen(dmxScreen
->beDisplay
));
102 pScreen
->mmHeight
= DisplayHeightMM(dmxScreen
->beDisplay
,
103 DefaultScreen(dmxScreen
->beDisplay
));
105 pScreen
->whitePixel
= dmxScreen
->beWhitePixel
;
106 pScreen
->blackPixel
= dmxScreen
->beBlackPixel
;
108 /* Handle screen savers and DPMS on the backend */
109 dmxDPMSInit(dmxScreen
);
111 /* Create root window for screen */
112 mask
= CWBackPixel
| CWEventMask
| CWColormap
| CWOverrideRedirect
;
113 attribs
.background_pixel
= dmxScreen
->beBlackPixel
;
114 attribs
.event_mask
= (KeyPressMask
123 attribs
.colormap
= dmxScreen
->beDefColormaps
[dmxScreen
->beDefVisualIndex
];
124 attribs
.override_redirect
= True
;
127 XCreateWindow(dmxScreen
->beDisplay
,
128 DefaultRootWindow(dmxScreen
->beDisplay
),
131 dmxScreen
->scrnWidth
,
132 dmxScreen
->scrnHeight
,
136 dmxScreen
->beVisuals
[dmxScreen
->beDefVisualIndex
].visual
,
139 dmxPropertyWindow(dmxScreen
);
142 * This turns off the cursor by defining a cursor with no visible
146 char noCursorData
[] = {0, 0, 0, 0,
151 pixmap
= XCreateBitmapFromData(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
,
153 XAllocNamedColor(dmxScreen
->beDisplay
, dmxScreen
->beDefColormaps
[0],
154 "black", &color
, &tmp
);
155 dmxScreen
->noCursor
= XCreatePixmapCursor(dmxScreen
->beDisplay
,
157 &color
, &color
, 0, 0);
158 XDefineCursor(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
,
159 dmxScreen
->noCursor
);
161 XFreePixmap(dmxScreen
->beDisplay
, pixmap
);
164 XMapWindow(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
);
170 gcvals
.function
= GXcopy
;
171 gcvals
.plane_mask
= AllPlanes
;
172 gcvals
.clip_mask
= None
;
174 dmxScreen
->shadowGC
= XCreateGC(dmxScreen
->beDisplay
,
178 dmxScreen
->shadowFBImage
=
179 XCreateImage(dmxScreen
->beDisplay
,
180 dmxScreen
->beVisuals
[dmxScreen
->beDefVisualIndex
].visual
,
184 (char *)dmxScreen
->shadow
,
185 dmxScreen
->scrnWidth
, dmxScreen
->scrnHeight
,
187 PixmapBytePad(dmxScreen
->scrnWidth
,
190 /* Create default drawables (used during GC creation) */
191 for (i
= 0; i
< dmxScreen
->beNumPixmapFormats
; i
++)
192 for (j
= 0; j
< dmxScreen
->beNumDepths
; j
++)
193 if ((dmxScreen
->bePixmapFormats
[i
].depth
== 1) ||
194 (dmxScreen
->bePixmapFormats
[i
].depth
==
195 dmxScreen
->beDepths
[j
])) {
196 dmxScreen
->scrnDefDrawables
[i
] = (Drawable
)
197 XCreatePixmap(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
,
198 1, 1, dmxScreen
->bePixmapFormats
[i
].depth
);
204 /** Initialize screen number \a idx. */
205 Bool
dmxScreenInit(int idx
, ScreenPtr pScreen
, int argc
, char *argv
[])
207 DMXScreenInfo
*dmxScreen
= &dmxScreens
[idx
];
210 if (dmxGeneration
!= serverGeneration
) {
212 /* Allocate picture private index */
213 dmxPictPrivateIndex
= AllocatePicturePrivateIndex();
214 if (dmxPictPrivateIndex
== -1)
217 /* Allocate glyph set private index */
218 dmxGlyphSetPrivateIndex
= AllocateGlyphSetPrivateIndex();
219 if (dmxGlyphSetPrivateIndex
== -1)
223 /* Allocate GC private index */
224 dmxGCPrivateIndex
= AllocateGCPrivateIndex();
225 if (dmxGCPrivateIndex
== -1)
228 /* Allocate window private index */
229 dmxWinPrivateIndex
= AllocateWindowPrivateIndex();
230 if (dmxWinPrivateIndex
== -1)
233 /* Allocate pixmap private index */
234 dmxPixPrivateIndex
= AllocatePixmapPrivateIndex();
235 if (dmxPixPrivateIndex
== -1)
238 /* Allocate font private index */
239 dmxFontPrivateIndex
= AllocateFontPrivateIndex();
240 if (dmxFontPrivateIndex
== -1)
243 /* Allocate screen private index */
244 dmxScreenPrivateIndex
= AllocateScreenPrivateIndex();
245 if (dmxScreenPrivateIndex
== -1)
248 dmxGeneration
= serverGeneration
;
252 dmxScreen
->shadow
= shadowAlloc(dmxScreen
->scrnWidth
,
253 dmxScreen
->scrnHeight
,
256 if (!dmxInitGC(pScreen
)) return FALSE
;
257 if (!dmxInitWindow(pScreen
)) return FALSE
;
258 if (!dmxInitPixmap(pScreen
)) return FALSE
;
262 * Initalise the visual types. miSetVisualTypesAndMasks() requires
263 * that all of the types for each depth be collected together. It's
264 * intended for slightly different usage to what we would like here.
265 * Maybe a miAddVisualTypeAndMask() function will be added to make
266 * things easier here.
268 for (i
= 0; i
< dmxScreen
->beNumDepths
; i
++) {
272 int preferredClass
= -1;
277 depth
= dmxScreen
->beDepths
[i
];
278 for (j
= 0; j
< dmxScreen
->beNumVisuals
; j
++) {
281 vi
= &dmxScreen
->beVisuals
[j
];
282 if (vi
->depth
== depth
) {
283 /* Assume the masks are all the same. */
284 visuals
|= (1 << vi
->class);
285 bitsPerRgb
= vi
->bits_per_rgb
;
286 redMask
= vi
->red_mask
;
287 greenMask
= vi
->green_mask
;
288 blueMask
= vi
->blue_mask
;
289 if (j
== dmxScreen
->beDefVisualIndex
) {
290 preferredClass
= vi
->class;
294 miSetVisualTypesAndMasks(depth
, visuals
, bitsPerRgb
, preferredClass
,
295 redMask
, greenMask
, blueMask
);
298 fbScreenInit(pScreen
,
299 dmxShadowFB
? dmxScreen
->shadow
: NULL
,
300 dmxScreen
->scrnWidth
,
301 dmxScreen
->scrnHeight
,
304 dmxScreen
->scrnWidth
,
307 (void)dmxPictureInit(pScreen
, 0, 0);
310 if (dmxShadowFB
&& !shadowInit(pScreen
, dmxShadowUpdateProc
, NULL
))
313 miInitializeBackingStore(pScreen
);
316 miDCInitialize(pScreen
, &dmxPointerCursorFuncs
);
318 MAXSCREENSALLOC(dmxCursorGeneration
);
319 if (dmxCursorGeneration
[idx
] != serverGeneration
) {
320 if (!(miPointerInitialize(pScreen
,
321 &dmxPointerSpriteFuncs
,
322 &dmxPointerCursorFuncs
,
326 dmxCursorGeneration
[idx
] = serverGeneration
;
330 DMX_WRAP(CloseScreen
, dmxCloseScreen
, dmxScreen
, pScreen
);
331 DMX_WRAP(SaveScreen
, dmxSaveScreen
, dmxScreen
, pScreen
);
333 dmxBEScreenInit(idx
, pScreen
);
336 /* Wrap GC functions */
337 DMX_WRAP(CreateGC
, dmxCreateGC
, dmxScreen
, pScreen
);
339 /* Wrap Window functions */
340 DMX_WRAP(CreateWindow
, dmxCreateWindow
, dmxScreen
, pScreen
);
341 DMX_WRAP(DestroyWindow
, dmxDestroyWindow
, dmxScreen
, pScreen
);
342 DMX_WRAP(PositionWindow
, dmxPositionWindow
, dmxScreen
, pScreen
);
343 DMX_WRAP(ChangeWindowAttributes
, dmxChangeWindowAttributes
, dmxScreen
,
345 DMX_WRAP(RealizeWindow
, dmxRealizeWindow
, dmxScreen
, pScreen
);
346 DMX_WRAP(UnrealizeWindow
, dmxUnrealizeWindow
, dmxScreen
, pScreen
);
347 DMX_WRAP(RestackWindow
, dmxRestackWindow
, dmxScreen
, pScreen
);
348 DMX_WRAP(WindowExposures
, dmxWindowExposures
, dmxScreen
, pScreen
);
349 DMX_WRAP(PaintWindowBackground
, dmxPaintWindowBackground
, dmxScreen
,
351 DMX_WRAP(PaintWindowBorder
, dmxPaintWindowBorder
, dmxScreen
, pScreen
);
352 DMX_WRAP(CopyWindow
, dmxCopyWindow
, dmxScreen
, pScreen
);
354 DMX_WRAP(ResizeWindow
, dmxResizeWindow
, dmxScreen
, pScreen
);
355 DMX_WRAP(ReparentWindow
, dmxReparentWindow
, dmxScreen
, pScreen
);
357 DMX_WRAP(ChangeBorderWidth
, dmxChangeBorderWidth
, dmxScreen
, pScreen
);
359 /* Wrap Image functions */
360 DMX_WRAP(GetImage
, dmxGetImage
, dmxScreen
, pScreen
);
361 DMX_WRAP(GetSpans
, dmxGetSpans
, dmxScreen
, pScreen
);
363 /* Wrap Pixmap functions */
364 DMX_WRAP(CreatePixmap
, dmxCreatePixmap
, dmxScreen
, pScreen
);
365 DMX_WRAP(DestroyPixmap
, dmxDestroyPixmap
, dmxScreen
, pScreen
);
366 DMX_WRAP(BitmapToRegion
, dmxBitmapToRegion
, dmxScreen
, pScreen
);
368 /* Wrap Font functions */
369 DMX_WRAP(RealizeFont
, dmxRealizeFont
, dmxScreen
, pScreen
);
370 DMX_WRAP(UnrealizeFont
, dmxUnrealizeFont
, dmxScreen
, pScreen
);
372 /* Wrap Colormap functions */
373 DMX_WRAP(CreateColormap
, dmxCreateColormap
, dmxScreen
, pScreen
);
374 DMX_WRAP(DestroyColormap
, dmxDestroyColormap
, dmxScreen
, pScreen
);
375 DMX_WRAP(InstallColormap
, dmxInstallColormap
, dmxScreen
, pScreen
);
376 DMX_WRAP(StoreColors
, dmxStoreColors
, dmxScreen
, pScreen
);
379 /* Wrap Shape functions */
380 DMX_WRAP(SetShape
, dmxSetShape
, dmxScreen
, pScreen
);
384 if (!dmxCreateDefColormap(pScreen
))
390 /** Close the \a pScreen resources on the back-end server. */
391 void dmxBECloseScreen(ScreenPtr pScreen
)
393 DMXScreenInfo
*dmxScreen
= &dmxScreens
[pScreen
->myNum
];
396 /* Restore the back-end screen-saver and DPMS state. */
397 dmxDPMSTerm(dmxScreen
);
399 /* Free the screen resources */
401 XFreeCursor(dmxScreen
->beDisplay
, dmxScreen
->noCursor
);
402 dmxScreen
->noCursor
= (Cursor
)0;
404 XUnmapWindow(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
);
405 XDestroyWindow(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
);
406 dmxScreen
->scrnWin
= (Window
)0;
409 /* Free the shadow GC and image assocated with the back-end server */
410 XFreeGC(dmxScreen
->beDisplay
, dmxScreen
->shadowGC
);
411 dmxScreen
->shadowGC
= NULL
;
412 XFree(dmxScreen
->shadowFBImage
);
413 dmxScreen
->shadowFBImage
= NULL
;
415 /* Free the default drawables */
416 for (i
= 0; i
< dmxScreen
->beNumPixmapFormats
; i
++) {
417 XFreePixmap(dmxScreen
->beDisplay
, dmxScreen
->scrnDefDrawables
[i
]);
418 dmxScreen
->scrnDefDrawables
[i
] = (Drawable
)0;
422 /* Free resources allocated during initialization (in dmxinit.c) */
423 for (i
= 0; i
< dmxScreen
->beNumDefColormaps
; i
++)
424 XFreeColormap(dmxScreen
->beDisplay
, dmxScreen
->beDefColormaps
[i
]);
425 xfree(dmxScreen
->beDefColormaps
);
426 dmxScreen
->beDefColormaps
= NULL
;
429 /* Do not free visuals, depths and pixmap formats here. Free them
430 * in dmxCloseScreen() instead -- see comment below. */
431 XFree(dmxScreen
->beVisuals
);
432 dmxScreen
->beVisuals
= NULL
;
434 XFree(dmxScreen
->beDepths
);
435 dmxScreen
->beDepths
= NULL
;
437 XFree(dmxScreen
->bePixmapFormats
);
438 dmxScreen
->bePixmapFormats
= NULL
;
442 if (dmxScreen
->glxVisuals
) {
443 XFree(dmxScreen
->glxVisuals
);
444 dmxScreen
->glxVisuals
= NULL
;
445 dmxScreen
->numGlxVisuals
= 0;
450 XCloseDisplay(dmxScreen
->beDisplay
);
451 dmxScreen
->beDisplay
= NULL
;
454 /** Close screen number \a idx. */
455 Bool
dmxCloseScreen(int idx
, ScreenPtr pScreen
)
457 DMXScreenInfo
*dmxScreen
= &dmxScreens
[idx
];
459 /* Reset the proc vectors */
468 /* Free the shadow framebuffer */
469 xfree(dmxScreen
->shadow
);
473 /* Unwrap Shape functions */
474 DMX_UNWRAP(SetShape
, dmxScreen
, pScreen
);
477 /* Unwrap the pScreen functions */
478 DMX_UNWRAP(CreateGC
, dmxScreen
, pScreen
);
480 DMX_UNWRAP(CreateWindow
, dmxScreen
, pScreen
);
481 DMX_UNWRAP(DestroyWindow
, dmxScreen
, pScreen
);
482 DMX_UNWRAP(PositionWindow
, dmxScreen
, pScreen
);
483 DMX_UNWRAP(ChangeWindowAttributes
, dmxScreen
, pScreen
);
484 DMX_UNWRAP(RealizeWindow
, dmxScreen
, pScreen
);
485 DMX_UNWRAP(UnrealizeWindow
, dmxScreen
, pScreen
);
486 DMX_UNWRAP(RestackWindow
, dmxScreen
, pScreen
);
487 DMX_UNWRAP(WindowExposures
, dmxScreen
, pScreen
);
488 DMX_UNWRAP(PaintWindowBackground
, dmxScreen
, pScreen
);
489 DMX_UNWRAP(PaintWindowBorder
, dmxScreen
, pScreen
);
490 DMX_UNWRAP(CopyWindow
, dmxScreen
, pScreen
);
492 DMX_UNWRAP(ResizeWindow
, dmxScreen
, pScreen
);
493 DMX_UNWRAP(ReparentWindow
, dmxScreen
, pScreen
);
495 DMX_UNWRAP(ChangeBorderWidth
, dmxScreen
, pScreen
);
497 DMX_UNWRAP(GetImage
, dmxScreen
, pScreen
);
498 DMX_UNWRAP(GetSpans
, dmxScreen
, pScreen
);
500 DMX_UNWRAP(CreatePixmap
, dmxScreen
, pScreen
);
501 DMX_UNWRAP(DestroyPixmap
, dmxScreen
, pScreen
);
502 DMX_UNWRAP(BitmapToRegion
, dmxScreen
, pScreen
);
504 DMX_UNWRAP(RealizeFont
, dmxScreen
, pScreen
);
505 DMX_UNWRAP(UnrealizeFont
, dmxScreen
, pScreen
);
507 DMX_UNWRAP(CreateColormap
, dmxScreen
, pScreen
);
508 DMX_UNWRAP(DestroyColormap
, dmxScreen
, pScreen
);
509 DMX_UNWRAP(InstallColormap
, dmxScreen
, pScreen
);
510 DMX_UNWRAP(StoreColors
, dmxScreen
, pScreen
);
513 DMX_UNWRAP(SaveScreen
, dmxScreen
, pScreen
);
515 if (dmxScreen
->beDisplay
) {
516 dmxBECloseScreen(pScreen
);
519 /* Free visuals, depths and pixmap formats here so that they
520 * won't be freed when a screen is detached, thereby allowing
521 * the screen to be reattached to be compared to the one
522 * previously removed.
524 XFree(dmxScreen
->beVisuals
);
525 dmxScreen
->beVisuals
= NULL
;
527 XFree(dmxScreen
->beDepths
);
528 dmxScreen
->beDepths
= NULL
;
530 XFree(dmxScreen
->bePixmapFormats
);
531 dmxScreen
->bePixmapFormats
= NULL
;
535 DMX_UNWRAP(CloseScreen
, dmxScreen
, pScreen
);
536 return pScreen
->CloseScreen(idx
, pScreen
);
539 static Bool
dmxSaveScreen(ScreenPtr pScreen
, int what
)
541 DMXScreenInfo
*dmxScreen
= &dmxScreens
[pScreen
->myNum
];
543 if (dmxScreen
->beDisplay
) {
545 case SCREEN_SAVER_OFF
:
546 case SCREEN_SAVER_FORCER
:
547 XResetScreenSaver(dmxScreen
->beDisplay
);
548 dmxSync(dmxScreen
, FALSE
);
550 case SCREEN_SAVER_ON
:
551 case SCREEN_SAVER_CYCLE
:
552 XActivateScreenSaver(dmxScreen
->beDisplay
);
553 dmxSync(dmxScreen
, FALSE
);