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