add a barrier before copyrows(), and add an RRE based fillrect functino, use it for eraserows and erasecolsdiff -r1.6 -r1.7 src/sys/arch/usermode/dev/vncfb.c
(jmcneill)
--- src/sys/arch/usermode/dev/vncfb.c 2011/12/30 13:08:30 1.6
+++ src/sys/arch/usermode/dev/vncfb.c 2011/12/30 14:20:33 1.7
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vncfb.c,v 1.6 2011/12/30 13:08:30 reinoud Exp $ */ | 1 | /* $NetBSD: vncfb.c,v 1.7 2011/12/30 14:20:33 jmcneill Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -25,27 +25,27 @@ | @@ -25,27 +25,27 @@ | |||
25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
32 | * POSSIBILITY OF SUCH DAMAGE. | 32 | * POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #include "opt_wsemul.h" | 35 | #include "opt_wsemul.h" | |
36 | 36 | |||
37 | #include <sys/cdefs.h> | 37 | #include <sys/cdefs.h> | |
38 | __KERNEL_RCSID(0, "$NetBSD: vncfb.c,v 1.6 2011/12/30 13:08:30 reinoud Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: vncfb.c,v 1.7 2011/12/30 14:20:33 jmcneill Exp $"); | |
39 | 39 | |||
40 | #include <sys/param.h> | 40 | #include <sys/param.h> | |
41 | #include <sys/systm.h> | 41 | #include <sys/systm.h> | |
42 | #include <sys/kernel.h> | 42 | #include <sys/kernel.h> | |
43 | #include <sys/device.h> | 43 | #include <sys/device.h> | |
44 | #include <sys/kmem.h> | 44 | #include <sys/kmem.h> | |
45 | 45 | |||
46 | #include <dev/wscons/wsconsio.h> | 46 | #include <dev/wscons/wsconsio.h> | |
47 | 47 | |||
48 | #include <dev/wscons/wsdisplayvar.h> | 48 | #include <dev/wscons/wsdisplayvar.h> | |
49 | #include <dev/wsfont/wsfont.h> | 49 | #include <dev/wsfont/wsfont.h> | |
50 | #include <dev/rasops/rasops.h> | 50 | #include <dev/rasops/rasops.h> | |
51 | #include <dev/wscons/wsdisplay_vconsvar.h> | 51 | #include <dev/wscons/wsdisplay_vconsvar.h> | |
@@ -93,27 +93,28 @@ CFATTACH_DECL_NEW(vncfb, sizeof(struct v | @@ -93,27 +93,28 @@ CFATTACH_DECL_NEW(vncfb, sizeof(struct v | |||
93 | static void vncfb_putchar(void *, int, int, u_int, long); | 93 | static void vncfb_putchar(void *, int, int, u_int, long); | |
94 | static void vncfb_copycols(void *, int, int, int, int); | 94 | static void vncfb_copycols(void *, int, int, int, int); | |
95 | static void vncfb_erasecols(void *, int, int, int, long); | 95 | static void vncfb_erasecols(void *, int, int, int, long); | |
96 | static void vncfb_copyrows(void *, int, int, int); | 96 | static void vncfb_copyrows(void *, int, int, int); | |
97 | static void vncfb_eraserows(void *, int, int, long); | 97 | static void vncfb_eraserows(void *, int, int, long); | |
98 | static void vncfb_cursor(void *, int, int, int); | 98 | static void vncfb_cursor(void *, int, int, int); | |
99 | 99 | |||
100 | static int vncfb_ioctl(void *, void *, u_long, void *, int, lwp_t *); | 100 | static int vncfb_ioctl(void *, void *, u_long, void *, int, lwp_t *); | |
101 | static paddr_t vncfb_mmap(void *, void *, off_t, int); | 101 | static paddr_t vncfb_mmap(void *, void *, off_t, int); | |
102 | 102 | |||
103 | static void vncfb_init_screen(void *, struct vcons_screen *, int, long *); | 103 | static void vncfb_init_screen(void *, struct vcons_screen *, int, long *); | |
104 | 104 | |||
105 | static void vncfb_update(struct vncfb_softc *, int, int, int, int); | 105 | static void vncfb_update(struct vncfb_softc *, int, int, int, int); | |
106 | static void vncfb_copyrect(struct vncfb_softc *sc, int, int, int, int, int, int); | 106 | static void vncfb_copyrect(struct vncfb_softc *, int, int, int, int, int, int); | |
107 | static void vncfb_fillrect(struct vncfb_softc *, int, int, int, int, uint32_t); | |||
107 | static int vncfb_intr(void *); | 108 | static int vncfb_intr(void *); | |
108 | static void vncfb_softintr(void *); | 109 | static void vncfb_softintr(void *); | |
109 | 110 | |||
110 | static int vncfb_kbd_enable(void *, int); | 111 | static int vncfb_kbd_enable(void *, int); | |
111 | static void vncfb_kbd_set_leds(void *, int); | 112 | static void vncfb_kbd_set_leds(void *, int); | |
112 | static int vncfb_kbd_ioctl(void *, u_long, void *, int, lwp_t *); | 113 | static int vncfb_kbd_ioctl(void *, u_long, void *, int, lwp_t *); | |
113 | 114 | |||
114 | static void vncfb_kbd_cngetc(void *, u_int *, int *); | 115 | static void vncfb_kbd_cngetc(void *, u_int *, int *); | |
115 | static void vncfb_kbd_cnpollc(void *, int); | 116 | static void vncfb_kbd_cnpollc(void *, int); | |
116 | static void vncfb_kbd_bell(void *, u_int, u_int, u_int); | 117 | static void vncfb_kbd_bell(void *, u_int, u_int, u_int); | |
117 | 118 | |||
118 | static struct vcons_screen vncfb_console_screen; | 119 | static struct vcons_screen vncfb_console_screen; | |
119 | 120 | |||
@@ -321,79 +322,85 @@ vncfb_copycols(void *priv, int row, int | @@ -321,79 +322,85 @@ vncfb_copycols(void *priv, int row, int | |||
321 | w = (srccol - dstcol) * ri->ri_font->fontwidth; | 322 | w = (srccol - dstcol) * ri->ri_font->fontwidth; | |
322 | } | 323 | } | |
323 | 324 | |||
324 | vncfb_update(sc, x, y, w, h); | 325 | vncfb_update(sc, x, y, w, h); | |
325 | } | 326 | } | |
326 | 327 | |||
327 | static void | 328 | static void | |
328 | vncfb_erasecols(void *priv, int row, int startcol, int ncols, long fillattr) | 329 | vncfb_erasecols(void *priv, int row, int startcol, int ncols, long fillattr) | |
329 | { | 330 | { | |
330 | struct rasops_info *ri = priv; | 331 | struct rasops_info *ri = priv; | |
331 | struct vcons_screen *scr = ri->ri_hw; | 332 | struct vcons_screen *scr = ri->ri_hw; | |
332 | struct vncfb_softc *sc = scr->scr_cookie; | 333 | struct vncfb_softc *sc = scr->scr_cookie; | |
333 | struct vncfb_fbops *ops = &sc->sc_ops; | 334 | struct vncfb_fbops *ops = &sc->sc_ops; | |
334 | int x, y, w, h; | 335 | int x, y, w, h, c; | |
335 | 336 | |||
336 | ops->erasecols(ri, row, startcol, ncols, fillattr); | 337 | ops->erasecols(ri, row, startcol, ncols, fillattr); | |
337 | 338 | |||
338 | y = ri->ri_yorigin + (row * ri->ri_font->fontheight); | 339 | y = ri->ri_yorigin + (row * ri->ri_font->fontheight); | |
339 | h = ri->ri_font->fontheight; | 340 | h = ri->ri_font->fontheight; | |
340 | x = ri->ri_xorigin + (startcol * ri->ri_font->fontwidth); | 341 | x = ri->ri_xorigin + (startcol * ri->ri_font->fontwidth); | |
341 | w = ncols * ri->ri_font->fontwidth; | 342 | w = ncols * ri->ri_font->fontwidth; | |
343 | c = ri->ri_devcmap[(fillattr >> 16) & 0xf] & 0xffffff; | |||
342 | 344 | |||
343 | vncfb_update(sc, x, y, w, h); | 345 | vncfb_fillrect(sc, x, y, w, h, c); | |
344 | } | 346 | } | |
345 | 347 | |||
346 | static void | 348 | static void | |
347 | vncfb_copyrows(void *priv, int srcrow, int dstrow, int nrows) | 349 | vncfb_copyrows(void *priv, int srcrow, int dstrow, int nrows) | |
348 | { | 350 | { | |
349 | struct rasops_info *ri = priv; | 351 | struct rasops_info *ri = priv; | |
350 | struct vcons_screen *scr = ri->ri_hw; | 352 | struct vcons_screen *scr = ri->ri_hw; | |
351 | struct vncfb_softc *sc = scr->scr_cookie; | 353 | struct vncfb_softc *sc = scr->scr_cookie; | |
352 | struct vncfb_fbops *ops = &sc->sc_ops; | 354 | struct vncfb_fbops *ops = &sc->sc_ops; | |
353 | int x, y, w, h, srcx, srcy; | 355 | int x, y, w, h, srcx, srcy; | |
354 | int fontheight; | 356 | int fontheight; | |
355 | 357 | |||
358 | /* barrier */ | |||
359 | while (sc->sc_rfb.nupdates > 0) | |||
360 | thunk_rfb_poll(&sc->sc_rfb, NULL); | |||
361 | ||||
356 | ops->copyrows(ri, srcrow, dstrow, nrows); | 362 | ops->copyrows(ri, srcrow, dstrow, nrows); | |
357 | 363 | |||
358 | fontheight = ri->ri_font->fontheight; | 364 | fontheight = ri->ri_font->fontheight; | |
359 | x = ri->ri_xorigin; | 365 | x = ri->ri_xorigin; | |
360 | y = ri->ri_yorigin + dstrow * fontheight; | 366 | y = ri->ri_yorigin + dstrow * fontheight; | |
361 | w = ri->ri_width; | 367 | w = ri->ri_width; | |
362 | h = nrows * fontheight; | 368 | h = nrows * fontheight; | |
363 | 369 | |||
364 | srcx = ri->ri_xorigin; | 370 | srcx = ri->ri_xorigin; | |
365 | srcy = ri->ri_yorigin + srcrow * fontheight; | 371 | srcy = ri->ri_yorigin + srcrow * fontheight; | |
366 | 372 | |||
367 | vncfb_copyrect(sc, x, y, w, h, srcx, srcy); | 373 | vncfb_copyrect(sc, x, y, w, h, srcx, srcy); | |
368 | } | 374 | } | |
369 | 375 | |||
370 | static void | 376 | static void | |
371 | vncfb_eraserows(void *priv, int row, int nrows, long fillattr) | 377 | vncfb_eraserows(void *priv, int row, int nrows, long fillattr) | |
372 | { | 378 | { | |
373 | struct rasops_info *ri = priv; | 379 | struct rasops_info *ri = priv; | |
374 | struct vcons_screen *scr = ri->ri_hw; | 380 | struct vcons_screen *scr = ri->ri_hw; | |
375 | struct vncfb_softc *sc = scr->scr_cookie; | 381 | struct vncfb_softc *sc = scr->scr_cookie; | |
376 | struct vncfb_fbops *ops = &sc->sc_ops; | 382 | struct vncfb_fbops *ops = &sc->sc_ops; | |
377 | int x, y, w, h; | 383 | int x, y, w, h, c; | |
378 | 384 | |||
379 | ops->eraserows(ri, row, nrows, fillattr); | 385 | ops->eraserows(ri, row, nrows, fillattr); | |
380 | 386 | |||
381 | y = ri->ri_yorigin + (row * ri->ri_font->fontheight); | 387 | y = ri->ri_yorigin + (row * ri->ri_font->fontheight); | |
382 | h = nrows * ri->ri_font->fontheight; | 388 | h = nrows * ri->ri_font->fontheight; | |
383 | x = ri->ri_xorigin; | 389 | x = ri->ri_xorigin; | |
384 | w = ri->ri_width; | 390 | w = ri->ri_width; | |
391 | c = ri->ri_devcmap[(fillattr >> 16) & 0xf] & 0xffffff; | |||
385 | 392 | |||
386 | vncfb_update(sc, x, y, w, h); | 393 | vncfb_fillrect(sc, x, y, w, h, c); | |
387 | } | 394 | } | |
388 | 395 | |||
389 | static void | 396 | static void | |
390 | vncfb_cursor(void *priv, int on, int row, int col) | 397 | vncfb_cursor(void *priv, int on, int row, int col) | |
391 | { | 398 | { | |
392 | struct rasops_info *ri = priv; | 399 | struct rasops_info *ri = priv; | |
393 | struct vcons_screen *scr = ri->ri_hw; | 400 | struct vcons_screen *scr = ri->ri_hw; | |
394 | struct vncfb_softc *sc = scr->scr_cookie; | 401 | struct vncfb_softc *sc = scr->scr_cookie; | |
395 | struct vncfb_fbops *ops = &sc->sc_ops; | 402 | struct vncfb_fbops *ops = &sc->sc_ops; | |
396 | int ox, oy, x, y, w, h; | 403 | int ox, oy, x, y, w, h; | |
397 | 404 | |||
398 | w = ri->ri_font->fontwidth; | 405 | w = ri->ri_font->fontwidth; | |
399 | h = ri->ri_font->fontheight; | 406 | h = ri->ri_font->fontheight; | |
@@ -455,26 +462,34 @@ vncfb_update(struct vncfb_softc *sc, int | @@ -455,26 +462,34 @@ vncfb_update(struct vncfb_softc *sc, int | |||
455 | { | 462 | { | |
456 | thunk_rfb_update(&sc->sc_rfb, x, y, w, h); | 463 | thunk_rfb_update(&sc->sc_rfb, x, y, w, h); | |
457 | softint_schedule(sc->sc_sih); | 464 | softint_schedule(sc->sc_sih); | |
458 | } | 465 | } | |
459 | 466 | |||
460 | static void | 467 | static void | |
461 | vncfb_copyrect(struct vncfb_softc *sc, int x, int y, int w, int h, | 468 | vncfb_copyrect(struct vncfb_softc *sc, int x, int y, int w, int h, | |
462 | int srcx, int srcy) | 469 | int srcx, int srcy) | |
463 | { | 470 | { | |
464 | thunk_rfb_copyrect(&sc->sc_rfb, x, y, w, h, srcx, srcy); | 471 | thunk_rfb_copyrect(&sc->sc_rfb, x, y, w, h, srcx, srcy); | |
465 | softint_schedule(sc->sc_sih); | 472 | softint_schedule(sc->sc_sih); | |
466 | } | 473 | } | |
467 | 474 | |||
475 | static void | |||
476 | vncfb_fillrect(struct vncfb_softc *sc, int x, int y, int w, int h, uint32_t c) | |||
477 | { | |||
478 | ||||
479 | thunk_rfb_fillrect(&sc->sc_rfb, x, y, w, h, (uint8_t *)&c); | |||
480 | softint_schedule(sc->sc_sih); | |||
481 | } | |||
482 | ||||
468 | static int | 483 | static int | |
469 | vncfb_intr(void *priv) | 484 | vncfb_intr(void *priv) | |
470 | { | 485 | { | |
471 | struct vncfb_softc *sc = priv; | 486 | struct vncfb_softc *sc = priv; | |
472 | 487 | |||
473 | softint_schedule(sc->sc_sih); | 488 | softint_schedule(sc->sc_sih); | |
474 | 489 | |||
475 | return 0; | 490 | return 0; | |
476 | } | 491 | } | |
477 | 492 | |||
478 | static void | 493 | static void | |
479 | vncfb_softintr(void *priv) | 494 | vncfb_softintr(void *priv) | |
480 | { | 495 | { |
--- src/sys/arch/usermode/include/thunk.h 2011/12/30 12:54:41 1.51
+++ src/sys/arch/usermode/include/thunk.h 2011/12/30 14:20:34 1.52
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: thunk.h,v 1.51 2011/12/30 12:54:41 jmcneill Exp $ */ | 1 | /* $NetBSD: thunk.h,v 1.52 2011/12/30 14:20:34 jmcneill Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -185,27 +185,27 @@ typedef struct { | @@ -185,27 +185,27 @@ typedef struct { | |||
185 | union { | 185 | union { | |
186 | struct { | 186 | struct { | |
187 | uint8_t down_flag; | 187 | uint8_t down_flag; | |
188 | uint32_t keysym; | 188 | uint32_t keysym; | |
189 | } key_event; | 189 | } key_event; | |
190 | } data; | 190 | } data; | |
191 | } thunk_rfb_event_t; | 191 | } thunk_rfb_event_t; | |
192 | 192 | |||
193 | 193 | |||
194 | typedef struct { | 194 | typedef struct { | |
195 | uint8_t enc; | 195 | uint8_t enc; | |
196 | uint16_t x, y, w, h; | 196 | uint16_t x, y, w, h; | |
197 | uint16_t srcx, srcy; | 197 | uint16_t srcx, srcy; | |
198 | uint32_t colour; /* for RRE clear */ | 198 | uint8_t pixel[4]; | |
199 | } thunk_rfb_update_t; | 199 | } thunk_rfb_update_t; | |
200 | #define THUNK_RFB_TYPE_RAW 0 | 200 | #define THUNK_RFB_TYPE_RAW 0 | |
201 | #define THUNK_RFB_TYPE_COPYRECT 1 | 201 | #define THUNK_RFB_TYPE_COPYRECT 1 | |
202 | #define THUNK_RFB_TYPE_RRE 2 /* rectangle fill */ | 202 | #define THUNK_RFB_TYPE_RRE 2 /* rectangle fill */ | |
203 | 203 | |||
204 | #define THUNK_RFB_QUEUELEN 128 | 204 | #define THUNK_RFB_QUEUELEN 128 | |
205 | 205 | |||
206 | typedef struct { | 206 | typedef struct { | |
207 | int sockfd; | 207 | int sockfd; | |
208 | int clientfd; | 208 | int clientfd; | |
209 | thunk_rfb_event_t event; | 209 | thunk_rfb_event_t event; | |
210 | 210 | |||
211 | bool connected; | 211 | bool connected; | |
@@ -217,15 +217,16 @@ typedef struct { | @@ -217,15 +217,16 @@ typedef struct { | |||
217 | uint8_t *framebuf; | 217 | uint8_t *framebuf; | |
218 | 218 | |||
219 | bool schedule_bell; | 219 | bool schedule_bell; | |
220 | unsigned int nupdates; | 220 | unsigned int nupdates; | |
221 | unsigned int first_mergable; | 221 | unsigned int first_mergable; | |
222 | thunk_rfb_update_t update[THUNK_RFB_QUEUELEN]; | 222 | thunk_rfb_update_t update[THUNK_RFB_QUEUELEN]; | |
223 | } thunk_rfb_t; | 223 | } thunk_rfb_t; | |
224 | 224 | |||
225 | int thunk_rfb_open(thunk_rfb_t *, uint16_t); | 225 | int thunk_rfb_open(thunk_rfb_t *, uint16_t); | |
226 | int thunk_rfb_poll(thunk_rfb_t *, thunk_rfb_event_t *); | 226 | int thunk_rfb_poll(thunk_rfb_t *, thunk_rfb_event_t *); | |
227 | void thunk_rfb_bell(thunk_rfb_t *); | 227 | void thunk_rfb_bell(thunk_rfb_t *); | |
228 | void thunk_rfb_update(thunk_rfb_t *, int, int, int, int); | 228 | void thunk_rfb_update(thunk_rfb_t *, int, int, int, int); | |
229 | void thunk_rfb_copyrect(thunk_rfb_t *, int, int, int, int, int, int); | 229 | void thunk_rfb_copyrect(thunk_rfb_t *, int, int, int, int, int, int); | |
230 | void thunk_rfb_fillrect(thunk_rfb_t *, int, int, int, int, uint8_t *); | |||
230 | 231 | |||
231 | #endif /* !_ARCH_USERMODE_INCLUDE_THUNK_H */ | 232 | #endif /* !_ARCH_USERMODE_INCLUDE_THUNK_H */ |
--- src/sys/arch/usermode/usermode/thunk.c 2011/12/30 13:08:30 1.65
+++ src/sys/arch/usermode/usermode/thunk.c 2011/12/30 14:20:34 1.66
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: thunk.c,v 1.65 2011/12/30 13:08:30 reinoud Exp $ */ | 1 | /* $NetBSD: thunk.c,v 1.66 2011/12/30 14:20:34 jmcneill Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -18,27 +18,27 @@ | @@ -18,27 +18,27 @@ | |||
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | #ifdef __NetBSD__ | 30 | #ifdef __NetBSD__ | |
31 | __RCSID("$NetBSD: thunk.c,v 1.65 2011/12/30 13:08:30 reinoud Exp $"); | 31 | __RCSID("$NetBSD: thunk.c,v 1.66 2011/12/30 14:20:34 jmcneill Exp $"); | |
32 | #endif | 32 | #endif | |
33 | 33 | |||
34 | #include <sys/types.h> | 34 | #include <sys/types.h> | |
35 | #include <sys/mman.h> | 35 | #include <sys/mman.h> | |
36 | #include <sys/reboot.h> | 36 | #include <sys/reboot.h> | |
37 | #include <sys/poll.h> | 37 | #include <sys/poll.h> | |
38 | #include <sys/sysctl.h> | 38 | #include <sys/sysctl.h> | |
39 | #include <sys/socket.h> | 39 | #include <sys/socket.h> | |
40 | #include <sys/audioio.h> | 40 | #include <sys/audioio.h> | |
41 | #include <sys/shm.h> | 41 | #include <sys/shm.h> | |
42 | #include <machine/vmparam.h> | 42 | #include <machine/vmparam.h> | |
43 | 43 | |||
44 | #include <net/if.h> | 44 | #include <net/if.h> | |
@@ -993,26 +993,27 @@ thunk_rfb_send_pending(thunk_rfb_t *rfb) | @@ -993,26 +993,27 @@ thunk_rfb_send_pending(thunk_rfb_t *rfb) | |||
993 | thunk_rfb_update_t *update; | 993 | thunk_rfb_update_t *update; | |
994 | uint8_t buf[32]; | 994 | uint8_t buf[32]; | |
995 | uint8_t *p; | 995 | uint8_t *p; | |
996 | unsigned int n; | 996 | unsigned int n; | |
997 | unsigned int bytes_per_pixel; | 997 | unsigned int bytes_per_pixel; | |
998 | ssize_t stride, line_len, len; | 998 | ssize_t stride, line_len, len; | |
999 | 999 | |||
1000 | if (rfb->connected == false || rfb->nupdates == 0) | 1000 | if (rfb->connected == false || rfb->nupdates == 0) | |
1001 | return; | 1001 | return; | |
1002 | 1002 | |||
1003 | /* If we have too many updates queued, just send a single update */ | 1003 | /* If we have too many updates queued, just send a single update */ | |
1004 | if (rfb->nupdates >= __arraycount(rfb->update)) { | 1004 | if (rfb->nupdates >= __arraycount(rfb->update)) { | |
1005 | rfb->nupdates = 1; | 1005 | rfb->nupdates = 1; | |
1006 | rfb->update[0].enc = THUNK_RFB_TYPE_RAW; | |||
1006 | rfb->update[0].x = 0; | 1007 | rfb->update[0].x = 0; | |
1007 | rfb->update[0].y = 0; | 1008 | rfb->update[0].y = 0; | |
1008 | rfb->update[0].w = rfb->width; | 1009 | rfb->update[0].w = rfb->width; | |
1009 | rfb->update[0].h = rfb->height; | 1010 | rfb->update[0].h = rfb->height; | |
1010 | } | 1011 | } | |
1011 | 1012 | |||
1012 | #ifdef RFB_DEBUG | 1013 | #ifdef RFB_DEBUG | |
1013 | fprintf(stdout, "rfb: sending %d updates\n", rfb->nupdates); | 1014 | fprintf(stdout, "rfb: sending %d updates\n", rfb->nupdates); | |
1014 | #endif | 1015 | #endif | |
1015 | 1016 | |||
1016 | p = buf; | 1017 | p = buf; | |
1017 | *(uint8_t *)p = 0; p += 1; /* FramebufferUpdate */ | 1018 | *(uint8_t *)p = 0; p += 1; /* FramebufferUpdate */ | |
1018 | *(uint8_t *)p = 0; p += 1; /* padding */ | 1019 | *(uint8_t *)p = 0; p += 1; /* padding */ | |
@@ -1029,42 +1030,64 @@ thunk_rfb_send_pending(thunk_rfb_t *rfb) | @@ -1029,42 +1030,64 @@ thunk_rfb_send_pending(thunk_rfb_t *rfb) | |||
1029 | update = &rfb->update[n]; | 1030 | update = &rfb->update[n]; | |
1030 | *(uint16_t *)p = htons(update->x); p += 2; | 1031 | *(uint16_t *)p = htons(update->x); p += 2; | |
1031 | *(uint16_t *)p = htons(update->y); p += 2; | 1032 | *(uint16_t *)p = htons(update->y); p += 2; | |
1032 | *(uint16_t *)p = htons(update->w); p += 2; | 1033 | *(uint16_t *)p = htons(update->w); p += 2; | |
1033 | *(uint16_t *)p = htons(update->h); p += 2; | 1034 | *(uint16_t *)p = htons(update->h); p += 2; | |
1034 | *(uint32_t *)p = htonl(update->enc); p += 4; /* encoding */ | 1035 | *(uint32_t *)p = htonl(update->enc); p += 4; /* encoding */ | |
1035 | 1036 | |||
1036 | #ifdef RFB_DEBUG | 1037 | #ifdef RFB_DEBUG | |
1037 | fprintf(stdout, "rfb: [%u] enc %d, [%d, %d] - [%d, %d]", | 1038 | fprintf(stdout, "rfb: [%u] enc %d, [%d, %d] - [%d, %d]", | |
1038 | n, update->enc, update->x, update->y, update->w, update->h); | 1039 | n, update->enc, update->x, update->y, update->w, update->h); | |
1039 | if (update->enc == THUNK_RFB_TYPE_COPYRECT) | 1040 | if (update->enc == THUNK_RFB_TYPE_COPYRECT) | |
1040 | fprintf(stdout, " from [%d, %d]", | 1041 | fprintf(stdout, " from [%d, %d]", | |
1041 | update->srcx, update->srcy); | 1042 | update->srcx, update->srcy); | |
1043 | if (update->enc == THUNK_RFB_TYPE_RRE) | |||
1044 | fprintf(stdout, " pixel [%02x %02x %02x %02x]", | |||
1045 | update->pixel[0], update->pixel[1], | |||
1046 | update->pixel[2], update->pixel[3]); | |||
1042 | fprintf(stdout, "\n"); | 1047 | fprintf(stdout, "\n"); | |
1043 | #endif | 1048 | #endif | |
1044 | 1049 | |||
1045 | len = safe_send(rfb->clientfd, buf, 12); | 1050 | len = safe_send(rfb->clientfd, buf, 12); | |
1046 | if (len < 0) | 1051 | if (len < 0) | |
1047 | goto disco; | 1052 | goto disco; | |
1048 | 1053 | |||
1049 | if (update->enc == THUNK_RFB_TYPE_COPYRECT) { | 1054 | if (update->enc == THUNK_RFB_TYPE_COPYRECT) { | |
1050 | p = buf; | 1055 | p = buf; | |
1051 | *(uint16_t *)p = htons(update->srcx); p += 2; | 1056 | *(uint16_t *)p = htons(update->srcx); p += 2; | |
1052 | *(uint16_t *)p = htons(update->srcy); p += 2; | 1057 | *(uint16_t *)p = htons(update->srcy); p += 2; | |
1053 | len = safe_send(rfb->clientfd, buf, 4); | 1058 | len = safe_send(rfb->clientfd, buf, 4); | |
1054 | if (len < 0) | 1059 | if (len < 0) | |
1055 | goto disco; | 1060 | goto disco; | |
1056 | } | 1061 | } | |
1057 | 1062 | |||
1063 | if (update->enc == THUNK_RFB_TYPE_RRE) { | |||
1064 | p = buf; | |||
1065 | ||||
1066 | /* header */ | |||
1067 | *(uint32_t *)p = htonl(1); p += 4; | |||
1068 | memcpy(p, update->pixel, 4); p += 4; | |||
1069 | /* subrectangle */ | |||
1070 | memcpy(p, update->pixel, 4); p += 4; | |||
1071 | *(uint16_t *)p = htons(update->x); p += 2; | |||
1072 | *(uint16_t *)p = htons(update->y); p += 2; | |||
1073 | *(uint16_t *)p = htons(update->w); p += 2; | |||
1074 | *(uint16_t *)p = htons(update->h); p += 2; | |||
1075 | /* send it */ | |||
1076 | len = safe_send(rfb->clientfd, buf, 20); | |||
1077 | if (len < 0) | |||
1078 | goto disco; | |||
1079 | } | |||
1080 | ||||
1058 | if (update->enc == THUNK_RFB_TYPE_RAW) { | 1081 | if (update->enc == THUNK_RFB_TYPE_RAW) { | |
1059 | p = rfb->framebuf + (update->y * stride) | 1082 | p = rfb->framebuf + (update->y * stride) | |
1060 | + (update->x * bytes_per_pixel); | 1083 | + (update->x * bytes_per_pixel); | |
1061 | line_len = update->w * bytes_per_pixel; | 1084 | line_len = update->w * bytes_per_pixel; | |
1062 | while (update->h-- > 0) { | 1085 | while (update->h-- > 0) { | |
1063 | len = safe_send(rfb->clientfd, p, line_len); | 1086 | len = safe_send(rfb->clientfd, p, line_len); | |
1064 | if (len < 0) | 1087 | if (len < 0) | |
1065 | goto disco; | 1088 | goto disco; | |
1066 | p += stride; | 1089 | p += stride; | |
1067 | } | 1090 | } | |
1068 | } | 1091 | } | |
1069 | } | 1092 | } | |
1070 | 1093 | |||
@@ -1136,26 +1159,29 @@ thunk_rfb_poll(thunk_rfb_t *rfb, thunk_r | @@ -1136,26 +1159,29 @@ thunk_rfb_poll(thunk_rfb_t *rfb, thunk_r | |||
1136 | return -1; | 1159 | return -1; | |
1137 | } | 1160 | } | |
1138 | 1161 | |||
1139 | rfb->schedule_bell = false; | 1162 | rfb->schedule_bell = false; | |
1140 | rfb->nupdates = 0; | 1163 | rfb->nupdates = 0; | |
1141 | rfb->first_mergable = 0; | 1164 | rfb->first_mergable = 0; | |
1142 | thunk_rfb_update(rfb, 0, 0, rfb->width, rfb->height); | 1165 | thunk_rfb_update(rfb, 0, 0, rfb->width, rfb->height); | |
1143 | } | 1166 | } | |
1144 | 1167 | |||
1145 | thunk_rfb_send_pending(rfb); | 1168 | thunk_rfb_send_pending(rfb); | |
1146 | if (rfb->clientfd == -1) | 1169 | if (rfb->clientfd == -1) | |
1147 | return -1; | 1170 | return -1; | |
1148 | 1171 | |||
1172 | if (event == NULL) | |||
1173 | return 0; | |||
1174 | ||||
1149 | if (rfb->schedule_bell) { | 1175 | if (rfb->schedule_bell) { | |
1150 | uint8_t msg_type = 2; /* bell */ | 1176 | uint8_t msg_type = 2; /* bell */ | |
1151 | safe_send(rfb->clientfd, &msg_type, sizeof(msg_type)); | 1177 | safe_send(rfb->clientfd, &msg_type, sizeof(msg_type)); | |
1152 | rfb->schedule_bell = false; | 1178 | rfb->schedule_bell = false; | |
1153 | } | 1179 | } | |
1154 | 1180 | |||
1155 | error = ioctl(rfb->clientfd, FIONREAD, &len); | 1181 | error = ioctl(rfb->clientfd, FIONREAD, &len); | |
1156 | if (error) { | 1182 | if (error) { | |
1157 | //printf("rfb: FIONREAD failed: %s\n", strerror(errno)); | 1183 | //printf("rfb: FIONREAD failed: %s\n", strerror(errno)); | |
1158 | close(rfb->clientfd); | 1184 | close(rfb->clientfd); | |
1159 | rfb->clientfd = -1; | 1185 | rfb->clientfd = -1; | |
1160 | return -1; | 1186 | return -1; | |
1161 | } | 1187 | } | |
@@ -1267,15 +1293,41 @@ thunk_rfb_copyrect(thunk_rfb_t *rfb, int | @@ -1267,15 +1293,41 @@ thunk_rfb_copyrect(thunk_rfb_t *rfb, int | |||
1267 | rfb->nupdates, x, y, w, h); | 1293 | rfb->nupdates, x, y, w, h); | |
1268 | #endif | 1294 | #endif | |
1269 | 1295 | |||
1270 | /* add the update request to the queue */ | 1296 | /* add the update request to the queue */ | |
1271 | update = &rfb->update[rfb->nupdates++]; | 1297 | update = &rfb->update[rfb->nupdates++]; | |
1272 | update->enc = THUNK_RFB_TYPE_COPYRECT; | 1298 | update->enc = THUNK_RFB_TYPE_COPYRECT; | |
1273 | update->x = x; | 1299 | update->x = x; | |
1274 | update->y = y; | 1300 | update->y = y; | |
1275 | update->w = w; | 1301 | update->w = w; | |
1276 | update->h = h; | 1302 | update->h = h; | |
1277 | update->srcx = srcx; | 1303 | update->srcx = srcx; | |
1278 | update->srcy = srcy; | 1304 | update->srcy = srcy; | |
1279 | 1305 | |||
1280 | rfb->first_mergable = rfb->nupdates+1; | 1306 | rfb->first_mergable = rfb->nupdates; | |
1307 | } | |||
1308 | ||||
1309 | void | |||
1310 | thunk_rfb_fillrect(thunk_rfb_t *rfb, int x, int y, int w, int h, uint8_t *pixel) | |||
1311 | { | |||
1312 | thunk_rfb_update_t *update = NULL; | |||
1313 | ||||
1314 | /* if the queue is full, just return */ | |||
1315 | if (rfb->nupdates >= __arraycount(rfb->update)) | |||
1316 | return; | |||
1317 | ||||
1318 | #ifdef RFB_DEBUG | |||
1319 | fprintf(stdout, "rfb: fillrect queue slot %d, x=%d y=%d w=%d h=%d\n", | |||
1320 | rfb->nupdates, x, y, w, h); | |||
1321 | #endif | |||
1322 | ||||
1323 | /* add the update request to the queue */ | |||
1324 | update = &rfb->update[rfb->nupdates++]; | |||
1325 | update->enc = THUNK_RFB_TYPE_RRE; | |||
1326 | update->x = x; | |||
1327 | update->y = y; | |||
1328 | update->w = w; | |||
1329 | update->h = h; | |||
1330 | memcpy(update->pixel, pixel, 4); | |||
1331 | ||||
1332 | rfb->first_mergable = rfb->nupdates; | |||
1281 | } | 1333 | } |