1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright 1990, 1998 The Open Group
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation.
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included
12*4882a593Smuzhiyun in all copies or substantial portions of the Software.
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17*4882a593Smuzhiyun IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall
23*4882a593Smuzhiyun not be used in advertising or otherwise to promote the sale, use or
24*4882a593Smuzhiyun other dealings in this Software without prior written authorization
25*4882a593Smuzhiyun from The Open Group.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
30*4882a593Smuzhiyun #include <dix-config.h>
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #include <X11/X.h>
34*4882a593Smuzhiyun #include "servermd.h"
35*4882a593Smuzhiyun #include "misc.h"
36*4882a593Smuzhiyun #include "mi.h"
37*4882a593Smuzhiyun #include "scrnintstr.h"
38*4882a593Smuzhiyun #include "pixmapstr.h"
39*4882a593Smuzhiyun #include "dix.h"
40*4882a593Smuzhiyun #include "miline.h"
41*4882a593Smuzhiyun #ifdef MITSHM
42*4882a593Smuzhiyun #include <X11/extensions/shm.h>
43*4882a593Smuzhiyun #include "shmint.h"
44*4882a593Smuzhiyun #endif
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /* We use this structure to propogate some information from miScreenInit to
47*4882a593Smuzhiyun * miCreateScreenResources. miScreenInit allocates the structure, fills it
48*4882a593Smuzhiyun * in, and puts it into pScreen->devPrivate. miCreateScreenResources
49*4882a593Smuzhiyun * extracts the info and frees the structure. We could've accomplished the
50*4882a593Smuzhiyun * same thing by adding fields to the screen structure, but they would have
51*4882a593Smuzhiyun * ended up being redundant, and would have exposed this mi implementation
52*4882a593Smuzhiyun * detail to the whole server.
53*4882a593Smuzhiyun */
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /* per-screen private data */
56*4882a593Smuzhiyun static DevPrivateKeyRec miScreenPrivKeyRec;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun #define miScreenPrivKey (&miScreenPrivKeyRec)
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun typedef struct {
61*4882a593Smuzhiyun CloseScreenProcPtr CloseScreen;
62*4882a593Smuzhiyun } miScreenRec, *miScreenPtr;
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #define miGetScreenPriv(s) ((miScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miScreenPrivKey)))
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun typedef struct {
67*4882a593Smuzhiyun void *pbits; /* pointer to framebuffer */
68*4882a593Smuzhiyun int width; /* delta to add to a framebuffer addr to move one row down */
69*4882a593Smuzhiyun } miScreenInitParmsRec, *miScreenInitParmsPtr;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun /* this plugs into pScreen->ModifyPixmapHeader */
72*4882a593Smuzhiyun Bool
miModifyPixmapHeader(PixmapPtr pPixmap,int width,int height,int depth,int bitsPerPixel,int devKind,void * pPixData)73*4882a593Smuzhiyun miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
74*4882a593Smuzhiyun int bitsPerPixel, int devKind, void *pPixData)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun if (!pPixmap)
77*4882a593Smuzhiyun return FALSE;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun /*
80*4882a593Smuzhiyun * If all arguments are specified, reinitialize everything (including
81*4882a593Smuzhiyun * validated state).
82*4882a593Smuzhiyun */
83*4882a593Smuzhiyun if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
84*4882a593Smuzhiyun (devKind > 0) && pPixData) {
85*4882a593Smuzhiyun pPixmap->drawable.depth = depth;
86*4882a593Smuzhiyun pPixmap->drawable.bitsPerPixel = bitsPerPixel;
87*4882a593Smuzhiyun pPixmap->drawable.id = 0;
88*4882a593Smuzhiyun pPixmap->drawable.x = 0;
89*4882a593Smuzhiyun pPixmap->drawable.y = 0;
90*4882a593Smuzhiyun pPixmap->drawable.width = width;
91*4882a593Smuzhiyun pPixmap->drawable.height = height;
92*4882a593Smuzhiyun pPixmap->devKind = devKind;
93*4882a593Smuzhiyun pPixmap->refcnt = 1;
94*4882a593Smuzhiyun pPixmap->devPrivate.ptr = pPixData;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun else {
97*4882a593Smuzhiyun /*
98*4882a593Smuzhiyun * Only modify specified fields, keeping all others intact.
99*4882a593Smuzhiyun */
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun if (width > 0)
102*4882a593Smuzhiyun pPixmap->drawable.width = width;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun if (height > 0)
105*4882a593Smuzhiyun pPixmap->drawable.height = height;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun if (depth > 0)
108*4882a593Smuzhiyun pPixmap->drawable.depth = depth;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun if (bitsPerPixel > 0)
111*4882a593Smuzhiyun pPixmap->drawable.bitsPerPixel = bitsPerPixel;
112*4882a593Smuzhiyun else if ((bitsPerPixel < 0) && (depth > 0))
113*4882a593Smuzhiyun pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /*
116*4882a593Smuzhiyun * CAVEAT: Non-SI DDXen may use devKind and devPrivate fields for
117*4882a593Smuzhiyun * other purposes.
118*4882a593Smuzhiyun */
119*4882a593Smuzhiyun if (devKind > 0)
120*4882a593Smuzhiyun pPixmap->devKind = devKind;
121*4882a593Smuzhiyun else if ((devKind < 0) && ((width > 0) || (depth > 0)))
122*4882a593Smuzhiyun pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
123*4882a593Smuzhiyun pPixmap->drawable.depth);
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun if (pPixData)
126*4882a593Smuzhiyun pPixmap->devPrivate.ptr = pPixData;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
129*4882a593Smuzhiyun return TRUE;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun static Bool
miCloseScreen(ScreenPtr pScreen)133*4882a593Smuzhiyun miCloseScreen(ScreenPtr pScreen)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun miScreenPtr pScreenPriv = miGetScreenPriv(pScreen);
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun if (pScreen->devPrivate) {
138*4882a593Smuzhiyun ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate));
139*4882a593Smuzhiyun pScreen->devPrivate = NULL;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun pScreen->CloseScreen = pScreenPriv->CloseScreen;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun free(pScreenPriv);
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun if (pScreen->CloseScreen)
147*4882a593Smuzhiyun return (*pScreen->CloseScreen) (pScreen);
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun return TRUE;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun void
miSourceValidate(DrawablePtr pDrawable,int x,int y,int w,int h,unsigned int subWindowMode)153*4882a593Smuzhiyun miSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
154*4882a593Smuzhiyun unsigned int subWindowMode)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun /* With the introduction of pixmap privates, the "screen pixmap" can no
159*4882a593Smuzhiyun * longer be created in miScreenInit, since all the modules that could
160*4882a593Smuzhiyun * possibly ask for pixmap private space have not been initialized at
161*4882a593Smuzhiyun * that time. pScreen->CreateScreenResources is called after all
162*4882a593Smuzhiyun * possible private-requesting modules have been inited; we create the
163*4882a593Smuzhiyun * screen pixmap here.
164*4882a593Smuzhiyun */
165*4882a593Smuzhiyun Bool
miCreateScreenResources(ScreenPtr pScreen)166*4882a593Smuzhiyun miCreateScreenResources(ScreenPtr pScreen)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun miScreenInitParmsPtr pScrInitParms;
169*4882a593Smuzhiyun void *value;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /* if width is non-zero, pScreen->devPrivate will be a pixmap
174*4882a593Smuzhiyun * else it will just take the value pbits
175*4882a593Smuzhiyun */
176*4882a593Smuzhiyun if (pScrInitParms->width) {
177*4882a593Smuzhiyun PixmapPtr pPixmap;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /* create a pixmap with no data, then redirect it to point to
180*4882a593Smuzhiyun * the screen
181*4882a593Smuzhiyun */
182*4882a593Smuzhiyun pPixmap =
183*4882a593Smuzhiyun (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
184*4882a593Smuzhiyun if (!pPixmap)
185*4882a593Smuzhiyun return FALSE;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
188*4882a593Smuzhiyun pScreen->height,
189*4882a593Smuzhiyun pScreen->rootDepth,
190*4882a593Smuzhiyun BitsPerPixel(pScreen->rootDepth),
191*4882a593Smuzhiyun PixmapBytePad(pScrInitParms->width,
192*4882a593Smuzhiyun pScreen->rootDepth),
193*4882a593Smuzhiyun pScrInitParms->pbits))
194*4882a593Smuzhiyun return FALSE;
195*4882a593Smuzhiyun value = (void *) pPixmap;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun else {
198*4882a593Smuzhiyun value = pScrInitParms->pbits;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
201*4882a593Smuzhiyun pScreen->devPrivate = value; /* pPixmap or pbits */
202*4882a593Smuzhiyun return TRUE;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun Bool
miScreenDevPrivateInit(ScreenPtr pScreen,int width,void * pbits)206*4882a593Smuzhiyun miScreenDevPrivateInit(ScreenPtr pScreen, int width, void *pbits)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun miScreenInitParmsPtr pScrInitParms;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
211*4882a593Smuzhiyun * to the screen, until CreateScreenResources can put them in the
212*4882a593Smuzhiyun * screen pixmap.
213*4882a593Smuzhiyun */
214*4882a593Smuzhiyun pScrInitParms = malloc(sizeof(miScreenInitParmsRec));
215*4882a593Smuzhiyun if (!pScrInitParms)
216*4882a593Smuzhiyun return FALSE;
217*4882a593Smuzhiyun pScrInitParms->pbits = pbits;
218*4882a593Smuzhiyun pScrInitParms->width = width;
219*4882a593Smuzhiyun pScreen->devPrivate = (void *) pScrInitParms;
220*4882a593Smuzhiyun return TRUE;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun static PixmapPtr
miGetScreenPixmap(ScreenPtr pScreen)224*4882a593Smuzhiyun miGetScreenPixmap(ScreenPtr pScreen)
225*4882a593Smuzhiyun {
226*4882a593Smuzhiyun return (PixmapPtr) (pScreen->devPrivate);
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun static void
miSetScreenPixmap(PixmapPtr pPix)230*4882a593Smuzhiyun miSetScreenPixmap(PixmapPtr pPix)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun if (pPix)
233*4882a593Smuzhiyun pPix->drawable.pScreen->devPrivate = (void *) pPix;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun Bool
miScreenInit(ScreenPtr pScreen,void * pbits,int xsize,int ysize,int dpix,int dpiy,int width,int rootDepth,int numDepths,DepthRec * depths,VisualID rootVisual,int numVisuals,VisualRec * visuals)237*4882a593Smuzhiyun miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */
238*4882a593Smuzhiyun int xsize, int ysize, /* in pixels */
239*4882a593Smuzhiyun int dpix, int dpiy, /* dots per inch */
240*4882a593Smuzhiyun int width, /* pixel width of frame buffer */
241*4882a593Smuzhiyun int rootDepth, /* depth of root window */
242*4882a593Smuzhiyun int numDepths, /* number of depths supported */
243*4882a593Smuzhiyun DepthRec * depths, /* supported depths */
244*4882a593Smuzhiyun VisualID rootVisual, /* root visual */
245*4882a593Smuzhiyun int numVisuals, /* number of visuals supported */
246*4882a593Smuzhiyun VisualRec * visuals /* supported visuals */
247*4882a593Smuzhiyun )
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun miScreenPtr pScreenPriv;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&miScreenPrivKeyRec, PRIVATE_SCREEN, 0))
252*4882a593Smuzhiyun return FALSE;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun pScreenPriv = calloc(1, sizeof(miScreenRec));
255*4882a593Smuzhiyun if (!pScreenPriv)
256*4882a593Smuzhiyun return FALSE;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun dixSetPrivate(&pScreen->devPrivates, miScreenPrivKey, pScreenPriv);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun pScreen->width = xsize;
261*4882a593Smuzhiyun pScreen->height = ysize;
262*4882a593Smuzhiyun pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
263*4882a593Smuzhiyun pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
264*4882a593Smuzhiyun pScreen->numDepths = numDepths;
265*4882a593Smuzhiyun pScreen->rootDepth = rootDepth;
266*4882a593Smuzhiyun pScreen->allowedDepths = depths;
267*4882a593Smuzhiyun pScreen->rootVisual = rootVisual;
268*4882a593Smuzhiyun /* defColormap */
269*4882a593Smuzhiyun pScreen->minInstalledCmaps = 1;
270*4882a593Smuzhiyun pScreen->maxInstalledCmaps = 1;
271*4882a593Smuzhiyun pScreen->backingStoreSupport = NotUseful;
272*4882a593Smuzhiyun pScreen->saveUnderSupport = NotUseful;
273*4882a593Smuzhiyun /* whitePixel, blackPixel */
274*4882a593Smuzhiyun pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
275*4882a593Smuzhiyun pScreen->CreateScreenResources = miCreateScreenResources;
276*4882a593Smuzhiyun pScreen->GetScreenPixmap = miGetScreenPixmap;
277*4882a593Smuzhiyun pScreen->SetScreenPixmap = miSetScreenPixmap;
278*4882a593Smuzhiyun pScreen->numVisuals = numVisuals;
279*4882a593Smuzhiyun pScreen->visuals = visuals;
280*4882a593Smuzhiyun if (width) {
281*4882a593Smuzhiyun #ifdef MITSHM
282*4882a593Smuzhiyun ShmRegisterFbFuncs(pScreen);
283*4882a593Smuzhiyun #endif
284*4882a593Smuzhiyun pScreenPriv->CloseScreen = pScreen->CloseScreen;
285*4882a593Smuzhiyun pScreen->CloseScreen = miCloseScreen;
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun /* else CloseScreen */
288*4882a593Smuzhiyun /* QueryBestSize, SaveScreen, GetImage, GetSpans */
289*4882a593Smuzhiyun pScreen->SourceValidate = miSourceValidate;
290*4882a593Smuzhiyun /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
291*4882a593Smuzhiyun /* RealizeWindow, UnrealizeWindow */
292*4882a593Smuzhiyun pScreen->ValidateTree = miValidateTree;
293*4882a593Smuzhiyun pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
294*4882a593Smuzhiyun pScreen->WindowExposures = miWindowExposures;
295*4882a593Smuzhiyun /* CopyWindow */
296*4882a593Smuzhiyun pScreen->ClearToBackground = miClearToBackground;
297*4882a593Smuzhiyun pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
298*4882a593Smuzhiyun pScreen->RestackWindow = (RestackWindowProcPtr) 0;
299*4882a593Smuzhiyun pScreen->PaintWindow = miPaintWindow;
300*4882a593Smuzhiyun /* CreatePixmap, DestroyPixmap */
301*4882a593Smuzhiyun /* RealizeFont, UnrealizeFont */
302*4882a593Smuzhiyun /* CreateGC */
303*4882a593Smuzhiyun /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
304*4882a593Smuzhiyun /* ListInstalledColormaps, StoreColors, ResolveColor */
305*4882a593Smuzhiyun /* BitmapToRegion */
306*4882a593Smuzhiyun pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
307*4882a593Smuzhiyun pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
308*4882a593Smuzhiyun pScreen->MarkWindow = miMarkWindow;
309*4882a593Smuzhiyun pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
310*4882a593Smuzhiyun pScreen->MoveWindow = miMoveWindow;
311*4882a593Smuzhiyun pScreen->ResizeWindow = miResizeWindow;
312*4882a593Smuzhiyun pScreen->GetLayerWindow = miGetLayerWindow;
313*4882a593Smuzhiyun pScreen->HandleExposures = miHandleValidateExposures;
314*4882a593Smuzhiyun pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
315*4882a593Smuzhiyun pScreen->ChangeBorderWidth = miChangeBorderWidth;
316*4882a593Smuzhiyun pScreen->SetShape = miSetShape;
317*4882a593Smuzhiyun pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
318*4882a593Smuzhiyun pScreen->XYToWindow = miXYToWindow;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun return miScreenDevPrivateInit(pScreen, width, pbits);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun DevPrivateKeyRec miZeroLineScreenKeyRec;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun void
miSetZeroLineBias(ScreenPtr pScreen,unsigned int bias)328*4882a593Smuzhiyun miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
331*4882a593Smuzhiyun return;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
334*4882a593Smuzhiyun (unsigned long *) (unsigned long) bias);
335*4882a593Smuzhiyun }
336