Module Name:    src
Committed By:   macallan
Date:           Thu Aug 20 00:59:28 UTC 2009

Modified Files:
        src/sys/dev/sbus: tcx.c

Log Message:
add support for a hardware cursor via wsdisplay


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/sys/dev/sbus/tcx.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/sbus/tcx.c
diff -u src/sys/dev/sbus/tcx.c:1.36 src/sys/dev/sbus/tcx.c:1.37
--- src/sys/dev/sbus/tcx.c:1.36	Wed Aug 19 20:51:47 2009
+++ src/sys/dev/sbus/tcx.c	Thu Aug 20 00:59:28 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: tcx.c,v 1.36 2009/08/19 20:51:47 macallan Exp $ */
+/*	$NetBSD: tcx.c,v 1.37 2009/08/20 00:59:28 macallan Exp $ */
 
 /*
  *  Copyright (c) 1996, 1998, 2009 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.36 2009/08/19 20:51:47 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.37 2009/08/20 00:59:28 macallan Exp $");
 
 /*
  * define for cg8 emulation on S24 (24-bit version of tcx) for the SS5;
@@ -101,6 +101,8 @@
 	u_char	sc_cmap_green[256];
 	u_char	sc_cmap_blue[256];
 	int 	sc_mode, sc_bg;
+	int	sc_cursor_x, sc_cursor_y;
+	int	sc_hotspot_x, sc_hotspot_y;
 	struct vcons_data vd;
 };
 
@@ -179,6 +181,8 @@
 static void	tcx_eraserows(void *, int, int, long);
 static void	tcx_putchar(void *, int, int, u_int, long);
 static void	tcx_set_video(struct tcx_softc *, int);
+static int	tcx_do_cursor(struct tcx_softc *, struct wsdisplay_cursor *);
+static void	tcx_set_cursor(struct tcx_softc *);
 
 struct wsdisplay_accessops tcx_accessops = {
 	tcx_ioctl,
@@ -238,6 +242,11 @@
 	sc->sc_bustag = sa->sa_bustag;
 	node = sa->sa_node;
 
+	sc->sc_cursor_x = 0x7fff;
+	sc->sc_cursor_y = 0x7fff;
+	sc->sc_hotspot_x = 0;
+	sc->sc_hotspot_y = 0;
+
 	fb->fb_driver = &tcx_fbdriver;
 	fb->fb_device = sc->sc_dev;
 	/* Mask out invalid flags from the user. */
@@ -357,6 +366,7 @@
 	}
 	tcx_loadcmap(sc, 0, 256);
 
+	tcx_set_cursor(sc);
 	/* enable video */
 	confreg = bus_space_read_4(sa->sa_bustag, sc->sc_thc, THC_MISC);
 	confreg |= THC_MISC_VIDEN;
@@ -495,11 +505,11 @@
 static void
 tcx_reset(struct tcx_softc *sc)
 {
+	uint32_t reg;
 
-	/* Disable cursor in Brooktree DAC. */
-	bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_ADDRESS,
-	    DAC_C1_CONTROL_0);
-	bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_CONTROL_1, 0);
+	reg = bus_space_read_4(sc->sc_bustag, sc->sc_thc, THC_MISC);
+	reg |= THC_MISC_CURSRES;
+	bus_space_write_4(sc->sc_bustag, sc->sc_thc, THC_MISC, reg);
 }
 
 static void
@@ -729,6 +739,40 @@
 						tcx_clearscreen(sc, 3);
 				}
 			}
+		case WSDISPLAYIO_GCURPOS:
+			{
+				struct wsdisplay_curpos *cp = (void *)data;
+
+				cp->x = sc->sc_cursor_x;
+				cp->y = sc->sc_cursor_y;
+			}
+			return 0;
+
+		case WSDISPLAYIO_SCURPOS:
+			{
+				struct wsdisplay_curpos *cp = (void *)data;
+
+				sc->sc_cursor_x = cp->x;
+				sc->sc_cursor_y = cp->y;
+				tcx_set_cursor(sc);
+			}
+			return 0;
+
+		case WSDISPLAYIO_GCURMAX:
+			{
+				struct wsdisplay_curpos *cp = (void *)data;
+
+				cp->x = 32;
+				cp->y = 32;
+			}
+			return 0;
+
+		case WSDISPLAYIO_SCURSOR:
+			{
+				struct wsdisplay_cursor *cursor = (void *)data;
+
+				return tcx_do_cursor(sc, cursor);
+			}
 	}
 	return EPASSTHROUGH;
 }
