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