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