@@ -1008,3 +1052,90 @@
 	}
 }
 
+static int
+tcx_do_cursor(struct tcx_softc *sc, struct wsdisplay_cursor *cur)
+{
+	if (cur->which & WSDISPLAY_CURSOR_DOCUR) {
+
+		if (cur->enable) {
+			tcx_set_cursor(sc);
+		} else {
+			/* move the cursor out of sight */
+			bus_space_write_4(sc->sc_bustag, sc->sc_thc,
+			    THC_CURSOR_POS, 0x7fff7fff);
+		}
+	}
+	if (cur->which & WSDISPLAY_CURSOR_DOHOT) {
+
+		sc->sc_hotspot_x = cur->hot.x;
+		sc->sc_hotspot_y = cur->hot.y;
+		tcx_set_cursor(sc);
+	}
+	if (cur->which & WSDISPLAY_CURSOR_DOPOS) {
+
+		sc->sc_cursor_x = cur->pos.x;
+		sc->sc_cursor_y = cur->pos.y;
+		tcx_set_cursor(sc);
+	}
+	if (cur->which & WSDISPLAY_CURSOR_DOCMAP) {
+#if 0
+		int i;
+	
+		for (i = 0; i < cur->cmap.count; i++) {
+			bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_ADDRESS,
+			    (cur->cmap.index + i + 2) << 24);
+			bus_space_write_4(sc->sc_bustag, sc->sc_bt,
+			    DAC_CURSOR_LUT, cur->cmap.red[i] << 24);
+			bus_space_write_4(sc->sc_bustag, sc->sc_bt,
+			    DAC_CURSOR_LUT, cur->cmap.green[i] << 24);
+			bus_space_write_4(sc->sc_bustag, sc->sc_bt,
+			    DAC_CURSOR_LUT, cur->cmap.blue[i] << 24);
+		}
+#endif
+	}
+	if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) {
+#if 1
+		int i;
+		uint32_t temp, poof;
+
+		for (i = 0; i < 128; i += 4) {
+			memcpy(&temp, &cur->mask[i], 4);
+			printf("%08x -> ", temp);
+			poof = ((temp & 0x80808080) >> 7) |
+			       ((temp & 0x40404040) >> 5) |
+			       ((temp & 0x20202020) >> 3) |
+			       ((temp & 0x10101010) >> 1) |
+			       ((temp & 0x08080808) << 1) |
+			       ((temp & 0x04040404) << 3) |
+			       ((temp & 0x02020202) << 5) |
+			       ((temp & 0x01010101) << 7);
+			printf("%08x\n", poof);
+			bus_space_write_4(sc->sc_bustag, sc->sc_thc,
+			    THC_CURSOR_1 + i, poof);
+			memcpy(&temp, &cur->image[i], 4);
+			poof = ((temp & 0x80808080) >> 7) |
+			       ((temp & 0x40404040) >> 5) |
+			       ((temp & 0x20202020) >> 3) |
+			       ((temp & 0x10101010) >> 1) |
+			       ((temp & 0x08080808) << 1) |
+			       ((temp & 0x04040404) << 3) |
+			       ((temp & 0x02020202) << 5) |
+			       ((temp & 0x01010101) << 7);
+			bus_space_write_4(sc->sc_bustag, sc->sc_thc,
+			    THC_CURSOR_0 + i, poof);
+		}
+	}
+#endif
+	return 0;
+}
+
+static void
+tcx_set_cursor(struct tcx_softc *sc)
+{
+	uint32_t reg;
+
+	reg = (sc->sc_cursor_x - sc->sc_hotspot_x) << 16 | 
+	     ((sc->sc_cursor_y - sc->sc_hotspot_y) & 0xffff);
+	bus_space_write_4(sc->sc_bustag, sc->sc_thc, THC_CURSOR_POS, reg);
+}
+

Reply via email to