wsfb_driver.c revision 357bfbb2
1/* $OpenBSD: wsfb_driver.c,v 1.19 2003/04/27 16:42:32 matthieu Exp $ */ 2/* 3 * Copyright (c) 2001 Matthieu Herrb 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/* 33 * Based on fbdev.c written by: 34 * 35 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 36 * Michel Dänzer, <michdaen@iiic.ethz.ch> 37 */ 38 39#ifdef HAVE_CONFIG_H 40#include "config.h" 41#endif 42 43#include <fcntl.h> 44#include <sys/types.h> 45#include <sys/time.h> 46#include <dev/wscons/wsconsio.h> 47 48/* all driver need this */ 49#include "xf86.h" 50#include "xf86_OSproc.h" 51#include "xf86_ansic.h" 52 53#include "mipointer.h" 54#include "mibstore.h" 55#include "micmap.h" 56#include "colormapst.h" 57#include "xf86cmap.h" 58#include "shadow.h" 59#include "dgaproc.h" 60 61/* for visuals */ 62#include "xf1bpp.h" 63#include "xf4bpp.h" 64#include "fb.h" 65 66#include "xf86Resources.h" 67#include "xf86RAC.h" 68 69#ifdef XvExtension 70#include "xf86xv.h" 71#endif 72 73/* #include "wsconsio.h" */ 74 75#ifndef XFree86LOADER 76#include <sys/mman.h> 77#endif 78 79#ifdef USE_PRIVSEP 80extern int priv_open_device(const char *); 81#else 82#define priv_open_device(n) open(n,O_RDWR|O_NONBLOCK|O_EXCL) 83#endif 84 85#if defined(__NetBSD__) 86#define WSFB_DEFAULT_DEV "/dev/ttyE0" 87#else 88#define WSFB_DEFAULT_DEV "/dev/ttyC0" 89#endif 90 91#define DEBUG 0 92 93#if DEBUG 94# define TRACE_ENTER(str) ErrorF("wsfb: " str " %d\n",pScrn->scrnIndex) 95# define TRACE_EXIT(str) ErrorF("wsfb: " str " done\n") 96# define TRACE(str) ErrorF("wsfb trace: " str "\n") 97#else 98# define TRACE_ENTER(str) 99# define TRACE_EXIT(str) 100# define TRACE(str) 101#endif 102 103/* Prototypes */ 104#ifdef XFree86LOADER 105static pointer WsfbSetup(pointer, pointer, int *, int *); 106#endif 107static Bool WsfbGetRec(ScrnInfoPtr); 108static void WsfbFreeRec(ScrnInfoPtr); 109static const OptionInfoRec * WsfbAvailableOptions(int, int); 110static void WsfbIdentify(int); 111static Bool WsfbProbe(DriverPtr, int); 112static Bool WsfbPreInit(ScrnInfoPtr, int); 113static Bool WsfbScreenInit(int, ScreenPtr, int, char **); 114static Bool WsfbCloseScreen(int, ScreenPtr); 115static void *WsfbWindowLinear(ScreenPtr, CARD32, CARD32, int, CARD32 *, 116 void *); 117static void WsfbPointerMoved(int, int, int); 118static Bool WsfbEnterVT(int, int); 119static void WsfbLeaveVT(int, int); 120static Bool WsfbSwitchMode(int, DisplayModePtr, int); 121static int WsfbValidMode(int, DisplayModePtr, Bool, int); 122static void WsfbLoadPalette(ScrnInfoPtr, int, int *, LOCO *, VisualPtr); 123static Bool WsfbSaveScreen(ScreenPtr, int); 124static void WsfbSave(ScrnInfoPtr); 125static void WsfbRestore(ScrnInfoPtr); 126 127/* dga stuff */ 128#ifdef XFreeXDGA 129static Bool WsfbDGAOpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 130 int *, int *, int *); 131static Bool WsfbDGASetMode(ScrnInfoPtr, DGAModePtr); 132static void WsfbDGASetViewport(ScrnInfoPtr, int, int, int); 133static Bool WsfbDGAInit(ScrnInfoPtr, ScreenPtr); 134#endif 135static Bool WsfbDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 136 pointer ptr); 137 138/* helper functions */ 139static int wsfb_open(char *); 140static pointer wsfb_mmap(size_t, off_t, int); 141 142enum { WSFB_ROTATE_NONE = 0, 143 WSFB_ROTATE_CCW = 90, 144 WSFB_ROTATE_UD = 180, 145 WSFB_ROTATE_CW = 270 146}; 147 148/* 149 * This is intentionally screen-independent. It indicates the binding 150 * choice made in the first PreInit. 151 */ 152static int pix24bpp = 0; 153 154#define WSFB_VERSION 4000 155#define WSFB_NAME "wsfb" 156#define WSFB_DRIVER_NAME "wsfb" 157 158_X_EXPORT DriverRec WSFB = { 159 WSFB_VERSION, 160 WSFB_DRIVER_NAME, 161 WsfbIdentify, 162 WsfbProbe, 163 WsfbAvailableOptions, 164 NULL, 165 0, 166 WsfbDriverFunc 167}; 168 169/* Supported "chipsets" */ 170static SymTabRec WsfbChipsets[] = { 171 { 0, "wsfb" }, 172 { -1, NULL } 173}; 174 175/* Supported options */ 176typedef enum { 177 OPTION_SHADOW_FB, 178 OPTION_ROTATE 179} WsfbOpts; 180 181static const OptionInfoRec WsfbOptions[] = { 182 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, 183 { OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE}, 184 { -1, NULL, OPTV_NONE, {0}, FALSE} 185}; 186 187/* Symbols needed from other modules */ 188static const char *fbSymbols[] = { 189 "fbPictureInit", 190 "fbScreenInit", 191 NULL 192}; 193static const char *shadowSymbols[] = { 194 "shadowAdd", 195 "shadowSetup", 196 "shadowUpdatePacked", 197 "shadowUpdatePackedWeak", 198 "shadowUpdateRotatePacked", 199 "shadowUpdateRotatePackedWeak", 200 NULL 201}; 202 203#ifdef XFree86LOADER 204static XF86ModuleVersionInfo WsfbVersRec = { 205 "wsfb", 206 MODULEVENDORSTRING, 207 MODINFOSTRING1, 208 MODINFOSTRING2, 209 XORG_VERSION_CURRENT, 210 PACKAGE_VERSION_MAJOR, 211 PACKAGE_VERSION_MINOR, 212 PACKAGE_VERSION_PATCHLEVEL, 213 ABI_CLASS_VIDEODRV, 214 ABI_VIDEODRV_VERSION, 215 NULL, 216 {0, 0, 0, 0} 217}; 218 219_X_EXPORT XF86ModuleData wsfbModuleData = { &WsfbVersRec, WsfbSetup, NULL }; 220 221static pointer 222WsfbSetup(pointer module, pointer opts, int *errmaj, int *errmin) 223{ 224 static Bool setupDone = FALSE; 225 const char *osname; 226 227 /* Check that we're being loaded on a OpenBSD or NetBSD system */ 228 LoaderGetOS(&osname, NULL, NULL, NULL); 229 if (!osname || (strcmp(osname, "openbsd") != 0 && 230 strcmp(osname, "netbsd") != 0)) { 231 if (errmaj) 232 *errmaj = LDR_BADOS; 233 if (errmin) 234 *errmin = 0; 235 return NULL; 236 } 237 if (!setupDone) { 238 setupDone = TRUE; 239 xf86AddDriver(&WSFB, module, HaveDriverFuncs); 240 LoaderRefSymLists(fbSymbols, shadowSymbols, NULL); 241 return (pointer)1; 242 } else { 243 if (errmaj != NULL) 244 *errmaj = LDR_ONCEONLY; 245 return NULL; 246 } 247} 248#endif /* XFree86LOADER */ 249 250/* private data */ 251typedef struct { 252 int fd; /* file descriptor of open device */ 253 struct wsdisplay_fbinfo info; /* frame buffer characteristics */ 254 int linebytes; /* number of bytes per row */ 255 unsigned char* fbstart; 256 unsigned char* fbmem; 257 size_t fbmem_len; 258 int rotate; 259 Bool shadowFB; 260 void * shadow; 261 CloseScreenProcPtr CloseScreen; 262 CreateScreenResourcesProcPtr CreateScreenResources; 263 void (*PointerMoved)(int, int, int); 264 EntityInfoPtr pEnt; 265 struct wsdisplay_cmap saved_cmap; 266 267#ifdef XFreeXDGA 268 /* DGA info */ 269 DGAModePtr pDGAMode; 270 int nDGAMode; 271#endif 272 OptionInfoPtr Options; 273} WsfbRec, *WsfbPtr; 274 275#define WSFBPTR(p) ((WsfbPtr)((p)->driverPrivate)) 276 277static Bool 278WsfbGetRec(ScrnInfoPtr pScrn) 279{ 280 281 if (pScrn->driverPrivate != NULL) 282 return TRUE; 283 284 pScrn->driverPrivate = xnfcalloc(sizeof(WsfbRec), 1); 285 return TRUE; 286} 287 288static void 289WsfbFreeRec(ScrnInfoPtr pScrn) 290{ 291 292 if (pScrn->driverPrivate == NULL) 293 return; 294 xfree(pScrn->driverPrivate); 295 pScrn->driverPrivate = NULL; 296} 297 298static const OptionInfoRec * 299WsfbAvailableOptions(int chipid, int busid) 300{ 301 return WsfbOptions; 302} 303 304static void 305WsfbIdentify(int flags) 306{ 307 xf86PrintChipsets(WSFB_NAME, "driver for wsdisplay framebuffer", 308 WsfbChipsets); 309} 310 311/* Open the framebuffer device */ 312static int 313wsfb_open(char *dev) 314{ 315 int fd = -1; 316 317 /* try argument from XF86Config first */ 318 if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) { 319 /* second: environment variable */ 320 dev = getenv("XDEVICE"); 321 if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) { 322 /* last try: default device */ 323 dev = WSFB_DEFAULT_DEV; 324 if ((fd = priv_open_device(dev)) == -1) { 325 return -1; 326 } 327 } 328 } 329 return fd; 330} 331 332/* Map the framebuffer's memory */ 333static pointer 334wsfb_mmap(size_t len, off_t off, int fd) 335{ 336 int pagemask, mapsize; 337 caddr_t addr; 338 pointer mapaddr; 339 340 pagemask = getpagesize() - 1; 341 mapsize = ((int) len + pagemask) & ~pagemask; 342 addr = 0; 343 344 /* 345 * try and make it private first, that way once we get it, an 346 * interloper, e.g. another server, can't get this frame buffer, 347 * and if another server already has it, this one won't. 348 */ 349 mapaddr = (pointer) mmap(addr, mapsize, 350 PROT_READ | PROT_WRITE, MAP_SHARED, 351 fd, off); 352 if (mapaddr == (pointer) -1) { 353 mapaddr = NULL; 354 } 355#if DEBUG 356 ErrorF("mmap returns: addr %p len 0x%x\n", mapaddr, mapsize); 357#endif 358 return mapaddr; 359} 360 361static Bool 362WsfbProbe(DriverPtr drv, int flags) 363{ 364 int i, fd, entity; 365 GDevPtr *devSections; 366 int numDevSections; 367 char *dev; 368 Bool foundScreen = FALSE; 369 370 TRACE("probe start"); 371 372 /* For now, just bail out for PROBE_DETECT. */ 373 if (flags & PROBE_DETECT) 374 return FALSE; 375 376 if ((numDevSections = xf86MatchDevice(WSFB_DRIVER_NAME, 377 &devSections)) <= 0) 378 return FALSE; 379 380 for (i = 0; i < numDevSections; i++) { 381 ScrnInfoPtr pScrn = NULL; 382 383 dev = xf86FindOptionValue(devSections[i]->options, "device"); 384 if ((fd = wsfb_open(dev)) >= 0) { 385 entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); 386 pScrn = xf86ConfigFbEntity(NULL,0,entity, 387 NULL,NULL,NULL,NULL); 388 if (pScrn != NULL) { 389 foundScreen = TRUE; 390 pScrn->driverVersion = WSFB_VERSION; 391 pScrn->driverName = WSFB_DRIVER_NAME; 392 pScrn->name = WSFB_NAME; 393 pScrn->Probe = WsfbProbe; 394 pScrn->PreInit = WsfbPreInit; 395 pScrn->ScreenInit = WsfbScreenInit; 396 pScrn->SwitchMode = WsfbSwitchMode; 397 pScrn->AdjustFrame = NULL; 398 pScrn->EnterVT = WsfbEnterVT; 399 pScrn->LeaveVT = WsfbLeaveVT; 400 pScrn->ValidMode = WsfbValidMode; 401 402 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 403 "using %s\n", dev != NULL ? dev : 404 "default device"); 405 } 406 } 407 } 408 xfree(devSections); 409 TRACE("probe done"); 410 return foundScreen; 411} 412 413static Bool 414WsfbPreInit(ScrnInfoPtr pScrn, int flags) 415{ 416 WsfbPtr fPtr; 417 int default_depth, wstype; 418 char *dev, *s; 419 char *mod = NULL; 420 const char *reqSym = NULL; 421 Gamma zeros = {0.0, 0.0, 0.0}; 422 DisplayModePtr mode; 423 424 if (flags & PROBE_DETECT) return FALSE; 425 426 TRACE_ENTER("PreInit"); 427 428 if (pScrn->numEntities != 1) return FALSE; 429 430 pScrn->monitor = pScrn->confScreen->monitor; 431 432 WsfbGetRec(pScrn); 433 fPtr = WSFBPTR(pScrn); 434 435 fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 436 437 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 438 pScrn->racIoFlags = pScrn->racMemFlags; 439 440 dev = xf86FindOptionValue(fPtr->pEnt->device->options, "device"); 441 fPtr->fd = wsfb_open(dev); 442 if (fPtr->fd == -1) { 443 return FALSE; 444 } 445 446 if (ioctl(fPtr->fd, WSDISPLAYIO_GINFO, &fPtr->info) == -1) { 447 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 448 "ioctl WSDISPLAY_GINFO: %s\n", 449 strerror(errno)); 450 return FALSE; 451 } 452 if (ioctl(fPtr->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) { 453 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 454 "ioctl WSDISPLAY_GTYPE: %s\n", 455 strerror(errno)); 456 return FALSE; 457 } 458 if (ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, &fPtr->linebytes) == -1) { 459 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 460 "ioctl WSDISPLAYIO_LINEBYTES: %s\n", 461 strerror(errno)); 462 return FALSE; 463 } 464 /* 465 * Allocate room for saving the colormap 466 */ 467 if (fPtr->info.cmsize != 0) { 468 fPtr->saved_cmap.red = 469 (unsigned char *)xalloc(fPtr->info.cmsize); 470 if (fPtr->saved_cmap.red == NULL) { 471 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 472 "Cannot malloc %d bytes\n", fPtr->info.cmsize); 473 return FALSE; 474 } 475 fPtr->saved_cmap.green = 476 (unsigned char *)xalloc(fPtr->info.cmsize); 477 if (fPtr->saved_cmap.green == NULL) { 478 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 479 "Cannot malloc %d bytes\n", fPtr->info.cmsize); 480 xfree(fPtr->saved_cmap.red); 481 return FALSE; 482 } 483 fPtr->saved_cmap.blue = 484 (unsigned char *)xalloc(fPtr->info.cmsize); 485 if (fPtr->saved_cmap.blue == NULL) { 486 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 487 "Cannot malloc %d bytes\n", fPtr->info.cmsize); 488 xfree(fPtr->saved_cmap.red); 489 xfree(fPtr->saved_cmap.green); 490 return FALSE; 491 } 492 } 493 494 /* Handle depth */ 495 default_depth = fPtr->info.depth <= 24 ? fPtr->info.depth : 24; 496 if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, 497 fPtr->info.depth, 498 fPtr->info.depth >= 24 ? Support24bppFb|Support32bppFb : 0)) 499 return FALSE; 500 501 /* Check consistency */ 502 if (pScrn->bitsPerPixel != fPtr->info.depth) { 503 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 504 "specified depth (%d) or bpp (%d) doesn't match " 505 "framebuffer depth (%d)\n", pScrn->depth, 506 pScrn->bitsPerPixel, fPtr->info.depth); 507 return FALSE; 508 } 509 xf86PrintDepthBpp(pScrn); 510 511 /* Get the depth24 pixmap format */ 512 if (pScrn->depth == 24 && pix24bpp == 0) 513 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 514 515 /* color weight */ 516 if (pScrn->depth > 8) { 517 rgb zeros = { 0, 0, 0 }, masks; 518 519 if (wstype == WSDISPLAY_TYPE_SUN24 || 520 wstype == WSDISPLAY_TYPE_SUNCG12 || 521 wstype == WSDISPLAY_TYPE_SUNCG14 || 522 wstype == WSDISPLAY_TYPE_SUNTCX || 523 wstype == WSDISPLAY_TYPE_SUNFFB) { 524 masks.red = 0x0000ff; 525 masks.green = 0x00ff00; 526 masks.blue = 0xff0000; 527 } else { 528 masks.red = 0; 529 masks.green = 0; 530 masks.blue = 0; 531 } 532 533 if (!xf86SetWeight(pScrn, zeros, masks)) 534 return FALSE; 535 } 536 537 /* visual init */ 538 if (!xf86SetDefaultVisual(pScrn, -1)) 539 return FALSE; 540 541 /* We don't currently support DirectColor at > 8bpp */ 542 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 543 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 544 " (%s) is not supported at depth %d\n", 545 xf86GetVisualName(pScrn->defaultVisual), 546 pScrn->depth); 547 return FALSE; 548 } 549 550 xf86SetGamma(pScrn,zeros); 551 552 pScrn->progClock = TRUE; 553 pScrn->rgbBits = 8; 554 pScrn->chipset = "wsfb"; 555 pScrn->videoRam = fPtr->linebytes * fPtr->info.height; 556 557 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n", 558 pScrn->videoRam/1024); 559 560 /* handle options */ 561 xf86CollectOptions(pScrn, NULL); 562 if (!(fPtr->Options = xalloc(sizeof(WsfbOptions)))) 563 return FALSE; 564 memcpy(fPtr->Options, WsfbOptions, sizeof(WsfbOptions)); 565 xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, 566 fPtr->Options); 567 568 /* use shadow framebuffer by default, on depth >= 8 */ 569 if (pScrn->depth >= 8) 570 fPtr->shadowFB = xf86ReturnOptValBool(fPtr->Options, 571 OPTION_SHADOW_FB, TRUE); 572 else 573 if (xf86ReturnOptValBool(fPtr->Options, 574 OPTION_SHADOW_FB, FALSE)) { 575 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 576 "Shadow FB option ignored on depth < 8"); 577 } 578 579 /* rotation */ 580 fPtr->rotate = WSFB_ROTATE_NONE; 581 if ((s = xf86GetOptValString(fPtr->Options, OPTION_ROTATE))) { 582 if (pScrn->depth >= 8) { 583 if (!xf86NameCmp(s, "CW")) { 584 fPtr->shadowFB = TRUE; 585 fPtr->rotate = WSFB_ROTATE_CW; 586 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 587 "Rotating screen clockwise\n"); 588 } else if (!xf86NameCmp(s, "CCW")) { 589 fPtr->shadowFB = TRUE; 590 fPtr->rotate = WSFB_ROTATE_CCW; 591 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 592 "Rotating screen counter clockwise\n"); 593 } else if (!xf86NameCmp(s, "UD")) { 594 fPtr->shadowFB = TRUE; 595 fPtr->rotate = WSFB_ROTATE_UD; 596 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 597 "Rotating screen upside down\n"); 598 } else { 599 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 600 "\"%s\" is not a valid value for Option " 601 "\"Rotate\"\n", s); 602 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 603 "Valid options are \"CW\", \"CCW\"," 604 " or \"UD\"\n"); 605 } 606 } else { 607 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 608 "Option \"Rotate\" ignored on depth < 8"); 609 } 610 } 611 612 /* fake video mode struct */ 613 mode = (DisplayModePtr)xalloc(sizeof(DisplayModeRec)); 614 mode->prev = mode; 615 mode->next = mode; 616 mode->name = "wsfb current mode"; 617 mode->status = MODE_OK; 618 mode->type = M_T_BUILTIN; 619 mode->Clock = 0; 620 mode->HDisplay = fPtr->info.width; 621 mode->HSyncStart = 0; 622 mode->HSyncEnd = 0; 623 mode->HTotal = 0; 624 mode->HSkew = 0; 625 mode->VDisplay = fPtr->info.height; 626 mode->VSyncStart = 0; 627 mode->VSyncEnd = 0; 628 mode->VTotal = 0; 629 mode->VScan = 0; 630 mode->Flags = 0; 631 if (pScrn->modes != NULL) { 632 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 633 "Ignoring mode specification from screen section\n"); 634 } 635 pScrn->currentMode = pScrn->modes = mode; 636 pScrn->virtualX = fPtr->info.width; 637 pScrn->virtualY = fPtr->info.height; 638 pScrn->displayWidth = pScrn->virtualX; 639 640 /* Set the display resolution */ 641 xf86SetDpi(pScrn, 0, 0); 642 643 /* Load bpp-specific modules */ 644 switch(pScrn->bitsPerPixel) { 645 case 1: 646 mod = "xf1bpp"; 647 reqSym = "xf1bppScreenInit"; 648 break; 649 case 4: 650 mod = "xf4bpp"; 651 reqSym = "xf4bppScreenInit"; 652 break; 653 default: 654 mod = "fb"; 655 break; 656 } 657 658 659 /* Load shadow if needed */ 660 if (fPtr->shadowFB) { 661 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 662 "Using \"Shadow Framebuffer\"\n"); 663 if (xf86LoadSubModule(pScrn, "shadow") == NULL) { 664 WsfbFreeRec(pScrn); 665 return FALSE; 666 } 667 xf86LoaderReqSymLists(shadowSymbols, NULL); 668 } 669 if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { 670 WsfbFreeRec(pScrn); 671 return FALSE; 672 } 673 if (mod) { 674 if (reqSym) { 675 xf86LoaderReqSymbols(reqSym, NULL); 676 } else { 677 xf86LoaderReqSymLists(fbSymbols, NULL); 678 } 679 } 680 TRACE_EXIT("PreInit"); 681 return TRUE; 682} 683 684static Bool 685WsfbCreateScreenResources(ScreenPtr pScreen) 686{ 687 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 688 WsfbPtr fPtr = WSFBPTR(pScrn); 689 PixmapPtr pPixmap; 690 Bool ret; 691 692 pScreen->CreateScreenResources = fPtr->CreateScreenResources; 693 ret = pScreen->CreateScreenResources(pScreen); 694 pScreen->CreateScreenResources = WsfbCreateScreenResources; 695 696 if (!ret) 697 return FALSE; 698 699 pPixmap = pScreen->GetScreenPixmap(pScreen); 700 701 if (!shadowAdd(pScreen, pPixmap, fPtr->rotate ? 702 shadowUpdateRotatePackedWeak() : shadowUpdatePackedWeak(), 703 WsfbWindowLinear, fPtr->rotate, NULL)) { 704 return FALSE; 705 } 706 return TRUE; 707} 708 709 710static Bool 711WsfbShadowInit(ScreenPtr pScreen) 712{ 713 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 714 WsfbPtr fPtr = WSFBPTR(pScrn); 715 716 if (!shadowSetup(pScreen)) 717 return FALSE; 718 fPtr->CreateScreenResources = pScreen->CreateScreenResources; 719 pScreen->CreateScreenResources = WsfbCreateScreenResources; 720 721 return TRUE; 722} 723 724static Bool 725WsfbScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 726{ 727 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 728 WsfbPtr fPtr = WSFBPTR(pScrn); 729 VisualPtr visual; 730 int ret, flags, ncolors; 731 int wsmode = WSDISPLAYIO_MODE_DUMBFB; 732 size_t len; 733 734 TRACE_ENTER("WsfbScreenInit"); 735#if DEBUG 736 ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" 737 "\tmask: %x,%x,%x, offset: %u,%u,%u\n", 738 pScrn->bitsPerPixel, 739 pScrn->depth, 740 xf86GetVisualName(pScrn->defaultVisual), 741 pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, 742 pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); 743#endif 744 switch (fPtr->info.depth) { 745 case 1: 746 case 4: 747 case 8: 748 len = fPtr->linebytes*fPtr->info.height; 749 break; 750 case 16: 751 if (fPtr->linebytes == fPtr->info.width) { 752 len = fPtr->info.width*fPtr->info.height*sizeof(short); 753 } else { 754 len = fPtr->linebytes*fPtr->info.height; 755 } 756 break; 757 case 24: 758 if (fPtr->linebytes == fPtr->info.width) { 759 len = fPtr->info.width*fPtr->info.height*3; 760 } else { 761 len = fPtr->linebytes*fPtr->info.height; 762 } 763 break; 764 case 32: 765 if (fPtr->linebytes == fPtr->info.width) { 766 len = fPtr->info.width*fPtr->info.height*sizeof(int); 767 } else { 768 len = fPtr->linebytes*fPtr->info.height; 769 } 770 break; 771 default: 772 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 773 "unsupported depth %d\n", fPtr->info.depth); 774 return FALSE; 775 } 776 /* Switch to graphics mode - required before mmap */ 777 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { 778 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 779 "ioctl WSDISPLAYIO_SMODE: %s\n", 780 strerror(errno)); 781 return FALSE; 782 } 783 fPtr->fbmem = wsfb_mmap(len, 0, fPtr->fd); 784 785 if (fPtr->fbmem == NULL) { 786 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 787 "wsfb_mmap: %s\n", strerror(errno)); 788 return FALSE; 789 } 790 fPtr->fbmem_len = len; 791 792 WsfbSave(pScrn); 793 pScrn->vtSema = TRUE; 794 795 /* mi layer */ 796 miClearVisualTypes(); 797 if (pScrn->bitsPerPixel > 8) { 798 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 799 pScrn->rgbBits, TrueColor)) 800 return FALSE; 801 } else { 802 if (!miSetVisualTypes(pScrn->depth, 803 miGetDefaultVisualMask(pScrn->depth), 804 pScrn->rgbBits, pScrn->defaultVisual)) 805 return FALSE; 806 } 807 if (!miSetPixmapDepths()) 808 return FALSE; 809 810 if (fPtr->rotate == WSFB_ROTATE_CW 811 || fPtr->rotate == WSFB_ROTATE_CCW) { 812 int tmp = pScrn->virtualX; 813 pScrn->virtualX = pScrn->displayWidth = pScrn->virtualY; 814 pScrn->virtualY = tmp; 815 } 816 if (fPtr->rotate && !fPtr->PointerMoved) { 817 fPtr->PointerMoved = pScrn->PointerMoved; 818 pScrn->PointerMoved = WsfbPointerMoved; 819 } 820 821 fPtr->fbstart = fPtr->fbmem; 822 823 switch (pScrn->bitsPerPixel) { 824 case 1: 825 ret = xf1bppScreenInit(pScreen, fPtr->fbstart, 826 pScrn->virtualX, pScrn->virtualY, 827 pScrn->xDpi, pScrn->yDpi, 828 pScrn->displayWidth); 829 break; 830 case 4: 831 ret = xf4bppScreenInit(pScreen, fPtr->fbstart, 832 pScrn->virtualX, pScrn->virtualY, 833 pScrn->xDpi, pScrn->yDpi, 834 pScrn->displayWidth); 835 break; 836 case 8: 837 case 16: 838 case 24: 839 case 32: 840 ret = fbScreenInit(pScreen, 841 fPtr->shadowFB ? fPtr->shadow : fPtr->fbstart, 842 pScrn->virtualX, pScrn->virtualY, 843 pScrn->xDpi, pScrn->yDpi, 844 pScrn->displayWidth, pScrn->bitsPerPixel); 845 break; 846 default: 847 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 848 "Unsupported bpp: %d", pScrn->bitsPerPixel); 849 return FALSE; 850 } /* case */ 851 852 if (!ret) 853 return FALSE; 854 855 if (pScrn->bitsPerPixel > 8) { 856 /* Fixup RGB ordering */ 857 visual = pScreen->visuals + pScreen->numVisuals; 858 while (--visual >= pScreen->visuals) { 859 if ((visual->class | DynamicClass) == DirectColor) { 860 visual->offsetRed = pScrn->offset.red; 861 visual->offsetGreen = pScrn->offset.green; 862 visual->offsetBlue = pScrn->offset.blue; 863 visual->redMask = pScrn->mask.red; 864 visual->greenMask = pScrn->mask.green; 865 visual->blueMask = pScrn->mask.blue; 866 } 867 } 868 } 869 870 if (pScrn->bitsPerPixel >= 8) { 871 if (!fbPictureInit(pScreen, NULL, 0)) 872 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 873 "RENDER extension initialisation failed."); 874 } 875 if (fPtr->shadowFB && !WsfbShadowInit(pScreen)) { 876 xf86DrvMsg(scrnIndex, X_ERROR, 877 "shadow framebuffer initialization failed\n"); 878 return FALSE; 879 } 880 881#ifdef XFreeXDGA 882 if (!fPtr->rotate) 883 WsfbDGAInit(pScrn, pScreen); 884 else 885 xf86DrvMsg(scrnIndex, X_INFO, "Rotated display, " 886 "disabling DGA\n"); 887#endif 888 if (fPtr->rotate) { 889 xf86DrvMsg(scrnIndex, X_INFO, "Enabling Driver Rotation, " 890 "disabling RandR\n"); 891 xf86DisableRandR(); 892 if (pScrn->bitsPerPixel == 24) 893 xf86DrvMsg(scrnIndex, X_WARNING, 894 "Rotation might be broken in 24 bpp\n"); 895 } 896 897 xf86SetBlackWhitePixels(pScreen); 898 miInitializeBackingStore(pScreen); 899 xf86SetBackingStore(pScreen); 900 901 /* software cursor */ 902 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 903 904 /* colormap */ 905 if (!miCreateDefColormap(pScreen)) 906 return FALSE; 907 flags = CMAP_RELOAD_ON_MODE_SWITCH; 908 ncolors = fPtr->info.cmsize; 909 /* on StaticGray visuals, fake a 256 entries colormap */ 910 if (ncolors == 0) 911 ncolors = 256; 912 if(!xf86HandleColormaps(pScreen, ncolors, 8, WsfbLoadPalette, 913 NULL, flags)) 914 return FALSE; 915 916 pScreen->SaveScreen = WsfbSaveScreen; 917 918#ifdef XvExtension 919 { 920 XF86VideoAdaptorPtr *ptr; 921 922 int n = xf86XVListGenericAdaptors(pScrn,&ptr); 923 if (n) { 924 xf86XVScreenInit(pScreen,ptr,n); 925 } 926 } 927#endif 928 929 /* Wrap the current CloseScreen function */ 930 fPtr->CloseScreen = pScreen->CloseScreen; 931 pScreen->CloseScreen = WsfbCloseScreen; 932 933 TRACE_EXIT("WsfbScreenInit"); 934 return TRUE; 935} 936 937static Bool 938WsfbCloseScreen(int scrnIndex, ScreenPtr pScreen) 939{ 940 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 941 WsfbPtr fPtr = WSFBPTR(pScrn); 942 943 TRACE_ENTER("WsfbCloseScreen"); 944 945 if (pScrn->vtSema) { 946 WsfbRestore(pScrn); 947 if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) { 948 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 949 "munmap: %s\n", strerror(errno)); 950 } 951 952 fPtr->fbmem = NULL; 953 } 954#ifdef XFreeXDGA 955 if (fPtr->pDGAMode) { 956 xfree(fPtr->pDGAMode); 957 fPtr->pDGAMode = NULL; 958 fPtr->nDGAMode = 0; 959 } 960#endif 961 pScrn->vtSema = FALSE; 962 963 /* unwrap CloseScreen */ 964 pScreen->CloseScreen = fPtr->CloseScreen; 965 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 966} 967 968static void * 969WsfbWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 970 CARD32 *size, void *closure) 971{ 972 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 973 WsfbPtr fPtr = WSFBPTR(pScrn); 974 975 if (fPtr->linebytes) 976 *size = fPtr->linebytes; 977 else { 978 if (ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, size) == -1) 979 return NULL; 980 fPtr->linebytes = *size; 981 } 982 return ((CARD8 *)fPtr->fbmem + row *fPtr->linebytes + offset); 983} 984 985static void 986WsfbPointerMoved(int index, int x, int y) 987{ 988 ScrnInfoPtr pScrn = xf86Screens[index]; 989 WsfbPtr fPtr = WSFBPTR(pScrn); 990 int newX, newY; 991 992 switch (fPtr->rotate) 993 { 994 case WSFB_ROTATE_CW: 995 /* 90 degrees CW rotation. */ 996 newX = pScrn->pScreen->height - y - 1; 997 newY = x; 998 break; 999 1000 case WSFB_ROTATE_CCW: 1001 /* 90 degrees CCW rotation. */ 1002 newX = y; 1003 newY = pScrn->pScreen->width - x - 1; 1004 break; 1005 1006 case WSFB_ROTATE_UD: 1007 /* 180 degrees UD rotation. */ 1008 newX = pScrn->pScreen->width - x - 1; 1009 newY = pScrn->pScreen->height - y - 1; 1010 break; 1011 1012 default: 1013 /* No rotation. */ 1014 newX = x; 1015 newY = y; 1016 break; 1017 } 1018 1019 /* Pass adjusted pointer coordinates to wrapped PointerMoved function. */ 1020 (*fPtr->PointerMoved)(index, newX, newY); 1021} 1022 1023static Bool 1024WsfbEnterVT(int scrnIndex, int flags) 1025{ 1026 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1027 1028 TRACE_ENTER("EnterVT"); 1029 pScrn->vtSema = TRUE; 1030 return TRUE; 1031} 1032 1033static void 1034WsfbLeaveVT(int scrnIndex, int flags) 1035{ 1036#if DEBUG 1037 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1038#endif 1039 1040 TRACE_ENTER("LeaveVT"); 1041} 1042 1043static Bool 1044WsfbSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 1045{ 1046#if DEBUG 1047 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1048#endif 1049 1050 TRACE_ENTER("SwitchMode"); 1051 /* Nothing else to do */ 1052 return TRUE; 1053} 1054 1055static int 1056WsfbValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 1057{ 1058#if DEBUG 1059 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1060#endif 1061 1062 TRACE_ENTER("ValidMode"); 1063 return MODE_OK; 1064} 1065 1066static void 1067WsfbLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 1068 LOCO *colors, VisualPtr pVisual) 1069{ 1070 WsfbPtr fPtr = WSFBPTR(pScrn); 1071 struct wsdisplay_cmap cmap; 1072 unsigned char red[256],green[256],blue[256]; 1073 int i, indexMin=256, indexMax=0; 1074 1075 TRACE_ENTER("LoadPalette"); 1076 1077 cmap.count = 1; 1078 cmap.red = red; 1079 cmap.green = green; 1080 cmap.blue = blue; 1081 1082 if (numColors == 1) { 1083 /* Optimisation */ 1084 cmap.index = indices[0]; 1085 red[0] = colors[indices[0]].red; 1086 green[0] = colors[indices[0]].green; 1087 blue[0] = colors[indices[0]].blue; 1088 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 1089 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 1090 } else { 1091 /* Change all colors in 2 syscalls */ 1092 /* and limit the data to be transfered */ 1093 for (i = 0; i < numColors; i++) { 1094 if (indices[i] < indexMin) 1095 indexMin = indices[i]; 1096 if (indices[i] > indexMax) 1097 indexMax = indices[i]; 1098 } 1099 cmap.index = indexMin; 1100 cmap.count = indexMax - indexMin + 1; 1101 cmap.red = &red[indexMin]; 1102 cmap.green = &green[indexMin]; 1103 cmap.blue = &blue[indexMin]; 1104 /* Get current map */ 1105 if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1) 1106 ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno)); 1107 /* Change the colors that require updating */ 1108 for (i = 0; i < numColors; i++) { 1109 red[indices[i]] = colors[indices[i]].red; 1110 green[indices[i]] = colors[indices[i]].green; 1111 blue[indices[i]] = colors[indices[i]].blue; 1112 } 1113 /* Write the colormap back */ 1114 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 1115 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 1116 } 1117 TRACE_EXIT("LoadPalette"); 1118} 1119 1120static Bool 1121WsfbSaveScreen(ScreenPtr pScreen, int mode) 1122{ 1123 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1124 WsfbPtr fPtr = WSFBPTR(pScrn); 1125 int state; 1126 1127 TRACE_ENTER("SaveScreen"); 1128 1129 if (!pScrn->vtSema) 1130 return TRUE; 1131 1132 if (mode != SCREEN_SAVER_FORCER) { 1133 state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON: 1134 WSDISPLAYIO_VIDEO_OFF; 1135 ioctl(fPtr->fd, 1136 WSDISPLAYIO_SVIDEO, &state); 1137 } 1138 return TRUE; 1139} 1140 1141 1142static void 1143WsfbSave(ScrnInfoPtr pScrn) 1144{ 1145 WsfbPtr fPtr = WSFBPTR(pScrn); 1146 1147 TRACE_ENTER("WsfbSave"); 1148 1149 if (fPtr->info.cmsize == 0) 1150 return; 1151 1152 fPtr->saved_cmap.index = 0; 1153 fPtr->saved_cmap.count = fPtr->info.cmsize; 1154 if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, 1155 &(fPtr->saved_cmap)) == -1) { 1156 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1157 "error saving colormap %s\n", strerror(errno)); 1158 } 1159 1160} 1161 1162static void 1163WsfbRestore(ScrnInfoPtr pScrn) 1164{ 1165 WsfbPtr fPtr = WSFBPTR(pScrn); 1166 int mode; 1167 1168 TRACE_ENTER("WsfbRestore"); 1169 1170 if (fPtr->info.cmsize != 0) { 1171 /* reset colormap for text mode */ 1172 if (ioctl(fPtr->fd, WSDISPLAYIO_PUTCMAP, 1173 &(fPtr->saved_cmap)) == -1) { 1174 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1175 "error restoring colormap %s\n", 1176 strerror(errno)); 1177 } 1178 } 1179 1180 /* Clear the screen */ 1181 memset(fPtr->fbmem, 0, fPtr->fbmem_len); 1182 1183 /* Restore the text mode */ 1184 mode = WSDISPLAYIO_MODE_EMUL; 1185 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) { 1186 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1187 "error setting text mode %s\n", strerror(errno)); 1188 } 1189 TRACE_EXIT("WsfbRestore"); 1190} 1191 1192#ifdef XFreeXDGA 1193/*********************************************************************** 1194 * DGA stuff 1195 ***********************************************************************/ 1196 1197static Bool 1198WsfbDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, 1199 unsigned char **ApertureBase, int *ApertureSize, 1200 int *ApertureOffset, int *flags) 1201{ 1202 *DeviceName = NULL; /* No special device */ 1203 *ApertureBase = (unsigned char *)(pScrn->memPhysBase); 1204 *ApertureSize = pScrn->videoRam; 1205 *ApertureOffset = pScrn->fbOffset; 1206 *flags = 0; 1207 1208 return TRUE; 1209} 1210 1211static Bool 1212WsfbDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode) 1213{ 1214 DisplayModePtr pMode; 1215 int scrnIdx = pScrn->pScreen->myNum; 1216 int frameX0, frameY0; 1217 1218 if (pDGAMode) { 1219 pMode = pDGAMode->mode; 1220 frameX0 = frameY0 = 0; 1221 } else { 1222 if (!(pMode = pScrn->currentMode)) 1223 return TRUE; 1224 1225 frameX0 = pScrn->frameX0; 1226 frameY0 = pScrn->frameY0; 1227 } 1228 1229 if (!(*pScrn->SwitchMode)(scrnIdx, pMode, 0)) 1230 return FALSE; 1231 (*pScrn->AdjustFrame)(scrnIdx, frameX0, frameY0, 0); 1232 1233 return TRUE; 1234} 1235 1236static void 1237WsfbDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 1238{ 1239 (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags); 1240} 1241 1242static int 1243WsfbDGAGetViewport(ScrnInfoPtr pScrn) 1244{ 1245 return (0); 1246} 1247 1248static DGAFunctionRec WsfbDGAFunctions = 1249{ 1250 WsfbDGAOpenFramebuffer, 1251 NULL, /* CloseFramebuffer */ 1252 WsfbDGASetMode, 1253 WsfbDGASetViewport, 1254 WsfbDGAGetViewport, 1255 NULL, /* Sync */ 1256 NULL, /* FillRect */ 1257 NULL, /* BlitRect */ 1258 NULL, /* BlitTransRect */ 1259}; 1260 1261static void 1262WsfbDGAAddModes(ScrnInfoPtr pScrn) 1263{ 1264 WsfbPtr fPtr = WSFBPTR(pScrn); 1265 DisplayModePtr pMode = pScrn->modes; 1266 DGAModePtr pDGAMode; 1267 1268 do { 1269 pDGAMode = xrealloc(fPtr->pDGAMode, 1270 (fPtr->nDGAMode + 1) * sizeof(DGAModeRec)); 1271 if (!pDGAMode) 1272 break; 1273 1274 fPtr->pDGAMode = pDGAMode; 1275 pDGAMode += fPtr->nDGAMode; 1276 (void)memset(pDGAMode, 0, sizeof(DGAModeRec)); 1277 1278 ++fPtr->nDGAMode; 1279 pDGAMode->mode = pMode; 1280 pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 1281 pDGAMode->byteOrder = pScrn->imageByteOrder; 1282 pDGAMode->depth = pScrn->depth; 1283 pDGAMode->bitsPerPixel = pScrn->bitsPerPixel; 1284 pDGAMode->red_mask = pScrn->mask.red; 1285 pDGAMode->green_mask = pScrn->mask.green; 1286 pDGAMode->blue_mask = pScrn->mask.blue; 1287 pDGAMode->visualClass = pScrn->bitsPerPixel > 8 ? 1288 TrueColor : PseudoColor; 1289 pDGAMode->xViewportStep = 1; 1290 pDGAMode->yViewportStep = 1; 1291 pDGAMode->viewportWidth = pMode->HDisplay; 1292 pDGAMode->viewportHeight = pMode->VDisplay; 1293 1294 if (fPtr->linebytes) 1295 pDGAMode->bytesPerScanline = fPtr->linebytes; 1296 else { 1297 ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, 1298 &fPtr->linebytes); 1299 pDGAMode->bytesPerScanline = fPtr->linebytes; 1300 } 1301 1302 pDGAMode->imageWidth = pMode->HDisplay; 1303 pDGAMode->imageHeight = pMode->VDisplay; 1304 pDGAMode->pixmapWidth = pDGAMode->imageWidth; 1305 pDGAMode->pixmapHeight = pDGAMode->imageHeight; 1306 pDGAMode->maxViewportX = pScrn->virtualX - 1307 pDGAMode->viewportWidth; 1308 pDGAMode->maxViewportY = pScrn->virtualY - 1309 pDGAMode->viewportHeight; 1310 1311 pDGAMode->address = fPtr->fbstart; 1312 1313 pMode = pMode->next; 1314 } while (pMode != pScrn->modes); 1315} 1316 1317static Bool 1318WsfbDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) 1319{ 1320 WsfbPtr fPtr = WSFBPTR(pScrn); 1321 1322 if (pScrn->depth < 8) 1323 return FALSE; 1324 1325 if (!fPtr->nDGAMode) 1326 WsfbDGAAddModes(pScrn); 1327 1328 return (DGAInit(pScreen, &WsfbDGAFunctions, 1329 fPtr->pDGAMode, fPtr->nDGAMode)); 1330} 1331#endif 1332 1333static Bool 1334WsfbDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 1335 pointer ptr) 1336{ 1337 xorgHWFlags *flag; 1338 1339 switch (op) { 1340 case GET_REQUIRED_HW_INTERFACES: 1341 flag = (CARD32*)ptr; 1342 (*flag) = 0; 1343 return TRUE; 1344 default: 1345 return FALSE; 1346 } 1347} 1348 1349