| File: | driver.c |
| Location: | line 706, column 58 |
| Description: | Access to field 'name' results in a dereference of a null pointer (loaded from variable 'mode') |
| 1 | /* | |||
| 2 | * Permission is hereby granted, free of charge, to any person obtaining a | |||
| 3 | * copy of this software and associated documentation files (the "Software"), | |||
| 4 | * to deal in the Software without restriction, including without limitation | |||
| 5 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 6 | * and/or sell copies of the Software, and to permit persons to whom the | |||
| 7 | * Software is furnished to do so, subject to the following conditions: | |||
| 8 | * | |||
| 9 | * The above copyright notice and this permission notice (including the next | |||
| 10 | * paragraph) shall be included in all copies or substantial portions of the | |||
| 11 | * Software. | |||
| 12 | * | |||
| 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 16 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 19 | * DEALINGS IN THE SOFTWARE. | |||
| 20 | * | |||
| 21 | * Authors: | |||
| 22 | * | |||
| 23 | * Paulo Zanoni <pzanoni@mandriva.com> | |||
| 24 | * Tuan Bui <tuanbui918@gmail.com> | |||
| 25 | * Colin Cornaby <colin.cornaby@mac.com> | |||
| 26 | * Timothy Fleck <tim.cs.pdx@gmail.com> | |||
| 27 | * Colin Hill <colin.james.hill@gmail.com> | |||
| 28 | * Weseung Hwang <weseung@gmail.com> | |||
| 29 | * Nathaniel Way <nathanielcw@hotmail.com> | |||
| 30 | */ | |||
| 31 | ||||
| 32 | #include <stdlib.h> | |||
| 33 | #include <string.h> | |||
| 34 | ||||
| 35 | #ifdef HAVE_CONFIG_H1 | |||
| 36 | #include "config.h" | |||
| 37 | #endif | |||
| 38 | ||||
| 39 | #include <xorg-server.h> | |||
| 40 | #include <fb.h> | |||
| 41 | #include <micmap.h> | |||
| 42 | #include <mipointer.h> | |||
| 43 | #include <shadow.h> | |||
| 44 | #include <xf86.h> | |||
| 45 | #include <xf86Module.h> | |||
| 46 | #include <xf86str.h> | |||
| 47 | #include "xf86Xinput.h" | |||
| 48 | ||||
| 49 | #include "compat-api.h" | |||
| 50 | ||||
| 51 | #include "client.h" | |||
| 52 | #include "nested_input.h" | |||
| 53 | ||||
| 54 | #define NESTED_VERSION0 0 | |||
| 55 | #define NESTED_NAME"NESTED" "NESTED" | |||
| 56 | #define NESTED_DRIVER_NAME"nested" "nested" | |||
| 57 | ||||
| 58 | #define NESTED_MAJOR_VERSION0 PACKAGE_VERSION_MAJOR0 | |||
| 59 | #define NESTED_MINOR_VERSION1 PACKAGE_VERSION_MINOR1 | |||
| 60 | #define NESTED_PATCHLEVEL0 PACKAGE_VERSION_PATCHLEVEL0 | |||
| 61 | ||||
| 62 | #define TIMER_CALLBACK_INTERVAL20 20 | |||
| 63 | ||||
| 64 | static MODULESETUPPROTO(NestedSetup)void *NestedSetup(void *, void *, int*, int*); | |||
| 65 | static void NestedIdentify(int flags); | |||
| 66 | static const OptionInfoRec *NestedAvailableOptions(int chipid, int busid); | |||
| 67 | static Bool NestedProbe(DriverPtr drv, int flags); | |||
| 68 | static Bool NestedDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, | |||
| 69 | pointer ptr); | |||
| 70 | ||||
| 71 | static Bool NestedPreInit(ScrnInfoPtr pScrn, int flags); | |||
| 72 | static Bool NestedScreenInit(SCREEN_INIT_ARGS_DECLScreenPtr pScreen, int argc, char **argv); | |||
| 73 | ||||
| 74 | static Bool NestedSwitchMode(SWITCH_MODE_ARGS_DECLScrnInfoPtr arg, DisplayModePtr mode); | |||
| 75 | static void NestedAdjustFrame(ADJUST_FRAME_ARGS_DECLScrnInfoPtr arg, int x, int y); | |||
| 76 | static Bool NestedEnterVT(VT_FUNC_ARGS_DECLScrnInfoPtr arg); | |||
| 77 | static void NestedLeaveVT(VT_FUNC_ARGS_DECLScrnInfoPtr arg); | |||
| 78 | static void NestedFreeScreen(FREE_SCREEN_ARGS_DECLScrnInfoPtr arg); | |||
| 79 | static ModeStatus NestedValidMode(SCRN_ARG_TYPEScrnInfoPtr arg, DisplayModePtr mode, | |||
| 80 | Bool verbose, int flags); | |||
| 81 | ||||
| 82 | static Bool NestedSaveScreen(ScreenPtr pScreen, int mode); | |||
| 83 | static Bool NestedCreateScreenResources(ScreenPtr pScreen); | |||
| 84 | ||||
| 85 | static void NestedShadowUpdate(ScreenPtr pScreen, shadowBufPtr pBuf); | |||
| 86 | static Bool NestedCloseScreen(CLOSE_SCREEN_ARGS_DECLScreenPtr pScreen); | |||
| 87 | ||||
| 88 | static void NestedBlockHandler(pointer data, OSTimePtr wt, pointer LastSelectMask); | |||
| 89 | static void NestedWakeupHandler(pointer data, int i, pointer LastSelectMask); | |||
| 90 | ||||
| 91 | int NestedValidateModes(ScrnInfoPtr pScrn); | |||
| 92 | Bool NestedAddMode(ScrnInfoPtr pScrn, int width, int height); | |||
| 93 | void NestedPrintPscreen(ScrnInfoPtr p); | |||
| 94 | void NestedPrintMode(ScrnInfoPtr p, DisplayModePtr m); | |||
| 95 | ||||
| 96 | typedef enum { | |||
| 97 | OPTION_DISPLAY, | |||
| 98 | OPTION_ORIGIN | |||
| 99 | } NestedOpts; | |||
| 100 | ||||
| 101 | typedef enum { | |||
| 102 | NESTED_CHIP | |||
| 103 | } NestedType; | |||
| 104 | ||||
| 105 | static SymTabRec NestedChipsets[] = { | |||
| 106 | { NESTED_CHIP, "nested" }, | |||
| 107 | {-1, NULL((void*)0) } | |||
| 108 | }; | |||
| 109 | ||||
| 110 | /* XXX: Shouldn't we allow NestedClient to define options too? If some day we | |||
| 111 | * port NestedClient to something that's not Xlib/Xcb we might need to add some | |||
| 112 | * custom options */ | |||
| 113 | static OptionInfoRec NestedOptions[] = { | |||
| 114 | { OPTION_DISPLAY, "Display", OPTV_STRING, {0}, FALSE0 }, | |||
| 115 | { OPTION_ORIGIN, "Origin", OPTV_STRING, {0}, FALSE0 }, | |||
| 116 | { -1, NULL((void*)0), OPTV_NONE, {0}, FALSE0 } | |||
| 117 | }; | |||
| 118 | ||||
| 119 | _X_EXPORT__attribute__((visibility("default"))) DriverRec NESTED = { | |||
| 120 | NESTED_VERSION0, | |||
| 121 | NESTED_DRIVER_NAME"nested", | |||
| 122 | NestedIdentify, | |||
| 123 | NestedProbe, | |||
| 124 | NestedAvailableOptions, | |||
| 125 | NULL((void*)0), /* module */ | |||
| 126 | 0, /* refCount */ | |||
| 127 | NestedDriverFunc, | |||
| 128 | NULL((void*)0), /* DeviceMatch */ | |||
| 129 | 0 /* PciProbe */ | |||
| 130 | }; | |||
| 131 | ||||
| 132 | _X_EXPORT__attribute__((visibility("default"))) InputDriverRec NESTEDINPUT = { | |||
| 133 | 1, | |||
| 134 | "nestedinput", | |||
| 135 | NULL((void*)0), | |||
| 136 | NestedInputPreInit, | |||
| 137 | NestedInputUnInit, | |||
| 138 | NULL((void*)0), | |||
| 139 | 0, | |||
| 140 | }; | |||
| 141 | ||||
| 142 | static XF86ModuleVersionInfo NestedVersRec = { | |||
| 143 | NESTED_DRIVER_NAME"nested", | |||
| 144 | MODULEVENDORSTRING"X.Org Foundation", | |||
| 145 | MODINFOSTRING10xef23fdc5, | |||
| 146 | MODINFOSTRING20x10dc023a, | |||
| 147 | XORG_VERSION_CURRENT(((1) * 10000000) + ((18) * 100000) + ((99) * 1000) + 1), | |||
| 148 | NESTED_MAJOR_VERSION0, | |||
| 149 | NESTED_MINOR_VERSION1, | |||
| 150 | NESTED_PATCHLEVEL0, | |||
| 151 | ABI_CLASS_VIDEODRV"X.Org Video Driver", | |||
| 152 | ABI_VIDEODRV_VERSION((((21) << 16) & 0xFFFF0000) | ((0) & 0x0000FFFF )), | |||
| 153 | MOD_CLASS_VIDEODRV"X.Org Video Driver", | |||
| 154 | {0, 0, 0, 0} /* checksum */ | |||
| 155 | }; | |||
| 156 | ||||
| 157 | _X_EXPORT__attribute__((visibility("default"))) XF86ModuleData nestedModuleData = { | |||
| 158 | &NestedVersRec, | |||
| 159 | NestedSetup, | |||
| 160 | NULL((void*)0), /* teardown */ | |||
| 161 | }; | |||
| 162 | ||||
| 163 | /* These stuff should be valid to all server generations */ | |||
| 164 | typedef struct NestedPrivate { | |||
| 165 | char *displayName; | |||
| 166 | int originX; | |||
| 167 | int originY; | |||
| 168 | NestedClientPrivatePtr clientData; | |||
| 169 | CreateScreenResourcesProcPtr CreateScreenResources; | |||
| 170 | CloseScreenProcPtr CloseScreen; | |||
| 171 | ShadowUpdateProc update; | |||
| 172 | } NestedPrivate, *NestedPrivatePtr; | |||
| 173 | ||||
| 174 | #define PNESTED(p)((NestedPrivatePtr)((p)->driverPrivate)) ((NestedPrivatePtr)((p)->driverPrivate)) | |||
| 175 | #define PCLIENTDATA(p)(((NestedPrivatePtr)((p)->driverPrivate))->clientData) (PNESTED(p)((NestedPrivatePtr)((p)->driverPrivate))->clientData) | |||
| 176 | ||||
| 177 | /*static ScrnInfoPtr NESTEDScrn;*/ | |||
| 178 | ||||
| 179 | static pointer | |||
| 180 | NestedSetup(pointer module, pointer opts, int *errmaj, int *errmin) { | |||
| 181 | static Bool setupDone = FALSE0; | |||
| 182 | ||||
| 183 | if (!setupDone) { | |||
| 184 | setupDone = TRUE1; | |||
| 185 | ||||
| 186 | xf86AddDriver(&NESTED, module, HaveDriverFuncs1); | |||
| 187 | xf86AddInputDriver(&NESTEDINPUT, module, 0); | |||
| 188 | ||||
| 189 | return (pointer)1; | |||
| 190 | } else { | |||
| 191 | if (errmaj) | |||
| 192 | *errmaj = LDR_ONCEONLY; | |||
| 193 | ||||
| 194 | return NULL((void*)0); | |||
| 195 | } | |||
| 196 | } | |||
| 197 | ||||
| 198 | static void | |||
| 199 | NestedIdentify(int flags) { | |||
| 200 | xf86PrintChipsets(NESTED_NAME"NESTED", "Driver for nested servers", | |||
| 201 | NestedChipsets); | |||
| 202 | } | |||
| 203 | ||||
| 204 | static const OptionInfoRec * | |||
| 205 | NestedAvailableOptions(int chipid, int busid) { | |||
| 206 | return NestedOptions; | |||
| 207 | } | |||
| 208 | ||||
| 209 | static Bool | |||
| 210 | NestedProbe(DriverPtr drv, int flags) { | |||
| 211 | Bool foundScreen = FALSE0; | |||
| 212 | int numDevSections; | |||
| 213 | GDevPtr *devSections; | |||
| 214 | int i; | |||
| 215 | ||||
| 216 | ScrnInfoPtr pScrn; | |||
| 217 | int entityIndex; | |||
| 218 | ||||
| 219 | if (flags & PROBE_DETECT0x01) | |||
| 220 | return FALSE0; | |||
| 221 | ||||
| 222 | if ((numDevSections = xf86MatchDevice(NESTED_DRIVER_NAME"nested", | |||
| 223 | &devSections)) <= 0) { | |||
| 224 | return FALSE0; | |||
| 225 | } | |||
| 226 | ||||
| 227 | if (numDevSections > 0) { | |||
| 228 | for(i = 0; i < numDevSections; i++) { | |||
| 229 | pScrn = NULL((void*)0); | |||
| 230 | entityIndex = xf86ClaimNoSlot(drv, NESTED_CHIP, devSections[i], | |||
| 231 | TRUE1); | |||
| 232 | pScrn = xf86AllocateScreen(drv, 0); | |||
| 233 | if (pScrn) { | |||
| 234 | xf86AddEntityToScreen(pScrn, entityIndex); | |||
| 235 | pScrn->driverVersion = NESTED_VERSION0; | |||
| 236 | pScrn->driverName = NESTED_DRIVER_NAME"nested"; | |||
| 237 | pScrn->name = NESTED_NAME"NESTED"; | |||
| 238 | pScrn->Probe = NestedProbe; | |||
| 239 | pScrn->PreInit = NestedPreInit; | |||
| 240 | pScrn->ScreenInit = NestedScreenInit; | |||
| 241 | pScrn->SwitchMode = NestedSwitchMode; | |||
| 242 | pScrn->AdjustFrame = NestedAdjustFrame; | |||
| 243 | pScrn->EnterVT = NestedEnterVT; | |||
| 244 | pScrn->LeaveVT = NestedLeaveVT; | |||
| 245 | pScrn->FreeScreen = NestedFreeScreen; | |||
| 246 | pScrn->ValidMode = NestedValidMode; | |||
| 247 | foundScreen = TRUE1; | |||
| 248 | } | |||
| 249 | } | |||
| 250 | } | |||
| 251 | ||||
| 252 | return foundScreen; | |||
| 253 | } | |||
| 254 | ||||
| 255 | #ifndef HW_SKIP_CONSOLE4 | |||
| 256 | #define HW_SKIP_CONSOLE4 4 | |||
| 257 | #endif | |||
| 258 | ||||
| 259 | static Bool | |||
| 260 | NestedDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) { | |||
| 261 | CARD32 *flag; | |||
| 262 | xf86Msg(X_INFO, "NestedDriverFunc\n"); | |||
| 263 | ||||
| 264 | /* XXX implement */ | |||
| 265 | switch(op) { | |||
| 266 | case GET_REQUIRED_HW_INTERFACES: | |||
| 267 | flag = (CARD32*)ptr; | |||
| 268 | (*flag) = HW_SKIP_CONSOLE4; | |||
| 269 | return TRUE1; | |||
| 270 | ||||
| 271 | case RR_GET_INFO: | |||
| 272 | case RR_SET_CONFIG: | |||
| 273 | case RR_GET_MODE_MM: | |||
| 274 | default: | |||
| 275 | return FALSE0; | |||
| 276 | } | |||
| 277 | } | |||
| 278 | ||||
| 279 | static Bool NestedAllocatePrivate(ScrnInfoPtr pScrn) { | |||
| 280 | if (pScrn->driverPrivate != NULL((void*)0)) { | |||
| 281 | xf86Msg(X_WARNING, "NestedAllocatePrivate called for an already " | |||
| 282 | "allocated private!\n"); | |||
| 283 | return FALSE0; | |||
| 284 | } | |||
| 285 | ||||
| 286 | pScrn->driverPrivate = xnfcalloc(sizeof(NestedPrivate), 1)XNFcallocarray((sizeof(NestedPrivate)), (1)); | |||
| 287 | if (pScrn->driverPrivate == NULL((void*)0)) | |||
| 288 | return FALSE0; | |||
| 289 | return TRUE1; | |||
| 290 | } | |||
| 291 | ||||
| 292 | static void NestedFreePrivate(ScrnInfoPtr pScrn) { | |||
| 293 | if (pScrn->driverPrivate == NULL((void*)0)) { | |||
| 294 | xf86DrvMsg(pScrn->scrnIndex, X_WARNING, | |||
| 295 | "Double freeing NestedPrivate!\n"); | |||
| 296 | return; | |||
| 297 | } | |||
| 298 | ||||
| 299 | free(pScrn->driverPrivate); | |||
| 300 | pScrn->driverPrivate = NULL((void*)0); | |||
| 301 | } | |||
| 302 | ||||
| 303 | /* Data from here is valid to all server generations */ | |||
| 304 | static Bool NestedPreInit(ScrnInfoPtr pScrn, int flags) { | |||
| 305 | NestedPrivatePtr pNested; | |||
| 306 | char *originString = NULL((void*)0); | |||
| 307 | ||||
| 308 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedPreInit\n"); | |||
| 309 | ||||
| 310 | if (flags & PROBE_DETECT0x01) | |||
| 311 | return FALSE0; | |||
| 312 | ||||
| 313 | if (!NestedAllocatePrivate(pScrn)) { | |||
| 314 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate private\n"); | |||
| 315 | return FALSE0; | |||
| 316 | } | |||
| 317 | ||||
| 318 | pNested = PNESTED(pScrn)((NestedPrivatePtr)((pScrn)->driverPrivate)); | |||
| 319 | ||||
| 320 | if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb0x01 | Support32bppFb0x02)) | |||
| 321 | return FALSE0; | |||
| 322 | ||||
| 323 | xf86PrintDepthBpp(pScrn); | |||
| 324 | ||||
| 325 | if (pScrn->depth > 8) { | |||
| 326 | rgb zeros = {0, 0, 0}; | |||
| 327 | if (!xf86SetWeight(pScrn, zeros, zeros)) { | |||
| 328 | return FALSE0; | |||
| 329 | } | |||
| 330 | } | |||
| 331 | ||||
| 332 | if (!xf86SetDefaultVisual(pScrn, -1)) | |||
| 333 | return FALSE0; | |||
| 334 | ||||
| 335 | pScrn->monitor = pScrn->confScreen->monitor; /* XXX */ | |||
| 336 | ||||
| 337 | xf86CollectOptions(pScrn, NULL((void*)0)); | |||
| 338 | xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, NestedOptions); | |||
| 339 | ||||
| 340 | if (xf86IsOptionSet(NestedOptions, OPTION_DISPLAY)) { | |||
| 341 | pNested->displayName = xf86GetOptValString(NestedOptions, | |||
| 342 | OPTION_DISPLAY); | |||
| 343 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using display \"%s\"\n", | |||
| 344 | pNested->displayName); | |||
| 345 | } else { | |||
| 346 | pNested->displayName = NULL((void*)0); | |||
| 347 | } | |||
| 348 | ||||
| 349 | if (xf86IsOptionSet(NestedOptions, OPTION_ORIGIN)) { | |||
| 350 | originString = xf86GetOptValString(NestedOptions, OPTION_ORIGIN); | |||
| 351 | if (sscanf(originString, "%d %d", &pNested->originX, | |||
| 352 | &pNested->originY) != 2) { | |||
| 353 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, | |||
| 354 | "Invalid value for option \"Origin\"\n"); | |||
| 355 | return FALSE0; | |||
| 356 | } | |||
| 357 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using origin x:%d y:%d\n", | |||
| 358 | pNested->originX, pNested->originY); | |||
| 359 | } else { | |||
| 360 | pNested->originX = 0; | |||
| 361 | pNested->originY = 0; | |||
| 362 | } | |||
| 363 | ||||
| 364 | xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); | |||
| 365 | ||||
| 366 | if (!NestedClientCheckDisplay(pNested->displayName)) { | |||
| 367 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Can't open display: %s\n", | |||
| 368 | pNested->displayName); | |||
| 369 | return FALSE0; | |||
| 370 | } | |||
| 371 | ||||
| 372 | if (!NestedClientValidDepth(pScrn->depth)) { | |||
| 373 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid depth: %d\n", | |||
| 374 | pScrn->depth); | |||
| 375 | return FALSE0; | |||
| 376 | } | |||
| 377 | ||||
| 378 | /*if (pScrn->depth > 1) { | |||
| 379 | Gamma zeros = {0.0, 0.0, 0.0}; | |||
| 380 | if (!xf86SetGamma(pScrn, zeros)) | |||
| 381 | return FALSE; | |||
| 382 | }*/ | |||
| 383 | ||||
| 384 | if (NestedValidateModes(pScrn) < 1) { | |||
| 385 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes\n"); | |||
| 386 | return FALSE0; | |||
| 387 | } | |||
| 388 | ||||
| 389 | ||||
| 390 | if (!pScrn->modes) { | |||
| 391 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); | |||
| 392 | return FALSE0; | |||
| 393 | } | |||
| 394 | xf86SetCrtcForModes(pScrn, 0); | |||
| 395 | ||||
| 396 | pScrn->currentMode = pScrn->modes; | |||
| 397 | ||||
| 398 | xf86SetDpi(pScrn, 0, 0); | |||
| 399 | ||||
| 400 | if (!xf86LoadSubModule(pScrn, "shadow")) | |||
| 401 | return FALSE0; | |||
| 402 | if (!xf86LoadSubModule(pScrn, "fb")) | |||
| 403 | return FALSE0; | |||
| 404 | ||||
| 405 | pScrn->memPhysBase = 0; | |||
| 406 | pScrn->fbOffset = 0; | |||
| 407 | ||||
| 408 | return TRUE1; | |||
| 409 | } | |||
| 410 | ||||
| 411 | int | |||
| 412 | NestedValidateModes(ScrnInfoPtr pScrn) { | |||
| 413 | DisplayModePtr mode; | |||
| 414 | int i, width, height, ret = 0; | |||
| 415 | int maxX = 0, maxY = 0; | |||
| 416 | ||||
| 417 | /* Print useless stuff */ | |||
| 418 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor wants these modes:\n"); | |||
| 419 | for(mode = pScrn->monitor->Modes; mode != NULL((void*)0); mode = mode->next) { | |||
| 420 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, " %s (%dx%d)\n", mode->name, | |||
| 421 | mode->HDisplay, mode->VDisplay); | |||
| 422 | } | |||
| 423 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Too bad for it...\n"); | |||
| 424 | ||||
| 425 | /* If user requested modes, add them. If not, use 640x480 */ | |||
| 426 | if (pScrn->display->modes != NULL((void*)0)) { | |||
| 427 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "User wants these modes:\n"); | |||
| 428 | for(i = 0; pScrn->display->modes[i] != NULL((void*)0); i++) { | |||
| 429 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, " %s\n", | |||
| 430 | pScrn->display->modes[i]); | |||
| 431 | if (sscanf(pScrn->display->modes[i], "%dx%d", &width, | |||
| 432 | &height) != 2) { | |||
| 433 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, | |||
| 434 | "This is not the mode name I was expecting...\n"); | |||
| 435 | return 0; | |||
| 436 | } | |||
| 437 | if (!NestedAddMode(pScrn, width, height)) { | |||
| 438 | return 0; | |||
| 439 | } | |||
| 440 | } | |||
| 441 | } else { | |||
| 442 | if (!NestedAddMode(pScrn, 640, 480)) { | |||
| 443 | return 0; | |||
| 444 | } | |||
| 445 | } | |||
| 446 | ||||
| 447 | pScrn->modePool = NULL((void*)0); | |||
| 448 | ||||
| 449 | /* Now set virtualX, virtualY, displayWidth and virtualFrom */ | |||
| 450 | ||||
| 451 | if (pScrn->display->virtualX >= pScrn->modes->HDisplay && | |||
| 452 | pScrn->display->virtualY >= pScrn->modes->VDisplay) { | |||
| 453 | pScrn->virtualX = pScrn->display->virtualX; | |||
| 454 | pScrn->virtualY = pScrn->display->virtualY; | |||
| 455 | } else { | |||
| 456 | /* XXX: if not specified, make virtualX and virtualY as big as the max X | |||
| 457 | * and Y. I'm not sure this is correct */ | |||
| 458 | mode = pScrn->modes; | |||
| 459 | while (mode != NULL((void*)0)) { | |||
| 460 | if (mode->HDisplay > maxX) | |||
| 461 | maxX = mode->HDisplay; | |||
| 462 | ||||
| 463 | if (mode->VDisplay > maxY) | |||
| 464 | maxY = mode->VDisplay; | |||
| 465 | ||||
| 466 | mode = mode->next; | |||
| 467 | } | |||
| 468 | pScrn->virtualX = maxX; | |||
| 469 | pScrn->virtualY = maxY; | |||
| 470 | } | |||
| 471 | pScrn->virtualFrom = X_DEFAULT; | |||
| 472 | pScrn->displayWidth = pScrn->virtualX; | |||
| 473 | ||||
| 474 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Virtual size: %dx%d\n", | |||
| 475 | pScrn->virtualX, pScrn->virtualY); | |||
| 476 | ||||
| 477 | /* Calculate the return value */ | |||
| 478 | mode = pScrn->modes; | |||
| 479 | while (mode != NULL((void*)0)) { | |||
| 480 | mode = mode->next; | |||
| 481 | ret++; | |||
| 482 | } | |||
| 483 | ||||
| 484 | /* Finally, make the mode list circular */ | |||
| 485 | pScrn->modes->prev->next = pScrn->modes; | |||
| 486 | ||||
| 487 | return ret; | |||
| 488 | } | |||
| 489 | ||||
| 490 | Bool | |||
| 491 | NestedAddMode(ScrnInfoPtr pScrn, int width, int height) { | |||
| 492 | DisplayModePtr mode; | |||
| 493 | char nameBuf[64]; | |||
| 494 | size_t len; | |||
| 495 | ||||
| 496 | if (snprintf(nameBuf, 64, "%dx%d", width, height)__builtin___snprintf_chk (nameBuf, 64, 0, __builtin_object_size (nameBuf, 2 > 1 ? 1 : 0), "%dx%d", width, height) >= 64) | |||
| 497 | return FALSE0; | |||
| 498 | ||||
| 499 | mode = XNFcalloc(sizeof(DisplayModeRec)); | |||
| 500 | mode->status = MODE_OK; | |||
| 501 | mode->type = M_T_DRIVER0x40; | |||
| 502 | mode->HDisplay = width; | |||
| 503 | mode->VDisplay = height; | |||
| 504 | ||||
| 505 | len = strlen(nameBuf); | |||
| 506 | mode->name = XNFalloc(len+1); | |||
| 507 | strcpy(mode->name, nameBuf)__builtin___strcpy_chk (mode->name, nameBuf, __builtin_object_size (mode->name, 2 > 1 ? 1 : 0)); | |||
| 508 | ||||
| 509 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Adding mode %s\n", mode->name); | |||
| 510 | ||||
| 511 | /* Now add mode to pScrn->modes. We'll keep the list non-circular for now, | |||
| 512 | * but we'll maintain pScrn->modes->prev to know the last element */ | |||
| 513 | mode->next = NULL((void*)0); | |||
| 514 | if (!pScrn->modes) { | |||
| 515 | pScrn->modes = mode; | |||
| 516 | mode->prev = mode; | |||
| 517 | } else { | |||
| 518 | mode->prev = pScrn->modes->prev; | |||
| 519 | pScrn->modes->prev->next = mode; | |||
| 520 | pScrn->modes->prev = mode; | |||
| 521 | } | |||
| 522 | ||||
| 523 | return TRUE1; | |||
| 524 | } | |||
| 525 | ||||
| 526 | // Wrapper for timed call to NestedInputLoadDriver. Used with timer in order | |||
| 527 | // to force the initialization to wait until the input core is initialized. | |||
| 528 | static CARD32 | |||
| 529 | NestedMouseTimer(OsTimerPtr timer, CARD32 time, pointer arg) { | |||
| 530 | NestedInputLoadDriver(arg); | |||
| 531 | return 0; | |||
| 532 | } | |||
| 533 | ||||
| 534 | static void | |||
| 535 | NestedBlockHandler(pointer data, OSTimePtr wt, pointer LastSelectMask) { | |||
| 536 | NestedClientPrivatePtr pNestedClient = data; | |||
| 537 | NestedClientCheckEvents(pNestedClient); | |||
| 538 | } | |||
| 539 | ||||
| 540 | static void | |||
| 541 | NestedWakeupHandler(pointer data, int i, pointer LastSelectMask) { | |||
| 542 | } | |||
| 543 | ||||
| 544 | /* Called at each server generation */ | |||
| 545 | static Bool NestedScreenInit(SCREEN_INIT_ARGS_DECLScreenPtr pScreen, int argc, char **argv) | |||
| 546 | { | |||
| 547 | ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); | |||
| 548 | NestedPrivatePtr pNested; | |||
| 549 | Pixel redMask, greenMask, blueMask; | |||
| 550 | ||||
| 551 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedScreenInit\n"); | |||
| 552 | ||||
| 553 | pNested = PNESTED(pScrn)((NestedPrivatePtr)((pScrn)->driverPrivate)); | |||
| 554 | /*NESTEDScrn = pScrn;*/ | |||
| 555 | ||||
| 556 | NestedPrintPscreen(pScrn); | |||
| 557 | ||||
| 558 | /* Save state: | |||
| 559 | * NestedSave(pScrn); */ | |||
| 560 | ||||
| 561 | //Load_Nested_Mouse(); | |||
| 562 | ||||
| 563 | pNested->clientData = NestedClientCreateScreen(pScrn->scrnIndex, | |||
| 564 | pNested->displayName, | |||
| 565 | pScrn->virtualX, | |||
| 566 | pScrn->virtualY, | |||
| 567 | pNested->originX, | |||
| 568 | pNested->originY, | |||
| 569 | pScrn->depth, | |||
| 570 | pScrn->bitsPerPixel, | |||
| 571 | &redMask, &greenMask, &blueMask); | |||
| 572 | ||||
| 573 | if (!pNested->clientData) { | |||
| 574 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to create client screen\n"); | |||
| 575 | return FALSE0; | |||
| 576 | } | |||
| 577 | ||||
| 578 | // Schedule the NestedInputLoadDriver function to load once the | |||
| 579 | // input core is initialized. | |||
| 580 | TimerSet(NULL((void*)0), 0, 1, NestedMouseTimer, pNested->clientData); | |||
| 581 | ||||
| 582 | miClearVisualTypes(); | |||
| 583 | if (!miSetVisualTypesAndMasks(pScrn->depth, | |||
| 584 | miGetDefaultVisualMask(pScrn->depth), | |||
| 585 | pScrn->rgbBits, pScrn->defaultVisual, | |||
| 586 | redMask, greenMask, blueMask)) | |||
| 587 | return FALSE0; | |||
| 588 | ||||
| 589 | if (!miSetPixmapDepths()) | |||
| 590 | return FALSE0; | |||
| 591 | ||||
| 592 | if (!fbScreenInit(pScreen, NestedClientGetFrameBuffer(PCLIENTDATA(pScrn)(((NestedPrivatePtr)((pScrn)->driverPrivate))->clientData )), | |||
| 593 | pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, | |||
| 594 | pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel)) | |||
| 595 | return FALSE0; | |||
| 596 | ||||
| 597 | fbPictureInit(pScreen, 0, 0); | |||
| 598 | ||||
| 599 | xf86SetBlackWhitePixels(pScreen); | |||
| 600 | xf86SetBackingStore(pScreen); | |||
| 601 | miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); | |||
| 602 | ||||
| 603 | if (!miCreateDefColormap(pScreen)) | |||
| 604 | return FALSE0; | |||
| 605 | ||||
| 606 | pNested->update = NestedShadowUpdate; | |||
| 607 | pScreen->SaveScreen = NestedSaveScreen; | |||
| 608 | ||||
| 609 | if (!shadowSetup(pScreen)) | |||
| 610 | return FALSE0; | |||
| 611 | ||||
| 612 | pNested->CreateScreenResources = pScreen->CreateScreenResources; | |||
| 613 | pScreen->CreateScreenResources = NestedCreateScreenResources; | |||
| 614 | ||||
| 615 | pNested->CloseScreen = pScreen->CloseScreen; | |||
| 616 | pScreen->CloseScreen = NestedCloseScreen; | |||
| 617 | ||||
| 618 | RegisterBlockAndWakeupHandlers(NestedBlockHandler, NestedWakeupHandler, pNested->clientData); | |||
| 619 | ||||
| 620 | return TRUE1; | |||
| 621 | } | |||
| 622 | ||||
| 623 | static Bool | |||
| 624 | NestedCreateScreenResources(ScreenPtr pScreen) { | |||
| 625 | xf86DrvMsg(pScreen->myNum, X_INFO, "NestedCreateScreenResources\n"); | |||
| 626 | ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); | |||
| 627 | NestedPrivatePtr pNested = PNESTED(pScrn)((NestedPrivatePtr)((pScrn)->driverPrivate)); | |||
| 628 | Bool ret; | |||
| 629 | ||||
| 630 | pScreen->CreateScreenResources = pNested->CreateScreenResources; | |||
| 631 | ret = pScreen->CreateScreenResources(pScreen); | |||
| 632 | pScreen->CreateScreenResources = NestedCreateScreenResources; | |||
| 633 | ||||
| 634 | if(!shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), | |||
| 635 | pNested->update, NULL((void*)0), 0, 0)) { | |||
| 636 | xf86DrvMsg(pScreen->myNum, X_ERROR, "NestedCreateScreenResources failed to shadowAdd.\n"); | |||
| 637 | return FALSE0; | |||
| 638 | } | |||
| 639 | ||||
| 640 | return ret; | |||
| 641 | } | |||
| 642 | ||||
| 643 | static void | |||
| 644 | NestedShadowUpdate(ScreenPtr pScreen, shadowBufPtr pBuf) { | |||
| 645 | RegionPtr pRegion = DamageRegion(pBuf->pDamage); | |||
| 646 | NestedClientUpdateScreen(PCLIENTDATA(xf86ScreenToScrn(pScreen))(((NestedPrivatePtr)((xf86ScreenToScrn(pScreen))->driverPrivate ))->clientData), | |||
| 647 | pRegion->extents.x1, pRegion->extents.y1, | |||
| 648 | pRegion->extents.x2, pRegion->extents.y2); | |||
| 649 | } | |||
| 650 | ||||
| 651 | static Bool | |||
| 652 | NestedCloseScreen(CLOSE_SCREEN_ARGS_DECLScreenPtr pScreen) { | |||
| 653 | ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); | |||
| 654 | ||||
| 655 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedCloseScreen\n"); | |||
| 656 | ||||
| 657 | shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); | |||
| 658 | ||||
| 659 | RemoveBlockAndWakeupHandlers(NestedBlockHandler, NestedWakeupHandler, PNESTED(pScrn)((NestedPrivatePtr)((pScrn)->driverPrivate))->clientData); | |||
| 660 | NestedClientCloseScreen(PCLIENTDATA(pScrn)(((NestedPrivatePtr)((pScrn)->driverPrivate))->clientData )); | |||
| 661 | ||||
| 662 | pScreen->CloseScreen = PNESTED(pScrn)((NestedPrivatePtr)((pScrn)->driverPrivate))->CloseScreen; | |||
| 663 | return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGSpScreen); | |||
| 664 | } | |||
| 665 | ||||
| 666 | static Bool NestedSaveScreen(ScreenPtr pScreen, int mode) { | |||
| 667 | xf86DrvMsg(pScreen->myNum, X_INFO, "NestedSaveScreen\n"); | |||
| 668 | return TRUE1; | |||
| 669 | } | |||
| 670 | ||||
| 671 | static Bool NestedSwitchMode(SWITCH_MODE_ARGS_DECLScrnInfoPtr arg, DisplayModePtr mode) { | |||
| 672 | SCRN_INFO_PTR(arg)ScrnInfoPtr pScrn = (arg); | |||
| 673 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedSwitchMode\n"); | |||
| 674 | return TRUE1; | |||
| 675 | } | |||
| 676 | ||||
| 677 | static void NestedAdjustFrame(ADJUST_FRAME_ARGS_DECLScrnInfoPtr arg, int x, int y) { | |||
| 678 | SCRN_INFO_PTR(arg)ScrnInfoPtr pScrn = (arg); | |||
| 679 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedAdjustFrame\n"); | |||
| 680 | } | |||
| 681 | ||||
| 682 | static Bool NestedEnterVT(VT_FUNC_ARGS_DECLScrnInfoPtr arg) { | |||
| 683 | SCRN_INFO_PTR(arg)ScrnInfoPtr pScrn = (arg); | |||
| 684 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedEnterVT\n"); | |||
| 685 | return TRUE1; | |||
| 686 | } | |||
| 687 | ||||
| 688 | static void NestedLeaveVT(VT_FUNC_ARGS_DECLScrnInfoPtr arg) { | |||
| 689 | SCRN_INFO_PTR(arg)ScrnInfoPtr pScrn = (arg); | |||
| 690 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedLeaveVT\n"); | |||
| 691 | } | |||
| 692 | ||||
| 693 | static void NestedFreeScreen(FREE_SCREEN_ARGS_DECLScrnInfoPtr arg) { | |||
| 694 | SCRN_INFO_PTR(arg)ScrnInfoPtr pScrn = (arg); | |||
| 695 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedFreeScreen\n"); | |||
| 696 | } | |||
| 697 | ||||
| 698 | static ModeStatus NestedValidMode(SCRN_ARG_TYPEScrnInfoPtr arg, DisplayModePtr mode, | |||
| 699 | Bool verbose, int flags) { | |||
| 700 | SCRN_INFO_PTR(arg)ScrnInfoPtr pScrn = (arg); | |||
| 701 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedValidMode:\n"); | |||
| 702 | ||||
| 703 | if (!mode) | |||
| ||||
| 704 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "NULL MODE!\n"); | |||
| 705 | ||||
| 706 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, " name: %s\n", mode->name); | |||
| ||||
| 707 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, " HDisplay: %d\n", mode->HDisplay); | |||
| 708 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, " VDisplay: %d\n", mode->VDisplay); | |||
| 709 | return MODE_OK; | |||
| 710 | } | |||
| 711 | ||||
| 712 | void NestedPrintPscreen(ScrnInfoPtr p) { | |||
| 713 | /* XXX: finish implementing this someday? */ | |||
| 714 | xf86DrvMsg(p->scrnIndex, X_INFO, "Printing pScrn:\n"); | |||
| 715 | xf86DrvMsg(p->scrnIndex, X_INFO, "driverVersion: %d\n", p->driverVersion); | |||
| 716 | xf86DrvMsg(p->scrnIndex, X_INFO, "driverName: %s\n", p->driverName); | |||
| 717 | xf86DrvMsg(p->scrnIndex, X_INFO, "pScreen: %p\n", p->pScreen); | |||
| 718 | xf86DrvMsg(p->scrnIndex, X_INFO, "scrnIndex: %d\n", p->scrnIndex); | |||
| 719 | xf86DrvMsg(p->scrnIndex, X_INFO, "configured: %d\n", p->configured); | |||
| 720 | xf86DrvMsg(p->scrnIndex, X_INFO, "origIndex: %d\n", p->origIndex); | |||
| 721 | xf86DrvMsg(p->scrnIndex, X_INFO, "imageByteOrder: %d\n", p->imageByteOrder); | |||
| 722 | /*xf86DrvMsg(p->scrnIndex, X_INFO, "bitmapScanlineUnit: %d\n"); | |||
| 723 | xf86DrvMsg(p->scrnIndex, X_INFO, "bitmapScanlinePad: %d\n"); | |||
| 724 | xf86DrvMsg(p->scrnIndex, X_INFO, "bitmapBitOrder: %d\n"); | |||
| 725 | xf86DrvMsg(p->scrnIndex, X_INFO, "numFormats: %d\n"); | |||
| 726 | xf86DrvMsg(p->scrnIndex, X_INFO, "formats[]: 0x%x\n"); | |||
| 727 | xf86DrvMsg(p->scrnIndex, X_INFO, "fbFormat: 0x%x\n"); */ | |||
| 728 | xf86DrvMsg(p->scrnIndex, X_INFO, "bitsPerPixel: %d\n", p->bitsPerPixel); | |||
| 729 | /*xf86DrvMsg(p->scrnIndex, X_INFO, "pixmap24: 0x%x\n"); */ | |||
| 730 | xf86DrvMsg(p->scrnIndex, X_INFO, "depth: %d\n", p->depth); | |||
| 731 | NestedPrintMode(p, p->currentMode); | |||
| 732 | /*xf86DrvMsg(p->scrnIndex, X_INFO, "depthFrom: %\n"); | |||
| 733 | xf86DrvMsg(p->scrnIndex, X_INFO, "\n");*/ | |||
| 734 | } | |||
| 735 | ||||
| 736 | void NestedPrintMode(ScrnInfoPtr p, DisplayModePtr m) { | |||
| 737 | xf86DrvMsg(p->scrnIndex, X_INFO, "HDisplay %d\n", m->HDisplay); | |||
| 738 | xf86DrvMsg(p->scrnIndex, X_INFO, "HSyncStart %d\n", m->HSyncStart); | |||
| 739 | xf86DrvMsg(p->scrnIndex, X_INFO, "HSyncEnd %d\n", m->HSyncEnd); | |||
| 740 | xf86DrvMsg(p->scrnIndex, X_INFO, "HTotal %d\n", m->HTotal); | |||
| 741 | xf86DrvMsg(p->scrnIndex, X_INFO, "HSkew %d\n", m->HSkew); | |||
| 742 | xf86DrvMsg(p->scrnIndex, X_INFO, "VDisplay %d\n", m->VDisplay); | |||
| 743 | xf86DrvMsg(p->scrnIndex, X_INFO, "VSyncStart %d\n", m->VSyncStart); | |||
| 744 | xf86DrvMsg(p->scrnIndex, X_INFO, "VSyncEnd %d\n", m->VSyncEnd); | |||
| 745 | xf86DrvMsg(p->scrnIndex, X_INFO, "VTotal %d\n", m->VTotal); | |||
| 746 | xf86DrvMsg(p->scrnIndex, X_INFO, "VScan %d\n", m->VScan); | |||
| 747 | } |