xref: /csrg-svn/sys/pmax/dev/xcfb.c (revision 56818)
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.1 (Berkeley) 11/15/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 #ifdef notyet
254 	    {
255 		pmKpCmd *kpCmdPtr;
256 		unsigned char *cp;
257 
258 		kpCmdPtr = (pmKpCmd *)data;
259 		if (kpCmdPtr->nbytes == 0)
260 			kpCmdPtr->cmd |= 0x80;
261 		if (!fp->GraphicsOpen)
262 			kpCmdPtr->cmd |= 1;
263 		(*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
264 		cp = &kpCmdPtr->par[0];
265 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
266 			if (kpCmdPtr->nbytes == 1)
267 				*cp |= 0x80;
268 			(*fp->KBDPutc)(fp->kbddev, (int)*cp);
269 		}
270 	    }
271 #endif /* notyet */
272 	    break;
273 
274 	case QIOCADDR:
275 		*(PM_Info **)data = &fp->fbu->scrInfo;
276 		break;
277 
278 	case QIOWCURSOR:
279 		xcfbLoadCursor((unsigned short *)data);
280 		break;
281 
282 	case QIOWCURSORCOLOR:
283 		xcfbCursorColor((unsigned int *)data);
284 		break;
285 
286 	case QIOSETCMAP:
287 		xcfbLoadColorMap((ColorMap *)data);
288 		break;
289 
290 	case QIOKERNLOOP:
291 		s = spltty();
292 		dtopDivertXInput = xcfbKbdEvent;
293 		dtopMouseEvent = xcfbMouseEvent;
294 		dtopMouseButtons = xcfbMouseButtons;
295 		splx(s);
296 		break;
297 
298 	case QIOKERNUNLOOP:
299 		s = spltty();
300 		dtopDivertXInput = (void (*)())0;
301 		dtopMouseEvent = (void (*)())0;
302 		dtopMouseButtons = (void (*)())0;
303 		splx(s);
304 		break;
305 
306 	case QIOVIDEOON:
307 		xcfbRestoreCursorColor();
308 		ims332_video_on();
309 		break;
310 
311 	case QIOVIDEOOFF:
312 		ims332_video_off();
313 		break;
314 
315 	default:
316 		printf("xcfb0: Unknown ioctl command %x\n", cmd);
317 		return (EINVAL);
318 	}
319 	return (0);
320 }
321 
322 xcfbselect(dev, flag, p)
323 	dev_t dev;
324 	int flag;
325 	struct proc *p;
326 {
327 	struct pmax_fb *fp = &xcfbfb;
328 
329 	switch (flag) {
330 	case FREAD:
331 		if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
332 			return (1);
333 		selrecord(p, &fp->selp);
334 		break;
335 	}
336 
337 	return (0);
338 }
339 
340 static u_char	cursor_RGB[6];	/* cursor color 2 & 3 */
341 
342 /*
343  *	Routines for the Inmos IMS-G332 Colour video controller
344  * 	Author: Alessandro Forin, Carnegie Mellon University
345  */
346 static u_int
347 ims332_read_register(regno)
348 {
349 	register u_char *regs = (u_char *)IMS332_ADDRESS;
350 	unsigned char *rptr;
351 	register u_int val, v1;
352 
353 	/* spec sez: */
354 	rptr = regs + 0x80000 + (regno << 4);
355 	val = *((volatile u_short *) rptr );
356 	v1  = *((volatile u_short *) regs );
357 
358 	return (val & 0xffff) | ((v1 & 0xff00) << 8);
359 }
360 
361 static void
362 ims332_write_register(regno, val)
363 	register unsigned int val;
364 {
365 	register u_char *regs = (u_char *)IMS332_ADDRESS;
366 	u_char *wptr;
367 
368 	/* spec sez: */
369 	wptr = regs + 0xa0000 + (regno << 4);
370 	*((volatile u_int *)(regs)) = (val >> 8) & 0xff00;
371 	*((volatile u_short *)(wptr)) = val;
372 }
373 
374 #define	assert_ims332_reset_bit(r)	*r &= ~0x40
375 #define	deassert_ims332_reset_bit(r)	*r |=  0x40
376 
377 /*
378  * Color map
379  */
380 static void
381 xcfbLoadColorMap(ptr)
382 	ColorMap *ptr;
383 {
384 	register int i;
385 
386 	if (ptr->index > 256)
387 		return;
388 	ims332_load_colormap_entry(ptr->index, ptr);
389 }
390 
391 static void
392 ims332_load_colormap_entry(entry, map)
393 	ColorMap *map;
394 {
395 	/* ?? stop VTG */
396 	ims332_write_register(IMS332_REG_LUT_BASE + (entry & 0xff),
397 			      (map->Entry.blue << 16) |
398 			      (map->Entry.green << 8) |
399 			      (map->Entry.red));
400 }
401 
402 static void
403 xcfbInitColorMap()
404 {
405 	register int i;
406 	ColorMap m;
407 
408 	m.Entry.red = m.Entry.green = m.Entry.blue = 0;
409 	ims332_load_colormap_entry(0, &m);
410 
411 	m.Entry.red = m.Entry.green = m.Entry.blue = 0xff;
412 	for (i = 1; i < 256; i++)
413 		ims332_load_colormap_entry(i, &m);
414 
415 	for (i = 0; i < 3; i++) {
416 		cursor_RGB[i] = 0x00;
417 		cursor_RGB[i + 3] = 0xff;
418 	}
419 	xcfbRestoreCursorColor();
420 }
421 
422 /*
423  * Video on/off
424  *
425  * It is unfortunate that X11 goes backward with white@0
426  * and black@1.  So we must stash away the zero-th entry
427  * and fix it while screen is off.  Also must remember
428  * it, sigh.
429  */
430 static struct {
431 	u_int	save;
432 	int	off;
433 } xcfb_vstate;
434 
435 static void
436 ims332_video_off()
437 {
438 	register u_int csr;
439 
440 	if (xcfb_vstate.off)
441 		return;
442 
443 	xcfb_vstate.save = ims332_read_register(IMS332_REG_LUT_BASE);
444 
445 	ims332_write_register(IMS332_REG_LUT_BASE, 0);
446 
447 	ims332_write_register(IMS332_REG_COLOR_MASK, 0);
448 
449 	/* cursor now */
450 	csr = ims332_read_register(IMS332_REG_CSR_A);
451 	csr |= IMS332_CSR_A_DISABLE_CURSOR;
452 	ims332_write_register(IMS332_REG_CSR_A, csr);
453 
454 	xcfb_vstate.off = 1;
455 }
456 
457 static void
458 ims332_video_on()
459 {
460 	register u_int csr;
461 
462 	if (!xcfb_vstate.off)
463 		return;
464 
465 	ims332_write_register(IMS332_REG_LUT_BASE, xcfb_vstate.save);
466 
467 	ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffffff);
468 
469 	/* cursor now */
470 	csr = ims332_read_register(IMS332_REG_CSR_A);
471 	csr &= ~IMS332_CSR_A_DISABLE_CURSOR;
472 	ims332_write_register(IMS332_REG_CSR_A, csr);
473 
474 	xcfb_vstate.off = 0;
475 }
476 
477 /*
478  * Cursor
479  */
480 void
481 xcfbPosCursor(x, y)
482 	register int x, y;
483 {
484 
485 	ims332_write_register(IMS332_REG_CURSOR_LOC,
486 		((x & 0xfff) << 12) | (y & 0xfff));
487 }
488 
489 /*
490  * xcfbRestoreCursorColor
491  */
492 static void
493 xcfbRestoreCursorColor()
494 {
495 
496 	/* Bg is color[0], Fg is color[1] */
497 	ims332_write_register(IMS332_REG_CURSOR_LUT_0,
498 			      (cursor_RGB[2] << 16) |
499 			      (cursor_RGB[1] << 8) |
500 			      (cursor_RGB[0]));
501 	ims332_write_register(IMS332_REG_CURSOR_LUT_1, 0x7f0000);
502 	ims332_write_register(IMS332_REG_CURSOR_LUT_2,
503 			      (cursor_RGB[5] << 16) |
504 			      (cursor_RGB[4] << 8) |
505 			      (cursor_RGB[3]));
506 }
507 
508 /*
509  * ----------------------------------------------------------------------------
510  *
511  * xcfbCursorColor --
512  *
513  *	Set the color of the cursor.
514  *
515  * Results:
516  *	None.
517  *
518  * Side effects:
519  *	None.
520  *
521  * ----------------------------------------------------------------------------
522  */
523 static void
524 xcfbCursorColor(color)
525 	unsigned int color[];
526 {
527 	register int i, j;
528 
529 	for (i = 0; i < 6; i++)
530 		cursor_RGB[i] = (u_char)(color[i] >> 8);
531 
532 	xcfbRestoreCursorColor();
533 }
534 
535 static void
536 xcfbLoadCursor(cursor)
537 	u_short *cursor;
538 {
539 	register int i, j, k, pos;
540 	register u_short ap, bp, out;
541 
542 	/*
543 	 * Fill in the cursor sprite using the A and B planes, as provided
544 	 * for the pmax.
545 	 * XXX This will have to change when the X server knows that this
546 	 * is not a pmax display.
547 	 */
548 	pos = 0;
549 	for (k = 0; k < 16; k++) {
550 		ap = *cursor;
551 		bp = *(cursor + 16);
552 		j = 0;
553 		while (j < 2) {
554 			out = 0;
555 			for (i = 0; i < 8; i++) {
556 				out = (out << 2) | ((ap & 0x1) << 1) |
557 					(bp & 0x1);
558 				ap >>= 1;
559 				bp >>= 1;
560 			}
561 			ims332_write_register(IMS332_REG_CURSOR_RAM + pos, out);
562 			pos++;
563 			j++;
564 		}
565 		while (j < 8) {
566 			ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0);
567 			pos++;
568 			j++;
569 		}
570 		cursor++;
571 	}
572 	while (pos < 512) {
573 		ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0);
574 		pos++;
575 	}
576 }
577 
578 /*
579  * Initialization
580  * (For some reason, X runs faster with the frame buffer cached?)
581  */
582 int
583 xcfbinit()
584 {
585 	register u_int *reset = (u_int *)IMS332_RESET_ADDRESS;
586 	register struct pmax_fb *fp = &xcfbfb;
587 
588 	fp->isMono = 0;
589 	fp->fr_addr = (char *)
590 		MACH_PHYS_TO_CACHED(XINE_PHYS_CFB_START + VRAM_OFFSET);
591 	fp->fbu = &xcfbu;
592 	fp->posCursor = xcfbPosCursor;
593 	fp->KBDPutc = dtopKBDPutc;
594 	fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT);
595 
596 	/*
597 	 * Initialize the screen.
598 	 */
599 #ifdef notdef
600 	assert_ims332_reset_bit(reset);
601 	DELAY(1);	/* specs sez 50ns.. */
602 	deassert_ims332_reset_bit(reset);
603 
604 	/* CLOCKIN appears to receive a 6.25 Mhz clock --> PLL 12 for 75Mhz monitor */
605 	ims332_write_register(IMS332_REG_BOOT, 12 | IMS332_BOOT_CLOCK_PLL);
606 
607 	/* initialize VTG */
608 	ims332_write_register(IMS332_REG_CSR_A,
609 				IMS332_BPP_8 | IMS332_CSR_A_DISABLE_CURSOR);
610 	DELAY(50);	/* spec does not say */
611 
612 	/* datapath registers (values taken from prom's settings) */
613 
614 	ims332_write_register(IMS332_REG_HALF_SYNCH, 0x10);
615 	ims332_write_register(IMS332_REG_BACK_PORCH, 0x21);
616 	ims332_write_register(IMS332_REG_DISPLAY, 0x100);
617 	ims332_write_register(IMS332_REG_SHORT_DIS, 0x5d);
618 	ims332_write_register(IMS332_REG_BROAD_PULSE, 0x9f);
619 	ims332_write_register(IMS332_REG_V_SYNC, 0xc);
620 	ims332_write_register(IMS332_REG_V_PRE_EQUALIZE, 2);
621 	ims332_write_register(IMS332_REG_V_POST_EQUALIZE, 2);
622 	ims332_write_register(IMS332_REG_V_BLANK, 0x2a);
623 	ims332_write_register(IMS332_REG_V_DISPLAY, 0x600);
624 	ims332_write_register(IMS332_REG_LINE_TIME, 0x146);
625 	ims332_write_register(IMS332_REG_LINE_START, 0x10);
626 	ims332_write_register(IMS332_REG_MEM_INIT, 0xa);
627 	ims332_write_register(IMS332_REG_XFER_DELAY, 0xa);
628 
629 	ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffff);
630 #endif
631 
632 	/*
633 	 * Initialize screen info.
634 	 */
635 	fp->fbu->scrInfo.max_row = 50;
636 	fp->fbu->scrInfo.max_col = 80;
637 	fp->fbu->scrInfo.max_x = 1024;
638 	fp->fbu->scrInfo.max_y = 768;
639 	fp->fbu->scrInfo.max_cur_x = 1023;
640 	fp->fbu->scrInfo.max_cur_y = 767;
641 	fp->fbu->scrInfo.version = 11;
642 	fp->fbu->scrInfo.mthreshold = 4;
643 	fp->fbu->scrInfo.mscale = 2;
644 	fp->fbu->scrInfo.min_cur_x = -15;
645 	fp->fbu->scrInfo.min_cur_y = -15;
646 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
647 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
648 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
649 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
650 	fp->fbu->scrInfo.qe.tcNext = 0;
651 
652 	xcfbInitColorMap();
653 
654 	ims332_write_register(IMS332_REG_CSR_A,
655 		IMS332_BPP_8 | IMS332_CSR_A_DMA_DISABLE | IMS332_CSR_A_VTG_ENABLE);
656 
657 	xcfbScreenInit();
658 	fbScroll(fp);
659 
660 	fp->initialized = 1;
661 	if (cn_tab.cn_fb == (struct pmax_fb *)0)
662 		cn_tab.cn_fb = fp;
663 	return (1);
664 }
665 
666 /*
667  * ----------------------------------------------------------------------------
668  *
669  * xcfbScreenInit --
670  *
671  *	Initialize the screen.
672  *
673  * Results:
674  *	None.
675  *
676  * Side effects:
677  *	The screen is initialized.
678  *
679  * ----------------------------------------------------------------------------
680  */
681 static void
682 xcfbScreenInit()
683 {
684 	register struct pmax_fb *fp = &xcfbfb;
685 
686 	/*
687 	 * Home the cursor.
688 	 * We want an LSI terminal emulation.  We want the graphics
689 	 * terminal to scroll from the bottom. So start at the bottom.
690 	 */
691 	fp->row = 49;
692 	fp->col = 0;
693 
694 	/*
695 	 * Load the cursor with the default values
696 	 *
697 	 */
698 	xcfbLoadCursor(defCursor);
699 }
700 
701 /*
702  * xcfb keyboard and mouse input. Just punt to the generic ones in fb.c
703  */
704 void
705 xcfbKbdEvent(ch)
706 	int ch;
707 {
708 	fbKbdEvent(ch, &xcfbfb);
709 }
710 
711 void
712 xcfbMouseEvent(newRepPtr)
713 	MouseReport *newRepPtr;
714 {
715 	fbMouseEvent(newRepPtr, &xcfbfb);
716 }
717 
718 void
719 xcfbMouseButtons(newRepPtr)
720 	MouseReport *newRepPtr;
721 {
722 	fbMouseButtons(newRepPtr, &xcfbfb);
723 }
724 #endif /* NDTOP */
725 #endif /* NXCFB */
726