First import
[xorg_rtime.git] / xorg-server-1.4 / hw / dmx / dmxscrinit.c
blob8ae448a5ecde1457bac69acdd3487a51910a2b75
1 /*
2 * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
4 * All Rights Reserved.
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
25 * SOFTWARE.
29 * Authors:
30 * Kevin E. Martin <kem@redhat.com>
31 * David H. Dawes <dawes@xfree86.org>
35 /** \file
36 * This file provides support for screen initialization. */
38 #ifdef HAVE_DMX_CONFIG_H
39 #include <dmx-config.h>
40 #endif
42 #include "dmx.h"
43 #include "dmxsync.h"
44 #include "dmxshadow.h"
45 #include "dmxscrinit.h"
46 #include "dmxcursor.h"
47 #include "dmxgc.h"
48 #include "dmxgcops.h"
49 #include "dmxwindow.h"
50 #include "dmxpixmap.h"
51 #include "dmxfont.h"
52 #include "dmxcmap.h"
53 #include "dmxprop.h"
54 #include "dmxdpms.h"
56 #ifdef RENDER
57 #include "dmxpict.h"
58 #endif
60 #include "fb.h"
61 #include "mipointer.h"
62 #include "micmap.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 */
76 #ifdef RENDER
77 int dmxPictPrivateIndex; /**< Private index for Picts */
78 int dmxGlyphSetPrivateIndex; /**< Private index for GlyphSets */
79 #endif
81 /** Initialize the parts of screen \a idx that require access to the
82 * back-end server. */
83 void dmxBEScreenInit(int idx, ScreenPtr pScreen)
85 DMXScreenInfo *dmxScreen = &dmxScreens[idx];
86 XSetWindowAttributes attribs;
87 XGCValues gcvals;
88 unsigned long mask;
89 int i, j;
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
97 * assumption.
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
115 | KeyReleaseMask
116 | ButtonPressMask
117 | ButtonReleaseMask
118 | EnterWindowMask
119 | LeaveWindowMask
120 | PointerMotionMask
121 | KeymapStateMask
122 | FocusChangeMask);
123 attribs.colormap = dmxScreen->beDefColormaps[dmxScreen->beDefVisualIndex];
124 attribs.override_redirect = True;
126 dmxScreen->scrnWin =
127 XCreateWindow(dmxScreen->beDisplay,
128 DefaultRootWindow(dmxScreen->beDisplay),
129 dmxScreen->scrnX,
130 dmxScreen->scrnY,
131 dmxScreen->scrnWidth,
132 dmxScreen->scrnHeight,
134 pScreen->rootDepth,
135 InputOutput,
136 dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
137 mask,
138 &attribs);
139 dmxPropertyWindow(dmxScreen);
142 * This turns off the cursor by defining a cursor with no visible
143 * components.
146 char noCursorData[] = {0, 0, 0, 0,
147 0, 0, 0, 0};
148 Pixmap pixmap;
149 XColor color, tmp;
151 pixmap = XCreateBitmapFromData(dmxScreen->beDisplay, dmxScreen->scrnWin,
152 noCursorData, 8, 8);
153 XAllocNamedColor(dmxScreen->beDisplay, dmxScreen->beDefColormaps[0],
154 "black", &color, &tmp);
155 dmxScreen->noCursor = XCreatePixmapCursor(dmxScreen->beDisplay,
156 pixmap, pixmap,
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);
166 if (dmxShadowFB) {
167 mask = (GCFunction
168 | GCPlaneMask
169 | GCClipMask);
170 gcvals.function = GXcopy;
171 gcvals.plane_mask = AllPlanes;
172 gcvals.clip_mask = None;
174 dmxScreen->shadowGC = XCreateGC(dmxScreen->beDisplay,
175 dmxScreen->scrnWin,
176 mask, &gcvals);
178 dmxScreen->shadowFBImage =
179 XCreateImage(dmxScreen->beDisplay,
180 dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
181 dmxScreen->beDepth,
182 ZPixmap,
184 (char *)dmxScreen->shadow,
185 dmxScreen->scrnWidth, dmxScreen->scrnHeight,
186 dmxScreen->beBPP,
187 PixmapBytePad(dmxScreen->scrnWidth,
188 dmxScreen->beBPP));
189 } else {
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);
199 break;
204 /** Initialize screen number \a idx. */
205 Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
207 DMXScreenInfo *dmxScreen = &dmxScreens[idx];
208 int i, j;
210 if (dmxGeneration != serverGeneration) {
211 #ifdef RENDER
212 /* Allocate picture private index */
213 dmxPictPrivateIndex = AllocatePicturePrivateIndex();
214 if (dmxPictPrivateIndex == -1)
215 return FALSE;
217 /* Allocate glyph set private index */
218 dmxGlyphSetPrivateIndex = AllocateGlyphSetPrivateIndex();
219 if (dmxGlyphSetPrivateIndex == -1)
220 return FALSE;
221 #endif
223 /* Allocate GC private index */
224 dmxGCPrivateIndex = AllocateGCPrivateIndex();
225 if (dmxGCPrivateIndex == -1)
226 return FALSE;
228 /* Allocate window private index */
229 dmxWinPrivateIndex = AllocateWindowPrivateIndex();
230 if (dmxWinPrivateIndex == -1)
231 return FALSE;
233 /* Allocate pixmap private index */
234 dmxPixPrivateIndex = AllocatePixmapPrivateIndex();
235 if (dmxPixPrivateIndex == -1)
236 return FALSE;
238 /* Allocate font private index */
239 dmxFontPrivateIndex = AllocateFontPrivateIndex();
240 if (dmxFontPrivateIndex == -1)
241 return FALSE;
243 /* Allocate screen private index */
244 dmxScreenPrivateIndex = AllocateScreenPrivateIndex();
245 if (dmxScreenPrivateIndex == -1)
246 return FALSE;
248 dmxGeneration = serverGeneration;
251 if (dmxShadowFB) {
252 dmxScreen->shadow = shadowAlloc(dmxScreen->scrnWidth,
253 dmxScreen->scrnHeight,
254 dmxScreen->beBPP);
255 } else {
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++) {
269 int depth;
270 int visuals = 0;
271 int bitsPerRgb = 0;
272 int preferredClass = -1;
273 Pixel redMask = 0;
274 Pixel greenMask = 0;
275 Pixel blueMask = 0;
277 depth = dmxScreen->beDepths[i];
278 for (j = 0; j < dmxScreen->beNumVisuals; j++) {
279 XVisualInfo *vi;
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,
302 dmxScreen->beXDPI,
303 dmxScreen->beXDPI,
304 dmxScreen->scrnWidth,
305 dmxScreen->beBPP);
306 #ifdef RENDER
307 (void)dmxPictureInit(pScreen, 0, 0);
308 #endif
310 if (dmxShadowFB && !shadowInit(pScreen, dmxShadowUpdateProc, NULL))
311 return FALSE;
313 miInitializeBackingStore(pScreen);
315 if (dmxShadowFB) {
316 miDCInitialize(pScreen, &dmxPointerCursorFuncs);
317 } else {
318 MAXSCREENSALLOC(dmxCursorGeneration);
319 if (dmxCursorGeneration[idx] != serverGeneration) {
320 if (!(miPointerInitialize(pScreen,
321 &dmxPointerSpriteFuncs,
322 &dmxPointerCursorFuncs,
323 FALSE)))
324 return FALSE;
326 dmxCursorGeneration[idx] = serverGeneration;
330 DMX_WRAP(CloseScreen, dmxCloseScreen, dmxScreen, pScreen);
331 DMX_WRAP(SaveScreen, dmxSaveScreen, dmxScreen, pScreen);
333 dmxBEScreenInit(idx, pScreen);
335 if (!dmxShadowFB) {
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,
344 pScreen);
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,
350 pScreen);
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);
378 #ifdef SHAPE
379 /* Wrap Shape functions */
380 DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
381 #endif
384 if (!dmxCreateDefColormap(pScreen))
385 return FALSE;
387 return TRUE;
390 /** Close the \a pScreen resources on the back-end server. */
391 void dmxBECloseScreen(ScreenPtr pScreen)
393 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
394 int i;
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;
408 if (dmxShadowFB) {
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;
414 } else {
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;
428 #if 0
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;
439 #endif
441 #ifdef GLXEXT
442 if (dmxScreen->glxVisuals) {
443 XFree(dmxScreen->glxVisuals);
444 dmxScreen->glxVisuals = NULL;
445 dmxScreen->numGlxVisuals = 0;
447 #endif
449 /* Close display */
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 */
460 if (idx == 0) {
461 #ifdef RENDER
462 dmxResetRender();
463 #endif
464 dmxResetFonts();
467 if (dmxShadowFB) {
468 /* Free the shadow framebuffer */
469 xfree(dmxScreen->shadow);
470 } else {
472 #ifdef SHAPE
473 /* Unwrap Shape functions */
474 DMX_UNWRAP(SetShape, dmxScreen, pScreen);
475 #endif
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);
518 #if 1
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;
532 #endif
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) {
544 switch (what) {
545 case SCREEN_SAVER_OFF:
546 case SCREEN_SAVER_FORCER:
547 XResetScreenSaver(dmxScreen->beDisplay);
548 dmxSync(dmxScreen, FALSE);
549 break;
550 case SCREEN_SAVER_ON:
551 case SCREEN_SAVER_CYCLE:
552 XActivateScreenSaver(dmxScreen->beDisplay);
553 dmxSync(dmxScreen, FALSE);
554 break;
558 return TRUE;