Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / dmx / dmxscrinit.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
3 *
4 * All Rights Reserved.
5 *
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:
13 *
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.
17 *
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.
26 */
27
28/*
29 * Authors:
30 * Kevin E. Martin <kem@redhat.com>
31 * David H. Dawes <dawes@xfree86.org>
32 *
33 */
34
35/** \file
36 * This file provides support for screen initialization. */
37
38#ifdef HAVE_DMX_CONFIG_H
39#include <dmx-config.h>
40#endif
41
42#include "dmx.h"
43#include "dmxsync.h"
44#include "dmxscrinit.h"
45#include "dmxcursor.h"
46#include "dmxgc.h"
47#include "dmxgcops.h"
48#include "dmxwindow.h"
49#include "dmxpixmap.h"
50#include "dmxfont.h"
51#include "dmxcmap.h"
52#include "dmxprop.h"
53#include "dmxdpms.h"
54
55#include "dmxpict.h"
56
57#include "fb.h"
58#include "mipointer.h"
59#include "micmap.h"
60
61extern Bool dmxCloseScreen(ScreenPtr pScreen);
62static Bool dmxSaveScreen(ScreenPtr pScreen, int what);
63
64static unsigned long dmxGeneration;
65static unsigned long *dmxCursorGeneration;
66
67DevPrivateKeyRec dmxGCPrivateKeyRec;
68DevPrivateKeyRec dmxWinPrivateKeyRec;
69DevPrivateKeyRec dmxPixPrivateKeyRec;
70int dmxFontPrivateIndex; /**< Private index for Fonts */
71DevPrivateKeyRec dmxScreenPrivateKeyRec;
72DevPrivateKeyRec dmxColormapPrivateKeyRec;
73DevPrivateKeyRec dmxPictPrivateKeyRec;
74DevPrivateKeyRec dmxGlyphSetPrivateKeyRec;
75
76/** Initialize the parts of screen \a idx that require access to the
77 * back-end server. */
78void
79dmxBEScreenInit(ScreenPtr pScreen)
80{
81 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
82 XSetWindowAttributes attribs;
83 XGCValues gcvals;
84 unsigned long mask;
85 int i, j;
86
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
93 * assumption.
94 */
95
96 pScreen->mmWidth = DisplayWidthMM(dmxScreen->beDisplay,
97 DefaultScreen(dmxScreen->beDisplay));
98 pScreen->mmHeight = DisplayHeightMM(dmxScreen->beDisplay,
99 DefaultScreen(dmxScreen->beDisplay));
100
101 pScreen->whitePixel = dmxScreen->beWhitePixel;
102 pScreen->blackPixel = dmxScreen->beBlackPixel;
103
104 /* Handle screen savers and DPMS on the backend */
105 dmxDPMSInit(dmxScreen);
106
107 /* Create root window for screen */
108 mask = CWBackPixel | CWEventMask | CWColormap | CWOverrideRedirect;
109 attribs.background_pixel = dmxScreen->beBlackPixel;
110 attribs.event_mask = (KeyPressMask
111 | KeyReleaseMask
112 | ButtonPressMask
113 | ButtonReleaseMask
114 | EnterWindowMask
115 | LeaveWindowMask
116 | PointerMotionMask
117 | KeymapStateMask | FocusChangeMask);
118 attribs.colormap = dmxScreen->beDefColormaps[dmxScreen->beDefVisualIndex];
119 attribs.override_redirect = True;
120
121 dmxScreen->scrnWin =
122 XCreateWindow(dmxScreen->beDisplay,
123 DefaultRootWindow(dmxScreen->beDisplay),
124 dmxScreen->scrnX,
125 dmxScreen->scrnY,
126 dmxScreen->scrnWidth,
127 dmxScreen->scrnHeight,
128 0,
129 pScreen->rootDepth,
130 InputOutput,
131 dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
132 mask, &attribs);
133 dmxPropertyWindow(dmxScreen);
134
135 /*
136 * This turns off the cursor by defining a cursor with no visible
137 * components.
138 */
139 {
140 char noCursorData[] = { 0, 0, 0, 0,
141 0, 0, 0, 0
142 };
143 Pixmap pixmap;
144 XColor color, tmp;
145
146 pixmap = XCreateBitmapFromData(dmxScreen->beDisplay, dmxScreen->scrnWin,
147 noCursorData, 8, 8);
148 XAllocNamedColor(dmxScreen->beDisplay, dmxScreen->beDefColormaps[0],
149 "black", &color, &tmp);
150 dmxScreen->noCursor = XCreatePixmapCursor(dmxScreen->beDisplay,
151 pixmap, pixmap,
152 &color, &color, 0, 0);
153 XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
154 dmxScreen->noCursor);
155
156 XFreePixmap(dmxScreen->beDisplay, pixmap);
157 }
158
159 XMapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
160
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,
169 1, 1,
170 dmxScreen->bePixmapFormats[i].depth);
171 break;
172 }
173}
174
175/** Initialize screen number \a pScreen->myNum. */
176Bool
177dmxScreenInit(ScreenPtr pScreen, int argc, char *argv[])
178{
179 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
180 int i, j;
181
182 if (!dixRegisterPrivateKey(&dmxScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
183 return FALSE;
184 if (!dixRegisterPrivateKey(&dmxColormapPrivateKeyRec, PRIVATE_COLORMAP, 0))
185 return FALSE;
186 if (!dixRegisterPrivateKey(&dmxGlyphSetPrivateKeyRec, PRIVATE_GLYPHSET, 0))
187 return FALSE;
188
189 if (dmxGeneration != serverGeneration) {
190 /* Allocate font private index */
191 dmxFontPrivateIndex = AllocateFontPrivateIndex();
192 if (dmxFontPrivateIndex == -1)
193 return FALSE;
194
195 dmxGeneration = serverGeneration;
196 }
197
198 if (!dmxInitGC(pScreen))
199 return FALSE;
200 if (!dmxInitWindow(pScreen))
201 return FALSE;
202 if (!dmxInitPixmap(pScreen))
203 return FALSE;
204
205 /*
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.
211 */
212 for (i = 0; i < dmxScreen->beNumDepths; i++) {
213 int depth;
214 int visuals = 0;
215 int bitsPerRgb = 0;
216 int preferredClass = -1;
217 Pixel redMask = 0;
218 Pixel greenMask = 0;
219 Pixel blueMask = 0;
220
221 depth = dmxScreen->beDepths[i];
222 for (j = 0; j < dmxScreen->beNumVisuals; j++) {
223 XVisualInfo *vi;
224
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;
235 }
236 }
237 }
238 miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb, preferredClass,
239 redMask, greenMask, blueMask);
240 }
241
242 fbScreenInit(pScreen,
243 NULL,
244 dmxScreen->scrnWidth,
245 dmxScreen->scrnHeight,
246 dmxScreen->beXDPI,
247 dmxScreen->beXDPI, dmxScreen->scrnWidth, dmxScreen->beBPP);
248 (void) dmxPictureInit(pScreen, 0, 0);
249
250 /* Not yet... */
251 pScreen->GetWindowPixmap = NULL;
252 pScreen->SetWindowPixmap = NULL;
253
254 MAXSCREENSALLOC(dmxCursorGeneration);
255 if (dmxCursorGeneration[pScreen->myNum] != serverGeneration) {
256 if (!(miPointerInitialize(pScreen,
257 &dmxPointerSpriteFuncs,
258 &dmxPointerCursorFuncs, FALSE)))
259 return FALSE;
260
261 dmxCursorGeneration[pScreen->myNum] = serverGeneration;
262 }
263
264 DMX_WRAP(CloseScreen, dmxCloseScreen, dmxScreen, pScreen);
265 DMX_WRAP(SaveScreen, dmxSaveScreen, dmxScreen, pScreen);
266
267 dmxBEScreenInit(pScreen);
268
269 /* Wrap GC functions */
270 DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
271
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,
277 pScreen);
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);
283
284 DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
285 DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
286
287 DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
288
289 /* Wrap Image functions */
290 DMX_WRAP(GetImage, dmxGetImage, dmxScreen, pScreen);
291 DMX_WRAP(GetSpans, dmxGetSpans, dmxScreen, pScreen);
292
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);
297
298 /* Wrap Font functions */
299 DMX_WRAP(RealizeFont, dmxRealizeFont, dmxScreen, pScreen);
300 DMX_WRAP(UnrealizeFont, dmxUnrealizeFont, dmxScreen, pScreen);
301
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);
307
308 /* Wrap Shape functions */
309 DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
310
311 if (!dmxCreateDefColormap(pScreen))
312 return FALSE;
313
314 return TRUE;
315}
316
317/** Close the \a pScreen resources on the back-end server. */
318void
319dmxBECloseScreen(ScreenPtr pScreen)
320{
321 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
322 int i;
323
324 /* Restore the back-end screen-saver and DPMS state. */
325 dmxDPMSTerm(dmxScreen);
326
327 /* Free the screen resources */
328
329 XFreeCursor(dmxScreen->beDisplay, dmxScreen->noCursor);
330 dmxScreen->noCursor = (Cursor) 0;
331
332 XUnmapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
333 XDestroyWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
334 dmxScreen->scrnWin = (Window) 0;
335
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;
342 }
343 }
344
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;
350
351#if 0
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;
356
357 XFree(dmxScreen->beDepths);
358 dmxScreen->beDepths = NULL;
359
360 XFree(dmxScreen->bePixmapFormats);
361 dmxScreen->bePixmapFormats = NULL;
362#endif
363
364#ifdef GLXEXT
365 if (dmxScreen->glxVisuals) {
366 XFree(dmxScreen->glxVisuals);
367 dmxScreen->glxVisuals = NULL;
368 dmxScreen->numGlxVisuals = 0;
369 }
370#endif
371
372 /* Close display */
373 XCloseDisplay(dmxScreen->beDisplay);
374 dmxScreen->beDisplay = NULL;
375}
376
377/** Close screen number \a idx. */
378Bool
379dmxCloseScreen(ScreenPtr pScreen)
380{
381 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
382
383 /* Reset the proc vectors */
384 if (pScreen->myNum == 0) {
385 dmxResetRender();
386 dmxResetFonts();
387 }
388
389 /* Unwrap Shape functions */
390 DMX_UNWRAP(SetShape, dmxScreen, pScreen);
391
392 /* Unwrap the pScreen functions */
393 DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
394
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);
404
405 DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
406 DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
407
408 DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
409
410 DMX_UNWRAP(GetImage, dmxScreen, pScreen);
411 DMX_UNWRAP(GetSpans, dmxScreen, pScreen);
412
413 DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
414 DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
415 DMX_UNWRAP(BitmapToRegion, dmxScreen, pScreen);
416
417 DMX_UNWRAP(RealizeFont, dmxScreen, pScreen);
418 DMX_UNWRAP(UnrealizeFont, dmxScreen, pScreen);
419
420 DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
421 DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
422 DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
423 DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
424
425 DMX_UNWRAP(SaveScreen, dmxScreen, pScreen);
426
427 if (dmxScreen->beDisplay) {
428 dmxBECloseScreen(pScreen);
429
430#if 1
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.
435 */
436 XFree(dmxScreen->beVisuals);
437 dmxScreen->beVisuals = NULL;
438
439 XFree(dmxScreen->beDepths);
440 dmxScreen->beDepths = NULL;
441
442 XFree(dmxScreen->bePixmapFormats);
443 dmxScreen->bePixmapFormats = NULL;
444#endif
445 }
446
447 DMX_UNWRAP(CloseScreen, dmxScreen, pScreen);
448 return pScreen->CloseScreen(pScreen);
449}
450
451static Bool
452dmxSaveScreen(ScreenPtr pScreen, int what)
453{
454 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
455
456 if (dmxScreen->beDisplay) {
457 switch (what) {
458 case SCREEN_SAVER_OFF:
459 case SCREEN_SAVER_FORCER:
460 XResetScreenSaver(dmxScreen->beDisplay);
461 dmxSync(dmxScreen, FALSE);
462 break;
463 case SCREEN_SAVER_ON:
464 case SCREEN_SAVER_CYCLE:
465 XActivateScreenSaver(dmxScreen->beDisplay);
466 dmxSync(dmxScreen, FALSE);
467 break;
468 }
469 }
470
471 return TRUE;
472}