1706f2543Smrg/**************************************************************
2706f2543Smrg *
3706f2543Smrg * Xquartz initialization code
4706f2543Smrg *
5706f2543Smrg * Copyright (c) 2007-2008 Apple Inc.
6706f2543Smrg * Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved.
7706f2543Smrg *
8706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
9706f2543Smrg * copy of this software and associated documentation files (the "Software"),
10706f2543Smrg * to deal in the Software without restriction, including without limitation
11706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
13706f2543Smrg * Software is furnished to do so, subject to the following conditions:
14706f2543Smrg *
15706f2543Smrg * The above copyright notice and this permission notice shall be included in
16706f2543Smrg * all copies or substantial portions of the Software.
17706f2543Smrg *
18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21706f2543Smrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
22706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24706f2543Smrg * DEALINGS IN THE SOFTWARE.
25706f2543Smrg *
26706f2543Smrg * Except as contained in this notice, the name(s) of the above copyright
27706f2543Smrg * holders shall not be used in advertising or otherwise to promote the sale,
28706f2543Smrg * use or other dealings in this Software without prior written authorization.
29706f2543Smrg */
30706f2543Smrg
31706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
32706f2543Smrg#include <dix-config.h>
33706f2543Smrg#endif
34706f2543Smrg
35706f2543Smrg#include <X11/X.h>
36706f2543Smrg#include <X11/Xproto.h>
37706f2543Smrg#include "os.h"
38706f2543Smrg#include "servermd.h"
39706f2543Smrg#include "inputstr.h"
40706f2543Smrg#include "scrnintstr.h"
41706f2543Smrg#include "mibstore.h"		// mi backing store implementation
42706f2543Smrg#include "mipointer.h"		// mi software cursor
43706f2543Smrg#include "micmap.h"		// mi colormap code
44706f2543Smrg#include "fb.h"			// fb framebuffer code
45706f2543Smrg#include "site.h"
46706f2543Smrg#include "globals.h"
47706f2543Smrg#include "dix.h"
48706f2543Smrg#include "xkbsrv.h"
49706f2543Smrg
50706f2543Smrg#include <X11/extensions/XI.h>
51706f2543Smrg#include <X11/extensions/XIproto.h>
52706f2543Smrg#include "exevents.h"
53706f2543Smrg#include "extinit.h"
54706f2543Smrg
55706f2543Smrg#include "xserver-properties.h"
56706f2543Smrg
57706f2543Smrg#include <sys/types.h>
58706f2543Smrg#include <sys/time.h>
59706f2543Smrg#include <sys/syslimits.h>
60706f2543Smrg#include <stdio.h>
61706f2543Smrg#include <fcntl.h>
62706f2543Smrg#include <unistd.h>
63706f2543Smrg
64706f2543Smrg#define HAS_UTSNAME 1
65706f2543Smrg#include <sys/utsname.h>
66706f2543Smrg
67706f2543Smrg#define NO_CFPLUGIN
68706f2543Smrg#include <IOKit/hidsystem/IOHIDLib.h>
69706f2543Smrg
70706f2543Smrg#ifdef MITSHM
71706f2543Smrg#include "shmint.h"
72706f2543Smrg#endif
73706f2543Smrg
74706f2543Smrg#include "darwin.h"
75706f2543Smrg#include "darwinEvents.h"
76706f2543Smrg#include "quartzKeyboard.h"
77706f2543Smrg#include "quartz.h"
78706f2543Smrg
79706f2543Smrg#ifdef ENABLE_DEBUG_LOG
80706f2543SmrgFILE *debug_log_fp = NULL;
81706f2543Smrg#endif
82706f2543Smrg
83706f2543Smrg/*
84706f2543Smrg * X server shared global variables
85706f2543Smrg */
86706f2543Smrgint                     darwinScreensFound = 0;
87706f2543SmrgDevPrivateKeyRec        darwinScreenKeyRec;
88706f2543Smrgio_connect_t            darwinParamConnect = 0;
89706f2543Smrgint                     darwinEventReadFD = -1;
90706f2543Smrgint                     darwinEventWriteFD = -1;
91706f2543Smrg// int                     darwinMouseAccelChange = 1;
92706f2543Smrgint                     darwinFakeButtons = 0;
93706f2543Smrg
94706f2543Smrg// location of X11's (0,0) point in global screen coordinates
95706f2543Smrgint                     darwinMainScreenX = 0;
96706f2543Smrgint                     darwinMainScreenY = 0;
97706f2543Smrg
98706f2543Smrg// parameters read from the command line or user preferences
99706f2543Smrgint                     darwinDesiredDepth = -1;
100706f2543Smrgint                     darwinSyncKeymap = FALSE;
101706f2543Smrg
102706f2543Smrg// modifier masks for faking mouse buttons - ANY of these bits trigger it  (not all)
103706f2543Smrg#ifdef NX_DEVICELCMDKEYMASK
104706f2543Smrgint                     darwinFakeMouse2Mask = NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK;
105706f2543Smrgint                     darwinFakeMouse3Mask = NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK;
106706f2543Smrg#else
107706f2543Smrgint                     darwinFakeMouse2Mask = NX_ALTERNATEMASK;
108706f2543Smrgint                     darwinFakeMouse3Mask = NX_COMMANDMASK;
109706f2543Smrg#endif
110706f2543Smrg
111706f2543Smrg// Modifier mask for overriding event delivery to appkit (might be useful to set this to rcommand for input menu
112706f2543Smrgunsigned int            darwinAppKitModMask = 0; // Any of these bits
113706f2543Smrg
114706f2543Smrg// Modifier mask for items in the Window menu (0 and -1 cause shortcuts to be disabled)
115706f2543Smrgunsigned int            windowItemModMask = NX_COMMANDMASK;
116706f2543Smrg
117706f2543Smrg// devices
118706f2543SmrgDeviceIntPtr            darwinKeyboard = NULL;
119706f2543SmrgDeviceIntPtr            darwinPointer = NULL;
120706f2543SmrgDeviceIntPtr            darwinTabletCurrent = NULL;
121706f2543SmrgDeviceIntPtr            darwinTabletStylus = NULL;
122706f2543SmrgDeviceIntPtr            darwinTabletCursor = NULL;
123706f2543SmrgDeviceIntPtr            darwinTabletEraser = NULL;
124706f2543Smrg
125706f2543Smrg// Common pixmap formats
126706f2543Smrgstatic PixmapFormatRec formats[] = {
127706f2543Smrg        { 1,    1,      BITMAP_SCANLINE_PAD },
128706f2543Smrg        { 4,    8,      BITMAP_SCANLINE_PAD },
129706f2543Smrg        { 8,    8,      BITMAP_SCANLINE_PAD },
130706f2543Smrg        { 15,   16,     BITMAP_SCANLINE_PAD },
131706f2543Smrg        { 16,   16,     BITMAP_SCANLINE_PAD },
132706f2543Smrg        { 24,   32,     BITMAP_SCANLINE_PAD },
133706f2543Smrg        { 32,   32,     BITMAP_SCANLINE_PAD }
134706f2543Smrg};
135706f2543Smrgconst int NUMFORMATS = sizeof(formats)/sizeof(formats[0]);
136706f2543Smrg
137706f2543Smrg#ifndef OSNAME
138706f2543Smrg#define OSNAME " Darwin"
139706f2543Smrg#endif
140706f2543Smrg#ifndef OSVENDOR
141706f2543Smrg#define OSVENDOR ""
142706f2543Smrg#endif
143706f2543Smrg#ifndef PRE_RELEASE
144706f2543Smrg#define PRE_RELEASE XORG_VERSION_SNAP
145706f2543Smrg#endif
146706f2543Smrg#ifndef BUILD_DATE
147706f2543Smrg#define BUILD_DATE ""
148706f2543Smrg#endif
149706f2543Smrg#ifndef XORG_RELEASE
150706f2543Smrg#define XORG_RELEASE "?"
151706f2543Smrg#endif
152706f2543Smrg
153706f2543Smrgvoid
154706f2543SmrgDarwinPrintBanner(void)
155706f2543Smrg{
156706f2543Smrg  // this should change depending on which specific server we are building
157706f2543Smrg  ErrorF("Xquartz starting:\n");
158706f2543Smrg  ErrorF("X.Org X Server %s\nBuild Date: %s\n", XSERVER_VERSION, BUILD_DATE );
159706f2543Smrg}
160706f2543Smrg
161706f2543Smrg
162706f2543Smrg/*
163706f2543Smrg * DarwinSaveScreen
164706f2543Smrg *  X screensaver support. Not implemented.
165706f2543Smrg */
166706f2543Smrgstatic Bool DarwinSaveScreen(ScreenPtr pScreen, int on)
167706f2543Smrg{
168706f2543Smrg    // FIXME
169706f2543Smrg    if (on == SCREEN_SAVER_FORCER) {
170706f2543Smrg    } else if (on == SCREEN_SAVER_ON) {
171706f2543Smrg    } else {
172706f2543Smrg    }
173706f2543Smrg    return TRUE;
174706f2543Smrg}
175706f2543Smrg
176706f2543Smrg/*
177706f2543Smrg * DarwinScreenInit
178706f2543Smrg *  This is a callback from dix during AddScreen() from InitOutput().
179706f2543Smrg *  Initialize the screen and communicate information about it back to dix.
180706f2543Smrg */
181706f2543Smrgstatic Bool DarwinScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) {
182706f2543Smrg    int         dpi;
183706f2543Smrg    static int  foundIndex = 0;
184706f2543Smrg    Bool        ret;
185706f2543Smrg    DarwinFramebufferPtr dfb;
186706f2543Smrg
187706f2543Smrg    if (!dixRegisterPrivateKey(&darwinScreenKeyRec, PRIVATE_SCREEN, 0))
188706f2543Smrg	return FALSE;
189706f2543Smrg
190706f2543Smrg    // reset index of found screens for each server generation
191706f2543Smrg    if (index == 0) {
192706f2543Smrg        foundIndex = 0;
193706f2543Smrg
194706f2543Smrg        // reset the visual list
195706f2543Smrg        miClearVisualTypes();
196706f2543Smrg    }
197706f2543Smrg
198706f2543Smrg    // allocate space for private per screen storage
199706f2543Smrg    dfb = malloc(sizeof(DarwinFramebufferRec));
200706f2543Smrg
201706f2543Smrg    // SCREEN_PRIV(pScreen) = dfb;
202706f2543Smrg    dixSetPrivate(&pScreen->devPrivates, darwinScreenKey, dfb);
203706f2543Smrg
204706f2543Smrg    // setup hardware/mode specific details
205706f2543Smrg    ret = QuartzAddScreen(foundIndex, pScreen);
206706f2543Smrg    foundIndex++;
207706f2543Smrg    if (! ret)
208706f2543Smrg        return FALSE;
209706f2543Smrg
210706f2543Smrg    // setup a single visual appropriate for our pixel type
211706f2543Smrg    if(!miSetVisualTypesAndMasks(dfb->depth, dfb->visuals, dfb->bitsPerRGB,
212706f2543Smrg                                 dfb->preferredCVC, dfb->redMask,
213706f2543Smrg                                 dfb->greenMask, dfb->blueMask)) {
214706f2543Smrg        return FALSE;
215706f2543Smrg    }
216706f2543Smrg
217706f2543Smrg// TODO: Make PseudoColor visuals not suck in TrueColor mode
218706f2543Smrg//    if(dfb->depth > 8)
219706f2543Smrg//        miSetVisualTypesAndMasks(8, PseudoColorMask, 8, PseudoColor, 0, 0, 0);
220706f2543Smrg    if(dfb->depth > 15)
221706f2543Smrg        miSetVisualTypesAndMasks(15, TrueColorMask, 5, TrueColor, RM_ARGB(0,5,5,5), GM_ARGB(0,5,5,5), BM_ARGB(0,5,5,5));
222706f2543Smrg    if(dfb->depth > 24)
223706f2543Smrg        miSetVisualTypesAndMasks(24, TrueColorMask, 8, TrueColor, RM_ARGB(0,8,8,8), GM_ARGB(0,8,8,8), BM_ARGB(0,8,8,8));
224706f2543Smrg
225706f2543Smrg    miSetPixmapDepths();
226706f2543Smrg
227706f2543Smrg    // machine independent screen init
228706f2543Smrg    // setup _Screen structure in pScreen
229706f2543Smrg    if (monitorResolution)
230706f2543Smrg        dpi = monitorResolution;
231706f2543Smrg    else
232706f2543Smrg        dpi = 96;
233706f2543Smrg
234706f2543Smrg    // initialize fb
235706f2543Smrg    if (! fbScreenInit(pScreen,
236706f2543Smrg                dfb->framebuffer,                 // pointer to screen bitmap
237706f2543Smrg                dfb->width, dfb->height,          // screen size in pixels
238706f2543Smrg                dpi, dpi,                         // dots per inch
239706f2543Smrg                dfb->pitch/(dfb->bitsPerPixel/8), // pixel width of framebuffer
240706f2543Smrg                dfb->bitsPerPixel))               // bits per pixel for screen
241706f2543Smrg    {
242706f2543Smrg        return FALSE;
243706f2543Smrg    }
244706f2543Smrg
245706f2543Smrg    if (! fbPictureInit(pScreen, 0, 0)) {
246706f2543Smrg        return FALSE;
247706f2543Smrg    }
248706f2543Smrg
249706f2543Smrg#ifdef MITSHM
250706f2543Smrg    ShmRegisterFbFuncs(pScreen);
251706f2543Smrg#endif
252706f2543Smrg
253706f2543Smrg    // this must be initialized (why doesn't X have a default?)
254706f2543Smrg    pScreen->SaveScreen = DarwinSaveScreen;
255706f2543Smrg
256706f2543Smrg    // finish mode dependent screen setup including cursor support
257706f2543Smrg    if (!QuartzSetupScreen(index, pScreen)) {
258706f2543Smrg        return FALSE;
259706f2543Smrg    }
260706f2543Smrg
261706f2543Smrg    // create and install the default colormap and
262706f2543Smrg    // set pScreen->blackPixel / pScreen->white
263706f2543Smrg    if (!miCreateDefColormap( pScreen )) {
264706f2543Smrg        return FALSE;
265706f2543Smrg    }
266706f2543Smrg
267706f2543Smrg    pScreen->x = dfb->x;
268706f2543Smrg    pScreen->y = dfb->y;
269706f2543Smrg
270706f2543Smrg    /*    ErrorF("Screen %d added: %dx%d @ (%d,%d)\n",
271706f2543Smrg	  index, dfb->width, dfb->height, dfb->x, dfb->y); */
272706f2543Smrg
273706f2543Smrg    return TRUE;
274706f2543Smrg}
275706f2543Smrg
276706f2543Smrg/*
277706f2543Smrg =============================================================================
278706f2543Smrg
279706f2543Smrg mouse and keyboard callbacks
280706f2543Smrg
281706f2543Smrg =============================================================================
282706f2543Smrg*/
283706f2543Smrg
284706f2543Smrg/*
285706f2543Smrg * DarwinMouseProc: Handle the initialization, etc. of a mouse
286706f2543Smrg */
287706f2543Smrgstatic int DarwinMouseProc(DeviceIntPtr pPointer, int what) {
288706f2543Smrg#define NBUTTONS 7
289706f2543Smrg#define NAXES 2
290706f2543Smrg	// 7 buttons: left, right, middle, then four scroll wheel "buttons"
291706f2543Smrg    CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3, 4, 5, 6, 7};
292706f2543Smrg    Atom btn_labels[NBUTTONS] = {0};
293706f2543Smrg    Atom axes_labels[NAXES] = {0};
294706f2543Smrg
295706f2543Smrg    switch (what) {
296706f2543Smrg        case DEVICE_INIT:
297706f2543Smrg            pPointer->public.on = FALSE;
298706f2543Smrg
299706f2543Smrg            btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
300706f2543Smrg            btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
301706f2543Smrg            btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
302706f2543Smrg            btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
303706f2543Smrg            btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
304706f2543Smrg            btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
305706f2543Smrg            btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
306706f2543Smrg
307706f2543Smrg            axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
308706f2543Smrg            axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
309706f2543Smrg
310706f2543Smrg
311706f2543Smrg            // Set button map.
312706f2543Smrg            InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
313706f2543Smrg                                    btn_labels,
314706f2543Smrg                                    (PtrCtrlProcPtr)NoopDDA,
315706f2543Smrg                                    GetMotionHistorySize(), NAXES,
316706f2543Smrg                                    axes_labels);
317706f2543Smrg            InitAbsoluteClassDeviceStruct(pPointer);
318706f2543Smrg//            InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
319706f2543Smrg//            InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
320706f2543Smrg            break;
321706f2543Smrg        case DEVICE_ON:
322706f2543Smrg            pPointer->public.on = TRUE;
323706f2543Smrg            AddEnabledDevice( darwinEventReadFD );
324706f2543Smrg            return Success;
325706f2543Smrg        case DEVICE_CLOSE:
326706f2543Smrg        case DEVICE_OFF:
327706f2543Smrg            pPointer->public.on = FALSE;
328706f2543Smrg            RemoveEnabledDevice(darwinEventReadFD);
329706f2543Smrg            return Success;
330706f2543Smrg    }
331706f2543Smrg
332706f2543Smrg    return Success;
333706f2543Smrg#undef NBUTTONS
334706f2543Smrg#undef NAXES
335706f2543Smrg}
336706f2543Smrg
337706f2543Smrgstatic int DarwinTabletProc(DeviceIntPtr pPointer, int what) {
338706f2543Smrg#define NBUTTONS 3
339706f2543Smrg#define NAXES 5
340706f2543Smrg    CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3};
341706f2543Smrg    Atom btn_labels[NBUTTONS] = {0};
342706f2543Smrg    Atom axes_labels[NAXES] = {0};
343706f2543Smrg
344706f2543Smrg    switch (what) {
345706f2543Smrg        case DEVICE_INIT:
346706f2543Smrg            pPointer->public.on = FALSE;
347706f2543Smrg
348706f2543Smrg            btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
349706f2543Smrg            btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
350706f2543Smrg            btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
351706f2543Smrg
352706f2543Smrg            axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
353706f2543Smrg            axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
354706f2543Smrg            axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
355706f2543Smrg            axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X);
356706f2543Smrg            axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
357706f2543Smrg
358706f2543Smrg            // Set button map.
359706f2543Smrg            InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
360706f2543Smrg                                    btn_labels,
361706f2543Smrg                                    (PtrCtrlProcPtr)NoopDDA,
362706f2543Smrg                                    GetMotionHistorySize(), NAXES,
363706f2543Smrg                                    axes_labels);
364706f2543Smrg            InitProximityClassDeviceStruct(pPointer);
365706f2543Smrg			InitAbsoluteClassDeviceStruct(pPointer);
366706f2543Smrg
367706f2543Smrg            InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
368706f2543Smrg            InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
369706f2543Smrg            InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
370706f2543Smrg            InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
371706f2543Smrg            InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
372706f2543Smrg//          pPointer->use = IsXExtensionDevice;
373706f2543Smrg            break;
374706f2543Smrg        case DEVICE_ON:
375706f2543Smrg            pPointer->public.on = TRUE;
376706f2543Smrg            AddEnabledDevice( darwinEventReadFD );
377706f2543Smrg            return Success;
378706f2543Smrg        case DEVICE_CLOSE:
379706f2543Smrg        case DEVICE_OFF:
380706f2543Smrg            pPointer->public.on = FALSE;
381706f2543Smrg            RemoveEnabledDevice(darwinEventReadFD);
382706f2543Smrg            return Success;
383706f2543Smrg    }
384706f2543Smrg    return Success;
385706f2543Smrg#undef NBUTTONS
386706f2543Smrg#undef NAXES
387706f2543Smrg}
388706f2543Smrg
389706f2543Smrg/*
390706f2543Smrg * DarwinKeybdProc
391706f2543Smrg *  Callback from X
392706f2543Smrg */
393706f2543Smrgstatic int DarwinKeybdProc( DeviceIntPtr pDev, int onoff )
394706f2543Smrg{
395706f2543Smrg    switch ( onoff ) {
396706f2543Smrg        case DEVICE_INIT:
397706f2543Smrg            DarwinKeyboardInit( pDev );
398706f2543Smrg            break;
399706f2543Smrg        case DEVICE_ON:
400706f2543Smrg            pDev->public.on = TRUE;
401706f2543Smrg            AddEnabledDevice( darwinEventReadFD );
402706f2543Smrg            break;
403706f2543Smrg        case DEVICE_OFF:
404706f2543Smrg            pDev->public.on = FALSE;
405706f2543Smrg            RemoveEnabledDevice( darwinEventReadFD );
406706f2543Smrg            break;
407706f2543Smrg        case DEVICE_CLOSE:
408706f2543Smrg            break;
409706f2543Smrg    }
410706f2543Smrg
411706f2543Smrg    return Success;
412706f2543Smrg}
413706f2543Smrg
414706f2543Smrg/*
415706f2543Smrg===========================================================================
416706f2543Smrg
417706f2543Smrg Utility routines
418706f2543Smrg
419706f2543Smrg===========================================================================
420706f2543Smrg*/
421706f2543Smrg
422706f2543Smrg/*
423706f2543Smrg * DarwinParseModifierList
424706f2543Smrg *  Parse a list of modifier names and return a corresponding modifier mask
425706f2543Smrg */
426706f2543Smrgint DarwinParseModifierList(const char *constmodifiers, int separatelr)
427706f2543Smrg{
428706f2543Smrg    int result = 0;
429706f2543Smrg
430706f2543Smrg    if (constmodifiers) {
431706f2543Smrg        char *modifiers = strdup(constmodifiers);
432706f2543Smrg        char *modifier;
433706f2543Smrg        int nxkey;
434706f2543Smrg        char *p = modifiers;
435706f2543Smrg
436706f2543Smrg        while (p) {
437706f2543Smrg            modifier = strsep(&p, " ,+&|/"); // allow lots of separators
438706f2543Smrg            nxkey = DarwinModifierStringToNXMask(modifier, separatelr);
439706f2543Smrg            if(nxkey)
440706f2543Smrg                result |= nxkey;
441706f2543Smrg            else
442706f2543Smrg                ErrorF("fakebuttons: Unknown modifier \"%s\"\n", modifier);
443706f2543Smrg        }
444706f2543Smrg        free(modifiers);
445706f2543Smrg    }
446706f2543Smrg    return result;
447706f2543Smrg}
448706f2543Smrg
449706f2543Smrg/*
450706f2543Smrg===========================================================================
451706f2543Smrg
452706f2543Smrg Functions needed to link against device independent X
453706f2543Smrg
454706f2543Smrg===========================================================================
455706f2543Smrg*/
456706f2543Smrg
457706f2543Smrg/*
458706f2543Smrg * InitInput
459706f2543Smrg *  Register the keyboard and mouse devices
460706f2543Smrg */
461706f2543Smrgvoid InitInput( int argc, char **argv )
462706f2543Smrg{
463706f2543Smrg    XkbRMLVOSet rmlvo = { .rules = "base", .model = "empty", .layout = "empty",
464706f2543Smrg                          .variant = NULL, .options = NULL };
465706f2543Smrg    /* We need to really have rules... or something... */
466706f2543Smrg    XkbSetRulesDflts(&rmlvo);
467706f2543Smrg
468706f2543Smrg    darwinKeyboard = AddInputDevice(serverClient, DarwinKeybdProc, TRUE);
469706f2543Smrg    darwinKeyboard->name = strdup("keyboard");
470706f2543Smrg
471706f2543Smrg    /* here's the snippet from the current gdk sources:
472706f2543Smrg    if (!strcmp (tmp_name, "pointer"))
473706f2543Smrg        gdkdev->info.source = GDK_SOURCE_MOUSE;
474706f2543Smrg    else if (!strcmp (tmp_name, "wacom") ||
475706f2543Smrg             !strcmp (tmp_name, "pen"))
476706f2543Smrg        gdkdev->info.source = GDK_SOURCE_PEN;
477706f2543Smrg    else if (!strcmp (tmp_name, "eraser"))
478706f2543Smrg        gdkdev->info.source = GDK_SOURCE_ERASER;
479706f2543Smrg    else if (!strcmp (tmp_name, "cursor"))
480706f2543Smrg        gdkdev->info.source = GDK_SOURCE_CURSOR;
481706f2543Smrg    else
482706f2543Smrg        gdkdev->info.source = GDK_SOURCE_PEN;
483706f2543Smrg    */
484706f2543Smrg
485706f2543Smrg    darwinPointer = AddInputDevice(serverClient, DarwinMouseProc, TRUE);
486706f2543Smrg    darwinPointer->name = strdup("pointer");
487706f2543Smrg
488706f2543Smrg    darwinTabletStylus = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
489706f2543Smrg    darwinTabletStylus->name = strdup("pen");
490706f2543Smrg
491706f2543Smrg    darwinTabletCursor = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
492706f2543Smrg    darwinTabletCursor->name = strdup("cursor");
493706f2543Smrg
494706f2543Smrg    darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
495706f2543Smrg    darwinTabletEraser->name = strdup("eraser");
496706f2543Smrg
497706f2543Smrg    darwinTabletCurrent = darwinTabletStylus;
498706f2543Smrg
499706f2543Smrg    DarwinEQInit();
500706f2543Smrg
501706f2543Smrg    QuartzInitInput(argc, argv);
502706f2543Smrg}
503706f2543Smrg
504706f2543Smrg
505706f2543Smrg/*
506706f2543Smrg * DarwinAdjustScreenOrigins
507706f2543Smrg *  Shift all screens so the X11 (0, 0) coordinate is at the top
508706f2543Smrg *  left of the global screen coordinates.
509706f2543Smrg *
510706f2543Smrg *  Screens can be arranged so the top left isn't on any screen, so
511706f2543Smrg *  instead use the top left of the leftmost screen as (0,0). This
512706f2543Smrg *  may mean some screen space is in -y, but it's better that (0,0)
513706f2543Smrg *  be onscreen, or else default xterms disappear. It's better that
514706f2543Smrg *  -y be used than -x, because when popup menus are forced
515706f2543Smrg *  "onscreen" by dumb window managers like twm, they'll shift the
516706f2543Smrg *  menus down instead of left, which still looks funny but is an
517706f2543Smrg *  easier target to hit.
518706f2543Smrg */
519706f2543Smrgvoid
520706f2543SmrgDarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo)
521706f2543Smrg{
522706f2543Smrg    int i, left, top;
523706f2543Smrg
524706f2543Smrg    left = pScreenInfo->screens[0]->x;
525706f2543Smrg    top  = pScreenInfo->screens[0]->y;
526706f2543Smrg
527706f2543Smrg    /* Find leftmost screen. If there's a tie, take the topmost of the two. */
528706f2543Smrg    for (i = 1; i < pScreenInfo->numScreens; i++) {
529706f2543Smrg        if (pScreenInfo->screens[i]->x < left  ||
530706f2543Smrg            (pScreenInfo->screens[i]->x == left && pScreenInfo->screens[i]->y < top))
531706f2543Smrg        {
532706f2543Smrg            left = pScreenInfo->screens[i]->x;
533706f2543Smrg            top = pScreenInfo->screens[i]->y;
534706f2543Smrg        }
535706f2543Smrg    }
536706f2543Smrg
537706f2543Smrg    darwinMainScreenX = left;
538706f2543Smrg    darwinMainScreenY = top;
539706f2543Smrg
540706f2543Smrg    DEBUG_LOG("top = %d, left=%d\n", top, left);
541706f2543Smrg
542706f2543Smrg    /* Shift all screens so that there is a screen whose top left
543706f2543Smrg     * is at X11 (0,0) and at global screen coordinate
544706f2543Smrg     * (darwinMainScreenX, darwinMainScreenY).
545706f2543Smrg     */
546706f2543Smrg
547706f2543Smrg    if (darwinMainScreenX != 0 || darwinMainScreenY != 0) {
548706f2543Smrg        for (i = 0; i < pScreenInfo->numScreens; i++) {
549706f2543Smrg            pScreenInfo->screens[i]->x -= darwinMainScreenX;
550706f2543Smrg            pScreenInfo->screens[i]->y -= darwinMainScreenY;
551706f2543Smrg            DEBUG_LOG("Screen %d placed at X11 coordinate (%d,%d).\n",
552706f2543Smrg                      i, pScreenInfo->screens[i]->x, pScreenInfo->screens[i]->y);
553706f2543Smrg        }
554706f2543Smrg    }
555706f2543Smrg}
556706f2543Smrg
557706f2543Smrg
558706f2543Smrg/*
559706f2543Smrg * InitOutput
560706f2543Smrg *  Initialize screenInfo for all actually accessible framebuffers.
561706f2543Smrg *
562706f2543Smrg *  The display mode dependent code gets called three times. The mode
563706f2543Smrg *  specific InitOutput routines are expected to discover the number
564706f2543Smrg *  of potentially useful screens and cache routes to them internally.
565706f2543Smrg *  Inside DarwinScreenInit are two other mode specific calls.
566706f2543Smrg *  A mode specific AddScreen routine is called for each screen to
567706f2543Smrg *  actually initialize the screen with the ScreenPtr structure.
568706f2543Smrg *  After other screen setup has been done, a mode specific
569706f2543Smrg *  SetupScreen function can be called to finalize screen setup.
570706f2543Smrg */
571706f2543Smrgvoid InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv )
572706f2543Smrg{
573706f2543Smrg    int i;
574706f2543Smrg
575706f2543Smrg    pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
576706f2543Smrg    pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
577706f2543Smrg    pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
578706f2543Smrg    pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
579706f2543Smrg
580706f2543Smrg    // List how we want common pixmap formats to be padded
581706f2543Smrg    pScreenInfo->numPixmapFormats = NUMFORMATS;
582706f2543Smrg    for (i = 0; i < NUMFORMATS; i++)
583706f2543Smrg        pScreenInfo->formats[i] = formats[i];
584706f2543Smrg
585706f2543Smrg    // Discover screens and do mode specific initialization
586706f2543Smrg    QuartzInitOutput(argc, argv);
587706f2543Smrg
588706f2543Smrg    // Add screens
589706f2543Smrg    for (i = 0; i < darwinScreensFound; i++) {
590706f2543Smrg        AddScreen(DarwinScreenInit, argc, argv);
591706f2543Smrg    }
592706f2543Smrg
593706f2543Smrg    DarwinAdjustScreenOrigins(pScreenInfo);
594706f2543Smrg}
595706f2543Smrg
596706f2543Smrg
597706f2543Smrg/*
598706f2543Smrg * OsVendorFatalError
599706f2543Smrg */
600706f2543Smrgvoid OsVendorFatalError( void )
601706f2543Smrg{
602706f2543Smrg    ErrorF( "   OsVendorFatalError\n" );
603706f2543Smrg}
604706f2543Smrg
605706f2543Smrg
606706f2543Smrg/*
607706f2543Smrg * OsVendorInit
608706f2543Smrg *  Initialization of Darwin OS support.
609706f2543Smrg */
610706f2543Smrgvoid OsVendorInit(void)
611706f2543Smrg{
612706f2543Smrg    if (serverGeneration == 1) {
613706f2543Smrg        DarwinPrintBanner();
614706f2543Smrg#ifdef ENABLE_DEBUG_LOG
615706f2543Smrg	{
616706f2543Smrg	  char *home_dir=NULL, *log_file_path=NULL;
617706f2543Smrg	  home_dir = getenv("HOME");
618706f2543Smrg	  if (home_dir) asprintf(&log_file_path, "%s/%s", home_dir, DEBUG_LOG_NAME);
619706f2543Smrg	  if (log_file_path) {
620706f2543Smrg	    if (!access(log_file_path, F_OK)) {
621706f2543Smrg	      debug_log_fp = fopen(log_file_path, "a");
622706f2543Smrg	      if (debug_log_fp) ErrorF("Debug logging enabled to %s\n", log_file_path);
623706f2543Smrg	    }
624706f2543Smrg	    free(log_file_path);
625706f2543Smrg	  }
626706f2543Smrg	}
627706f2543Smrg#endif
628706f2543Smrg    }
629706f2543Smrg}
630706f2543Smrg
631706f2543Smrg
632706f2543Smrg/*
633706f2543Smrg * ddxProcessArgument
634706f2543Smrg *  Process device-dependent command line args. Returns 0 if argument is
635706f2543Smrg *  not device dependent, otherwise Count of number of elements of argv
636706f2543Smrg *  that are part of a device dependent commandline option.
637706f2543Smrg */
638706f2543Smrgint ddxProcessArgument( int argc, char *argv[], int i )
639706f2543Smrg{
640706f2543Smrg//    if ( !strcmp( argv[i], "-fullscreen" ) ) {
641706f2543Smrg//        ErrorF( "Running full screen in parallel with Mac OS X Quartz window server.\n" );
642706f2543Smrg//        return 1;
643706f2543Smrg//    }
644706f2543Smrg
645706f2543Smrg//    if ( !strcmp( argv[i], "-rootless" ) ) {
646706f2543Smrg//        ErrorF( "Running rootless inside Mac OS X window server.\n" );
647706f2543Smrg//        return 1;
648706f2543Smrg//    }
649706f2543Smrg
650706f2543Smrg    // This command line arg is passed when launched from the Aqua GUI.
651706f2543Smrg    if ( !strncmp( argv[i], "-psn_", 5 ) ) {
652706f2543Smrg        return 1;
653706f2543Smrg    }
654706f2543Smrg
655706f2543Smrg    if ( !strcmp( argv[i], "-fakebuttons" ) ) {
656706f2543Smrg        darwinFakeButtons = TRUE;
657706f2543Smrg        ErrorF( "Faking a three button mouse\n" );
658706f2543Smrg        return 1;
659706f2543Smrg    }
660706f2543Smrg
661706f2543Smrg    if ( !strcmp( argv[i], "-nofakebuttons" ) ) {
662706f2543Smrg        darwinFakeButtons = FALSE;
663706f2543Smrg        ErrorF( "Not faking a three button mouse\n" );
664706f2543Smrg        return 1;
665706f2543Smrg    }
666706f2543Smrg
667706f2543Smrg    if (!strcmp( argv[i], "-fakemouse2" ) ) {
668706f2543Smrg        if ( i == argc-1 ) {
669706f2543Smrg            FatalError( "-fakemouse2 must be followed by a modifer list\n" );
670706f2543Smrg        }
671706f2543Smrg        if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], ""))
672706f2543Smrg            darwinFakeMouse2Mask = 0;
673706f2543Smrg        else
674706f2543Smrg            darwinFakeMouse2Mask = DarwinParseModifierList(argv[i+1], 1);
675706f2543Smrg        ErrorF("Modifier mask to fake mouse button 2 = 0x%x\n",
676706f2543Smrg               darwinFakeMouse2Mask);
677706f2543Smrg        return 2;
678706f2543Smrg    }
679706f2543Smrg
680706f2543Smrg    if (!strcmp( argv[i], "-fakemouse3" ) ) {
681706f2543Smrg        if ( i == argc-1 ) {
682706f2543Smrg            FatalError( "-fakemouse3 must be followed by a modifer list\n" );
683706f2543Smrg        }
684706f2543Smrg        if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], ""))
685706f2543Smrg            darwinFakeMouse3Mask = 0;
686706f2543Smrg        else
687706f2543Smrg            darwinFakeMouse3Mask = DarwinParseModifierList(argv[i+1], 1);
688706f2543Smrg        ErrorF("Modifier mask to fake mouse button 3 = 0x%x\n",
689706f2543Smrg               darwinFakeMouse3Mask);
690706f2543Smrg        return 2;
691706f2543Smrg    }
692706f2543Smrg
693706f2543Smrg    if ( !strcmp( argv[i], "+synckeymap" ) ) {
694706f2543Smrg        darwinSyncKeymap = TRUE;
695706f2543Smrg        return 1;
696706f2543Smrg    }
697706f2543Smrg
698706f2543Smrg    if ( !strcmp( argv[i], "-synckeymap" ) ) {
699706f2543Smrg        darwinSyncKeymap = FALSE;
700706f2543Smrg        return 1;
701706f2543Smrg    }
702706f2543Smrg
703706f2543Smrg    if ( !strcmp( argv[i], "-depth" ) ) {
704706f2543Smrg        if ( i == argc-1 ) {
705706f2543Smrg            FatalError( "-depth must be followed by a number\n" );
706706f2543Smrg        }
707706f2543Smrg        darwinDesiredDepth = atoi( argv[i+1] );
708706f2543Smrg        if(darwinDesiredDepth != -1 &&
709706f2543Smrg           darwinDesiredDepth != 8 &&
710706f2543Smrg           darwinDesiredDepth != 15 &&
711706f2543Smrg           darwinDesiredDepth != 24) {
712706f2543Smrg            FatalError( "Unsupported pixel depth. Use 8, 15, or 24 bits\n" );
713706f2543Smrg        }
714706f2543Smrg
715706f2543Smrg        ErrorF( "Attempting to use pixel depth of %i\n", darwinDesiredDepth );
716706f2543Smrg        return 2;
717706f2543Smrg    }
718706f2543Smrg
719706f2543Smrg    if (!strcmp( argv[i], "-showconfig" ) || !strcmp( argv[i], "-version" )) {
720706f2543Smrg        DarwinPrintBanner();
721706f2543Smrg        exit(0);
722706f2543Smrg    }
723706f2543Smrg
724706f2543Smrg    return 0;
725706f2543Smrg}
726706f2543Smrg
727706f2543Smrg
728706f2543Smrg/*
729706f2543Smrg * ddxUseMsg --
730706f2543Smrg *  Print out correct use of device dependent commandline options.
731706f2543Smrg *  Maybe the user now knows what really to do ...
732706f2543Smrg */
733706f2543Smrgvoid ddxUseMsg( void )
734706f2543Smrg{
735706f2543Smrg    ErrorF("\n");
736706f2543Smrg    ErrorF("\n");
737706f2543Smrg    ErrorF("Device Dependent Usage:\n");
738706f2543Smrg    ErrorF("\n");
739706f2543Smrg    ErrorF("-depth <8,15,24> : use this bit depth.\n");
740706f2543Smrg    ErrorF("-fakebuttons : fake a three button mouse with Command and Option keys.\n");
741706f2543Smrg    ErrorF("-nofakebuttons : don't fake a three button mouse.\n");
742706f2543Smrg    ErrorF("-fakemouse2 <modifiers> : fake middle mouse button with modifier keys.\n");
743706f2543Smrg    ErrorF("-fakemouse3 <modifiers> : fake right mouse button with modifier keys.\n");
744706f2543Smrg    ErrorF("  ex: -fakemouse2 \"option,shift\" = option-shift-click is middle button.\n");
745706f2543Smrg    ErrorF("-version : show the server version.\n");
746706f2543Smrg    ErrorF("\n");
747706f2543Smrg}
748706f2543Smrg
749706f2543Smrg
750706f2543Smrg/*
751706f2543Smrg * ddxGiveUp --
752706f2543Smrg *      Device dependent cleanup. Called by dix before normal server death.
753706f2543Smrg */
754706f2543Smrgvoid ddxGiveUp( void )
755706f2543Smrg{
756706f2543Smrg    ErrorF( "Quitting Xquartz\n" );
757706f2543Smrg}
758706f2543Smrg
759706f2543Smrg
760706f2543Smrg/*
761706f2543Smrg * AbortDDX --
762706f2543Smrg *      DDX - specific abort routine.  Called by AbortServer(). The attempt is
763706f2543Smrg *      made to restore all original setting of the displays. Also all devices
764706f2543Smrg *      are closed.
765706f2543Smrg */
766706f2543Smrgvoid AbortDDX( void )
767706f2543Smrg{
768706f2543Smrg    ErrorF( "   AbortDDX\n" );
769706f2543Smrg    OsAbort();
770706f2543Smrg}
771706f2543Smrg
772706f2543Smrg#include "mivalidate.h" // for union _Validate used by windowstr.h
773706f2543Smrg#include "windowstr.h"  // for struct _Window
774706f2543Smrg#include "scrnintstr.h" // for struct _Screen
775706f2543Smrg
776706f2543Smrg// This is copied from Xserver/hw/xfree86/common/xf86Helper.c.
777706f2543Smrg// Quartz mode uses this when switching in and out of Quartz.
778706f2543Smrg// Quartz or IOKit can use this when waking from sleep.
779706f2543Smrg// Copyright (c) 1997-1998 by The XFree86 Project, Inc.
780706f2543Smrg
781706f2543Smrg/*
782706f2543Smrg * xf86SetRootClip --
783706f2543Smrg *	Enable or disable rendering to the screen by
784706f2543Smrg *	setting the root clip list and revalidating
785706f2543Smrg *	all of the windows
786706f2543Smrg */
787706f2543Smrg
788706f2543Smrgvoid
789706f2543Smrgxf86SetRootClip (ScreenPtr pScreen, int enable)
790706f2543Smrg{
791706f2543Smrg    WindowPtr	pWin = pScreen->root;
792706f2543Smrg    WindowPtr	pChild;
793706f2543Smrg    Bool	WasViewable = (Bool)(pWin->viewable);
794706f2543Smrg    Bool	anyMarked = TRUE;
795706f2543Smrg    RegionPtr	pOldClip = NULL;
796706f2543Smrg    WindowPtr   pLayerWin;
797706f2543Smrg    BoxRec	box;
798706f2543Smrg
799706f2543Smrg    if (WasViewable)
800706f2543Smrg    {
801706f2543Smrg	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
802706f2543Smrg	{
803706f2543Smrg	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
804706f2543Smrg						     pChild,
805706f2543Smrg						     &pLayerWin);
806706f2543Smrg	}
807706f2543Smrg	(*pScreen->MarkWindow) (pWin);
808706f2543Smrg	anyMarked = TRUE;
809706f2543Smrg	if (pWin->valdata)
810706f2543Smrg	{
811706f2543Smrg	    if (HasBorder (pWin))
812706f2543Smrg	    {
813706f2543Smrg		RegionPtr	borderVisible;
814706f2543Smrg
815706f2543Smrg		borderVisible = RegionCreate(NullBox, 1);
816706f2543Smrg		RegionSubtract(borderVisible,
817706f2543Smrg				&pWin->borderClip, &pWin->winSize);
818706f2543Smrg		pWin->valdata->before.borderVisible = borderVisible;
819706f2543Smrg	    }
820706f2543Smrg	    pWin->valdata->before.resized = TRUE;
821706f2543Smrg	}
822706f2543Smrg    }
823706f2543Smrg
824706f2543Smrg    /*
825706f2543Smrg     * Use REGION_BREAK to avoid optimizations in ValidateTree
826706f2543Smrg     * that assume the root borderClip can't change well, normally
827706f2543Smrg     * it doesn't...)
828706f2543Smrg     */
829706f2543Smrg    if (enable)
830706f2543Smrg    {
831706f2543Smrg	box.x1 = 0;
832706f2543Smrg	box.y1 = 0;
833706f2543Smrg	box.x2 = pScreen->width;
834706f2543Smrg	box.y2 = pScreen->height;
835706f2543Smrg	RegionReset(&pWin->borderClip, &box);
836706f2543Smrg	RegionBreak(&pWin->clipList);
837706f2543Smrg    }
838706f2543Smrg    else
839706f2543Smrg    {
840706f2543Smrg	RegionEmpty(&pWin->borderClip);
841706f2543Smrg	RegionBreak(&pWin->clipList);
842706f2543Smrg    }
843706f2543Smrg
844706f2543Smrg    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
845706f2543Smrg
846706f2543Smrg    if (WasViewable)
847706f2543Smrg    {
848706f2543Smrg	if (pWin->backStorage)
849706f2543Smrg	{
850706f2543Smrg	    pOldClip = RegionCreate(NullBox, 1);
851706f2543Smrg	    RegionCopy(pOldClip, &pWin->clipList);
852706f2543Smrg	}
853706f2543Smrg
854706f2543Smrg	if (pWin->firstChild)
855706f2543Smrg	{
856706f2543Smrg	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
857706f2543Smrg							   pWin->firstChild,
858706f2543Smrg							   (WindowPtr *)NULL);
859706f2543Smrg	}
860706f2543Smrg	else
861706f2543Smrg	{
862706f2543Smrg	    (*pScreen->MarkWindow) (pWin);
863706f2543Smrg	    anyMarked = TRUE;
864706f2543Smrg	}
865706f2543Smrg
866706f2543Smrg
867706f2543Smrg	if (anyMarked)
868706f2543Smrg	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
869706f2543Smrg    }
870706f2543Smrg
871706f2543Smrg    if (WasViewable)
872706f2543Smrg    {
873706f2543Smrg	if (anyMarked)
874706f2543Smrg	    (*pScreen->HandleExposures)(pWin);
875706f2543Smrg	if (anyMarked && pScreen->PostValidateTree)
876706f2543Smrg	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
877706f2543Smrg    }
878706f2543Smrg    if (pWin->realized)
879706f2543Smrg	WindowsRestructured ();
880706f2543Smrg    FlushAllOutput ();
881706f2543Smrg}
882