1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ralph Campbell and Rick Macklem. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)xcfb.c 7.2 (Berkeley) 12/20/92 11 */ 12 13 /* 14 * Mach Operating System 15 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 16 * All Rights Reserved. 17 * 18 * Permission to use, copy, modify and distribute this software and its 19 * documentation is hereby granted, provided that both the copyright 20 * notice and this permission notice appear in all copies of the 21 * software, derivative works or modified versions, and any portions 22 * thereof, and that both notices appear in supporting documentation. 23 * 24 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 25 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 26 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 27 * 28 * Carnegie Mellon requests users of this software to return to 29 * 30 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 31 * School of Computer Science 32 * Carnegie Mellon University 33 * Pittsburgh PA 15213-3890 34 * 35 * any improvements or extensions that they make and grant Carnegie the 36 * rights to redistribute these changes. 37 */ 38 /* 39 * devGraphics.c -- 40 * 41 * This file contains machine-dependent routines for the graphics device. 42 * 43 * Copyright (C) 1989 Digital Equipment Corporation. 44 * Permission to use, copy, modify, and distribute this software and 45 * its documentation for any purpose and without fee is hereby granted, 46 * provided that the above copyright notice appears in all copies. 47 * Digital Equipment Corporation makes no representations about the 48 * suitability of this software for any purpose. It is provided "as is" 49 * without express or implied warranty. 50 * 51 * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, 52 * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; 53 */ 54 55 #include <xcfb.h> 56 #include <dtop.h> 57 #if NXCFB > 0 58 #if NDTOP == 0 59 xcfb needs dtop device 60 #else 61 62 #include <sys/param.h> 63 #include <sys/time.h> 64 #include <sys/kernel.h> 65 #include <sys/ioctl.h> 66 #include <sys/file.h> 67 #include <sys/errno.h> 68 #include <sys/proc.h> 69 #include <sys/mman.h> 70 71 #include <vm/vm.h> 72 73 #include <machine/machConst.h> 74 #include <machine/pmioctl.h> 75 76 #include <pmax/pmax/maxine.h> 77 #include <pmax/pmax/cons.h> 78 #include <pmax/pmax/pmaxtype.h> 79 80 #include <pmax/dev/device.h> 81 #include <pmax/dev/xcfbreg.h> 82 #include <pmax/dev/dtopreg.h> 83 #include <pmax/dev/fbreg.h> 84 85 /* 86 * These need to be mapped into user space. 87 */ 88 struct fbuaccess xcfbu; 89 struct pmax_fb xcfbfb; 90 91 /* 92 * Forward references. 93 */ 94 extern void fbScroll(); 95 96 static void xcfbScreenInit(); 97 static void xcfbLoadCursor(); 98 static void xcfbRestoreCursorColor(); 99 static void xcfbCursorColor(); 100 void xcfbPosCursor(); 101 static void xcfbInitColorMap(); 102 static void xcfbLoadColorMap(); 103 static u_int ims332_read_register(); 104 static void ims332_write_register(); 105 static void ims332_load_colormap_entry(); 106 static void ims332_video_off(); 107 static void ims332_video_on(); 108 109 extern void dtopKBDPutc(), fbKbdEvent(), fbMouseEvent(), fbMouseButtons(); 110 void xcfbKbdEvent(), xcfbMouseEvent(), xcfbMouseButtons(); 111 extern void (*dtopDivertXInput)(); 112 extern void (*dtopMouseEvent)(); 113 extern void (*dtopMouseButtons)(); 114 extern int pmax_boardtype; 115 extern u_short defCursor[32]; 116 extern struct consdev cn_tab; 117 118 int xcfbprobe(); 119 struct driver xcfbdriver = { 120 "xcfb", xcfbprobe, 0, 0, 121 }; 122 123 /* 124 * Test to see if device is present. 125 * Return true if found and initialized ok. 126 */ 127 /*ARGSUSED*/ 128 xcfbprobe(cp) 129 register struct pmax_ctlr *cp; 130 { 131 register struct pmax_fb *fp = &xcfbfb; 132 133 if (pmax_boardtype != DS_MAXINE) 134 return (0); 135 if (!fp->initialized && !xcfbinit()) 136 return (0); 137 printf("xcfb0 (color display)\n"); 138 return (1); 139 } 140 141 /*ARGSUSED*/ 142 xcfbopen(dev, flag) 143 dev_t dev; 144 int flag; 145 { 146 register struct pmax_fb *fp = &xcfbfb; 147 int s; 148 149 if (!fp->initialized) 150 return (ENXIO); 151 if (fp->GraphicsOpen) 152 return (EBUSY); 153 154 fp->GraphicsOpen = 1; 155 xcfbInitColorMap(); 156 /* 157 * Set up event queue for later 158 */ 159 fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 160 fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 161 fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 162 fp->fbu->scrInfo.qe.tcNext = 0; 163 fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 164 s = spltty(); 165 dtopDivertXInput = xcfbKbdEvent; 166 dtopMouseEvent = xcfbMouseEvent; 167 dtopMouseButtons = xcfbMouseButtons; 168 splx(s); 169 return (0); 170 } 171 172 /*ARGSUSED*/ 173 xcfbclose(dev, flag) 174 dev_t dev; 175 int flag; 176 { 177 register struct pmax_fb *fp = &xcfbfb; 178 int s; 179 180 if (!fp->GraphicsOpen) 181 return (EBADF); 182 183 fp->GraphicsOpen = 0; 184 xcfbInitColorMap(); 185 s = spltty(); 186 dtopDivertXInput = (void (*)())0; 187 dtopMouseEvent = (void (*)())0; 188 dtopMouseButtons = (void (*)())0; 189 splx(s); 190 xcfbScreenInit(); 191 vmUserUnmap(); 192 bzero((caddr_t)fp->fr_addr, 1024 * 768); 193 xcfbPosCursor(fp->col * 8, fp->row * 15); 194 return (0); 195 } 196 197 /*ARGSUSED*/ 198 xcfbioctl(dev, cmd, data, flag) 199 dev_t dev; 200 caddr_t data; 201 { 202 register struct pmax_fb *fp = &xcfbfb; 203 int s; 204 205 switch (cmd) { 206 case QIOCGINFO: 207 { 208 caddr_t addr; 209 extern caddr_t vmUserMap(); 210 211 /* 212 * Map the all the data the user needs access to into 213 * user space. 214 */ 215 addr = vmUserMap(sizeof(struct fbuaccess), (unsigned)fp->fbu); 216 if (addr == (caddr_t)0) 217 goto mapError; 218 *(PM_Info **)data = &((struct fbuaccess *)addr)->scrInfo; 219 fp->fbu->scrInfo.qe.events = ((struct fbuaccess *)addr)->events; 220 fp->fbu->scrInfo.qe.tcs = ((struct fbuaccess *)addr)->tcs; 221 fp->fbu->scrInfo.planemask = (char *)0; 222 /* 223 * Map the frame buffer into the user's address space. 224 */ 225 addr = vmUserMap(1024 * 1024, (unsigned)fp->fr_addr); 226 if (addr == (caddr_t)0) 227 goto mapError; 228 fp->fbu->scrInfo.bitmap = (char *)addr; 229 break; 230 231 mapError: 232 vmUserUnmap(); 233 printf("Cannot map shared data structures\n"); 234 return (EIO); 235 } 236 237 case QIOCPMSTATE: 238 /* 239 * Set mouse state. 240 */ 241 fp->fbu->scrInfo.mouse = *(pmCursor *)data; 242 xcfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 243 break; 244 245 case QIOCINIT: 246 /* 247 * Initialize the screen. 248 */ 249 xcfbScreenInit(); 250 break; 251 252 case QIOCKPCMD: 253 { 254 pmKpCmd *kpCmdPtr; 255 unsigned char *cp; 256 257 kpCmdPtr = (pmKpCmd *)data; 258 if (kpCmdPtr->nbytes == 0) 259 kpCmdPtr->cmd |= 0x80; 260 if (!fp->GraphicsOpen) 261 kpCmdPtr->cmd |= 1; 262 (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 263 cp = &kpCmdPtr->par[0]; 264 for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 265 if (kpCmdPtr->nbytes == 1) 266 *cp |= 0x80; 267 (*fp->KBDPutc)(fp->kbddev, (int)*cp); 268 } 269 } 270 break; 271 272 case QIOCADDR: 273 *(PM_Info **)data = &fp->fbu->scrInfo; 274 break; 275 276 case QIOWCURSOR: 277 xcfbLoadCursor((unsigned short *)data); 278 break; 279 280 case QIOWCURSORCOLOR: 281 xcfbCursorColor((unsigned int *)data); 282 break; 283 284 case QIOSETCMAP: 285 xcfbLoadColorMap((ColorMap *)data); 286 break; 287 288 case QIOKERNLOOP: 289 s = spltty(); 290 dtopDivertXInput = xcfbKbdEvent; 291 dtopMouseEvent = xcfbMouseEvent; 292 dtopMouseButtons = xcfbMouseButtons; 293 splx(s); 294 break; 295 296 case QIOKERNUNLOOP: 297 s = spltty(); 298 dtopDivertXInput = (void (*)())0; 299 dtopMouseEvent = (void (*)())0; 300 dtopMouseButtons = (void (*)())0; 301 splx(s); 302 break; 303 304 case QIOVIDEOON: 305 xcfbRestoreCursorColor(); 306 ims332_video_on(); 307 break; 308 309 case QIOVIDEOOFF: 310 ims332_video_off(); 311 break; 312 313 default: 314 printf("xcfb0: Unknown ioctl command %x\n", cmd); 315 return (EINVAL); 316 } 317 return (0); 318 } 319 320 xcfbselect(dev, flag, p) 321 dev_t dev; 322 int flag; 323 struct proc *p; 324 { 325 struct pmax_fb *fp = &xcfbfb; 326 327 switch (flag) { 328 case FREAD: 329 if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 330 return (1); 331 selrecord(p, &fp->selp); 332 break; 333 } 334 335 return (0); 336 } 337 338 static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 339 340 /* 341 * Routines for the Inmos IMS-G332 Colour video controller 342 * Author: Alessandro Forin, Carnegie Mellon University 343 */ 344 static u_int 345 ims332_read_register(regno) 346 { 347 register u_char *regs = (u_char *)IMS332_ADDRESS; 348 unsigned char *rptr; 349 register u_int val, v1; 350 351 /* spec sez: */ 352 rptr = regs + 0x80000 + (regno << 4); 353 val = *((volatile u_short *) rptr ); 354 v1 = *((volatile u_short *) regs ); 355 356 return (val & 0xffff) | ((v1 & 0xff00) << 8); 357 } 358 359 static void 360 ims332_write_register(regno, val) 361 register unsigned int val; 362 { 363 register u_char *regs = (u_char *)IMS332_ADDRESS; 364 u_char *wptr; 365 366 /* spec sez: */ 367 wptr = regs + 0xa0000 + (regno << 4); 368 *((volatile u_int *)(regs)) = (val >> 8) & 0xff00; 369 *((volatile u_short *)(wptr)) = val; 370 } 371 372 #define assert_ims332_reset_bit(r) *r &= ~0x40 373 #define deassert_ims332_reset_bit(r) *r |= 0x40 374 375 /* 376 * Color map 377 */ 378 static void 379 xcfbLoadColorMap(ptr) 380 ColorMap *ptr; 381 { 382 register int i; 383 384 if (ptr->index > 256) 385 return; 386 ims332_load_colormap_entry(ptr->index, ptr); 387 } 388 389 static void 390 ims332_load_colormap_entry(entry, map) 391 ColorMap *map; 392 { 393 /* ?? stop VTG */ 394 ims332_write_register(IMS332_REG_LUT_BASE + (entry & 0xff), 395 (map->Entry.blue << 16) | 396 (map->Entry.green << 8) | 397 (map->Entry.red)); 398 } 399 400 static void 401 xcfbInitColorMap() 402 { 403 register int i; 404 ColorMap m; 405 406 m.Entry.red = m.Entry.green = m.Entry.blue = 0; 407 ims332_load_colormap_entry(0, &m); 408 409 m.Entry.red = m.Entry.green = m.Entry.blue = 0xff; 410 for (i = 1; i < 256; i++) 411 ims332_load_colormap_entry(i, &m); 412 413 for (i = 0; i < 3; i++) { 414 cursor_RGB[i] = 0x00; 415 cursor_RGB[i + 3] = 0xff; 416 } 417 xcfbRestoreCursorColor(); 418 } 419 420 /* 421 * Video on/off 422 * 423 * It is unfortunate that X11 goes backward with white@0 424 * and black@1. So we must stash away the zero-th entry 425 * and fix it while screen is off. Also must remember 426 * it, sigh. 427 */ 428 static struct { 429 u_int save; 430 int off; 431 } xcfb_vstate; 432 433 static void 434 ims332_video_off() 435 { 436 register u_int csr; 437 438 if (xcfb_vstate.off) 439 return; 440 441 xcfb_vstate.save = ims332_read_register(IMS332_REG_LUT_BASE); 442 443 ims332_write_register(IMS332_REG_LUT_BASE, 0); 444 445 ims332_write_register(IMS332_REG_COLOR_MASK, 0); 446 447 /* cursor now */ 448 csr = ims332_read_register(IMS332_REG_CSR_A); 449 csr |= IMS332_CSR_A_DISABLE_CURSOR; 450 ims332_write_register(IMS332_REG_CSR_A, csr); 451 452 xcfb_vstate.off = 1; 453 } 454 455 static void 456 ims332_video_on() 457 { 458 register u_int csr; 459 460 if (!xcfb_vstate.off) 461 return; 462 463 ims332_write_register(IMS332_REG_LUT_BASE, xcfb_vstate.save); 464 465 ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffffff); 466 467 /* cursor now */ 468 csr = ims332_read_register(IMS332_REG_CSR_A); 469 csr &= ~IMS332_CSR_A_DISABLE_CURSOR; 470 ims332_write_register(IMS332_REG_CSR_A, csr); 471 472 xcfb_vstate.off = 0; 473 } 474 475 /* 476 * Cursor 477 */ 478 void 479 xcfbPosCursor(x, y) 480 register int x, y; 481 { 482 register struct pmax_fb *fp = &xcfbfb; 483 484 if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 485 y = fp->fbu->scrInfo.max_cur_y; 486 if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 487 x = fp->fbu->scrInfo.max_cur_x; 488 fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 489 fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 490 ims332_write_register(IMS332_REG_CURSOR_LOC, 491 ((x & 0xfff) << 12) | (y & 0xfff)); 492 } 493 494 /* 495 * xcfbRestoreCursorColor 496 */ 497 static void 498 xcfbRestoreCursorColor() 499 { 500 501 /* Bg is color[0], Fg is color[1] */ 502 ims332_write_register(IMS332_REG_CURSOR_LUT_0, 503 (cursor_RGB[2] << 16) | 504 (cursor_RGB[1] << 8) | 505 (cursor_RGB[0])); 506 ims332_write_register(IMS332_REG_CURSOR_LUT_1, 0x7f0000); 507 ims332_write_register(IMS332_REG_CURSOR_LUT_2, 508 (cursor_RGB[5] << 16) | 509 (cursor_RGB[4] << 8) | 510 (cursor_RGB[3])); 511 } 512 513 /* 514 * ---------------------------------------------------------------------------- 515 * 516 * xcfbCursorColor -- 517 * 518 * Set the color of the cursor. 519 * 520 * Results: 521 * None. 522 * 523 * Side effects: 524 * None. 525 * 526 * ---------------------------------------------------------------------------- 527 */ 528 static void 529 xcfbCursorColor(color) 530 unsigned int color[]; 531 { 532 register int i, j; 533 534 for (i = 0; i < 6; i++) 535 cursor_RGB[i] = (u_char)(color[i] >> 8); 536 537 xcfbRestoreCursorColor(); 538 } 539 540 static void 541 xcfbLoadCursor(cursor) 542 u_short *cursor; 543 { 544 register int i, j, k, pos; 545 register u_short ap, bp, out; 546 547 /* 548 * Fill in the cursor sprite using the A and B planes, as provided 549 * for the pmax. 550 * XXX This will have to change when the X server knows that this 551 * is not a pmax display. 552 */ 553 pos = 0; 554 for (k = 0; k < 16; k++) { 555 ap = *cursor; 556 bp = *(cursor + 16); 557 j = 0; 558 while (j < 2) { 559 out = 0; 560 for (i = 0; i < 8; i++) { 561 out = ((out >> 2) & 0x3fff) | 562 ((ap & 0x1) << 15) | 563 ((bp & 0x1) << 14); 564 ap >>= 1; 565 bp >>= 1; 566 } 567 ims332_write_register(IMS332_REG_CURSOR_RAM + pos, out); 568 pos++; 569 j++; 570 } 571 while (j < 8) { 572 ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0); 573 pos++; 574 j++; 575 } 576 cursor++; 577 } 578 while (pos < 512) { 579 ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0); 580 pos++; 581 } 582 } 583 584 /* 585 * Initialization 586 */ 587 int 588 xcfbinit() 589 { 590 register u_int *reset = (u_int *)IMS332_RESET_ADDRESS; 591 register struct pmax_fb *fp = &xcfbfb; 592 593 fp->isMono = 0; 594 595 /* 596 * Or Cached? A comment in the Mach driver suggests that the X server 597 * runs faster in cached address space, but the X server is going 598 * to blow away the data cache whenever it updates the screen, so.. 599 */ 600 fp->fr_addr = (char *) 601 MACH_PHYS_TO_UNCACHED(XINE_PHYS_CFB_START + VRAM_OFFSET); 602 603 /* 604 * Must be in Uncached space or the Xserver sees a stale version of 605 * the event queue and acts totally wacko. I don't understand this, 606 * since the R3000 uses a physical address cache? 607 */ 608 fp->fbu = (struct fbuaccess *) 609 MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&xcfbu)); 610 fp->posCursor = xcfbPosCursor; 611 fp->KBDPutc = dtopKBDPutc; 612 fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT); 613 614 /* 615 * Initialize the screen. 616 */ 617 #ifdef notdef 618 assert_ims332_reset_bit(reset); 619 DELAY(1); /* specs sez 50ns.. */ 620 deassert_ims332_reset_bit(reset); 621 622 /* CLOCKIN appears to receive a 6.25 Mhz clock --> PLL 12 for 75Mhz monitor */ 623 ims332_write_register(IMS332_REG_BOOT, 12 | IMS332_BOOT_CLOCK_PLL); 624 625 /* initialize VTG */ 626 ims332_write_register(IMS332_REG_CSR_A, 627 IMS332_BPP_8 | IMS332_CSR_A_DISABLE_CURSOR); 628 DELAY(50); /* spec does not say */ 629 630 /* datapath registers (values taken from prom's settings) */ 631 632 ims332_write_register(IMS332_REG_HALF_SYNCH, 0x10); 633 ims332_write_register(IMS332_REG_BACK_PORCH, 0x21); 634 ims332_write_register(IMS332_REG_DISPLAY, 0x100); 635 ims332_write_register(IMS332_REG_SHORT_DIS, 0x5d); 636 ims332_write_register(IMS332_REG_BROAD_PULSE, 0x9f); 637 ims332_write_register(IMS332_REG_V_SYNC, 0xc); 638 ims332_write_register(IMS332_REG_V_PRE_EQUALIZE, 2); 639 ims332_write_register(IMS332_REG_V_POST_EQUALIZE, 2); 640 ims332_write_register(IMS332_REG_V_BLANK, 0x2a); 641 ims332_write_register(IMS332_REG_V_DISPLAY, 0x600); 642 ims332_write_register(IMS332_REG_LINE_TIME, 0x146); 643 ims332_write_register(IMS332_REG_LINE_START, 0x10); 644 ims332_write_register(IMS332_REG_MEM_INIT, 0xa); 645 ims332_write_register(IMS332_REG_XFER_DELAY, 0xa); 646 647 ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffff); 648 #endif 649 650 /* 651 * Initialize screen info. 652 */ 653 fp->fbu->scrInfo.max_row = 50; 654 fp->fbu->scrInfo.max_col = 80; 655 fp->fbu->scrInfo.max_x = 1024; 656 fp->fbu->scrInfo.max_y = 768; 657 fp->fbu->scrInfo.max_cur_x = 1008; 658 fp->fbu->scrInfo.max_cur_y = 752; 659 fp->fbu->scrInfo.version = 11; 660 fp->fbu->scrInfo.mthreshold = 4; 661 fp->fbu->scrInfo.mscale = 2; 662 fp->fbu->scrInfo.min_cur_x = -15; 663 fp->fbu->scrInfo.min_cur_y = -15; 664 fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 665 fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 666 fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 667 fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 668 fp->fbu->scrInfo.qe.tcNext = 0; 669 670 xcfbInitColorMap(); 671 672 ims332_write_register(IMS332_REG_CSR_A, 673 IMS332_BPP_8 | IMS332_CSR_A_DMA_DISABLE | IMS332_CSR_A_VTG_ENABLE); 674 675 xcfbScreenInit(); 676 fbScroll(fp); 677 678 fp->initialized = 1; 679 if (cn_tab.cn_fb == (struct pmax_fb *)0) 680 cn_tab.cn_fb = fp; 681 return (1); 682 } 683 684 /* 685 * ---------------------------------------------------------------------------- 686 * 687 * xcfbScreenInit -- 688 * 689 * Initialize the screen. 690 * 691 * Results: 692 * None. 693 * 694 * Side effects: 695 * The screen is initialized. 696 * 697 * ---------------------------------------------------------------------------- 698 */ 699 static void 700 xcfbScreenInit() 701 { 702 register struct pmax_fb *fp = &xcfbfb; 703 704 /* 705 * Home the cursor. 706 * We want an LSI terminal emulation. We want the graphics 707 * terminal to scroll from the bottom. So start at the bottom. 708 */ 709 fp->row = 49; 710 fp->col = 0; 711 712 /* 713 * Load the cursor with the default values 714 * 715 */ 716 xcfbLoadCursor(defCursor); 717 } 718 719 /* 720 * xcfb keyboard and mouse input. Just punt to the generic ones in fb.c 721 */ 722 void 723 xcfbKbdEvent(ch) 724 int ch; 725 { 726 fbKbdEvent(ch, &xcfbfb); 727 } 728 729 void 730 xcfbMouseEvent(newRepPtr) 731 MouseReport *newRepPtr; 732 { 733 fbMouseEvent(newRepPtr, &xcfbfb); 734 } 735 736 void 737 xcfbMouseButtons(newRepPtr) 738 MouseReport *newRepPtr; 739 { 740 fbMouseButtons(newRepPtr, &xcfbfb); 741 } 742 #endif /* NDTOP */ 743 #endif /* NXCFB */ 744