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