1 /* $NetBSD: mfb.c,v 1.53 2008/12/17 20:51:35 cegger Exp $ */
4 * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: mfb.c,v 1.53 2008/12/17 20:51:35 cegger Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/device.h>
39 #include <sys/malloc.h>
41 #include <sys/ioctl.h>
46 #include <dev/wscons/wsconsio.h>
47 #include <dev/wscons/wsdisplayvar.h>
49 #include <dev/rasops/rasops.h>
50 #include <dev/wsfont/wsfont.h>
52 #include <dev/tc/tcvar.h>
53 #include <dev/ic/bt431reg.h>
55 #include <uvm/uvm_extern.h>
58 #define machine_btop(x) mips_btop(MIPS_KSEG1_TO_PHYS(x))
62 #define machine_btop(x) alpha_btop(ALPHA_K0SEG_TO_PHYS(x))
65 /* Bt455 hardware registers, memory-mapped in 32bit stride */
71 /* Bt431 hardware registers, memory-mapped in 32bit stride */
77 #define REGWRITE32(p,i,v) do { \
78 *(volatile uint32_t *)((p) + (i)) = (v); tc_wmb(); \
81 #define SELECT455(p,r) do { \
82 REGWRITE32((p), bt_reg, (r)); \
83 REGWRITE32((p), bt_clr, 0); \
86 #define TWIN(x) ((x)|((x) << 8))
87 #define TWIN_LO(x) (twin = (x) & 0x00ff, twin << 8 | twin)
88 #define TWIN_HI(x) (twin = (x) & 0xff00, twin | twin >> 8)
90 #define SELECT431(p,r) do { \
91 REGWRITE32((p), bt_lo, TWIN(r)); \
92 REGWRITE32((p), bt_hi, 0); \
96 struct wsdisplay_curpos cc_pos
;
97 struct wsdisplay_curpos cc_hot
;
98 struct wsdisplay_curpos cc_size
;
99 struct wsdisplay_curpos cc_magic
;
100 #define CURSOR_MAX_SIZE 64
102 uint64_t cc_image
[CURSOR_MAX_SIZE
];
103 uint64_t cc_mask
[CURSOR_MAX_SIZE
];
109 struct rasops_info
*sc_ri
;
110 struct hwcursor64 sc_cursor
; /* software copy of cursor */
112 int sc_curenb
; /* cursor sprite enabled */
113 int sc_changed
; /* need update of hardware */
117 #define MX_MAGIC_X 360
118 #define MX_MAGIC_Y 36
120 #define MX_FB_OFFSET 0x200000
121 #define MX_FB_SIZE 0x200000
122 #define MX_BT455_OFFSET 0x100000
123 #define MX_BT431_OFFSET 0x180000
124 #define MX_IREQ_OFFSET 0x080000 /* Interrupt req. control */
126 static int mfbmatch(device_t
, cfdata_t
, void *);
127 static void mfbattach(device_t
, device_t
, void *);
129 CFATTACH_DECL_NEW(mfb
, sizeof(struct mfb_softc
),
130 mfbmatch
, mfbattach
, NULL
, NULL
);
132 static void mfb_common_init(struct rasops_info
*);
133 static struct rasops_info mfb_console_ri
;
134 static tc_addr_t mfb_consaddr
;
136 static struct wsscreen_descr mfb_stdscreen
= {
143 static const struct wsscreen_descr
*_mfb_scrlist
[] = {
147 static const struct wsscreen_list mfb_screenlist
= {
148 sizeof(_mfb_scrlist
) / sizeof(struct wsscreen_descr
*), _mfb_scrlist
151 static int mfbioctl(void *, void *, u_long
, void *, int, struct lwp
*);
152 static paddr_t
mfbmmap(void *, void *, off_t
, int);
154 static int mfb_alloc_screen(void *, const struct wsscreen_descr
*,
155 void **, int *, int *, long *);
156 static void mfb_free_screen(void *, void *);
157 static int mfb_show_screen(void *, void *, int,
158 void (*) (void *, int, int), void *);
160 static const struct wsdisplay_accessops mfb_accessops
= {
169 int mfb_cnattach(tc_addr_t
);
170 static int mfbintr(void *);
171 static void mfbhwinit(void *);
173 static int set_cursor(struct mfb_softc
*, struct wsdisplay_cursor
*);
174 static int get_cursor(struct mfb_softc
*, struct wsdisplay_cursor
*);
175 static void set_curpos(struct mfb_softc
*, struct wsdisplay_curpos
*);
177 /* bit order reverse */
178 static const uint8_t flip
[256] = {
179 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
180 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
181 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
182 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
183 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
184 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
185 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
186 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
187 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
188 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
189 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
190 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
191 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
192 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
193 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
194 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
195 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
196 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
197 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
198 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
199 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
200 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
201 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
202 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
203 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
204 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
205 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
206 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
207 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
208 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
209 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
210 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
214 mfbmatch(device_t parent
, cfdata_t match
, void *aux
)
216 struct tc_attach_args
*ta
= aux
;
218 if (strncmp("PMAG-AA ", ta
->ta_modname
, TC_ROM_LLEN
) != 0)
225 mfbattach(device_t parent
, device_t self
, void *aux
)
227 struct mfb_softc
*sc
= device_private(self
);
228 struct tc_attach_args
*ta
= aux
;
229 struct rasops_info
*ri
;
230 struct wsemuldisplaydev_attach_args waa
;
232 volatile register int junk
;
234 console
= (ta
->ta_addr
== mfb_consaddr
);
236 sc
->sc_ri
= ri
= &mfb_console_ri
;
240 ri
= malloc(sizeof(struct rasops_info
),
243 printf(": can't alloc memory\n");
246 memset(ri
, 0, sizeof(struct rasops_info
));
248 ri
->ri_hw
= (void *)ta
->ta_addr
;
252 printf(": %dx%d, 1bpp\n", ri
->ri_width
, ri
->ri_height
);
254 sc
->sc_vaddr
= ta
->ta_addr
;
255 sc
->sc_cursor
.cc_magic
.x
= MX_MAGIC_X
;
256 sc
->sc_cursor
.cc_magic
.y
= MX_MAGIC_Y
;
257 sc
->sc_blanked
= sc
->sc_curenb
= 0;
259 tc_intr_establish(parent
, ta
->ta_cookie
, IPL_TTY
, mfbintr
, sc
);
261 /* clear any pending interrupts */
262 *(uint8_t *)((char *)ri
->ri_hw
+ MX_IREQ_OFFSET
) = 0;
263 junk
= *(uint8_t *)((char *)ri
->ri_hw
+ MX_IREQ_OFFSET
);
264 *(uint8_t *)((char *)ri
->ri_hw
+ MX_IREQ_OFFSET
) = 1;
266 waa
.console
= console
;
267 waa
.scrdata
= &mfb_screenlist
;
268 waa
.accessops
= &mfb_accessops
;
269 waa
.accesscookie
= sc
;
271 config_found(self
, &waa
, wsemuldisplaydevprint
);
275 mfb_common_init(struct rasops_info
*ri
)
280 base
= (void *)ri
->ri_hw
;
282 /* initialize colormap and cursor hardware */
285 ri
->ri_flg
= RI_CENTER
| RI_FORCEMONO
;
286 ri
->ri_depth
= 8; /* !! watch out !! */
288 ri
->ri_height
= 1024;
289 ri
->ri_stride
= 2048;
290 ri
->ri_bits
= base
+ MX_FB_OFFSET
;
292 /* clear the screen */
293 memset(ri
->ri_bits
, 0, ri
->ri_stride
* ri
->ri_height
);
296 /* prefer 12 pixel wide font */
297 cookie
= wsfont_find(NULL
, 12, 0, 0, WSDISPLAY_FONTORDER_L2R
,
298 WSDISPLAY_FONTORDER_L2R
);
300 cookie
= wsfont_find(NULL
, 0, 0, 0, WSDISPLAY_FONTORDER_L2R
,
301 WSDISPLAY_FONTORDER_L2R
);
303 printf("mfb: font table is empty\n");
307 if (wsfont_lock(cookie
, &ri
->ri_font
)) {
308 printf("mfb: couldn't lock font\n");
311 ri
->ri_wsfcookie
= cookie
;
313 rasops_init(ri
, 34, 80);
315 /* XXX shouldn't be global */
316 mfb_stdscreen
.nrows
= ri
->ri_rows
;
317 mfb_stdscreen
.ncols
= ri
->ri_cols
;
318 mfb_stdscreen
.textops
= &ri
->ri_ops
;
319 mfb_stdscreen
.capabilities
= ri
->ri_caps
;
323 mfbioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
325 struct mfb_softc
*sc
= v
;
326 struct rasops_info
*ri
= sc
->sc_ri
;
330 case WSDISPLAYIO_GTYPE
:
331 *(u_int
*)data
= WSDISPLAY_TYPE_MFB
;
334 case WSDISPLAYIO_GINFO
:
335 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
336 wsd_fbip
->height
= ri
->ri_height
;
337 wsd_fbip
->width
= ri
->ri_width
;
338 wsd_fbip
->depth
= ri
->ri_depth
;
339 wsd_fbip
->cmsize
= 0;
343 case WSDISPLAYIO_GETCMAP
:
344 case WSDISPLAYIO_PUTCMAP
:
345 return (EPASSTHROUGH
);
347 case WSDISPLAYIO_SVIDEO
:
348 turnoff
= *(int *)data
== WSDISPLAYIO_VIDEO_OFF
;
349 if (sc
->sc_blanked
!= turnoff
) {
350 sc
->sc_blanked
= turnoff
;
351 #if 0 /* XXX later XXX */
353 - assign Bt455 cmap
[1].green with value
0 (black
),
354 - assign Bt431
register #0 with value 0x04 to hide sprite cursor.
355 #endif /* XXX XXX XXX */
359 case WSDISPLAYIO_GVIDEO
:
360 *(u_int
*)data
= sc
->sc_blanked
?
361 WSDISPLAYIO_VIDEO_OFF
: WSDISPLAYIO_VIDEO_ON
;
364 case WSDISPLAYIO_GCURPOS
:
365 *(struct wsdisplay_curpos
*)data
= sc
->sc_cursor
.cc_pos
;
368 case WSDISPLAYIO_SCURPOS
:
370 set_curpos(sc
, (struct wsdisplay_curpos
*)data
);
371 sc
->sc_changed
|= WSDISPLAY_CURSOR_DOPOS
;
375 case WSDISPLAYIO_GCURMAX
:
376 ((struct wsdisplay_curpos
*)data
)->x
=
377 ((struct wsdisplay_curpos
*)data
)->y
= CURSOR_MAX_SIZE
;
380 case WSDISPLAYIO_GCURSOR
:
381 return get_cursor(sc
, (struct wsdisplay_cursor
*)data
);
383 case WSDISPLAYIO_SCURSOR
:
384 return set_cursor(sc
, (struct wsdisplay_cursor
*)data
);
386 case WSDISPLAYIO_SMODE
:
387 if (*(int *)data
== WSDISPLAYIO_MODE_EMUL
) {
391 sc
->sc_changed
|= WSDISPLAY_CURSOR_DOCUR
;
396 return (EPASSTHROUGH
);
400 mfbmmap(void *v
, void *vs
, off_t offset
, int prot
)
402 struct mfb_softc
*sc
= v
;
404 if (offset
>= MX_FB_SIZE
|| offset
< 0)
406 return machine_btop(sc
->sc_vaddr
+ MX_FB_OFFSET
+ offset
);
410 mfb_alloc_screen(void *v
, const struct wsscreen_descr
*type
, void **cookiep
,
411 int *curxp
, int *curyp
, long *attrp
)
413 struct mfb_softc
*sc
= v
;
414 struct rasops_info
*ri
= sc
->sc_ri
;
417 if (sc
->nscreens
> 0)
420 *cookiep
= ri
; /* one and only for now */
423 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
430 mfb_free_screen(void *v
, void *cookie
)
432 struct mfb_softc
*sc
= v
;
434 if (sc
->sc_ri
== &mfb_console_ri
)
435 panic("mfb_free_screen: console");
441 mfb_show_screen(void *v
, void *cookie
, int waitok
,
442 void (*cb
)(void *, int, int), void *cbarg
)
449 mfb_cnattach(tc_addr_t addr
)
451 struct rasops_info
*ri
;
454 ri
= &mfb_console_ri
;
455 ri
->ri_hw
= (void *)addr
;
457 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
458 wsdisplay_cnattach(&mfb_stdscreen
, ri
, 0, 0, defattr
);
466 struct mfb_softc
*sc
= arg
;
467 char *base
, *vdac
, *curs
;
469 volatile register int junk
;
471 base
= (void *)sc
->sc_ri
->ri_hw
;
472 junk
= *(uint8_t *)(base
+ MX_IREQ_OFFSET
);
474 *(uint8_t *)(base
+ MX_IREQ_OFFSET
) = 0;
476 if (sc
->sc_changed
== 0)
479 vdac
= base
+ MX_BT455_OFFSET
;
480 curs
= base
+ MX_BT431_OFFSET
;
482 if (v
& WSDISPLAY_CURSOR_DOCUR
) {
485 onoff
= (sc
->sc_curenb
) ? 0x4444 : 0x0404;
486 SELECT431(curs
, BT431_REG_COMMAND
);
487 REGWRITE32(curs
, bt_ctl
, onoff
);
489 if (v
& (WSDISPLAY_CURSOR_DOPOS
| WSDISPLAY_CURSOR_DOHOT
)) {
493 x
= sc
->sc_cursor
.cc_pos
.x
- sc
->sc_cursor
.cc_hot
.x
;
494 y
= sc
->sc_cursor
.cc_pos
.y
- sc
->sc_cursor
.cc_hot
.y
;
496 x
+= sc
->sc_cursor
.cc_magic
.x
;
497 y
+= sc
->sc_cursor
.cc_magic
.y
;
499 SELECT431(curs
, BT431_REG_CURSOR_X_LOW
);
500 REGWRITE32(curs
, bt_ctl
, TWIN_LO(x
));
501 REGWRITE32(curs
, bt_ctl
, TWIN_HI(x
));
502 REGWRITE32(curs
, bt_ctl
, TWIN_LO(y
));
503 REGWRITE32(curs
, bt_ctl
, TWIN_HI(y
));
505 if (v
& WSDISPLAY_CURSOR_DOCMAP
) {
506 uint8_t *cp
= sc
->sc_cursor
.cc_color
;
509 REGWRITE32(vdac
, bt_cmap
, 0);
510 REGWRITE32(vdac
, bt_cmap
, cp
[1]);
511 REGWRITE32(vdac
, bt_cmap
, 0);
513 REGWRITE32(vdac
, bt_cmap
, 0);
514 REGWRITE32(vdac
, bt_cmap
, cp
[1]);
515 REGWRITE32(vdac
, bt_cmap
, 0);
517 REGWRITE32(vdac
, bt_ovly
, 0);
518 REGWRITE32(vdac
, bt_ovly
, cp
[0]);
519 REGWRITE32(vdac
, bt_ovly
, 0);
521 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
522 uint8_t *ip
, *mp
, img
, msk
;
525 ip
= (uint8_t *)sc
->sc_cursor
.cc_image
;
526 mp
= (uint8_t *)sc
->sc_cursor
.cc_mask
;
528 SELECT431(curs
, BT431_REG_CRAM_BASE
);
530 /* 64 pixel scan line is consisted with 16 byte cursor ram */
531 while (bcnt
< sc
->sc_cursor
.cc_size
.y
* 16) {
532 /* pad right half 32 pixel when smaller than 33 */
533 if ((bcnt
& 0x8) && sc
->sc_cursor
.cc_size
.x
< 33) {
534 REGWRITE32(curs
, bt_ram
, 0);
541 img
&= msk
; /* cookie off image */
542 half
= (flip
[msk
] << 8) | flip
[img
];
543 REGWRITE32(curs
, bt_ram
, half
);
547 /* pad unoccupied scan lines */
548 while (bcnt
< CURSOR_MAX_SIZE
* 16) {
549 REGWRITE32(curs
, bt_ram
, 0);
558 mfbhwinit(void *mfbbase
)
563 vdac
= (char *)mfbbase
+ MX_BT455_OFFSET
;
564 curs
= (char *)mfbbase
+ MX_BT431_OFFSET
;
565 SELECT431(curs
, BT431_REG_COMMAND
);
566 REGWRITE32(curs
, bt_ctl
, 0x0404);
567 REGWRITE32(curs
, bt_ctl
, 0); /* XLO */
568 REGWRITE32(curs
, bt_ctl
, 0); /* XHI */
569 REGWRITE32(curs
, bt_ctl
, 0); /* YLO */
570 REGWRITE32(curs
, bt_ctl
, 0); /* YHI */
571 REGWRITE32(curs
, bt_ctl
, 0); /* XWLO */
572 REGWRITE32(curs
, bt_ctl
, 0); /* XWHI */
573 REGWRITE32(curs
, bt_ctl
, 0); /* WYLO */
574 REGWRITE32(curs
, bt_ctl
, 0); /* WYLO */
575 REGWRITE32(curs
, bt_ctl
, 0); /* WWLO */
576 REGWRITE32(curs
, bt_ctl
, 0); /* WWHI */
577 REGWRITE32(curs
, bt_ctl
, 0); /* WHLO */
578 REGWRITE32(curs
, bt_ctl
, 0); /* WHHI */
580 /* 0: black, 1: white, 8,9: cursor mask, ovly: cursor image */
582 REGWRITE32(vdac
, bt_cmap
, 0);
583 REGWRITE32(vdac
, bt_cmap
, 0);
584 REGWRITE32(vdac
, bt_cmap
, 0);
585 REGWRITE32(vdac
, bt_cmap
, 0);
586 REGWRITE32(vdac
, bt_cmap
, 0xff);
587 REGWRITE32(vdac
, bt_cmap
, 0);
588 for (i
= 2; i
< 16; i
++) {
589 REGWRITE32(vdac
, bt_cmap
, 0);
590 REGWRITE32(vdac
, bt_cmap
, 0);
591 REGWRITE32(vdac
, bt_cmap
, 0);
593 REGWRITE32(vdac
, bt_ovly
, 0);
594 REGWRITE32(vdac
, bt_ovly
, 0xff);
595 REGWRITE32(vdac
, bt_ovly
, 0);
597 SELECT431(curs
, BT431_REG_CRAM_BASE
);
598 for (i
= 0; i
< 512; i
++) {
599 REGWRITE32(curs
, bt_ram
, 0);
604 set_cursor(struct mfb_softc
*sc
, struct wsdisplay_cursor
*p
)
606 #define cc (&sc->sc_cursor)
607 u_int v
, count
= 0, icount
= 0, index
= 0;
608 uint64_t image
[CURSOR_MAX_SIZE
];
609 uint64_t mask
[CURSOR_MAX_SIZE
];
614 if (v
& WSDISPLAY_CURSOR_DOCMAP
) {
615 index
= p
->cmap
.index
;
616 count
= p
->cmap
.count
;
617 if (index
>= 2 || (index
+ count
) > 2)
619 error
= copyin(p
->cmap
.red
, &color
[index
], count
);
623 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
624 if (p
->size
.x
> CURSOR_MAX_SIZE
|| p
->size
.y
> CURSOR_MAX_SIZE
)
626 icount
= ((p
->size
.x
< 33) ? 4 : 8) * p
->size
.y
;
627 error
= copyin(p
->image
, image
, icount
);
630 error
= copyin(p
->mask
, mask
, icount
);
636 if (v
& WSDISPLAY_CURSOR_DOCUR
)
637 sc
->sc_curenb
= p
->enable
;
638 if (v
& WSDISPLAY_CURSOR_DOPOS
)
639 set_curpos(sc
, &p
->pos
);
640 if (v
& WSDISPLAY_CURSOR_DOHOT
)
642 if (v
& WSDISPLAY_CURSOR_DOCMAP
)
643 memcpy(&cc
->cc_color
[index
], &color
[index
], count
);
644 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
645 cc
->cc_size
= p
->size
;
646 memset(cc
->cc_image
, 0, sizeof cc
->cc_image
);
647 memcpy(cc
->cc_image
, image
, icount
);
648 memset(cc
->cc_mask
, 0, sizeof cc
->cc_mask
);
649 memcpy(cc
->cc_mask
, mask
, icount
);
659 get_cursor(struct mfb_softc
*sc
, struct wsdisplay_cursor
*p
)
661 return (EPASSTHROUGH
); /* XXX */
665 set_curpos(struct mfb_softc
*sc
, struct wsdisplay_curpos
*curpos
)
667 struct rasops_info
*ri
= sc
->sc_ri
;
668 int x
= curpos
->x
, y
= curpos
->y
;
672 else if (y
> ri
->ri_height
)
676 else if (x
> ri
->ri_width
)
678 sc
->sc_cursor
.cc_pos
.x
= x
;
679 sc
->sc_cursor
.cc_pos
.y
= y
;