crime_driver.c revision c59a3c9d
1/* $NetBSD: crime_driver.c,v 1.8 2010/11/24 02:54:07 mrg Exp $ */ 2/* 3 * Copyright (c) 2008 Michael Lorenz 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 32/* a driver for the CRIME rendering engine foundin SGI O2 workstations */ 33 34#ifdef HAVE_CONFIG_H 35#include "config.h" 36#endif 37 38#include <fcntl.h> 39#include <errno.h> 40#include <sys/types.h> 41#include <sys/time.h> 42#include <sys/mman.h> 43#include <dev/wscons/wsconsio.h> 44 45/* all driver need this */ 46#include "xf86.h" 47#include "xf86_OSproc.h" 48 49#include "mipointer.h" 50#include "mibstore.h" 51#include "micmap.h" 52#include "colormapst.h" 53#include "xf86cmap.h" 54 55/* for visuals */ 56#include "fb.h" 57 58#include "xf86Resources.h" 59#include "xf86RAC.h" 60 61#ifdef XvExtension 62#include "xf86xv.h" 63#endif 64 65#include "crime.h" 66 67/* #include "wsconsio.h" */ 68 69#ifndef XFree86LOADER 70#include <sys/mman.h> 71#endif 72 73#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 6 74#define xf86LoaderReqSymLists(...) do {} while (0) 75#define LoaderRefSymLists(...) do {} while (0) 76#endif 77 78#define CRIME_DEFAULT_DEV "/dev/ttyE0" 79 80/* Prototypes */ 81#ifdef XFree86LOADER 82static pointer CrimeSetup(pointer, pointer, int *, int *); 83#endif 84static Bool CrimeGetRec(ScrnInfoPtr); 85static void CrimeFreeRec(ScrnInfoPtr); 86static const OptionInfoRec * CrimeAvailableOptions(int, int); 87static void CrimeIdentify(int); 88static Bool CrimeProbe(DriverPtr, int); 89static Bool CrimePreInit(ScrnInfoPtr, int); 90static Bool CrimeScreenInit(int, ScreenPtr, int, char **); 91static Bool CrimeCloseScreen(int, ScreenPtr); 92static Bool CrimeEnterVT(int, int); 93static void CrimeLeaveVT(int, int); 94static Bool CrimeSwitchMode(int, DisplayModePtr, int); 95static int CrimeValidMode(int, DisplayModePtr, Bool, int); 96static void CrimeLoadPalette(ScrnInfoPtr, int, int *, LOCO *, VisualPtr); 97static Bool CrimeSaveScreen(ScreenPtr, int); 98static void CrimeSave(ScrnInfoPtr); 99static void CrimeRestore(ScrnInfoPtr); 100 101/* helper functions */ 102static int crime_open(char *); 103static pointer crime_mmap(size_t, off_t, int, int); 104 105/* 106 * This is intentionally screen-independent. It indicates the binding 107 * choice made in the first PreInit. 108 */ 109static int pix24bpp = 0; 110 111#define VERSION 4000 112#define CRIME_NAME "crime" 113#define CRIME_DRIVER_NAME "crime" 114#define CRIME_MAJOR_VERSION 0 115#define CRIME_MINOR_VERSION 1 116 117DriverRec CRIME = { 118 VERSION, 119 CRIME_DRIVER_NAME, 120 CrimeIdentify, 121 CrimeProbe, 122 CrimeAvailableOptions, 123 NULL, 124 0 125}; 126 127/* Supported "chipsets" */ 128static SymTabRec CrimeChipsets[] = { 129 { 0, "crime" }, 130 { -1, NULL } 131}; 132 133/* Supported options */ 134typedef enum { 135 OPTION_HW_CURSOR, 136 OPTION_SW_CURSOR 137} CrimeOpts; 138 139static const OptionInfoRec CrimeOptions[] = { 140 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 141 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 142 { -1, NULL, OPTV_NONE, {0}, FALSE} 143}; 144 145/* Symbols needed from other modules */ 146static const char *fbSymbols[] = { 147 "fbPictureInit", 148 "fbScreenInit", 149 NULL 150}; 151 152static const char *xaaSymbols[] = 153{ 154 "XAACreateInfoRec", 155 "XAADestroyInfoRec", 156 "XAAInit", 157 "XAAScreenIndex", 158 NULL 159}; 160 161static const char *ramdacSymbols[] = { 162 "xf86CreateCursorInfoRec", 163 "xf86DestroyCursorInfoRec", 164 "xf86InitCursor", 165 NULL 166}; 167 168#ifdef XFree86LOADER 169static XF86ModuleVersionInfo CrimeVersRec = { 170 "crime", 171 MODULEVENDORSTRING, 172 MODINFOSTRING1, 173 MODINFOSTRING2, 174 XORG_VERSION_CURRENT, 175 CRIME_MAJOR_VERSION, CRIME_MINOR_VERSION, 0, 176 ABI_CLASS_VIDEODRV, 177 ABI_VIDEODRV_VERSION, 178 NULL, 179 {0, 0, 0, 0} 180}; 181 182_X_EXPORT XF86ModuleData crimeModuleData = { &CrimeVersRec, CrimeSetup, NULL }; 183 184static pointer 185CrimeSetup(pointer module, pointer opts, int *errmaj, int *errmin) 186{ 187 static Bool setupDone = FALSE; 188 const char *osname; 189 190 /* Check that we're being loaded on a OpenBSD or NetBSD system */ 191 LoaderGetOS(&osname, NULL, NULL, NULL); 192 if (!osname 193 && (strcmp(osname, "netbsd") != 0)) { 194 if (errmaj) 195 *errmaj = LDR_BADOS; 196 if (errmin) 197 *errmin = 0; 198 return NULL; 199 } 200 if (!setupDone) { 201 setupDone = TRUE; 202 xf86AddDriver(&CRIME, module, 0); 203 LoaderRefSymLists(xaaSymbols, fbSymbols, NULL); 204 return (pointer)1; 205 } else { 206 if (errmaj != NULL) 207 *errmaj = LDR_ONCEONLY; 208 return NULL; 209 } 210} 211#endif /* XFree86LOADER */ 212 213static Bool 214CrimeGetRec(ScrnInfoPtr pScrn) 215{ 216 217 if (pScrn->driverPrivate != NULL) 218 return TRUE; 219 220 pScrn->driverPrivate = xnfcalloc(sizeof(CrimeRec), 1); 221 return TRUE; 222} 223 224static void 225CrimeFreeRec(ScrnInfoPtr pScrn) 226{ 227 228 if (pScrn->driverPrivate == NULL) 229 return; 230 xfree(pScrn->driverPrivate); 231 pScrn->driverPrivate = NULL; 232} 233 234static const OptionInfoRec * 235CrimeAvailableOptions(int chipid, int busid) 236{ 237 return CrimeOptions; 238} 239 240static void 241CrimeIdentify(int flags) 242{ 243 xf86PrintChipsets(CRIME_NAME, "driver for CRIME framebuffer", 244 CrimeChipsets); 245} 246 247 248#define priv_open_device(n) open(n,O_RDWR|O_NONBLOCK|O_EXCL) 249 250/* Open the framebuffer device */ 251static int 252crime_open(char *dev) 253{ 254 int fd = -1; 255 256 /* try argument from XF86Config first */ 257 if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) { 258 /* second: environment variable */ 259 dev = getenv("XDEVICE"); 260 if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) { 261 /* last try: default device */ 262 dev = CRIME_DEFAULT_DEV; 263 if ((fd = priv_open_device(dev)) == -1) { 264 return -1; 265 } 266 } 267 } 268 return fd; 269} 270 271/* Map the framebuffer's memory */ 272static pointer 273crime_mmap(size_t len, off_t off, int fd, int ro) 274{ 275 pointer mapaddr; 276 277 /* 278 * try and make it private first, that way once we get it, an 279 * interloper, e.g. another server, can't get this frame buffer, 280 * and if another server already has it, this one won't. 281 */ 282 if (ro) { 283 mapaddr = (pointer) mmap(NULL, len, 284 PROT_READ, MAP_SHARED, 285 fd, off); 286 xf86Msg(X_ERROR, "mapping %08x read only\n", off); 287 } else { 288 mapaddr = (pointer) mmap(NULL, len, 289 PROT_READ | PROT_WRITE, MAP_SHARED, 290 fd, off); 291 xf86Msg(X_ERROR, "mapping %08x read/write\n", off); 292 } 293 if (mapaddr == (pointer) -1) { 294 mapaddr = NULL; 295 } 296#ifdef CRIME_DEBUG 297 ErrorF("mmap returns: addr %p len 0x%x\n", mapaddr, len); 298#endif 299 return mapaddr; 300} 301 302static Bool 303CrimeProbe(DriverPtr drv, int flags) 304{ 305 ScrnInfoPtr pScrn = NULL; 306 int i, fd, entity, wstype; 307 GDevPtr *devSections; 308 int numDevSections; 309 char *dev; 310 Bool foundScreen = FALSE; 311 312 if ((numDevSections = xf86MatchDevice(CRIME_DRIVER_NAME, 313 &devSections)) <= 0) 314 return FALSE; 315 316 317 if ((fd = crime_open(CRIME_DEFAULT_DEV)) == 0) 318 return FALSE; 319 320 if (ioctl(fd, WSDISPLAYIO_GTYPE, &wstype) == -1) 321 return FALSE; 322 if (wstype != WSDISPLAY_TYPE_CRIME) 323 return FALSE; 324 325 xf86Msg(X_INFO, "%s: CRIME found\n", __func__); 326 327 if ( xf86DoConfigure && xf86DoConfigurePass1 ) { 328 GDevPtr pGDev; 329 330 pGDev = xf86AddBusDeviceToConfigure(CRIME_DRIVER_NAME, BUS_NONE, 331 NULL, 0); 332 if (pGDev) { 333 /* 334 * XF86Match???Instances() treat chipID and chipRev as 335 * overrides, so clobber them here. 336 */ 337 pGDev->chipID = pGDev->chipRev = -1; 338 } 339 } 340 341 if (flags & PROBE_DETECT) { 342 return TRUE; 343 } 344 345 if (numDevSections > 1) { 346 xf86Msg(X_ERROR, "Ignoring additional device sections\n"); 347 numDevSections = 1; 348 } 349 /* ok, at this point we know we've got a CRIME */ 350 for (i = 0; i < numDevSections; i++) { 351 352 entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); 353 pScrn = xf86ConfigFbEntity(NULL, 0, entity, 354 NULL, NULL, NULL, NULL); 355 if (pScrn != NULL) { 356 foundScreen = TRUE; 357 pScrn->driverVersion = VERSION; 358 pScrn->driverName = CRIME_DRIVER_NAME; 359 pScrn->name = CRIME_NAME; 360 pScrn->Probe = CrimeProbe; 361 pScrn->PreInit = CrimePreInit; 362 pScrn->ScreenInit = CrimeScreenInit; 363 pScrn->SwitchMode = CrimeSwitchMode; 364 pScrn->AdjustFrame = NULL; 365 pScrn->EnterVT = CrimeEnterVT; 366 pScrn->LeaveVT = CrimeLeaveVT; 367 pScrn->ValidMode = CrimeValidMode; 368 369 } 370 } 371 xfree(devSections); 372 return foundScreen; 373} 374 375static Bool 376CrimePreInit(ScrnInfoPtr pScrn, int flags) 377{ 378 CrimePtr fPtr; 379 int default_depth, wstype; 380 char *dev; 381 char *mod = NULL; 382 const char *reqSym = NULL; 383 Gamma zeros = {0.0, 0.0, 0.0}; 384 DisplayModePtr mode; 385 MessageType from; 386 rgb rgbzeros = { 0, 0, 0 }, masks; 387 388 if (flags & PROBE_DETECT) return FALSE; 389 390 if (pScrn->numEntities != 1) return FALSE; 391 392 pScrn->monitor = pScrn->confScreen->monitor; 393 394 CrimeGetRec(pScrn); 395 fPtr = CRIMEPTR(pScrn); 396 397 fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 398 399 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 400 pScrn->racIoFlags = pScrn->racMemFlags; 401 402 dev = xf86FindOptionValue(fPtr->pEnt->device->options, "device"); 403 fPtr->fd = crime_open(dev); 404 if (fPtr->fd == -1) { 405 return FALSE; 406 } 407 408 if (ioctl(fPtr->fd, WSDISPLAYIO_GINFO, &fPtr->info) == -1) { 409 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 410 "ioctl WSDISPLAY_GINFO: %s\n", 411 strerror(errno)); 412 return FALSE; 413 } 414 if (ioctl(fPtr->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) { 415 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 416 "ioctl WSDISPLAY_GTYPE: %s\n", 417 strerror(errno)); 418 return FALSE; 419 } 420 421 /* Handle depth */ 422 default_depth = fPtr->info.depth <= 24 ? fPtr->info.depth : 24; 423 if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, 424 fPtr->info.depth, Support24bppFb|Support32bppFb)) 425 return FALSE; 426 xf86PrintDepthBpp(pScrn); 427 428 /* Get the depth24 pixmap format */ 429 if (pScrn->depth == 24 && pix24bpp == 0) 430 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 431 432 /* color weight */ 433 masks.red = 0x00ff0000; 434 masks.green = 0x0000ff00; 435 masks.blue = 0x000000ff; 436 if (!xf86SetWeight(pScrn, rgbzeros, masks)) 437 return FALSE; 438 439 /* visual init */ 440 if (!xf86SetDefaultVisual(pScrn, -1)) 441 return FALSE; 442 443 /* We don't currently support DirectColor at > 8bpp */ 444 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 445 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 446 " (%s) is not supported at depth %d\n", 447 xf86GetVisualName(pScrn->defaultVisual), 448 pScrn->depth); 449 return FALSE; 450 } 451 452 xf86SetGamma(pScrn,zeros); 453 454 pScrn->progClock = TRUE; 455 pScrn->rgbBits = 8; 456 pScrn->chipset = "crime"; 457 pScrn->videoRam = fPtr->info.width * 4 * 2048; 458 459 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n", 460 pScrn->videoRam/1024); 461 462 /* handle options */ 463 xf86CollectOptions(pScrn, NULL); 464 if (!(fPtr->Options = xalloc(sizeof(CrimeOptions)))) 465 return FALSE; 466 memcpy(fPtr->Options, CrimeOptions, sizeof(CrimeOptions)); 467 xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, 468 fPtr->Options); 469 470 /* fake video mode struct */ 471 mode = (DisplayModePtr)xalloc(sizeof(DisplayModeRec)); 472 mode->prev = mode; 473 mode->next = mode; 474 mode->name = "crime current mode"; 475 mode->status = MODE_OK; 476 mode->type = M_T_BUILTIN; 477 mode->Clock = 0; 478 mode->HDisplay = fPtr->info.width; 479 mode->HSyncStart = 0; 480 mode->HSyncEnd = 0; 481 mode->HTotal = 0; 482 mode->HSkew = 0; 483 mode->VDisplay = fPtr->info.height; 484 mode->VSyncStart = 0; 485 mode->VSyncEnd = 0; 486 mode->VTotal = 0; 487 mode->VScan = 0; 488 mode->Flags = 0; 489 if (pScrn->modes != NULL) { 490 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 491 "Ignoring mode specification from screen section\n"); 492 } 493 pScrn->currentMode = pScrn->modes = mode; 494 pScrn->virtualX = fPtr->info.width; 495 pScrn->virtualY = fPtr->info.height; 496 pScrn->displayWidth = pScrn->virtualX; 497 498 /* Set the display resolution */ 499 xf86SetDpi(pScrn, 0, 0); 500 501 from = X_DEFAULT; 502 fPtr->HWCursor = TRUE; 503 if (xf86GetOptValBool(fPtr->Options, OPTION_HW_CURSOR, &fPtr->HWCursor)) 504 from = X_CONFIG; 505 if (xf86ReturnOptValBool(fPtr->Options, OPTION_SW_CURSOR, FALSE)) { 506 from = X_CONFIG; 507 fPtr->HWCursor = FALSE; 508 } 509 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 510 fPtr->HWCursor ? "HW" : "SW"); 511 512 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 513 CrimeFreeRec(pScrn); 514 return FALSE; 515 } 516 xf86LoaderReqSymLists(fbSymbols, NULL); 517 518 if (xf86LoadSubModule(pScrn, "xaa") == NULL) { 519 PnozzFreeRec(pScrn); 520 return FALSE; 521 } 522 xf86LoaderReqSymLists(xaaSymbols, NULL); 523 524 if (xf86LoadSubModule(pScrn, "ramdac") == NULL) { 525 CrimeFreeRec(pScrn); 526 return FALSE; 527 } 528 xf86LoaderReqSymLists(ramdacSymbols, NULL); 529 530 return TRUE; 531} 532 533static Bool 534CrimeScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 535{ 536 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 537 CrimePtr fPtr = CRIMEPTR(pScrn); 538 VisualPtr visual; 539 int ret, flags, width, height, i, j; 540 int wsmode = WSDISPLAYIO_MODE_DUMBFB; 541 size_t len; 542 543#ifdef CRIME_DEBUG 544 ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" 545 "\tmask: %x,%x,%x, offset: %d,%d,%d\n", 546 pScrn->bitsPerPixel, 547 pScrn->depth, 548 xf86GetVisualName(pScrn->defaultVisual), 549 pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, 550 pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); 551#endif 552 553 /* Switch to graphics mode - required before mmap */ 554 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { 555 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 556 "ioctl WSDISPLAYIO_SMODE: %s\n", 557 strerror(errno)); 558 return FALSE; 559 } 560 fPtr->engine = crime_mmap(0x5000, 0x15000000, fPtr->fd, 0); 561 562 if (fPtr->engine == NULL) { 563 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 564 "crime_mmap engine: %s\n", strerror(errno)); 565 return FALSE; 566 } 567 568 fPtr->linear = crime_mmap(0x10000, 0x15010000, fPtr->fd, 0); 569 if (fPtr->linear == NULL) { 570 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 571 "crime_mmap linear: %s\n", strerror(errno)); 572 return FALSE; 573 } 574 575 memset(fPtr->linear, 0, 0x10000); 576#ifdef CRIME_DEBUG 577 fPtr->fb = crime_mmap(8192 * fPtr->info.height, 0, fPtr->fd, 1); 578 if (fPtr->fb == NULL) { 579 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 580 "crime_mmap fb: %s\n", strerror(errno)); 581 return FALSE; 582 } 583#else 584 fPtr->fb = malloc(8192 * fPtr->info.height); 585 if (fPtr->fb == NULL) { 586 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 587 "Cannot allocate fake fb: %s\n", strerror(errno)); 588 return FALSE; 589 } 590#endif 591 592 CrimeSave(pScrn); 593 pScrn->vtSema = TRUE; 594 595 /* mi layer */ 596 miClearVisualTypes(); 597 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 598 pScrn->rgbBits, TrueColor)) 599 return FALSE; 600 601 if (!miSetPixmapDepths()) 602 return FALSE; 603 604 height = pScrn->virtualY; 605 width = pScrn->virtualX; 606 607 ret = fbScreenInit(pScreen, 608 fPtr->fb, 609 width, height, 610 pScrn->xDpi, pScrn->yDpi, 611 pScrn->displayWidth, 612 pScrn->bitsPerPixel); 613 614 if (!ret) 615 return FALSE; 616 617 /* Fixup RGB ordering */ 618 visual = pScreen->visuals + pScreen->numVisuals; 619 while (--visual >= pScreen->visuals) { 620 if ((visual->class | DynamicClass) == DirectColor) { 621 visual->offsetRed = pScrn->offset.red; 622 visual->offsetGreen = pScrn->offset.green; 623 visual->offsetBlue = pScrn->offset.blue; 624 visual->redMask = pScrn->mask.red; 625 visual->greenMask = pScrn->mask.green; 626 visual->blueMask = pScrn->mask.blue; 627 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 628 "%d %d %d %08x %08x %08x\n", 629 visual->offsetRed, visual->offsetGreen, 630 visual->offsetBlue, visual->redMask, 631 visual->greenMask, visual->blueMask); 632 } 633 } 634 635 if (!fbPictureInit(pScreen, NULL, 0)) 636 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 637 "RENDER extension initialisation failed."); 638 639 xf86SetBlackWhitePixels(pScreen); 640 miInitializeBackingStore(pScreen); 641 xf86SetBackingStore(pScreen); 642 643 if (fPtr) { 644 BoxRec bx; 645 fPtr->pXAA = XAACreateInfoRec(); 646 CrimeAccelInit(pScrn); 647 bx.x1 = bx.y1 = 0; 648 bx.x2 = fPtr->info.width; 649 bx.y2 = 2048; 650 xf86InitFBManager(pScreen, &bx); 651 if(!XAAInit(pScreen, fPtr->pXAA)) 652 return FALSE; 653 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using acceleration\n"); 654 } 655 656 /* software cursor */ 657 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 658 659 /* check for hardware cursor support */ 660 CrimeSetupCursor(pScreen); 661 662 /* colormap */ 663 if (!miCreateDefColormap(pScreen)) 664 return FALSE; 665 flags = CMAP_RELOAD_ON_MODE_SWITCH; 666 if(!xf86HandleColormaps(pScreen, 256, 8, CrimeLoadPalette, 667 NULL, flags)) 668 return FALSE; 669 670 pScreen->SaveScreen = CrimeSaveScreen; 671 672#ifdef XvExtension 673 { 674 XF86VideoAdaptorPtr *ptr; 675 676 int n = xf86XVListGenericAdaptors(pScrn,&ptr); 677 if (n) { 678 xf86XVScreenInit(pScreen,ptr,n); 679 } 680 } 681#endif 682 683 /* Wrap the current CloseScreen function */ 684 fPtr->CloseScreen = pScreen->CloseScreen; 685 pScreen->CloseScreen = CrimeCloseScreen; 686 687 return TRUE; 688} 689 690static Bool 691CrimeCloseScreen(int scrnIndex, ScreenPtr pScreen) 692{ 693 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 694 CrimePtr fPtr = CRIMEPTR(pScrn); 695 696 if (pScrn->vtSema) { 697 CrimeRestore(pScrn); 698 if (munmap(fPtr->engine, 0x5000) == -1) { 699 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 700 "munmap engine: %s\n", strerror(errno)); 701 } 702 703 if (munmap(fPtr->linear, 0x10000) == -1) { 704 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 705 "munmap linear: %s\n", strerror(errno)); 706 } 707#ifdef CRIME_DEBUG 708 if (munmap(fPtr->fb, 8192 * fPtr->info.height) == -1) { 709 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 710 "munmap fb: %s\n", strerror(errno)); 711 } 712#else 713 free(fPtr->fb); 714#endif 715 716 fPtr->engine = NULL; 717 fPtr->linear = NULL; 718 } 719 pScrn->vtSema = FALSE; 720 721 /* unwrap CloseScreen */ 722 pScreen->CloseScreen = fPtr->CloseScreen; 723 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 724} 725 726static Bool 727CrimeEnterVT(int scrnIndex, int flags) 728{ 729 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 730 731 pScrn->vtSema = TRUE; 732 return TRUE; 733} 734 735static void 736CrimeLeaveVT(int scrnIndex, int flags) 737{ 738} 739 740static Bool 741CrimeSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 742{ 743 744 /* Nothing else to do */ 745 return TRUE; 746} 747 748static int 749CrimeValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 750{ 751 752 return MODE_OK; 753} 754 755static void 756CrimeLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 757 LOCO *colors, VisualPtr pVisual) 758{ 759 CrimePtr fPtr = CRIMEPTR(pScrn); 760 struct wsdisplay_cmap cmap; 761 unsigned char red[256],green[256],blue[256]; 762 int i, indexMin=256, indexMax=0; 763 764 cmap.count = 1; 765 cmap.red = red; 766 cmap.green = green; 767 cmap.blue = blue; 768 769 if (numColors == 1) { 770 /* Optimisation */ 771 cmap.index = indices[0]; 772 red[0] = colors[indices[0]].red; 773 green[0] = colors[indices[0]].green; 774 blue[0] = colors[indices[0]].blue; 775 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 776 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 777 } else { 778 /* Change all colors in 2 syscalls */ 779 /* and limit the data to be transfered */ 780 for (i = 0; i < numColors; i++) { 781 if (indices[i] < indexMin) 782 indexMin = indices[i]; 783 if (indices[i] > indexMax) 784 indexMax = indices[i]; 785 } 786 cmap.index = indexMin; 787 cmap.count = indexMax - indexMin + 1; 788 cmap.red = &red[indexMin]; 789 cmap.green = &green[indexMin]; 790 cmap.blue = &blue[indexMin]; 791 /* Get current map */ 792 if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1) 793 ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno)); 794 /* Change the colors that require updating */ 795 for (i = 0; i < numColors; i++) { 796 red[indices[i]] = colors[indices[i]].red; 797 green[indices[i]] = colors[indices[i]].green; 798 blue[indices[i]] = colors[indices[i]].blue; 799 } 800 /* Write the colormap back */ 801 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 802 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 803 } 804} 805 806static Bool 807CrimeSaveScreen(ScreenPtr pScreen, int mode) 808{ 809 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 810 CrimePtr fPtr = CRIMEPTR(pScrn); 811 int state; 812 813 if (!pScrn->vtSema) 814 return TRUE; 815 816 if (mode != SCREEN_SAVER_FORCER) { 817 state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON: 818 WSDISPLAYIO_VIDEO_OFF; 819 ioctl(fPtr->fd, 820 WSDISPLAYIO_SVIDEO, &state); 821 } 822 return TRUE; 823} 824 825 826static void 827CrimeSave(ScrnInfoPtr pScrn) 828{ 829} 830 831static void 832CrimeRestore(ScrnInfoPtr pScrn) 833{ 834 CrimePtr fPtr = CRIMEPTR(pScrn); 835 int mode; 836 837 /* Restore the text mode */ 838 mode = WSDISPLAYIO_MODE_EMUL; 839 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) { 840 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 841 "error setting text mode %s\n", strerror(errno)); 842 } 843} 844