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 "dmxscrinit.h"
45 #include "dmxcursor.h"
48 #include "dmxwindow.h"
49 #include "dmxpixmap.h"
58 #include "mipointer.h"
61 extern Bool
dmxCloseScreen(ScreenPtr pScreen
);
62 static Bool
dmxSaveScreen(ScreenPtr pScreen
, int what
);
64 static unsigned long dmxGeneration
;
65 static unsigned long *dmxCursorGeneration
;
67 DevPrivateKeyRec dmxGCPrivateKeyRec
;
68 DevPrivateKeyRec dmxWinPrivateKeyRec
;
69 DevPrivateKeyRec dmxPixPrivateKeyRec
;
70 int dmxFontPrivateIndex
; /**< Private index for Fonts */
71 DevPrivateKeyRec dmxScreenPrivateKeyRec
;
72 DevPrivateKeyRec dmxColormapPrivateKeyRec
;
73 DevPrivateKeyRec dmxPictPrivateKeyRec
;
74 DevPrivateKeyRec dmxGlyphSetPrivateKeyRec
;
76 /** Initialize the parts of screen \a idx that require access to the
79 dmxBEScreenInit(ScreenPtr pScreen
)
81 DMXScreenInfo
*dmxScreen
= &dmxScreens
[pScreen
->myNum
];
82 XSetWindowAttributes attribs
;
87 /* FIXME: The dmxScreenInit() code currently assumes that it will
88 * not be called if the Xdmx server is started with this screen
89 * detached -- i.e., it assumes that dmxScreen->beDisplay is always
90 * valid. This is not necessarily a valid assumption when full
91 * addition/removal of screens is implemented, but when this code is
92 * broken out for screen reattachment, then we will reevaluate this
96 pScreen
->mmWidth
= DisplayWidthMM(dmxScreen
->beDisplay
,
97 DefaultScreen(dmxScreen
->beDisplay
));
98 pScreen
->mmHeight
= DisplayHeightMM(dmxScreen
->beDisplay
,
99 DefaultScreen(dmxScreen
->beDisplay
));
101 pScreen
->whitePixel
= dmxScreen
->beWhitePixel
;
102 pScreen
->blackPixel
= dmxScreen
->beBlackPixel
;
104 /* Handle screen savers and DPMS on the backend */
105 dmxDPMSInit(dmxScreen
);
107 /* Create root window for screen */
108 mask
= CWBackPixel
| CWEventMask
| CWColormap
| CWOverrideRedirect
;
109 attribs
.background_pixel
= dmxScreen
->beBlackPixel
;
110 attribs
.event_mask
= (KeyPressMask
117 | KeymapStateMask
| FocusChangeMask
);
118 attribs
.colormap
= dmxScreen
->beDefColormaps
[dmxScreen
->beDefVisualIndex
];
119 attribs
.override_redirect
= True
;
122 XCreateWindow(dmxScreen
->beDisplay
,
123 DefaultRootWindow(dmxScreen
->beDisplay
),
126 dmxScreen
->scrnWidth
,
127 dmxScreen
->scrnHeight
,
131 dmxScreen
->beVisuals
[dmxScreen
->beDefVisualIndex
].visual
,
133 dmxPropertyWindow(dmxScreen
);
136 * This turns off the cursor by defining a cursor with no visible
140 char noCursorData
[] = { 0, 0, 0, 0,
146 pixmap
= XCreateBitmapFromData(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
,
148 XAllocNamedColor(dmxScreen
->beDisplay
, dmxScreen
->beDefColormaps
[0],
149 "black", &color
, &tmp
);
150 dmxScreen
->noCursor
= XCreatePixmapCursor(dmxScreen
->beDisplay
,
152 &color
, &color
, 0, 0);
153 XDefineCursor(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
,
154 dmxScreen
->noCursor
);
156 XFreePixmap(dmxScreen
->beDisplay
, pixmap
);
159 XMapWindow(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
);
161 /* Create default drawables (used during GC creation) */
162 for (i
= 0; i
< dmxScreen
->beNumPixmapFormats
; i
++)
163 for (j
= 0; j
< dmxScreen
->beNumDepths
; j
++)
164 if ((dmxScreen
->bePixmapFormats
[i
].depth
== 1) ||
165 (dmxScreen
->bePixmapFormats
[i
].depth
==
166 dmxScreen
->beDepths
[j
])) {
167 dmxScreen
->scrnDefDrawables
[i
] = (Drawable
)
168 XCreatePixmap(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
,
170 dmxScreen
->bePixmapFormats
[i
].depth
);
175 /** Initialize screen number \a pScreen->myNum. */
177 dmxScreenInit(ScreenPtr pScreen
, int argc
, char *argv
[])
179 DMXScreenInfo
*dmxScreen
= &dmxScreens
[pScreen
->myNum
];
182 if (!dixRegisterPrivateKey(&dmxScreenPrivateKeyRec
, PRIVATE_SCREEN
, 0))
184 if (!dixRegisterPrivateKey(&dmxColormapPrivateKeyRec
, PRIVATE_COLORMAP
, 0))
186 if (!dixRegisterPrivateKey(&dmxGlyphSetPrivateKeyRec
, PRIVATE_GLYPHSET
, 0))
189 if (dmxGeneration
!= serverGeneration
) {
190 /* Allocate font private index */
191 dmxFontPrivateIndex
= AllocateFontPrivateIndex();
192 if (dmxFontPrivateIndex
== -1)
195 dmxGeneration
= serverGeneration
;
198 if (!dmxInitGC(pScreen
))
200 if (!dmxInitWindow(pScreen
))
202 if (!dmxInitPixmap(pScreen
))
206 * Initalise the visual types. miSetVisualTypesAndMasks() requires
207 * that all of the types for each depth be collected together. It's
208 * intended for slightly different usage to what we would like here.
209 * Maybe a miAddVisualTypeAndMask() function will be added to make
210 * things easier here.
212 for (i
= 0; i
< dmxScreen
->beNumDepths
; i
++) {
216 int preferredClass
= -1;
221 depth
= dmxScreen
->beDepths
[i
];
222 for (j
= 0; j
< dmxScreen
->beNumVisuals
; j
++) {
225 vi
= &dmxScreen
->beVisuals
[j
];
226 if (vi
->depth
== depth
) {
227 /* Assume the masks are all the same. */
228 visuals
|= (1 << vi
->class);
229 bitsPerRgb
= vi
->bits_per_rgb
;
230 redMask
= vi
->red_mask
;
231 greenMask
= vi
->green_mask
;
232 blueMask
= vi
->blue_mask
;
233 if (j
== dmxScreen
->beDefVisualIndex
) {
234 preferredClass
= vi
->class;
238 miSetVisualTypesAndMasks(depth
, visuals
, bitsPerRgb
, preferredClass
,
239 redMask
, greenMask
, blueMask
);
242 fbScreenInit(pScreen
,
244 dmxScreen
->scrnWidth
,
245 dmxScreen
->scrnHeight
,
247 dmxScreen
->beXDPI
, dmxScreen
->scrnWidth
, dmxScreen
->beBPP
);
248 (void) dmxPictureInit(pScreen
, 0, 0);
251 pScreen
->GetWindowPixmap
= NULL
;
252 pScreen
->SetWindowPixmap
= NULL
;
254 MAXSCREENSALLOC(dmxCursorGeneration
);
255 if (dmxCursorGeneration
[pScreen
->myNum
] != serverGeneration
) {
256 if (!(miPointerInitialize(pScreen
,
257 &dmxPointerSpriteFuncs
,
258 &dmxPointerCursorFuncs
, FALSE
)))
261 dmxCursorGeneration
[pScreen
->myNum
] = serverGeneration
;
264 DMX_WRAP(CloseScreen
, dmxCloseScreen
, dmxScreen
, pScreen
);
265 DMX_WRAP(SaveScreen
, dmxSaveScreen
, dmxScreen
, pScreen
);
267 dmxBEScreenInit(pScreen
);
269 /* Wrap GC functions */
270 DMX_WRAP(CreateGC
, dmxCreateGC
, dmxScreen
, pScreen
);
272 /* Wrap Window functions */
273 DMX_WRAP(CreateWindow
, dmxCreateWindow
, dmxScreen
, pScreen
);
274 DMX_WRAP(DestroyWindow
, dmxDestroyWindow
, dmxScreen
, pScreen
);
275 DMX_WRAP(PositionWindow
, dmxPositionWindow
, dmxScreen
, pScreen
);
276 DMX_WRAP(ChangeWindowAttributes
, dmxChangeWindowAttributes
, dmxScreen
,
278 DMX_WRAP(RealizeWindow
, dmxRealizeWindow
, dmxScreen
, pScreen
);
279 DMX_WRAP(UnrealizeWindow
, dmxUnrealizeWindow
, dmxScreen
, pScreen
);
280 DMX_WRAP(RestackWindow
, dmxRestackWindow
, dmxScreen
, pScreen
);
281 DMX_WRAP(WindowExposures
, dmxWindowExposures
, dmxScreen
, pScreen
);
282 DMX_WRAP(CopyWindow
, dmxCopyWindow
, dmxScreen
, pScreen
);
284 DMX_WRAP(ResizeWindow
, dmxResizeWindow
, dmxScreen
, pScreen
);
285 DMX_WRAP(ReparentWindow
, dmxReparentWindow
, dmxScreen
, pScreen
);
287 DMX_WRAP(ChangeBorderWidth
, dmxChangeBorderWidth
, dmxScreen
, pScreen
);
289 /* Wrap Image functions */
290 DMX_WRAP(GetImage
, dmxGetImage
, dmxScreen
, pScreen
);
291 DMX_WRAP(GetSpans
, dmxGetSpans
, dmxScreen
, pScreen
);
293 /* Wrap Pixmap functions */
294 DMX_WRAP(CreatePixmap
, dmxCreatePixmap
, dmxScreen
, pScreen
);
295 DMX_WRAP(DestroyPixmap
, dmxDestroyPixmap
, dmxScreen
, pScreen
);
296 DMX_WRAP(BitmapToRegion
, dmxBitmapToRegion
, dmxScreen
, pScreen
);
298 /* Wrap Font functions */
299 DMX_WRAP(RealizeFont
, dmxRealizeFont
, dmxScreen
, pScreen
);
300 DMX_WRAP(UnrealizeFont
, dmxUnrealizeFont
, dmxScreen
, pScreen
);
302 /* Wrap Colormap functions */
303 DMX_WRAP(CreateColormap
, dmxCreateColormap
, dmxScreen
, pScreen
);
304 DMX_WRAP(DestroyColormap
, dmxDestroyColormap
, dmxScreen
, pScreen
);
305 DMX_WRAP(InstallColormap
, dmxInstallColormap
, dmxScreen
, pScreen
);
306 DMX_WRAP(StoreColors
, dmxStoreColors
, dmxScreen
, pScreen
);
308 /* Wrap Shape functions */
309 DMX_WRAP(SetShape
, dmxSetShape
, dmxScreen
, pScreen
);
311 if (!dmxCreateDefColormap(pScreen
))
317 /** Close the \a pScreen resources on the back-end server. */
319 dmxBECloseScreen(ScreenPtr pScreen
)
321 DMXScreenInfo
*dmxScreen
= &dmxScreens
[pScreen
->myNum
];
324 /* Restore the back-end screen-saver and DPMS state. */
325 dmxDPMSTerm(dmxScreen
);
327 /* Free the screen resources */
329 XFreeCursor(dmxScreen
->beDisplay
, dmxScreen
->noCursor
);
330 dmxScreen
->noCursor
= (Cursor
) 0;
332 XUnmapWindow(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
);
333 XDestroyWindow(dmxScreen
->beDisplay
, dmxScreen
->scrnWin
);
334 dmxScreen
->scrnWin
= (Window
) 0;
336 /* Free the default drawables */
337 for (i
= 0; i
< dmxScreen
->beNumPixmapFormats
; i
++) {
338 if (dmxScreen
->scrnDefDrawables
[i
]) {
339 XFreePixmap(dmxScreen
->beDisplay
,
340 dmxScreen
->scrnDefDrawables
[i
]);
341 dmxScreen
->scrnDefDrawables
[i
] = (Drawable
) 0;
345 /* Free resources allocated during initialization (in dmxinit.c) */
346 for (i
= 0; i
< dmxScreen
->beNumDefColormaps
; i
++)
347 XFreeColormap(dmxScreen
->beDisplay
, dmxScreen
->beDefColormaps
[i
]);
348 free(dmxScreen
->beDefColormaps
);
349 dmxScreen
->beDefColormaps
= NULL
;
352 /* Do not free visuals, depths and pixmap formats here. Free them
353 * in dmxCloseScreen() instead -- see comment below. */
354 XFree(dmxScreen
->beVisuals
);
355 dmxScreen
->beVisuals
= NULL
;
357 XFree(dmxScreen
->beDepths
);
358 dmxScreen
->beDepths
= NULL
;
360 XFree(dmxScreen
->bePixmapFormats
);
361 dmxScreen
->bePixmapFormats
= NULL
;
365 if (dmxScreen
->glxVisuals
) {
366 XFree(dmxScreen
->glxVisuals
);
367 dmxScreen
->glxVisuals
= NULL
;
368 dmxScreen
->numGlxVisuals
= 0;
373 XCloseDisplay(dmxScreen
->beDisplay
);
374 dmxScreen
->beDisplay
= NULL
;
377 /** Close screen number \a idx. */
379 dmxCloseScreen(ScreenPtr pScreen
)
381 DMXScreenInfo
*dmxScreen
= &dmxScreens
[pScreen
->myNum
];
383 /* Reset the proc vectors */
384 if (pScreen
->myNum
== 0) {
389 /* Unwrap Shape functions */
390 DMX_UNWRAP(SetShape
, dmxScreen
, pScreen
);
392 /* Unwrap the pScreen functions */
393 DMX_UNWRAP(CreateGC
, dmxScreen
, pScreen
);
395 DMX_UNWRAP(CreateWindow
, dmxScreen
, pScreen
);
396 DMX_UNWRAP(DestroyWindow
, dmxScreen
, pScreen
);
397 DMX_UNWRAP(PositionWindow
, dmxScreen
, pScreen
);
398 DMX_UNWRAP(ChangeWindowAttributes
, dmxScreen
, pScreen
);
399 DMX_UNWRAP(RealizeWindow
, dmxScreen
, pScreen
);
400 DMX_UNWRAP(UnrealizeWindow
, dmxScreen
, pScreen
);
401 DMX_UNWRAP(RestackWindow
, dmxScreen
, pScreen
);
402 DMX_UNWRAP(WindowExposures
, dmxScreen
, pScreen
);
403 DMX_UNWRAP(CopyWindow
, dmxScreen
, pScreen
);
405 DMX_UNWRAP(ResizeWindow
, dmxScreen
, pScreen
);
406 DMX_UNWRAP(ReparentWindow
, dmxScreen
, pScreen
);
408 DMX_UNWRAP(ChangeBorderWidth
, dmxScreen
, pScreen
);
410 DMX_UNWRAP(GetImage
, dmxScreen
, pScreen
);
411 DMX_UNWRAP(GetSpans
, dmxScreen
, pScreen
);
413 DMX_UNWRAP(CreatePixmap
, dmxScreen
, pScreen
);
414 DMX_UNWRAP(DestroyPixmap
, dmxScreen
, pScreen
);
415 DMX_UNWRAP(BitmapToRegion
, dmxScreen
, pScreen
);
417 DMX_UNWRAP(RealizeFont
, dmxScreen
, pScreen
);
418 DMX_UNWRAP(UnrealizeFont
, dmxScreen
, pScreen
);
420 DMX_UNWRAP(CreateColormap
, dmxScreen
, pScreen
);
421 DMX_UNWRAP(DestroyColormap
, dmxScreen
, pScreen
);
422 DMX_UNWRAP(InstallColormap
, dmxScreen
, pScreen
);
423 DMX_UNWRAP(StoreColors
, dmxScreen
, pScreen
);
425 DMX_UNWRAP(SaveScreen
, dmxScreen
, pScreen
);
427 if (dmxScreen
->beDisplay
) {
428 dmxBECloseScreen(pScreen
);
431 /* Free visuals, depths and pixmap formats here so that they
432 * won't be freed when a screen is detached, thereby allowing
433 * the screen to be reattached to be compared to the one
434 * previously removed.
436 XFree(dmxScreen
->beVisuals
);
437 dmxScreen
->beVisuals
= NULL
;
439 XFree(dmxScreen
->beDepths
);
440 dmxScreen
->beDepths
= NULL
;
442 XFree(dmxScreen
->bePixmapFormats
);
443 dmxScreen
->bePixmapFormats
= NULL
;
447 DMX_UNWRAP(CloseScreen
, dmxScreen
, pScreen
);
448 return pScreen
->CloseScreen(pScreen
);
452 dmxSaveScreen(ScreenPtr pScreen
, int what
)
454 DMXScreenInfo
*dmxScreen
= &dmxScreens
[pScreen
->myNum
];
456 if (dmxScreen
->beDisplay
) {
458 case SCREEN_SAVER_OFF
:
459 case SCREEN_SAVER_FORCER
:
460 XResetScreenSaver(dmxScreen
->beDisplay
);
461 dmxSync(dmxScreen
, FALSE
);
463 case SCREEN_SAVER_ON
:
464 case SCREEN_SAVER_CYCLE
:
465 XActivateScreenSaver(dmxScreen
->beDisplay
);
466 dmxSync(dmxScreen
, FALSE
);