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