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