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