1/* 2 3Copyright (c) 1995 Jon Tombs 4Copyright (c) 1995,1996 The XFree86 Project, Inc 5 6*/ 7 8/* THIS IS NOT AN X CONSORTIUM STANDARD */ 9#ifdef HAVE_CONFIG_H 10#include <config.h> 11#endif 12 13 14#include <X11/Xlibint.h> 15#include <X11/extensions/Xxf86dga.h> 16#include <X11/extensions/xf86dgaproto.h> 17#include <X11/extensions/Xext.h> 18#include <X11/extensions/extutil.h> 19#include <stdio.h> 20 21#include <stdint.h> 22#include <limits.h> 23 24/* If you change this, change the Bases[] array below as well */ 25#define MAX_HEADS 16 26 27const char *xdga_extension_name = XF86DGANAME; 28 29static XExtensionInfo _xdga_info_data; 30static XExtensionInfo *xdga_info = &_xdga_info_data; 31 32 33Bool XDGAMapFramebuffer(int, char *, unsigned char*, CARD32, CARD32, CARD32); 34void XDGAUnmapFramebuffer(int); 35unsigned char* XDGAGetMappedMemory(int); 36 37#define XDGACheckExtension(dpy,i,val) \ 38 XextCheckExtension (dpy, i, xdga_extension_name, val) 39 40/***************************************************************************** 41 * * 42 * private utility routines * 43 * * 44 *****************************************************************************/ 45 46static int xdga_close_display(Display *dpy, XExtCodes *codes); 47static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev); 48static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev); 49 50static XExtensionHooks xdga_extension_hooks = { 51 NULL, /* create_gc */ 52 NULL, /* copy_gc */ 53 NULL, /* flush_gc */ 54 NULL, /* free_gc */ 55 NULL, /* create_font */ 56 NULL, /* free_font */ 57 xdga_close_display, /* close_display */ 58 xdga_wire_to_event, /* wire_to_event */ 59 xdga_event_to_wire, /* event_to_wire */ 60 NULL, /* error */ 61 NULL, /* error_string */ 62}; 63 64static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info) 65 66 67XExtDisplayInfo* xdga_find_display(Display*); 68XEXT_GENERATE_FIND_DISPLAY (xdga_find_display, xdga_info, 69 "XFree86-DGA", 70 &xdga_extension_hooks, 71 0, NULL) 72 73 74static Status 75xdga_event_to_wire( 76 Display *dpy, 77 XEvent *event, 78 xEvent *wire_ev 79){ 80 return True; 81} 82 83static Bool 84xdga_wire_to_event( 85 Display *dpy, 86 XEvent *event, 87 xEvent *wire_ev 88){ 89 dgaEvent *wire = (dgaEvent *) wire_ev; 90 XDGAButtonEvent *bevent; 91 XDGAKeyEvent *kevent; 92 XDGAMotionEvent *mevent; 93 XExtDisplayInfo *info = xdga_find_display (dpy); 94 95 XDGACheckExtension (dpy, info, False); 96 97 switch((wire->u.u.type & 0x7f) - info->codes->first_event) { 98 case MotionNotify: 99 mevent = (XDGAMotionEvent*)event; 100 mevent->type = wire->u.u.type & 0x7F; 101 mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); 102 mevent->display = dpy; 103 mevent->screen = wire->u.event.screen; 104 mevent->time = wire->u.event.time; 105 mevent->state = wire->u.event.state; 106 mevent->dx = wire->u.event.dx; 107 mevent->dy = wire->u.event.dy; 108 return True; 109 case ButtonPress: 110 case ButtonRelease: 111 bevent = (XDGAButtonEvent*)event; 112 bevent->type = wire->u.u.type & 0x7F; 113 bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); 114 bevent->display = dpy; 115 bevent->screen = wire->u.event.screen; 116 bevent->time = wire->u.event.time; 117 bevent->state = wire->u.event.state; 118 bevent->button = wire->u.u.detail; 119 return True; 120 case KeyPress: 121 case KeyRelease: 122 kevent = (XDGAKeyEvent*)event; 123 kevent->type = wire->u.u.type & 0x7F; 124 kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); 125 kevent->display = dpy; 126 kevent->screen = wire->u.event.screen; 127 kevent->time = wire->u.event.time; 128 kevent->state = wire->u.event.state; 129 kevent->keycode = wire->u.u.detail; 130 return True; 131 } 132 133 return False; 134} 135 136 137Bool XDGAQueryExtension ( 138 Display *dpy, 139 int *event_basep, 140 int *error_basep 141){ 142 XExtDisplayInfo *info = xdga_find_display (dpy); 143 144 if (XextHasExtension(info)) { 145 *event_basep = info->codes->first_event; 146 *error_basep = info->codes->first_error; 147 return True; 148 } else { 149 return False; 150 } 151} 152 153 154Bool XDGAQueryVersion( 155 Display *dpy, 156 int *majorVersion, 157 int *minorVersion 158){ 159 XExtDisplayInfo *info = xdga_find_display (dpy); 160 xXDGAQueryVersionReply rep; 161 xXDGAQueryVersionReq *req; 162 163 XDGACheckExtension (dpy, info, False); 164 165 LockDisplay(dpy); 166 GetReq(XDGAQueryVersion, req); 167 req->reqType = info->codes->major_opcode; 168 req->dgaReqType = X_XDGAQueryVersion; 169 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 170 UnlockDisplay(dpy); 171 SyncHandle(); 172 return False; 173 } 174 *majorVersion = rep.majorVersion; 175 *minorVersion = rep.minorVersion; 176 UnlockDisplay(dpy); 177 SyncHandle(); 178 if (*majorVersion >= 2) 179 { 180 int i, j; 181 182 for (i = 0, j = info->codes->first_event; 183 i < XF86DGANumberEvents; 184 i++, j++) 185 { 186 XESetWireToEvent (dpy, j, xdga_wire_to_event); 187 XESetEventToWire (dpy, j, xdga_event_to_wire); 188 } 189 XDGASetClientVersion(dpy); 190 } 191 return True; 192} 193 194Bool XDGASetClientVersion( 195 Display *dpy 196){ 197 XExtDisplayInfo *info = xdga_find_display (dpy); 198 xXDGASetClientVersionReq *req; 199 200 XDGACheckExtension (dpy, info, False); 201 202 LockDisplay(dpy); 203 GetReq(XDGASetClientVersion, req); 204 req->reqType = info->codes->major_opcode; 205 req->dgaReqType = X_XDGASetClientVersion; 206 req->major = XDGA_MAJOR_VERSION; 207 req->minor = XDGA_MINOR_VERSION; 208 UnlockDisplay(dpy); 209 SyncHandle(); 210 return True; 211} 212 213Bool XDGAOpenFramebuffer( 214 Display *dpy, 215 int screen 216){ 217 XExtDisplayInfo *info = xdga_find_display (dpy); 218 xXDGAOpenFramebufferReply rep; 219 xXDGAOpenFramebufferReq *req; 220 char *deviceName = NULL; 221 Bool ret; 222 223 XDGACheckExtension (dpy, info, False); 224 225 LockDisplay(dpy); 226 GetReq(XDGAOpenFramebuffer, req); 227 req->reqType = info->codes->major_opcode; 228 req->dgaReqType = X_XDGAOpenFramebuffer; 229 req->screen = screen; 230 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 231 UnlockDisplay(dpy); 232 SyncHandle(); 233 return False; 234 } 235 236 if (rep.length) { 237 if (rep.length < (INT_MAX >> 2)) { 238 unsigned long size = rep.length << 2; 239 deviceName = Xmalloc(size); 240 _XRead(dpy, deviceName, size); 241 deviceName[size - 1] = '\0'; 242 } else 243 _XEatDataWords(dpy, rep.length); 244 } 245 246 ret = XDGAMapFramebuffer(screen, deviceName, 247 (unsigned char*)(long)rep.mem1, 248 rep.size, rep.offset, rep.extra); 249 250 if(deviceName) 251 Xfree(deviceName); 252 253 UnlockDisplay(dpy); 254 SyncHandle(); 255 return ret; 256} 257 258void XDGACloseFramebuffer( 259 Display *dpy, 260 int screen 261){ 262 XExtDisplayInfo *info = xdga_find_display (dpy); 263 xXDGACloseFramebufferReq *req; 264 265 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 266 267 XDGAUnmapFramebuffer(screen); 268 269 LockDisplay(dpy); 270 GetReq(XDGACloseFramebuffer, req); 271 req->reqType = info->codes->major_opcode; 272 req->dgaReqType = X_XDGACloseFramebuffer; 273 req->screen = screen; 274 UnlockDisplay(dpy); 275 SyncHandle(); 276} 277 278 279 280XDGAMode* XDGAQueryModes( 281 Display *dpy, 282 int screen, 283 int *num 284){ 285 XExtDisplayInfo *dinfo = xdga_find_display (dpy); 286 xXDGAQueryModesReply rep; 287 xXDGAQueryModesReq *req; 288 XDGAMode *modes = NULL; 289 290 *num = 0; 291 292 XDGACheckExtension (dpy, dinfo, NULL); 293 294 LockDisplay(dpy); 295 GetReq(XDGAQueryModes, req); 296 req->reqType = dinfo->codes->major_opcode; 297 req->dgaReqType = X_XDGAQueryModes; 298 req->screen = screen; 299 300 if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 301 if(rep.length) { 302 xXDGAModeInfo info; 303 unsigned long size = 0; 304 char *offset; 305 306 if ((rep.length < (INT_MAX >> 2)) && 307 (rep.number < (INT_MAX / sizeof(XDGAMode)))) { 308 size = rep.length << 2; 309 if (size > (rep.number * sz_xXDGAModeInfo)) { 310 size -= rep.number * sz_xXDGAModeInfo; /* find text size */ 311 modes = Xmalloc((rep.number * sizeof(XDGAMode)) + size); 312 offset = (char*)(&modes[rep.number]); /* start of text */ 313 } 314 } 315 316 if (modes != NULL) { 317 unsigned int i; 318 for(i = 0; i < rep.number; i++) { 319 _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo); 320 321 modes[i].num = info.num; 322 modes[i].verticalRefresh = 323 (float)info.vsync_num / (float)info.vsync_den; 324 modes[i].flags = info.flags; 325 modes[i].imageWidth = info.image_width; 326 modes[i].imageHeight = info.image_height; 327 modes[i].pixmapWidth = info.pixmap_width; 328 modes[i].pixmapHeight = info.pixmap_height; 329 modes[i].bytesPerScanline = info.bytes_per_scanline; 330 modes[i].byteOrder = info.byte_order; 331 modes[i].depth = info.depth; 332 modes[i].bitsPerPixel = info.bpp; 333 modes[i].redMask = info.red_mask; 334 modes[i].greenMask = info.green_mask; 335 modes[i].blueMask = info.blue_mask; 336 modes[i].visualClass = info.visual_class; 337 modes[i].viewportWidth = info.viewport_width; 338 modes[i].viewportHeight = info.viewport_height; 339 modes[i].xViewportStep = info.viewport_xstep; 340 modes[i].yViewportStep = info.viewport_ystep; 341 modes[i].maxViewportX = info.viewport_xmax; 342 modes[i].maxViewportY = info.viewport_ymax; 343 modes[i].viewportFlags = info.viewport_flags; 344 modes[i].reserved1 = info.reserved1; 345 modes[i].reserved2 = info.reserved2; 346 347 if (info.name_size > 0 && info.name_size <= size) { 348 _XRead(dpy, offset, info.name_size); 349 modes[i].name = offset; 350 modes[i].name[info.name_size - 1] = '\0'; 351 offset += info.name_size; 352 size -= info.name_size; 353 } else { 354 _XEatData(dpy, info.name_size); 355 modes[i].name = NULL; 356 } 357 } 358 *num = rep.number; 359 } else 360 _XEatDataWords(dpy, rep.length); 361 } 362 } 363 364 UnlockDisplay(dpy); 365 SyncHandle(); 366 367 return modes; 368} 369 370 371XDGADevice * 372XDGASetMode( 373 Display *dpy, 374 int screen, 375 int mode 376){ 377 XExtDisplayInfo *dinfo = xdga_find_display (dpy); 378 xXDGASetModeReply rep; 379 xXDGASetModeReq *req; 380 XDGADevice *dev = NULL; 381 Pixmap pid; 382 383 XDGACheckExtension (dpy, dinfo, NULL); 384 385 LockDisplay(dpy); 386 GetReq(XDGASetMode, req); 387 req->reqType = dinfo->codes->major_opcode; 388 req->dgaReqType = X_XDGASetMode; 389 req->screen = screen; 390 req->mode = mode; 391 req->pid = pid = XAllocID(dpy); 392 393 if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 394 if(rep.length) { 395 xXDGAModeInfo info; 396 unsigned long size; 397 398 if ((rep.length < (INT_MAX >> 2)) && 399 (rep.length > (sz_xXDGAModeInfo >> 2))) { 400 size = rep.length << 2; 401 size -= sz_xXDGAModeInfo; /* get text size */ 402 403 dev = Xmalloc(sizeof(XDGADevice) + size); 404 } 405 406 if(dev) { 407 _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo); 408 409 dev->mode.num = info.num; 410 dev->mode.verticalRefresh = 411 (float)info.vsync_num / (float)info.vsync_den; 412 dev->mode.flags = info.flags; 413 dev->mode.imageWidth = info.image_width; 414 dev->mode.imageHeight = info.image_height; 415 dev->mode.pixmapWidth = info.pixmap_width; 416 dev->mode.pixmapHeight = info.pixmap_height; 417 dev->mode.bytesPerScanline = info.bytes_per_scanline; 418 dev->mode.byteOrder = info.byte_order; 419 dev->mode.depth = info.depth; 420 dev->mode.bitsPerPixel = info.bpp; 421 dev->mode.redMask = info.red_mask; 422 dev->mode.greenMask = info.green_mask; 423 dev->mode.blueMask = info.blue_mask; 424 dev->mode.visualClass = info.visual_class; 425 dev->mode.viewportWidth = info.viewport_width; 426 dev->mode.viewportHeight = info.viewport_height; 427 dev->mode.xViewportStep = info.viewport_xstep; 428 dev->mode.yViewportStep = info.viewport_ystep; 429 dev->mode.maxViewportX = info.viewport_xmax; 430 dev->mode.maxViewportY = info.viewport_ymax; 431 dev->mode.viewportFlags = info.viewport_flags; 432 dev->mode.reserved1 = info.reserved1; 433 dev->mode.reserved2 = info.reserved2; 434 435 if (info.name_size > 0 && info.name_size <= size) { 436 dev->mode.name = (char*)(&dev[1]); 437 _XRead(dpy, dev->mode.name, info.name_size); 438 dev->mode.name[info.name_size - 1] = '\0'; 439 } else { 440 dev->mode.name = NULL; 441 _XEatDataWords(dpy, rep.length); 442 } 443 444 dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0; 445 dev->data = XDGAGetMappedMemory(screen); 446 447 if(dev->data) 448 dev->data += rep.offset; 449 } 450 /* not sure what to do if the allocation fails */ 451 else 452 _XEatDataWords(dpy, rep.length); 453 } 454 } 455 456 UnlockDisplay(dpy); 457 SyncHandle(); 458 459 return dev; 460} 461 462 463void XDGASetViewport( 464 Display *dpy, 465 int screen, 466 int x, 467 int y, 468 int flags 469){ 470 XExtDisplayInfo *info = xdga_find_display (dpy); 471 xXDGASetViewportReq *req; 472 473 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 474 475 LockDisplay(dpy); 476 GetReq(XDGASetViewport, req); 477 req->reqType = info->codes->major_opcode; 478 req->dgaReqType = X_XDGASetViewport; 479 req->screen = screen; 480 req->x = x; 481 req->y = y; 482 req->flags = flags; 483 UnlockDisplay(dpy); 484 SyncHandle(); 485} 486 487 488void XDGAInstallColormap( 489 Display *dpy, 490 int screen, 491 Colormap cmap 492){ 493 XExtDisplayInfo *info = xdga_find_display (dpy); 494 xXDGAInstallColormapReq *req; 495 496 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 497 498 LockDisplay(dpy); 499 GetReq(XDGAInstallColormap, req); 500 req->reqType = info->codes->major_opcode; 501 req->dgaReqType = X_XDGAInstallColormap; 502 req->screen = screen; 503 req->cmap = cmap; 504 UnlockDisplay(dpy); 505 SyncHandle(); 506} 507 508void XDGASelectInput( 509 Display *dpy, 510 int screen, 511 long mask 512){ 513 XExtDisplayInfo *info = xdga_find_display (dpy); 514 xXDGASelectInputReq *req; 515 516 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 517 518 LockDisplay(dpy); 519 GetReq(XDGASelectInput, req); 520 req->reqType = info->codes->major_opcode; 521 req->dgaReqType = X_XDGASelectInput; 522 req->screen = screen; 523 req->mask = mask; 524 UnlockDisplay(dpy); 525 SyncHandle(); 526} 527 528void XDGAFillRectangle( 529 Display *dpy, 530 int screen, 531 int x, 532 int y, 533 unsigned int width, 534 unsigned int height, 535 unsigned long color 536){ 537 XExtDisplayInfo *info = xdga_find_display (dpy); 538 xXDGAFillRectangleReq *req; 539 540 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 541 542 LockDisplay(dpy); 543 GetReq(XDGAFillRectangle, req); 544 req->reqType = info->codes->major_opcode; 545 req->dgaReqType = X_XDGAFillRectangle; 546 req->screen = screen; 547 req->x = x; 548 req->y = y; 549 req->width = width; 550 req->height = height; 551 req->color = color; 552 UnlockDisplay(dpy); 553 SyncHandle(); 554} 555 556void XDGACopyArea( 557 Display *dpy, 558 int screen, 559 int srcx, 560 int srcy, 561 unsigned int width, 562 unsigned int height, 563 int dstx, 564 int dsty 565){ 566 XExtDisplayInfo *info = xdga_find_display (dpy); 567 xXDGACopyAreaReq *req; 568 569 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 570 571 LockDisplay(dpy); 572 GetReq(XDGACopyArea, req); 573 req->reqType = info->codes->major_opcode; 574 req->dgaReqType = X_XDGACopyArea; 575 req->screen = screen; 576 req->srcx = srcx; 577 req->srcy = srcy; 578 req->width = width; 579 req->height = height; 580 req->dstx = dstx; 581 req->dsty = dsty; 582 UnlockDisplay(dpy); 583 SyncHandle(); 584} 585 586void XDGACopyTransparentArea( 587 Display *dpy, 588 int screen, 589 int srcx, 590 int srcy, 591 unsigned int width, 592 unsigned int height, 593 int dstx, 594 int dsty, 595 unsigned long key 596){ 597 XExtDisplayInfo *info = xdga_find_display (dpy); 598 xXDGACopyTransparentAreaReq *req; 599 600 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 601 602 LockDisplay(dpy); 603 GetReq(XDGACopyTransparentArea, req); 604 req->reqType = info->codes->major_opcode; 605 req->dgaReqType = X_XDGACopyTransparentArea; 606 req->screen = screen; 607 req->srcx = srcx; 608 req->srcy = srcy; 609 req->width = width; 610 req->height = height; 611 req->dstx = dstx; 612 req->dsty = dsty; 613 req->key = key; 614 UnlockDisplay(dpy); 615 SyncHandle(); 616} 617 618 619int XDGAGetViewportStatus( 620 Display *dpy, 621 int screen 622){ 623 XExtDisplayInfo *info = xdga_find_display (dpy); 624 xXDGAGetViewportStatusReply rep; 625 xXDGAGetViewportStatusReq *req; 626 int status = 0; 627 628 XDGACheckExtension (dpy, info, 0); 629 630 LockDisplay(dpy); 631 GetReq(XDGAGetViewportStatus, req); 632 req->reqType = info->codes->major_opcode; 633 req->dgaReqType = X_XDGAGetViewportStatus; 634 req->screen = screen; 635 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) 636 status = rep.status; 637 UnlockDisplay(dpy); 638 SyncHandle(); 639 return status; 640} 641 642void XDGASync( 643 Display *dpy, 644 int screen 645){ 646 XExtDisplayInfo *info = xdga_find_display (dpy); 647 xXDGASyncReply rep; 648 xXDGASyncReq *req; 649 650 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 651 652 LockDisplay(dpy); 653 GetReq(XDGASync, req); 654 req->reqType = info->codes->major_opcode; 655 req->dgaReqType = X_XDGASync; 656 req->screen = screen; 657 _XReply(dpy, (xReply *)&rep, 0, xFalse); 658 UnlockDisplay(dpy); 659 SyncHandle(); 660} 661 662 663void XDGAChangePixmapMode( 664 Display *dpy, 665 int screen, 666 int *x, 667 int *y, 668 int mode 669){ 670 XExtDisplayInfo *info = xdga_find_display (dpy); 671 xXDGAChangePixmapModeReq *req; 672 xXDGAChangePixmapModeReply rep; 673 674 XextSimpleCheckExtension (dpy, info, xdga_extension_name); 675 676 LockDisplay(dpy); 677 GetReq(XDGAChangePixmapMode, req); 678 req->reqType = info->codes->major_opcode; 679 req->dgaReqType = X_XDGAChangePixmapMode; 680 req->screen = screen; 681 req->x = *x; 682 req->y = *y; 683 req->flags = mode; 684 _XReply(dpy, (xReply *)&rep, 0, xFalse); 685 *x = rep.x; 686 *y = rep.y; 687 UnlockDisplay(dpy); 688 SyncHandle(); 689} 690 691Colormap XDGACreateColormap( 692 Display *dpy, 693 int screen, 694 XDGADevice *dev, 695 int alloc 696){ 697 XExtDisplayInfo *info = xdga_find_display (dpy); 698 xXDGACreateColormapReq *req; 699 Colormap cid; 700 701 XDGACheckExtension (dpy, info, -1); 702 703 LockDisplay(dpy); 704 GetReq(XDGACreateColormap, req); 705 req->reqType = info->codes->major_opcode; 706 req->dgaReqType = X_XDGACreateColormap; 707 req->screen = screen; 708 req->mode = dev->mode.num; 709 req->alloc = alloc; 710 cid = req->id = XAllocID(dpy); 711 UnlockDisplay(dpy); 712 SyncHandle(); 713 714 return cid; 715} 716 717 718void XDGAKeyEventToXKeyEvent( 719 XDGAKeyEvent* dk, 720 XKeyEvent* xk 721){ 722 xk->type = dk->type; 723 xk->serial = dk->serial; 724 xk->send_event = False; 725 xk->display = dk->display; 726 xk->window = RootWindow(dk->display, dk->screen); 727 xk->root = xk->window; 728 xk->subwindow = None; 729 xk->time = dk->time; 730 xk->x = xk->y = xk->x_root = xk->y_root = 0; 731 xk->state = dk->state; 732 xk->keycode = dk->keycode; 733 xk->same_screen = True; 734} 735 736#include <X11/Xmd.h> 737#include <stdlib.h> 738#include <stdio.h> 739#include <fcntl.h> 740#include <sys/mman.h> 741#include <sys/wait.h> 742#include <signal.h> 743#include <unistd.h> 744 745#if defined(SVR4) && !defined(sun) 746#define DEV_MEM "/dev/pmem" 747#elif defined(SVR4) && defined(sun) 748#define DEV_MEM "/dev/xsvc" 749#elif defined(HAS_APERTURE_DRV) 750#define DEV_MEM "/dev/xf86" 751#else 752#define DEV_MEM "/dev/mem" 753#endif 754 755 756 757typedef struct _DGAMapRec{ 758 unsigned char *physical; 759 unsigned char *virtual; 760 CARD32 size; 761 int fd; 762 int screen; 763 struct _DGAMapRec *next; 764} DGAMapRec, *DGAMapPtr; 765 766static Bool 767DGAMapPhysical(int, const char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr); 768static void DGAUnmapPhysical(DGAMapPtr); 769 770static DGAMapPtr _Maps = NULL; 771 772 773unsigned char* 774XDGAGetMappedMemory(int screen) 775{ 776 DGAMapPtr pMap = _Maps; 777 unsigned char *pntr = NULL; 778 779 while(pMap != NULL) { 780 if(pMap->screen == screen) { 781 pntr = pMap->virtual; 782 break; 783 } 784 pMap = pMap->next; 785 } 786 787 return pntr; 788} 789 790Bool 791XDGAMapFramebuffer( 792 int screen, 793 char *name, /* optional device name */ 794 unsigned char* base, /* physical memory */ 795 CARD32 size, /* size */ 796 CARD32 offset, /* optional offset */ 797 CARD32 extra /* optional extra data */ 798){ 799 DGAMapPtr pMap = _Maps; 800 Bool result; 801 802 /* is it already mapped ? */ 803 while(pMap != NULL) { 804 if(pMap->screen == screen) 805 return True; 806 pMap = pMap->next; 807 } 808 809 if(extra & XDGANeedRoot) { 810 /* we should probably check if we have root permissions and 811 return False here */ 812 813 } 814 815 pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec)); 816 817 result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap); 818 819 if(result) { 820 pMap->next = _Maps; 821 _Maps = pMap; 822 } else 823 Xfree(pMap); 824 825 return result; 826} 827 828void 829XDGAUnmapFramebuffer(int screen) 830{ 831 DGAMapPtr pMap = _Maps; 832 DGAMapPtr pPrev = NULL; 833 834 /* is it already mapped */ 835 while(pMap != NULL) { 836 if(pMap->screen == screen) 837 break; 838 pPrev = pMap; 839 pMap = pMap->next; 840 } 841 842 if(!pMap) 843 return; 844 845 DGAUnmapPhysical(pMap); 846 847 if(!pPrev) 848 _Maps = pMap->next; 849 else 850 pPrev->next = pMap->next; 851 852 Xfree(pMap); 853} 854 855 856static Bool 857DGAMapPhysical( 858 int screen, 859 const char *name, /* optional device name */ 860 unsigned char* base, /* physical memory */ 861 CARD32 size, /* size */ 862 CARD32 offset, /* optional offset */ 863 CARD32 extra, /* optional extra data */ 864 DGAMapPtr pMap 865) { 866 867 base += offset; 868 869 pMap->screen = screen; 870 pMap->physical = base; 871 pMap->size = size; 872 873#ifndef MAP_FILE 874#define MAP_FILE 0 875#endif 876 if (!name) 877 name = DEV_MEM; 878 if ((pMap->fd = open(name, O_RDWR)) < 0) 879 return False; 880 pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE, 881 MAP_FILE | MAP_SHARED, pMap->fd, (off_t)(uintptr_t)base); 882 if (pMap->virtual == (void *)-1) 883 return False; 884 mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE); 885 886 return True; 887} 888 889 890 891static void 892DGAUnmapPhysical(DGAMapPtr pMap) 893{ 894 if (pMap->virtual && pMap->virtual != (void *)-1) { 895 mprotect(pMap->virtual,pMap->size, PROT_READ); 896 munmap(pMap->virtual, pMap->size); 897 pMap->virtual = 0; 898 } 899 if (pMap->fd >= 0) { 900 close(pMap->fd); 901 pMap->fd = -1; 902 } 903} 904