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