First version of the uVNC server port to Contiki
diff --git a/contiki/ctk/ctk-vncarch.h b/contiki/ctk/ctk-vncarch.h
new file mode 100644
index 0000000..e32b6be
--- /dev/null
+++ b/contiki/ctk/ctk-vncarch.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2002, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the "ctk" console GUI toolkit for cc65
+ *
+ * $Id: ctk-vncarch.h,v 1.1 2003/07/02 21:34:47 adamdunkels Exp $
+ *
+ */
+#ifndef __CTK_VNCARCH_H__
+#define __CTK_VNCARCH_H__
+
+
+typedef char ctk_arch_key_t;
+
+unsigned char ctk_arch_keyavail(void);
+ctk_arch_key_t ctk_arch_getkey(void);
+
+#define CH_ENTER 0x0d
+#define CH_DEL 0x08
+
+#define CH_ESC 0x1b
+
+#define CH_HOME 0x50
+
+#define CH_TAB 0x09
+
+#define CH_CURS_LEFT 0x51
+#define CH_CURS_UP 0x52
+#define CH_CURS_RIGHT 0x53
+#define CH_CURS_DOWN 0x54
+
+
+
+
+
+#endif /* __CTK_VNCARCH_H__ */
diff --git a/contiki/ctk/ctk-vncfont.c b/contiki/ctk/ctk-vncfont.c
new file mode 100644
index 0000000..61d867c
--- /dev/null
+++ b/contiki/ctk/ctk-vncfont.c
@@ -0,0 +1,1203 @@
+/*
+ * Copyright (c) 2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the Contiki VNC server
+ *
+ * $Id: ctk-vncfont.c,v 1.1 2003/07/02 21:34:00 adamdunkels Exp $
+ *
+ */
+
+#define _ 0x00
+#define o 0x01 /* 1001 0010 */
+#define X 0x02 /* 1111 0110 */
+
+#ifndef NOT_AVR
+#include <avr/pgmspace.h>
+#else
+#define prog_char unsigned char
+#endif
+
+prog_char ctk_vncfont[] = {
+/* Char 0x0 '?' */
+o,X,X,X,X,o,
+X,X,o,o,X,X,
+X,X,_,X,X,X,
+X,X,_,X,X,X,
+X,X,_,_,_,_,
+X,X,o,_,_,X,
+o,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x1 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,X,X,X,o,_,
+_,o,_,o,X,_,
+o,X,X,X,X,_,
+X,o,_,o,X,_,
+o,X,X,X,X,o,
+_,_,_,_,_,_,
+/* Char 0x2 '?' */
+_,_,_,_,_,_,
+X,o,_,_,_,_,
+X,_,_,_,_,_,
+X,X,X,X,o,_,
+X,_,_,o,X,_,
+X,_,_,o,X,_,
+X,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x3 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+o,X,X,X,o,_,
+X,o,_,_,_,_,
+X,_,_,_,_,_,
+X,o,_,_,o,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x4 '?' */
+_,_,_,_,_,_,
+_,_,_,o,X,_,
+_,_,_,_,X,_,
+o,X,X,X,X,_,
+X,o,_,_,X,_,
+X,o,_,_,X,_,
+o,X,X,X,X,o,
+_,_,_,_,_,_,
+/* Char 0x5 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+o,X,X,X,o,_,
+X,_,_,_,X,_,
+X,X,X,X,o,_,
+X,o,_,_,_,_,
+o,X,X,X,_,_,
+_,_,_,_,_,_,
+/* Char 0x6 '?' */
+_,_,_,_,_,_,
+_,_,o,X,X,_,
+_,_,X,o,_,_,
+_,X,X,X,X,_,
+_,o,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,o,_,_,
+_,_,_,_,_,_,
+/* Char 0x7 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+o,X,X,X,X,_,
+X,o,_,o,X,_,
+X,o,_,o,X,_,
+o,X,X,X,X,_,
+_,_,_,o,X,_,
+_,X,X,X,o,_,
+/* Char 0x8 '?' */
+_,_,_,_,_,_,
+X,o,_,_,_,_,
+X,_,_,_,_,_,
+X,X,X,X,o,_,
+X,_,_,o,X,_,
+X,_,_,_,X,_,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0x9 '?' */
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+_,X,X,_,_,_,
+_,o,X,_,_,_,
+_,o,X,o,_,_,
+_,X,X,X,_,_,
+_,_,_,_,_,_,
+/* Char 0xa '?' */
+_,_,_,_,_,_,
+_,_,_,_,X,_,
+_,_,_,_,_,_,
+_,_,_,X,X,_,
+_,_,_,o,X,_,
+_,_,_,_,X,_,
+_,_,_,o,X,_,
+_,X,X,X,o,_,
+/* Char 0xb '?' */
+_,_,_,_,_,_,
+X,o,_,_,_,_,
+X,_,_,_,_,_,
+X,_,o,X,_,_,
+X,X,X,o,_,_,
+X,_,o,X,o,_,
+X,o,_,o,X,o,
+_,_,_,_,_,_,
+/* Char 0xc '?' */
+_,_,_,_,_,_,
+_,X,X,_,_,_,
+_,o,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,o,X,o,_,_,
+_,X,X,X,_,_,
+_,_,_,_,_,_,
+/* Char 0xd '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,o,X,o,_,
+X,X,X,X,X,_,
+X,o,X,o,X,_,
+X,_,o,_,X,o,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0xe '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,o,X,X,o,_,
+X,X,_,o,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0xf '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,_,_,_,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x10 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,o,_,
+X,_,_,o,X,_,
+X,_,_,o,X,_,
+X,X,X,X,o,_,
+X,_,_,_,_,_,
+X,o,_,_,_,_,
+/* Char 0x11 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+o,X,X,X,X,_,
+X,o,_,_,X,_,
+X,o,_,_,X,_,
+o,X,X,X,X,_,
+_,_,_,o,X,_,
+_,_,_,_,X,o,
+/* Char 0x12 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,o,X,X,o,_,
+X,X,_,o,X,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,o,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x13 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+o,X,X,X,o,_,
+X,_,_,_,_,_,
+o,X,X,X,o,_,
+_,_,_,o,X,_,
+X,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x14 '?' */
+_,_,_,_,_,_,
+_,o,X,_,_,_,
+X,X,X,X,X,_,
+_,_,X,o,_,_,
+_,_,X,_,_,_,
+_,_,X,o,_,_,
+_,_,o,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x15 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,o,_,_,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,o,_,_,X,_,
+o,X,X,X,X,o,
+_,_,_,_,_,_,
+/* Char 0x16 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,o,_,_,X,o,
+X,_,_,_,X,_,
+X,o,_,o,X,_,
+o,X,o,X,o,_,
+_,o,X,o,_,_,
+_,_,_,_,_,_,
+/* Char 0x17 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,o,_,_,X,o,
+X,_,_,_,X,_,
+X,_,o,_,X,_,
+X,o,X,o,X,_,
+o,X,o,X,X,o,
+_,_,_,_,_,_,
+/* Char 0x18 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,o,_,o,X,o,
+o,X,o,X,o,_,
+_,o,X,o,_,_,
+o,X,o,X,o,_,
+X,o,_,o,X,o,
+_,_,_,_,_,_,
+/* Char 0x19 '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,o,_,_,X,o,
+X,_,_,_,X,_,
+X,o,_,_,X,_,
+o,X,X,X,X,_,
+_,_,_,o,X,_,
+_,o,X,X,o,_,
+/* Char 0x1a '?' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,_,
+o,_,o,X,o,_,
+_,o,X,o,_,_,
+o,X,o,_,X,_,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x1b '?' */
+_,X,X,X,X,_,
+_,X,o,_,_,_,
+_,X,_,_,_,_,
+_,X,_,_,_,_,
+_,X,_,_,_,_,
+_,X,o,_,_,_,
+_,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x1c '?' */
+_,_,_,X,X,_,
+_,o,X,_,_,X,
+o,X,X,o,_,_,
+X,X,X,X,X,_,
+o,X,X,o,_,_,
+X,X,o,_,_,X,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x1d '?' */
+_,X,X,X,X,_,
+_,_,_,o,X,_,
+_,_,_,_,X,_,
+_,_,_,_,X,_,
+_,_,_,_,X,_,
+_,_,_,o,X,_,
+_,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x1e '?' */
+_,_,_,_,_,_,
+o,X,o,_,_,_,
+X,o,X,o,X,_,
+_,_,o,X,o,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x1f '?' */
+_,_,_,_,_,_,
+_,o,X,_,_,_,
+o,X,X,o,_,_,
+X,X,X,X,X,X,
+X,X,X,X,X,X,
+o,X,X,o,_,_,
+_,o,X,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x20 ' ' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x21 '!' */
+_,_,X,X,_,_,
+_,_,X,o,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x22 '"' */
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x23 '#' */
+_,X,_,_,X,_,
+_,X,o,o,X,_,
+X,X,X,X,X,X,
+_,X,o,o,X,_,
+X,X,X,X,X,X,
+_,X,_,_,X,_,
+_,X,_,_,X,_,
+_,_,_,_,_,_,
+/* Char 0x24 '$' */
+_,o,X,X,o,_,
+o,X,X,X,X,X,
+X,X,o,_,_,_,
+o,X,X,X,X,o,
+_,_,_,o,X,X,
+X,X,X,X,X,o,
+_,o,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x25 '%' */
+X,X,_,_,o,X,
+X,X,_,o,X,X,
+_,_,o,X,X,o,
+_,o,X,X,o,_,
+o,X,X,o,_,_,
+X,X,o,_,X,X,
+X,o,_,_,X,X,
+_,_,_,_,_,_,
+/* Char 0x26 '&' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,o,X,o,_,_,
+X,o,_,_,X,_,
+X,o,o,X,X,_,
+o,X,X,o,X,_,
+_,_,_,_,_,_,
+/* Char 0x27 ''' */
+_,_,_,o,X,_,
+_,_,o,X,o,_,
+_,_,X,o,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x28 '(' */
+_,_,o,X,_,_,
+_,o,X,o,_,_,
+_,X,o,_,_,_,
+_,X,_,_,_,_,
+_,X,o,_,_,_,
+_,o,X,o,_,_,
+_,_,o,X,_,_,
+_,_,_,_,_,_,
+/* Char 0x29 ')' */
+_,_,X,o,_,_,
+_,_,o,X,o,_,
+_,_,_,o,X,_,
+_,_,_,_,X,_,
+_,_,_,o,X,_,
+_,_,o,X,o,_,
+_,_,X,o,_,_,
+_,_,_,_,_,_,
+/* Char 0x2a '*' */
+_,_,_,_,_,_,
+X,o,_,o,X,_,
+o,X,o,X,o,_,
+X,X,X,X,X,_,
+o,X,o,X,o,_,
+X,o,_,o,X,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x2b '+' */
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,_,X,o,_,_,
+X,X,X,X,X,_,
+_,o,X,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x2c ',' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,o,X,_,_,_,
+_,X,o,_,_,_,
+/* Char 0x2d '-' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x2e '.' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x2f '/' */
+_,_,_,_,_,_,
+_,_,_,o,X,_,
+_,_,o,X,o,_,
+_,o,X,o,_,_,
+_,X,o,_,_,_,
+o,X,o,_,_,_,
+o,X,o,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x30 '0' */
+o,X,X,X,o,_,
+X,_,_,o,X,_,
+X,_,o,X,X,_,
+X,_,X,o,X,_,
+X,X,o,_,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x31 '1' */
+_,o,X,_,_,_,
+_,X,X,_,_,_,
+_,o,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,o,X,o,_,_,
+_,X,X,X,_,_,
+_,_,_,_,_,_,
+/* Char 0x32 '2' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+_,_,_,o,X,_,
+_,o,X,X,o,_,
+o,X,o,_,_,_,
+X,o,_,_,_,_,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x33 '3' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+_,_,_,o,X,_,
+_,_,X,X,o,_,
+_,_,_,o,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x34 '4' */
+_,_,_,o,X,_,
+_,_,o,X,X,_,
+_,o,X,o,X,_,
+o,X,o,_,X,_,
+X,X,X,X,X,_,
+_,_,_,o,X,_,
+_,_,_,_,X,X,
+_,_,_,_,_,_,
+/* Char 0x35 '5' */
+X,X,X,X,X,_,
+X,o,_,_,o,_,
+X,X,X,X,o,_,
+_,_,_,o,X,_,
+_,_,_,_,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x36 '6' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,o,_,_,_,_,
+X,X,X,X,o,_,
+X,o,_,o,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x37 '7' */
+X,X,X,X,X,_,
+X,_,_,o,X,_,
+_,_,_,o,X,_,
+_,_,_,X,o,_,
+_,_,o,X,_,_,
+_,_,X,o,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x38 '8' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x39 '9' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,o,_,_,X,_,
+o,X,X,X,X,_,
+_,_,_,o,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x3a ':' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x3b ';' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,o,X,_,_,_,
+_,X,o,o,_,_,
+/* Char 0x3c '<' */
+_,_,o,X,X,_,
+_,o,X,o,_,_,
+o,X,o,_,_,_,
+X,o,_,_,_,_,
+o,X,o,_,_,_,
+_,o,X,o,_,_,
+_,_,o,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x3d '=' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x3e '>' */
+X,X,o,_,_,_,
+_,o,X,o,_,_,
+_,_,o,X,o,_,
+_,_,_,o,X,_,
+_,_,o,X,o,_,
+_,o,X,o,_,_,
+X,X,o,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x3f '?' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+_,_,_,o,X,_,
+_,_,o,X,o,_,
+_,_,X,o,_,_,
+_,_,_,_,_,_,
+_,_,X,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x40 '@' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,X,
+X,X,X,X,X,X,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x41 'A' */
+_,o,X,o,_,_,
+o,X,o,X,o,_,
+X,o,_,o,X,_,
+X,o,_,o,X,_,
+X,X,X,X,X,_,
+X,_,_,o,X,_,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0x42 'B' */
+X,X,X,X,o,_,
+X,_,_,o,X,_,
+X,_,_,o,X,_,
+X,X,X,X,o,_,
+X,_,_,o,X,_,
+X,_,_,o,X,_,
+X,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x43 'C' */
+o,X,X,X,o,_,
+X,o,_,_,X,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,o,_,_,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x44 'D' */
+X,X,X,o,_,_,
+X,_,o,X,o,_,
+X,_,_,o,X,_,
+X,_,_,_,X,_,
+X,_,_,o,X,_,
+X,_,o,X,o,_,
+X,X,X,o,_,_,
+_,_,_,_,_,_,
+/* Char 0x45 'E' */
+X,X,X,X,X,_,
+X,_,_,_,o,_,
+X,_,_,_,_,_,
+X,X,X,X,_,_,
+X,_,_,_,_,_,
+X,_,_,_,o,_,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x46 'F' */
+X,X,X,X,X,_,
+X,_,_,_,o,_,
+X,_,_,_,_,_,
+X,X,X,o,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,o,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x47 'G' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,_,_,_,_,_,
+X,_,_,X,X,_,
+X,_,_,o,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x48 'H' */
+X,o,_,_,X,o,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,X,X,X,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0x49 'I' */
+_,X,X,X,_,_,
+_,o,X,o,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,o,X,o,_,_,
+_,X,X,X,_,_,
+_,_,_,_,_,_,
+/* Char 0x4a 'J' */
+_,_,X,X,X,_,
+_,_,o,X,o,_,
+_,_,_,X,_,_,
+_,_,_,X,_,_,
+_,_,_,X,_,_,
+X,o,o,X,_,_,
+o,X,X,o,_,_,
+_,_,_,_,_,_,
+/* Char 0x4b 'K' */
+X,o,_,_,X,o,
+X,_,_,o,X,_,
+X,_,_,o,_,_,
+X,X,X,o,_,_,
+X,_,_,o,_,_,
+X,_,_,o,X,_,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0x4c 'L' */
+X,o,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,o,_,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x4d 'M' */
+X,o,_,o,X,o,
+X,X,o,X,X,_,
+X,X,X,X,X,_,
+X,o,X,o,X,_,
+X,_,o,_,X,_,
+X,_,_,_,X,_,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0x4e 'N' */
+X,o,_,_,X,o,
+X,X,o,_,X,_,
+X,o,X,o,X,_,
+X,_,o,X,X,_,
+X,_,_,X,X,_,
+X,_,_,o,X,_,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0x4f 'O' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x50 'P' */
+X,X,X,X,o,_,
+X,_,_,o,X,_,
+X,_,_,o,X,_,
+X,X,X,X,o,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,o,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x51 'Q' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,o,_,_,X,_,
+o,X,X,o,X,o,
+_,_,o,X,o,X,
+_,_,_,_,_,_,
+/* Char 0x52 'R' */
+X,X,X,X,o,_,
+X,_,_,o,X,_,
+X,_,_,o,X,_,
+X,X,X,X,o,_,
+X,_,o,X,o,_,
+X,_,_,o,X,_,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0x53 'S' */
+o,X,X,X,o,_,
+X,o,_,o,X,_,
+X,o,_,_,_,_,
+o,X,X,X,o,_,
+_,_,_,o,X,_,
+X,o,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x54 'T' */
+X,X,X,X,X,_,
+o,_,X,_,o,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,X,X,X,_,_,
+_,_,_,_,_,_,
+/* Char 0x55 'U' */
+X,o,_,_,X,o,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,_,_,o,X,_,
+o,X,X,X,o,_,
+_,_,_,_,_,_,
+/* Char 0x56 'V' */
+X,o,_,_,X,o,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,o,_,o,X,_,
+o,X,_,X,o,_,
+o,X,o,X,o,_,
+_,o,X,o,_,_,
+_,_,_,_,_,_,
+/* Char 0x57 'W' */
+X,o,_,_,X,o,
+X,_,_,_,X,_,
+X,_,_,_,X,_,
+X,_,o,_,X,_,
+X,o,X,o,X,_,
+X,X,o,X,X,_,
+X,o,_,o,X,o,
+_,_,_,_,_,_,
+/* Char 0x58 'X' */
+X,o,_,_,X,o,
+X,o,_,o,X,_,
+o,X,o,X,o,_,
+_,o,X,o,_,_,
+o,X,o,X,o,_,
+X,o,_,o,X,_,
+X,o,_,_,X,o,
+_,_,_,_,_,_,
+/* Char 0x59 'Y' */
+X,o,_,_,X,o,
+X,_,_,_,X,_,
+X,o,_,o,X,_,
+o,X,o,X,o,_,
+_,o,X,o,_,_,
+_,o,X,o,_,_,
+_,X,X,X,_,_,
+_,_,_,_,_,_,
+/* Char 0x5a 'Z' */
+X,X,X,X,X,_,
+X,o,_,o,X,_,
+_,_,o,X,o,_,
+_,o,X,o,_,_,
+o,X,o,_,_,_,
+X,o,_,o,X,_,
+X,X,X,X,X,o,
+_,_,_,_,_,_,
+/* Char 0x5b '[' */
+_,X,X,X,X,_,
+_,X,_,_,_,_,
+_,X,_,_,_,_,
+_,X,_,_,_,_,
+_,X,_,_,_,_,
+_,X,_,_,_,_,
+_,X,_,_,_,_,
+_,X,X,X,X,_,
+/* Char 0x5c '\' */
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+_,X,X,_,_,_,
+_,X,X,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+_,X,X,_,_,_,
+_,X,X,_,_,_,
+/* Char 0x5d ']' */
+_,X,X,X,X,_,
+_,_,_,_,X,_,
+_,_,_,_,X,_,
+_,_,_,_,X,_,
+_,_,_,_,X,_,
+_,_,_,_,X,_,
+_,_,_,_,X,_,
+_,X,X,X,X,_,
+/* Char 0x5e '^' */
+_,X,X,_,_,X,
+_,X,X,_,_,X,
+X,_,_,X,X,_,
+X,_,_,X,X,_,
+_,X,X,_,_,X,
+_,X,X,_,_,X,
+X,_,_,X,X,_,
+X,_,_,X,X,_,
+/* Char 0x5f '_' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,_,
+_,_,_,_,_,_,
+/* Char 0x60 '`' */
+X,o,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,5,5,5,
+X,_,5,4,4,4,
+X,_,5,4,3,3,
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+/* Char 0x61 'a' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+5,5,5,5,5,5,
+4,4,4,4,4,4,
+3,3,3,3,3,3,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x62 'b' */
+_,_,_,_,o,X,
+_,_,_,_,_,X,
+5,5,5,_,_,X,
+4,4,4,3,_,X,
+3,3,4,3,_,X,
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+/* Char 0x63 'c' */
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+/* Char 0x64 'd' */
+_,5,4,3,_,X,
+_,5,4,3,_,X,
+5,5,4,3,_,X,
+4,4,4,3,_,X,
+3,3,3,_,_,X,
+_,_,_,_,_,X,
+_,_,_,_,o,X,
+X,X,X,X,X,X,
+/* Char 0x65 'e' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+5,5,5,5,5,5,
+4,4,4,4,4,4,
+3,3,3,3,3,3,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,X,
+/* Char 0x66 'f' */
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+X,_,5,4,3,5,
+X,_,5,4,4,4,
+X,_,_,3,3,3,
+X,_,_,_,_,_,
+X,o,_,_,_,_,
+X,X,X,X,X,X,
+/* Char 0x67 'g' */
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+X,_,5,4,3,_,
+/* Char 0x68 'h' */
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+_,_,X,_,_,_,
+/* Char 0x69 'i' */
+X,X,X,X,X,X,
+_,_,_,_,_,_,
+X,X,X,X,X,X,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x6a 'j' */
+X,X,X,X,X,X,
+_,_,_,_,_,X,
+X,X,X,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+/* Char 0x6b 'k' */
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+/* Char 0x6c 'l' */
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+_,_,_,X,_,X,
+X,X,X,X,_,X,
+_,_,_,_,_,X,
+X,X,X,X,X,X,
+/* Char 0x6d 'm' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,X,
+_,_,_,_,_,_,
+X,X,X,X,X,X,
+/* Char 0x6e 'n' */
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,X,X,X,
+X,_,_,_,_,_,
+X,X,X,X,X,X,
+/* Char 0x6f 'o' */
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+/* Char 0x70 'p' */
+6,6,7,7,_,_,
+6,7,_,_,4,3,
+6,7,_,5,3,_,
+6,_,4,3,_,_,
+6,_,3,_,_,_,
+6,7,_,_,_,_,
+6,7,_,_,_,_,
+6,6,7,7,_,_,
+/* Char 0x71 'q' */
+_,_,7,7,6,6,
+_,_,_,_,7,6,
+_,_,_,_,7,6,
+_,_,_,_,_,6,
+_,_,_,_,_,6,
+_,_,_,_,7,6,
+_,_,_,_,7,6,
+_,_,7,7,6,6,
+/* Char 0x72 'r' */
+X,X,X,X,X,X,
+X,_,_,_,_,_,
+X,_,X,X,X,X,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+X,_,X,_,_,_,
+/* Char 0x73 's' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,X,
+X,X,X,X,X,X,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x74 't' */
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+X,_,_,_,_,_,
+/* Char 0x75 'u' */
+X,X,_,_,_,_,
+X,X,_,_,_,_,
+X,X,_,_,_,_,
+X,X,_,_,_,_,
+X,X,_,_,_,_,
+X,X,_,_,_,_,
+X,X,_,_,_,_,
+X,X,_,_,_,_,
+/* Char 0x76 'v' */
+_,_,_,_,X,X,
+_,_,_,_,X,X,
+_,_,_,_,X,X,
+_,_,_,_,X,X,
+_,_,_,_,X,X,
+_,_,_,_,X,X,
+_,_,_,_,X,X,
+_,_,_,_,X,X,
+/* Char 0x77 'w' */
+X,X,X,X,X,X,
+X,X,X,X,X,X,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x78 'x' */
+X,X,X,X,X,X,
+X,X,X,X,X,X,
+X,X,X,X,X,X,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x79 'y' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,X,X,X,
+X,X,X,X,X,X,
+X,X,X,X,X,X,
+/* Char 0x7a 'z' */
+_,_,_,_,_,_,
+_,_,_,_,o,X,
+_,_,_,o,X,X,
+X,X,o,X,X,o,
+X,X,X,X,o,_,
+X,X,X,o,_,_,
+X,X,o,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x7b '{' */
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+/* Char 0x7c '|' */
+_,_,_,X,X,X,
+_,_,_,X,X,X,
+_,_,_,X,X,X,
+_,_,_,X,X,X,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x7d '}' */
+_,_,X,X,_,_,
+_,_,X,X,_,_,
+_,o,X,X,_,_,
+X,X,X,X,_,_,
+X,X,X,X,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x7e '~' */
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+_,_,_,_,_,_,
+/* Char 0x7f '?' */
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+X,X,X,_,_,_,
+_,_,_,X,X,X,
+_,_,_,X,X,X,
+_,_,_,X,X,X,
+_,_,_,X,X,X,
+
+};
diff --git a/contiki/ctk/ctk-vncfont.h b/contiki/ctk/ctk-vncfont.h
new file mode 100644
index 0000000..18a8f08
--- /dev/null
+++ b/contiki/ctk/ctk-vncfont.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the Contiki VNC server
+ *
+ * $Id: ctk-vncfont.h,v 1.1 2003/07/02 21:34:00 adamdunkels Exp $
+ *
+ */
+#ifndef __CTK_VNCFONT_H__
+#define __CTK_VNCFONT_H__
+
+unsigned char ctk_vncfont[6*8*128];
+
+#endif /* __CTK_VNCFONT_H__ */
diff --git a/contiki/ctk/ctk-vncserver.c b/contiki/ctk/ctk-vncserver.c
new file mode 100644
index 0000000..66ede6f
--- /dev/null
+++ b/contiki/ctk/ctk-vncserver.c
@@ -0,0 +1,884 @@
+/*
+ * Copyright (c) 2002, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the "ctk" console GUI toolkit for cc65
+ *
+ * $Id: ctk-vncserver.c,v 1.1 2003/07/02 21:34:00 adamdunkels Exp $
+ *
+ */
+
+#include "ctk.h"
+#include "ctk-draw.h"
+
+#include "dispatcher.h"
+#include "loader.h"
+#include "vnc-server.h"
+#include "vnc-out.h"
+
+static unsigned char sizex, sizey;
+
+#define CH_ULCORNER 0x00
+#define CH_TITLEBAR 0x01
+#define CH_URCORNER 0x02
+#define CH_WINDOWRBORDER 0x03
+#define CH_LRCORNER 0x04
+#define CH_WINDOWLOWERBORDER 0x05
+#define CH_LLCORNER 0x06
+#define CH_WINDOWLBORDER 0x07
+
+#define CH_DIALOG_ULCORNER 0x12
+#define CH_DIALOGUPPERBORDER 0x09
+#define CH_DIALOG_URCORNER 0x0a
+#define CH_DIALOGRBORDER 0x0b
+#define CH_DIALOG_LRCORNER 0x0c
+#define CH_DIALOGLOWERBORDER 0x0d
+#define CH_DIALOG_LLCORNER 0x0e
+#define CH_DIALOGLBORDER 0x0f
+
+#define CH_BUTTONLEFT 0x10
+#define CH_BUTTONRIGHT 0x11
+
+#define CH_SEPARATOR 0x13
+
+#include "libconio.h"
+
+#define SCREENCOLOR 0
+#define BORDERCOLOR 1
+
+#define WIDGETCOLOR 2
+#define WIDGETCOLOR_FWIN 3
+#define WIDGETCOLOR_FOCUS 4
+#define WIDGETCOLOR_DIALOG 5
+#define WIDGETCOLOR_HLINK 6
+#define WIDGETCOLOR_HLINK_FOCUS 7
+
+#define WINDOWCOLOR 8
+#define WINDOWCOLOR_FOCUS 9
+
+#define WINDOWBORDER 10
+#define WINDOWBORDER_FOCUS 11
+
+#define DIALOGCOLOR 12
+
+#define OPENMENUCOLOR 13
+
+#define ACTIVEMENUITEMCOLOR 14
+
+#define MENUCOLOR 15
+
+static DISPATCHER_UIPCALL(ctk_vncserver_appcall, state);
+
+static struct dispatcher_proc p =
+ {DISPATCHER_PROC("CTK VNC server", NULL, NULL,
+ ctk_vncserver_appcall)};
+static ek_id_t id;
+
+
+#define VNCSERVER_CONF_NUMCONNS 8
+static struct vnc_server_state conns[VNCSERVER_CONF_NUMCONNS];
+
+#define PRINTF(x)
+
+#define revers(x)
+
+
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_server_update_add(struct vnc_server_state *vs,
+ struct vnc_server_update *a)
+{
+ /* XXX: test both head and tail placement!*/
+ a->next = vs->updates_pending;
+ vs->updates_pending = a;
+}
+struct vnc_server_update *
+vnc_server_update_alloc(struct vnc_server_state *vs)
+{
+ struct vnc_server_update *a;
+
+ a = vs->updates_free;
+ if(a == NULL) {
+ return NULL;
+ }
+ vs->updates_free = a->next;
+ a->next = NULL;
+ return a;
+}
+void
+vnc_server_update_free(struct vnc_server_state *vs,
+ struct vnc_server_update *a)
+{
+ a->next = vs->updates_free;
+ vs->updates_free = a;
+}
+struct vnc_server_update *
+vnc_server_update_dequeue(struct vnc_server_state *vs)
+{
+ struct vnc_server_update *a;
+
+ a = vs->updates_pending;
+ if(a == NULL) {
+ return a;
+ }
+ vs->updates_pending = a->next;
+ a->next = NULL;
+ return a;
+}
+void
+vnc_server_update_remove(struct vnc_server_state *vs,
+ struct vnc_server_update *a)
+{
+ struct vnc_server_update *b, *c;
+
+ if(a == vs->updates_pending) {
+ vs->updates_pending = a->next;
+ } else {
+
+ for(c = vs->updates_pending; c != a; b = c, c = c->next);
+
+ b->next = a->next;
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+update_area(u8_t x, u8_t y, u8_t w, u8_t h)
+{
+ u8_t i;
+
+ if(h == 0 || w == 0) {
+ return;
+ }
+
+ /* Update for all active VNC connections. */
+ for(i = 0; i < VNCSERVER_CONF_NUMCONNS; ++i) {
+ if(conns[i].state != VNC_DEALLOCATED) {
+ vnc_out_update_area(&conns[i],
+ x, y, w, h);
+ }
+ }
+
+}
+/*-----------------------------------------------------------------------------------*/
+static struct vnc_server_state *
+alloc_state(void)
+{
+ u8_t i;
+ for(i = 0; i < VNCSERVER_CONF_NUMCONNS; ++i) {
+ if(conns[i].state == VNC_DEALLOCATED) {
+ return &conns[i];
+ }
+ }
+
+ /* We are overloaded! XXX: we'll just kick all other connections! */
+ for(i = 0; i < VNCSERVER_CONF_NUMCONNS; ++i) {
+ conns[i].state = VNC_DEALLOCATED;
+ }
+
+ return NULL;
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+dealloc_state(struct vnc_server_state *s)
+{
+ s->state = VNC_DEALLOCATED;
+}
+/*-----------------------------------------------------------------------------------*/
+static char tmp[40];
+static void
+cputsn(char *str, unsigned char len)
+{
+ strncpy(tmp, str, len);
+ tmp[len] = 0;
+ cputs(tmp);
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_draw_init(void)
+{
+ bgcolor(SCREENCOLOR);
+ bordercolor(BORDERCOLOR);
+ screensize(&sizex, &sizey);
+ ctk_draw_clear(0, sizey);
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+draw_widget(struct ctk_widget *w,
+ unsigned char x, unsigned char y,
+ unsigned char clipx,
+ unsigned char clipy,
+ unsigned char clipy1, unsigned char clipy2,
+ unsigned char focus)
+{
+ unsigned char xpos, ypos, xscroll;
+ unsigned char i, j;
+ unsigned char iconnum;
+ char c, *text;
+ unsigned char len;
+
+ /*
+ if(focus & CTK_FOCUS_WINDOW) {
+ textcolor(WIDGETCOLOR_FWIN);
+ if(focus & CTK_FOCUS_WIDGET) {
+ textcolor(WIDGETCOLOR_FOCUS);
+ }
+ } else if(focus & CTK_FOCUS_DIALOG) {
+ textcolor(WIDGETCOLOR_DIALOG);
+ if(focus & CTK_FOCUS_WIDGET) {
+ textcolor(WIDGETCOLOR_FOCUS);
+ }
+ } else {
+ textcolor(WIDGETCOLOR);
+ }
+*/
+ xpos = x + w->x;
+ ypos = y + w->y;
+
+ switch(w->type) {
+ case CTK_WIDGET_SEPARATOR:
+ textcolor(VNC_OUT_SEPARATORCOLOR + focus);
+ if(ypos >= clipy1 && ypos < clipy2) {
+ /* chlinexy(xpos, ypos, w->w);*/
+ gotoxy(xpos, ypos);
+ for(i = 0; i < w->w; ++i) {
+ cputc(CH_SEPARATOR);
+ }
+ }
+ break;
+ case CTK_WIDGET_LABEL:
+ textcolor(VNC_OUT_LABELCOLOR + focus);
+ text = w->widget.label.text;
+ for(i = 0; i < w->h; ++i) {
+ if(ypos >= clipy1 && ypos < clipy2) {
+ gotoxy(xpos, ypos);
+ cputsn(text, w->w);
+ if(w->w - (wherex() - xpos) > 0) {
+ cclear(w->w - (wherex() - xpos));
+ }
+ }
+ ++ypos;
+ text += w->w;
+ }
+ break;
+ case CTK_WIDGET_BUTTON:
+ textcolor(VNC_OUT_BUTTONCOLOR + focus);
+ if(ypos >= clipy1 && ypos < clipy2) {
+ if(focus & CTK_FOCUS_WIDGET) {
+ revers(1);
+ } else {
+ revers(0);
+ }
+ cputcxy(xpos, ypos, CH_BUTTONLEFT);
+ cputsn(w->widget.button.text, w->w);
+ cputc(CH_BUTTONRIGHT);
+ revers(0);
+ }
+ break;
+ case CTK_WIDGET_HYPERLINK:
+ textcolor(VNC_OUT_HYPERLINKCOLOR + focus);
+ if(ypos >= clipy1 && ypos < clipy2) {
+ /* if(focus & CTK_FOCUS_WIDGET) {
+ textcolor(WIDGETCOLOR_HLINK_FOCUS);
+ revers(0);
+ } else {
+ textcolor(WIDGETCOLOR_HLINK);
+ revers(1);
+ }*/
+ gotoxy(xpos, ypos);
+ cputsn(w->widget.button.text, w->w);
+ revers(0);
+ }
+ break;
+ case CTK_WIDGET_TEXTENTRY:
+ textcolor(VNC_OUT_TEXTENTRYCOLOR + focus);
+ text = w->widget.textentry.text;
+ if(focus & CTK_FOCUS_WIDGET) {
+ revers(1);
+ } else {
+ revers(0);
+ }
+ xscroll = 0;
+ if(w->widget.textentry.xpos >= w->w - 1) {
+ xscroll = w->widget.textentry.xpos - w->w + 1;
+ }
+ for(j = 0; j < w->h; ++j) {
+ if(ypos >= clipy1 && ypos < clipy2) {
+ if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT &&
+ w->widget.textentry.ypos == j) {
+ revers(0);
+ cputcxy(xpos, ypos, '>');
+ for(i = 0; i < w->w; ++i) {
+ c = text[i + xscroll];
+ if(i == w->widget.textentry.xpos - xscroll) {
+ textcolor(VNC_OUT_TEXTENTRYCOLOR + (focus ^ 0x01));
+ revers(1);
+ } else {
+ revers(0);
+ }
+ if(c == 0) {
+ cputc(' ');
+ } else {
+ cputc(c);
+ }
+ revers(0);
+ textcolor(VNC_OUT_TEXTENTRYCOLOR + focus);
+ }
+ cputc('<');
+ } else {
+ cvlinexy(xpos, ypos, 1);
+ gotoxy(xpos + 1, ypos);
+ cputsn(text, w->w);
+ i = wherex();
+ if(i - xpos - 1 < w->w) {
+ cclear(w->w - (i - xpos) + 1);
+ }
+ cvline(1);
+ }
+ }
+ ++ypos;
+ text += w->w;
+ }
+ revers(0);
+ break;
+ case CTK_WIDGET_ICON:
+ if(ypos >= clipy1 && ypos < clipy2) {
+ textcolor(VNC_OUT_ICONCOLOR + focus);
+ if(focus & 1) {
+ revers(1);
+ } else {
+ revers(0);
+ }
+
+ x = xpos;
+ len = strlen(w->widget.icon.title);
+ if(x + len >= sizex) {
+ x = sizex - len;
+ }
+
+ gotoxy(x, ypos + 3);
+ if(ypos >= clipy1 && ypos < clipy2) {
+ cputs(w->widget.icon.title);
+ }
+
+ gotoxy(xpos, ypos);
+ if(w->widget.icon.bitmap != NULL) {
+ iconnum = vnc_out_add_icon((struct ctk_icon *)w);
+ gotoxy(xpos, ypos);
+ textcolor(iconnum | (focus << 6));
+ cputc(0x80);
+ cputc(0x81);
+ cputc(0x82);
+ cputc(0x83);
+ ++ypos;
+ gotoxy(xpos, ypos);
+ cputc(0x90);
+ cputc(0x91);
+ cputc(0x92);
+ cputc(0x93);
+ ++ypos;
+ gotoxy(xpos, ypos);
+ cputc(0xa0);
+ cputc(0xa1);
+ cputc(0xa2);
+ cputc(0xa3);
+ ++ypos;
+ textcolor(0);
+ /* for(i = 0; i < 3; ++i) {
+
+ if(ypos >= clipy1 && ypos < clipy2) {
+ cputc(w->widget.icon.textmap[0 + 3 * i]);
+ cputc(w->widget.icon.textmap[1 + 3 * i]);
+ cputc(w->widget.icon.textmap[2 + 3 * i]);
+ }
+ ++ypos;
+ }*/
+ }
+ x = xpos;
+
+ revers(0);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_draw_widget(struct ctk_widget *w,
+ unsigned char focus,
+ unsigned char clipy1,
+ unsigned char clipy2)
+{
+ struct ctk_window *win = w->window;
+ struct ctk_icon *icon;
+ unsigned char posx, posy, x, len;
+
+ posx = win->x + 1;
+ posy = win->y + 2;
+
+ if(w == win->focused) {
+ focus |= CTK_FOCUS_WIDGET;
+ }
+
+ draw_widget(w, posx, posy,
+ posx + win->w,
+ posy + win->h,
+ clipy1, clipy2,
+ focus);
+
+ if(w->type != CTK_WIDGET_ICON) {
+ update_area(posx + w->x,
+ posy + w->y, w->w + 2, w->h);
+ } else {
+ icon = (struct ctk_icon *)w;
+
+ len = strlen(icon->title);
+ x = posx + w->x;
+ if(x + len >= sizex) {
+ x = sizex - len;
+ }
+
+ update_area(x, posy + w->y, len > 4? len: 4, w->h);
+ }
+
+#ifdef CTK_CONIO_CONF_UPDATE
+ CTK_CONIO_CONF_UPDATE();
+#endif /* CTK_CONIO_CONF_UPDATE */
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_draw_clear_window(struct ctk_window *window,
+ unsigned char focus,
+ unsigned char clipy1,
+ unsigned char clipy2)
+{
+ unsigned char i;
+ unsigned char h;
+ /*
+ if(focus & CTK_FOCUS_WINDOW){
+ textcolor(WINDOWCOLOR_FOCUS);
+ } else {
+ textcolor(WINDOWCOLOR);
+ }*/
+ textcolor(VNC_OUT_WINDOWCOLOR + focus);
+
+ h = window->y + 2 + window->h;
+ /* Clear window contents. */
+ for(i = window->y + 2; i < h; ++i) {
+ if(i >= clipy1 && i < clipy2) {
+ cclearxy(window->x + 1, i, window->w);
+ }
+ }
+
+ update_area(window->x + 1, window->y + 2, window->w, window->h);
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+draw_window_contents(struct ctk_window *window, unsigned char focus,
+ unsigned char clipy1, unsigned char clipy2,
+ unsigned char x1, unsigned char x2,
+ unsigned char y1, unsigned char y2)
+{
+ struct ctk_widget *w;
+ unsigned char wfocus;
+
+ /* Draw inactive widgets. */
+ for(w = window->inactive; w != NULL; w = w->next) {
+ draw_widget(w, x1, y1, x2, y2,
+ clipy1, clipy2,
+ focus);
+ }
+
+ /* Draw active widgets. */
+ for(w = window->active; w != NULL; w = w->next) {
+ wfocus = focus;
+ if(w == window->focused) {
+ wfocus |= CTK_FOCUS_WIDGET;
+ }
+
+ draw_widget(w, x1, y1, x2, y2,
+ clipy1, clipy2,
+ wfocus);
+ }
+
+#ifdef CTK_CONIO_CONF_UPDATE
+ CTK_CONIO_CONF_UPDATE();
+#endif /* CTK_CONIO_CONF_UPDATE */
+
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_draw_window(struct ctk_window *window, unsigned char focus,
+ unsigned char clipy1, unsigned char clipy2)
+{
+ unsigned char x, y;
+ unsigned char h;
+ unsigned char x1, y1, x2, y2;
+ unsigned char i;
+
+
+ if(window->y + 1 >= clipy2) {
+ return;
+ }
+
+ x = window->x;
+ y = window->y + 1;
+
+ textcolor(VNC_OUT_WINDOWCOLOR + focus);
+ /* if(focus & CTK_FOCUS_WINDOW) {
+ textcolor(WINDOWCOLOR_FOCUS);
+ } else {
+ textcolor(WINDOWCOLOR);
+ }*/
+
+ x1 = x + 1;
+ y1 = y + 1;
+ x2 = x1 + window->w;
+ y2 = y1 + window->h;
+
+ /* Draw window frame. */
+ if(y >= clipy1) {
+ cputcxy(x, y, CH_ULCORNER);
+ for(i = wherex() + window->titlelen + 2; i < x2; ++i) {
+ cputcxy(i, y, CH_TITLEBAR);
+ }
+ cputcxy(x2, y, CH_URCORNER);
+ }
+
+ h = window->h;
+
+ if(clipy1 > y1) {
+ if(clipy1 - y1 < h) {
+ h = clipy1 - y1;
+ y1 = clipy1;
+ } else {
+ h = 0;
+ }
+ }
+
+ if(clipy2 < y1 + h) {
+ if(y1 >= clipy2) {
+ h = 0;
+ } else {
+ h = clipy2 - y1;
+ }
+ }
+
+ for(i = y1; i < y1 + h; ++i) {
+ cputcxy(x, i, CH_WINDOWLBORDER);
+ cputcxy(x2, i, CH_WINDOWRBORDER);
+ }
+
+ /* cvlinexy(x, y1, h);
+ cvlinexy(x2, y1, h); */
+
+ if(y + window->h >= clipy1 &&
+ y + window->h < clipy2) {
+ cputcxy(x, y2, CH_LLCORNER);
+ for(i = x1; i < x2; ++i) {
+ cputcxy(i, y2, CH_WINDOWLOWERBORDER);
+ }
+ /* chlinexy(x1, y2, window->w);*/
+ cputcxy(x2, y2, CH_LRCORNER);
+ }
+
+ draw_window_contents(window, focus & CTK_FOCUS_WINDOW, clipy1, clipy2,
+ x1, x2, y + 1, y2);
+
+ update_area(window->x, window->y, window->w + 2, window->h + 2);
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_draw_dialog(struct ctk_window *dialog)
+{
+ unsigned char x, y;
+ unsigned char i;
+ unsigned char x1, y1, x2, y2;
+
+ /* textcolor(DIALOGCOLOR);*/
+ textcolor(VNC_OUT_WINDOWCOLOR + CTK_FOCUS_DIALOG);
+
+ x = dialog->x;
+ y = dialog->y + 1;
+
+
+ x1 = x + 1;
+ y1 = y + 1;
+ x2 = x1 + dialog->w;
+ y2 = y1 + dialog->h;
+
+
+ /* Draw dialog frame. */
+
+ for(i = y1; i < y1 + dialog->h; ++i) {
+ cputcxy(x, i, CH_DIALOGLBORDER);
+ cputcxy(x2, i, CH_DIALOGRBORDER);
+ }
+ /* cvlinexy(x, y1,
+ dialog->h);
+ cvlinexy(x2, y1,
+ dialog->h);*/
+
+
+ for(i = x1; i < x2; ++i) {
+ cputcxy(i, y, CH_DIALOGUPPERBORDER);
+ cputcxy(i, y2, CH_DIALOGLOWERBORDER);
+ }
+ /* chlinexy(x1, y,
+ dialog->w);
+ chlinexy(x1, y2,
+ dialog->w);*/
+
+ cputcxy(x, y, CH_DIALOG_ULCORNER);
+ cputcxy(x, y2, CH_DIALOG_LLCORNER);
+ cputcxy(x2, y, CH_DIALOG_URCORNER);
+ cputcxy(x2, y2, CH_DIALOG_LRCORNER);
+
+
+ /* Clear dialog contents. */
+ for(i = y1; i < y2; ++i) {
+ cclearxy(x1, i, dialog->w);
+ }
+
+ draw_window_contents(dialog, CTK_FOCUS_DIALOG, 0, sizey,
+ x1, x2, y1, y2);
+
+ update_area(dialog->x, dialog->y, dialog->w, dialog->h);
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_draw_clear(unsigned char y1, unsigned char y2)
+{
+ unsigned char i;
+
+ textcolor(VNC_OUT_BACKGROUNDCOLOR);
+ for(i = y1; i < y2; ++i) {
+ cclearxy(0, i, sizex);
+ }
+
+ update_area(0, y1, sizex, y2 - y1);
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+draw_menu(struct ctk_menu *m)
+{
+ unsigned char x, x2, y;
+
+ textcolor(VNC_OUT_MENUCOLOR);
+ x = wherex();
+ cputs(m->title);
+ cputc(' ');
+ x2 = wherex();
+ if(x + CTK_CONF_MENUWIDTH > sizex) {
+ x = sizex - CTK_CONF_MENUWIDTH;
+ }
+
+
+ for(y = 0; y < m->nitems; ++y) {
+ if(y == m->active) {
+ textcolor(VNC_OUT_ACTIVEMENUCOLOR);
+ revers(0);
+ } else {
+ textcolor(VNC_OUT_MENUCOLOR);
+ }
+ gotoxy(x, y + 1);
+ if(m->items[y].title[0] == '-') {
+ chline(CTK_CONF_MENUWIDTH);
+ } else {
+ cputs(m->items[y].title);
+ }
+ if(x + CTK_CONF_MENUWIDTH > wherex()) {
+ cclear(x + CTK_CONF_MENUWIDTH - wherex());
+ }
+ revers(1);
+ }
+
+ gotoxy(x2, 0);
+ textcolor(VNC_OUT_MENUCOLOR);
+
+ update_area(x, 0, CTK_CONF_MENUWIDTH, m->nitems + 1);
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_draw_menus(struct ctk_menus *menus)
+{
+ struct ctk_menu *m;
+
+
+ /* Draw menus */
+ textcolor(VNC_OUT_MENUCOLOR);
+ gotoxy(0, 0);
+ revers(1);
+ cputc(' ');
+ for(m = menus->menus->next; m != NULL; m = m->next) {
+ if(m != menus->open) {
+ update_area(wherex(), 0, strlen(m->title) + 1, 1);
+ cputs(m->title);
+ cputc(' ');
+ } else {
+ draw_menu(m);
+ }
+ }
+
+
+ if(wherex() + strlen(menus->desktopmenu->title) + 1>= sizex) {
+ gotoxy(sizex - strlen(menus->desktopmenu->title) - 1, 0);
+ } else {
+ cclear(sizex - wherex() -
+ strlen(menus->desktopmenu->title) - 1);
+ update_area(wherex(), 0, sizex - wherex() -
+ strlen(menus->desktopmenu->title) - 1, 1);
+ }
+
+ /* Draw desktopmenu */
+ if(menus->desktopmenu != menus->open) {
+ update_area(wherex(), 0, strlen(menus->desktopmenu->title) + 1, 1);
+ cputs(menus->desktopmenu->title);
+ cputc(' ');
+ } else {
+ draw_menu(menus->desktopmenu);
+ }
+
+ revers(0);
+
+
+
+}
+/*-----------------------------------------------------------------------------------*/
+unsigned char
+ctk_draw_height(void)
+{
+ return sizey;
+}
+/*-----------------------------------------------------------------------------------*/
+unsigned char
+ctk_draw_width(void)
+{
+ return sizex;
+}
+/*-----------------------------------------------------------------------------------*/
+static unsigned char
+ascii2screen(unsigned char c)
+{
+ if(c == '|') {
+ return 0x68;
+ }
+ if(c < 0x20) {
+ return c + 0x60;
+ }
+ if(c > 0x20 && c < 0x40) {
+ return c;
+ }
+ if(c >= 0x40 && c < 0x60) {
+ return c;
+ }
+ if(c >= 0x60 && c < 0x80) {
+ return c - 0x60;
+ }
+ if(c >= 0x80) {
+ return c;
+ }
+
+ return 32;
+}
+
+void
+ctk_arch_draw_char(char c,
+ unsigned char xpos,
+ unsigned char ypos,
+ unsigned char reversedflag,
+ unsigned char color)
+{
+
+ vnc_out_update_screen(xpos, ypos, ascii2screen(c),
+ color);
+ /* vnc_out_update_screen(xpos, ypos, c |
+ (reversedflag? 0x80: 0));*/
+}
+
+unsigned char
+ctk_arch_keyavail(void)
+{
+ return vnc_out_keyavail();
+}
+
+ctk_arch_key_t
+ctk_arch_getkey(void)
+{
+ return vnc_out_getkey() & 0x7f;
+}
+/*-----------------------------------------------------------------------------------*/
+static
+DISPATCHER_UIPCALL(ctk_vncserver_appcall, state)
+{
+ static struct vnc_server_state *vs;
+ DISPATCHER_UIPCALL_ARG(state);
+
+ vs = (struct vnc_server_state *)(state);
+
+ if(uip_connected()) {
+
+ /* Since we've just been connected, the state pointer should be
+ NULL and we need to allocate a new state object. If we have run
+ out of memory for state objects, we'll have to abort the
+ connection and return. */
+ if(vs == NULL) {
+ vs = alloc_state();
+ if(vs == NULL) {
+ uip_close();
+ return;
+ }
+ dispatcher_markconn(uip_conn, (void *)vs);
+ }
+ } else if(uip_closed() || uip_aborted()) {
+ if(vs != NULL) {
+ dealloc_state(vs);
+ }
+ return;
+ }
+ vnc_server_appcall(vs);
+}
+/*-----------------------------------------------------------------------------------*/
+LOADER_INIT_FUNC(ctk_vncserver_init)
+{
+ u8_t i;
+
+ if(id == EK_ID_NONE) {
+ id = dispatcher_start(&p);
+ dispatcher_uiplisten(5900);
+
+ for(i = 0; i < VNCSERVER_CONF_NUMCONNS; ++i) {
+ conns[i].state = VNC_DEALLOCATED;
+ }
+ }
+}
+/*-----------------------------------------------------------------------------------*/
diff --git a/contiki/ctk/ctk-vncserver.h b/contiki/ctk/ctk-vncserver.h
new file mode 100644
index 0000000..aed42d9
--- /dev/null
+++ b/contiki/ctk/ctk-vncserver.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2002, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the "ctk" console GUI toolkit for cc65
+ *
+ * $Id: ctk-vncserver.h,v 1.1 2003/07/02 21:34:00 adamdunkels Exp $
+ *
+ */
+#ifndef __CTK_VNCSERVER_H__
+#define __CTK_VNCSERVER_H__
+
+void ctk_vncserver_init(void);
+
+
+
+#endif /* __CTK_VNCSERVER_H__ */
diff --git a/contiki/ctk/vnc-out.c b/contiki/ctk/vnc-out.c
new file mode 100644
index 0000000..9e14d2f
--- /dev/null
+++ b/contiki/ctk/vnc-out.c
@@ -0,0 +1,964 @@
+/*
+ * Copyright (c) 2001, Adam Dunkels
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: vnc-out.c,v 1.1 2003/07/02 21:34:00 adamdunkels Exp $
+ *
+ */
+
+#include "uip.h"
+#include "vnc-server.h"
+#include "vnc-out.h"
+
+#include "libconio.h"
+
+#include "ctk-vncfont.h"
+
+#include "ctk-arch.h"
+
+#include "ctk-mouse.h"
+
+#ifndef NOT_AVR
+#include <avr/pgmspace.h>
+#else
+#define memcpy_P memcpy
+#endif /* NOT_AVR */
+
+#define CHARS_WIDTH LIBCONIO_CONF_SCREEN_WIDTH
+#define CHARS_HEIGHT LIBCONIO_CONF_SCREEN_HEIGHT
+
+#define SCREEN_X 10
+#define SCREEN_Y 8
+
+#define FONT_WIDTH 6
+#define FONT_HEIGHT 8
+
+#define SCREEN_WIDTH (CHARS_WIDTH * FONT_WIDTH + 2 * SCREEN_X) /*420*/
+#define SCREEN_HEIGHT (CHARS_HEIGHT * FONT_HEIGHT + 2 * SCREEN_Y) /*300*/
+#define BORDER_COLOR 0x00
+#define TEXT_COLOR 0x38 /*0xe0*/
+#define SCREEN_COLOR 0x00 /*0xc0*/
+
+#define BGR(b,g,r) (((b) << 6) | (g) << 3 | (r))
+
+#define BGCOLOR BGR(1,0,1)
+
+static u8_t menucolor[] = {
+ BGR(0,7,7), /* Background. */
+ BGR(0,5,5), /* Anti-alias font color. */
+ BGR(0,0,0), /* Font color. */
+};
+
+
+static u8_t activemenucolor[] = {
+ BGR(3,7,7), /* Background. */
+ BGR(3,6,6), /* Anti-alias font color. */
+ BGR(0,0,0), /* Font color. */
+};
+
+
+static unsigned char backgroundcolor[] = {BGR(1,0,1)};
+
+static unsigned char wincol[] =
+ {BGR(2,5,5),BGR(2,2,2),BGR(0,1,1),BGR(1,0,0),BGR(2,0,0),BGR(2,1,1)};
+static unsigned char wincol_f[] =
+ {BGR(3,6,6),BGR(1,2,2),BGR(0,1,1),BGR(2,0,0),BGR(3,2,2),BGR(3,4,4)};
+static unsigned char wincol_d[] =
+ {BGR(3,7,7),BGR(1,5,5),BGR(0,0,0),BGR(2,0,0),BGR(3,2,2),BGR(3,4,4)};
+
+static unsigned char sepcol[] =
+ {BGR(2,5,5),BGR(2,6,6),BGR(3,6,6)};
+static unsigned char sepcol_f[] =
+ {BGR(3,6,6),BGR(3,5,5),BGR(2,5,5)};
+static unsigned char sepcol_d[] =
+ {BGR(3,7,7),BGR(1,5,7),BGR(0,0,0)};
+
+static unsigned char labcol[] =
+ {BGR(2,5,5),BGR(1,3,3),BGR(0,1,1)};
+static unsigned char labcol_f[] =
+ {BGR(3,6,6),BGR(3,5,5),BGR(0,0,0)};
+static unsigned char labcol_d[] =
+ {BGR(3,7,7),BGR(1,5,5),BGR(0,0,0)};
+
+
+static unsigned char butcol[] =
+ {BGR(2,4,4),BGR(1,3,3),BGR(0,1,1),BGR(2,4,4),BGR(2,4,4),BGR(2,4,4),
+ BGR(2,5,5),BGR(2,5,5)};
+static unsigned char butcol_w[] =
+ {BGR(2,4,4),BGR(1,3,3),BGR(0,1,1),BGR(2,4,4),BGR(2,4,4),BGR(2,4,4),
+ BGR(2,5,5),BGR(2,5,5)};
+static unsigned char butcol_f[] =
+ {BGR(2,3,3),BGR(3,5,5),BGR(3,6,6),BGR(3,5,5),BGR(3,6,6),BGR(3,7,7),
+ BGR(3,6,6),BGR(2,5,5)};
+static unsigned char butcol_fw[] =
+ {BGR(3,7,7),BGR(3,6,6),BGR(0,0,0),BGR(1,7,7),BGR(2,7,7),BGR(3,7,7),
+ BGR(3,6,6),BGR(3,7,6)};
+static unsigned char butcol_d[] =
+ {BGR(2,3,3),BGR(2,5,5),BGR(3,6,6),BGR(1,3,4),BGR(1,5,6),BGR(2,6,7),
+ BGR(3,7,7),BGR(2,5,5)};
+static unsigned char butcol_dw[] =
+ {BGR(0,0,0),BGR(2,5,5),BGR(3,7,7),BGR(1,3,4),BGR(1,5,6),BGR(2,6,7),
+ BGR(3,7,7),BGR(2,5,5)};
+
+
+static unsigned char hlcol[] =
+ {BGR(2,5,5),BGR(1,3,3),BGR(1,0,0)};
+static unsigned char hlcol_w[] =
+ {BGR(2,5,5),BGR(1,3,3),BGR(1,0,0)};
+static unsigned char hlcol_f[] =
+ {BGR(3,6,6),BGR(3,5,5),BGR(3,0,0)};
+static unsigned char hlcol_fw[] =
+ {BGR(3,6,6),BGR(3,6,7),BGR(3,7,7)};
+static unsigned char hlcol_d[] =
+ {BGR(3,7,7),BGR(3,5,5),BGR(2,0,0)};
+static unsigned char hlcol_dw[] =
+ {BGR(3,7,7),BGR(1,5,5),BGR(0,0,0)};
+
+static unsigned char iconcol[] =
+ {BGR(0,1,1),BGR(2,3,3),BGR(2,5,5)};
+static unsigned char iconcol_w[] =
+ {BGR(0,1,1),BGR(2,5,5),BGR(3,7,7)};
+
+
+
+static u8_t *colortheme[] =
+ {
+ backgroundcolor,
+
+ /* Window colors */
+ wincol, wincol, wincol_f, wincol_f, wincol_d, wincol_d,
+
+ /* Separator colors. */
+ sepcol, sepcol, sepcol_f, sepcol_f, sepcol_d, sepcol_d,
+
+ /* Label colors. */
+ labcol, labcol, labcol_f, labcol_f, labcol_d, labcol_d,
+
+ /* Button colors. */
+ butcol, butcol_w, butcol_f, butcol_fw, butcol_d, butcol_dw,
+
+ /* Hyperlink colors. */
+ hlcol, hlcol_w, hlcol_f, hlcol_fw, hlcol_d, hlcol_dw,
+
+ /* Textentry colors. */
+ butcol, butcol_w, butcol_f, butcol_fw, butcol_d, butcol_dw,
+
+ /* Icon colors */
+ iconcol, iconcol_w, iconcol, iconcol_w, iconcol, iconcol_w,
+
+ /* Menu colors. */
+ menucolor, activemenucolor, activemenucolor
+ };
+
+
+static int mouse_x, mouse_y, mouse_button;
+
+static u8_t screen[CHARS_WIDTH * CHARS_HEIGHT],
+ colorscreen[CHARS_WIDTH * CHARS_HEIGHT];
+
+
+#define PRINTF(x)
+
+/*-----------------------------------------------------------------------------------*/
+#define MAX_ICONS 16
+struct ctk_icon *icons[MAX_ICONS];
+
+unsigned char
+vnc_out_add_icon(struct ctk_icon *icon)
+{
+ u8_t i;
+ signed int empty;
+
+ empty = -1;
+ for(i = 0; i < MAX_ICONS; ++i) {
+ if(icon == icons[i]) {
+ return i;
+ }
+ if(icons[i] == NULL && empty < 0){
+ empty = i;
+ }
+ }
+
+ if(empty == -1) {
+ empty = 0;
+ }
+ icons[empty] = icon;
+ return empty;
+}
+
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_out_init(void)
+{
+ u16_t i;
+ for(i = 0; i < CHARS_WIDTH * CHARS_HEIGHT; ++i) {
+ screen[i] = 0x20;
+ }
+}
+
+void
+vnc_out_update_screen(u8_t xpos, u8_t ypos, u8_t c, u8_t color)
+{
+ screen[xpos + ypos * CHARS_WIDTH] = c;
+ colorscreen[xpos + ypos * CHARS_WIDTH] = color;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_out_update_area(struct vnc_server_state *vs,
+ u8_t x, u8_t y, u8_t w, u8_t h)
+{
+ u8_t x2, y2, ax2, ay2;
+ struct vnc_server_update *a, *b;
+
+ PRINTF(("update_area_connection: should update (%d:%d) (%d:%d)\n",
+ x, y, w, h));
+
+ /* First check if we already have a full update queued. If so, there
+ is no need to put this update on the list. If there is a full
+ update, it is always the first one on the list, so there is no
+ need to go step the list in search for it. */
+
+ if(vs->updates_pending != NULL &&
+ vs->updates_pending->type == VNC_SERVER_UPDATE_FULL) {
+ PRINTF(("Update_area_connecion: full update already queued...\n"));
+ return;
+ }
+
+ again:
+
+ /* Check that we don't update the same area twice by going through
+ the list and search for an update with the same coordinates. */
+ for(a = vs->updates_pending; a != NULL; a = a->next) {
+ if(a->x == x && a->y == y &&
+ a->w == w && a->h == h) {
+ PRINTF(("Update_area_connecion: found equal area\n"));
+ return;
+ }
+ }
+
+ /* Next we check if this update covers an existing update. If so, we
+ remove the old update, expand this update so that it covers both
+ areas to be updated and run through the process again. */
+ b = NULL;
+ for(a = vs->updates_pending; a != NULL; a = a->next) {
+ x2 = x + w;
+ y2 = y + h;
+
+ ax2 = a->x + a->w;
+ ay2 = a->y + a->h;
+
+ /* Test the corners of both updates to see if they are inside the
+ other area. */
+#define INSIDE(x,y,x1,y1,x2,y2) ((x1) <= (x) && \
+ (x2) >= (x) && \
+ (y1) <= (y) && \
+ (y2) >= (y))
+ if(INSIDE(x, y, a->x, a->y, ax2, ay2) ||
+ INSIDE(x, y2, a->x, a->y, ax2, ay2) ||
+ INSIDE(x2, y2, a->x, a->y, ax2, ay2) ||
+ INSIDE(x2, y, a->x, a->y, ax2, ay2) ||
+ INSIDE(a->x, a->y, x, y, x2, y2) ||
+ INSIDE(a->x, ay2, x, y, x2, y2) ||
+ INSIDE(ax2, ay2, x, y, x2, y2) ||
+ INSIDE(ax2, a->y, x, y, x2, y2)) {
+
+ /* Remove the old update from the list. */
+ vnc_server_update_remove(vs, a);
+
+ /* Put it on the free list. */
+ vnc_server_update_free(vs, a);
+
+ PRINTF(("update_area_connection: inside (%d:%d, %d:%d)\n",
+ a->x, a->y, ax2, ay2));
+
+ /* Find the area that covers both updates. */
+#define MIN(a,b) ((a) < (b)? (a): (b))
+#define MAX(a,b) ((a) > (b)? (a): (b))
+ x = MIN(a->x, x);
+ y = MIN(a->y, y);
+ ax2 = MAX(ax2, x2);
+ ay2 = MAX(ay2, y2);
+ w = ax2 - x;
+ h = ay2 - y;
+
+ /* This should really be done by a recursive call to this
+ function: update_area_connection(vs, x, y, w, h); but because
+ some compilers might not be able to optimize away the
+ recursive call, we do it using a goto instead. */
+ PRINTF(("Update_area_connecion: trying larger area (%d:%d) (%d:%d)\n", x, y, w, h));
+ goto again;
+ }
+ if(b != NULL) {
+ b = b->next;
+ }
+ }
+
+ /* Allocate an update object by pulling it off the free list. If
+ there are no free objects, we go for a full update instead. */
+
+ /* a = vs->updates_free;*/
+ a = vnc_server_update_alloc(vs);
+ if(a == NULL) {
+ PRINTF(("Update_area_connecion: no free updates, doing full\n"));
+ /* Put all pending updates, except for one, on the free list. Use
+ the remaining update as a full update. */
+ while(vs->updates_pending != NULL) {
+ a = vs->updates_pending;
+ vnc_server_update_remove(vs, a);
+ vnc_server_update_free(vs, a);
+ }
+
+ a = vnc_server_update_alloc(vs);
+ a->type = VNC_SERVER_UPDATE_FULL;
+ vnc_server_update_add(vs, a);
+
+
+ } else {
+
+ PRINTF(("Update_area_connecion: allocated update for (%d:%d) (%d:%d)\n", x, y, w, h));
+ /* Else, we put the update object at the end of the pending
+ list. */
+ a->type = VNC_SERVER_UPDATE_PARTS;
+ a->x = x;
+ a->y = y;
+ a->w = w;
+ a->h = h;
+ vnc_server_update_add(vs, a);
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+init_send_screen(struct vnc_server_state *vs)
+{
+ vs->sendmsg = SEND_SCREEN;
+ vs->x = vs->y = 0;
+ vs->x1 = vs->y1 = 0;
+ vs->x2 = vs->y2 = 0;
+ vs->w = CHARS_WIDTH;
+ vs->h = CHARS_HEIGHT;
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+check_updates(struct vnc_server_state *vs)
+{
+
+ if(vs->state == VNC_RUNNING &&
+ vs->sendmsg == SEND_NONE &&
+ vs->updates_current == NULL) {
+ if(vs->updates_pending != NULL &&
+ vs->update_requested != 0) {
+ vs->update_requested = 0;
+ /* vs->updates_current = vs->updates_pending;
+ vs->updates_pending = vs->updates_pending->next;
+ vs->updates_current->next = NULL;*/
+
+ vs->updates_current = vnc_server_update_dequeue(vs);
+
+ if(vs->updates_current->type == VNC_SERVER_UPDATE_PARTS) {
+ vs->x = vs->x1 = vs->x2 = vs->updates_current->x;
+ vs->y = vs->y1 = vs->y2 = vs->updates_current->y;
+ vs->w = vs->updates_current->w;
+ vs->h = vs->updates_current->h;
+ vs->sendmsg = SEND_UPDATE;
+
+ PRINTF(("New update from (%d:%d) (%d:%d) to (%d:%d)\n",
+ vs->x, vs->y, vs->x1, vs->y1, vs->x + vs->w,
+ vs->y + vs->h));
+ } else if(vs->updates_current->type == VNC_SERVER_UPDATE_FULL) {
+ init_send_screen(vs);
+ PRINTF(("New full update\n"));
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+static u8_t tmp[FONT_WIDTH * FONT_HEIGHT];
+static void
+makechar(char *ptr, u8_t x, u8_t y)
+{
+ u8_t i, *tmpptr;
+ u8_t *colorscheme;
+ unsigned char *bitmap;
+ u8_t b, b2;
+ u8_t xmove, ymove;
+ unsigned char c, color;
+
+ color = colorscreen[x + y * CHARS_WIDTH];
+ c = screen[x + y * CHARS_WIDTH];
+
+ colorscheme = colortheme[color];
+
+ /* First check if the character is a special icon character. These
+ are to be interpreted in a special manner: the first character of
+ the icon (the top left corner) has the highest bit set, but not
+ but 6. All other characters have bit 6 set, and also count the
+ number of positions away from the top left corner. Only the top
+ left corner contains enough information to identify the icon, all
+ other chars only contain the number of steps to reach the
+ identifying icon. */
+ if((c & 0x80) != 0) {
+ xmove = c & 0x0f;
+ ymove = (c & 0x30) >> 4;
+
+ c = colorscreen[x + y * CHARS_WIDTH];
+ bitmap = icons[c & 0x3f]->bitmap + ymove * 8*3;
+
+ colorscheme = colortheme[VNC_OUT_ICONCOLOR + (c >> 6)];
+ switch(xmove) {
+ case 0:
+ for(i = 0; i < FONT_HEIGHT; ++i) {
+ b = bitmap[i];
+ *ptr++ = colorscheme[(b >> 7) & 0x01];
+ *ptr++ = colorscheme[(b >> 6) & 0x01];
+ *ptr++ = colorscheme[(b >> 5) & 0x01];
+ *ptr++ = colorscheme[(b >> 4) & 0x01];
+ *ptr++ = colorscheme[(b >> 3) & 0x01];
+ *ptr++ = colorscheme[(b >> 2) & 0x01];
+ }
+ break;
+ case 1:
+ for(i = 0; i < FONT_HEIGHT; ++i) {
+ b = bitmap[i];
+ b2 = bitmap[i + 8];
+ *ptr++ = colorscheme[(b >> 1) & 0x01];
+ *ptr++ = colorscheme[(b >> 0) & 0x01];
+ *ptr++ = colorscheme[(b2 >> 7) & 0x01];
+ *ptr++ = colorscheme[(b2 >> 6) & 0x01];
+ *ptr++ = colorscheme[(b2 >> 5) & 0x01];
+ *ptr++ = colorscheme[(b2 >> 4) & 0x01];
+ }
+ break;
+ case 2:
+ for(i = 0; i < FONT_HEIGHT; ++i) {
+ b = bitmap[i+8];
+ b2 = bitmap[i+16];
+ *ptr++ = colorscheme[(b >> 3) & 0x01];
+ *ptr++ = colorscheme[(b >> 2) & 0x01];
+ *ptr++ = colorscheme[(b >> 1) & 0x01];
+ *ptr++ = colorscheme[(b >> 0) & 0x01];
+ *ptr++ = colorscheme[(b2 >> 7) & 0x01];
+ *ptr++ = colorscheme[(b2 >> 6) & 0x01];
+ }
+ break;
+ case 3:
+ for(i = 0; i < FONT_HEIGHT; ++i) {
+ b = bitmap[i+16];
+ *ptr++ = colorscheme[(b >> 5) & 0x01];
+ *ptr++ = colorscheme[(b >> 4) & 0x01];
+ *ptr++ = colorscheme[(b >> 3) & 0x01];
+ *ptr++ = colorscheme[(b >> 2) & 0x01];
+ *ptr++ = colorscheme[(b >> 1) & 0x01];
+ *ptr++ = colorscheme[(b >> 0) & 0x01];
+ }
+ break;
+ }
+ } else {
+ memcpy_P(tmp, &ctk_vncfont[c * (FONT_WIDTH * FONT_HEIGHT)],
+ FONT_WIDTH * FONT_HEIGHT);
+
+ tmpptr = tmp;
+
+
+ for(i = 0; i < FONT_HEIGHT * FONT_WIDTH; ++i) {
+ *ptr++ = colorscheme[*tmpptr++];
+ }
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_out_new(struct vnc_server_state *vs)
+{
+ u8_t i;
+
+ vs->width = SCREEN_WIDTH;
+ vs->height = SCREEN_HEIGHT;
+ vs->x = vs->y = vs->x1 = vs->y1 = vs->x2 = vs->y2 = 0;
+ vs->w = CHARS_WIDTH;
+ vs->h = CHARS_HEIGHT;
+
+ /* Initialize the linked list of updates. */
+ for(i = 0; i < VNC_SERVER_MAX_UPDATES - 1; ++i) {
+ vs->updates_pool[i].next = &vs->updates_pool[i + 1];
+ }
+ vs->updates_pool[VNC_SERVER_MAX_UPDATES].next = NULL;
+
+ vs->updates_free = &vs->updates_pool[0];
+ vs->updates_pending = vs->updates_current = NULL;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_out_send_blank(struct vnc_server_state *vs)
+{
+ struct rfb_fb_update *umsg;
+ u8_t *ptr;
+ u16_t len;
+ u8_t msglen;
+
+ vs->x = vs->y = 0;
+ vs->x2 = vs->y2 = 0;
+
+ umsg = (struct rfb_fb_update *)uip_appdata;
+
+ umsg->type = RFB_FB_UPDATE;
+ umsg->rects = HTONS(2);
+
+ ptr = (u8_t *)umsg + sizeof(struct rfb_fb_update);
+ len = sizeof(struct rfb_fb_update);
+
+ msglen = vnc_server_draw_rect(ptr, 0, 0,
+ HTONS(SCREEN_WIDTH),
+ HTONS(SCREEN_HEIGHT),
+ BORDER_COLOR);
+
+
+ ptr += msglen;
+ len += msglen;
+
+ msglen = vnc_server_draw_rect(ptr,
+ HTONS(SCREEN_X), HTONS(SCREEN_Y),
+ HTONS(SCREEN_WIDTH - SCREEN_X * 2),
+ HTONS(SCREEN_HEIGHT - SCREEN_Y * 2),
+ SCREEN_COLOR);
+
+ uip_send(uip_appdata, len + msglen);
+
+ vs->sendmsg = SENT_BLANK;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_out_send_screen(struct vnc_server_state *vs)
+{
+ vnc_out_send_update(vs);
+}
+/*-----------------------------------------------------------------------------------*/
+
+void
+vnc_out_send_update(struct vnc_server_state *vs)
+{
+ u8_t x, y, x0;
+ u8_t msglen;
+ u16_t len, n;
+ u8_t *ptr;
+ struct rfb_fb_update *umsg;
+ struct rfb_fb_update_rect_hdr *recthdr;
+ struct rfb_rre_hdr *rrehdr;
+ u8_t c, color, lastcolor;
+ u8_t numblanks;
+
+ /* First, check if we need to feed the update function with a new
+ pending update. */
+ check_updates(vs);
+
+ /* PRINTF(("Sending Update from (%d:%d) (%d:%d) to (%d:%d)\n",
+ vs->x, vs->y, vs->x1, vs->y1, vs->x + vs->w,
+ vs->y + vs->h));*/
+
+ umsg = (struct rfb_fb_update *)uip_appdata;
+
+ umsg->type = RFB_FB_UPDATE;
+
+ x0 = vs->x1;
+ n = 0;
+ msglen = 0;
+ ptr = (u8_t *)umsg + sizeof(struct rfb_fb_update);
+ len = sizeof(struct rfb_fb_update);
+
+ /* Loop over all characters that are covered by this update. */
+ for(y = vs->y1; y < vs->y + vs->h; ++y) {
+ for(x = x0; x < vs->x + vs->w; ++x) {
+
+
+ /* First check if there are any blank space characters, and if
+ so, find out how many of them there are in a row. Instead of
+ sending the individual space characters as raw bitmaps, we
+ can send the entire string of blanks as a single color
+ rectangle instead. */
+
+ c = screen[x + y * CHARS_WIDTH];
+ numblanks = 0;
+ lastcolor = color = colorscreen[x + y * CHARS_WIDTH];
+
+ /* If the character is a blank, we continue reading characters
+ until we find one that has a different color, or one that is
+ not a blank. We must keep within the update rectangle, so we
+ make sure that the "x" variable does not increase beyond the
+ edge. The "numblanks" variable is used to keep track of how
+ many blank characters we have found. */
+ while(lastcolor == color &&
+ c == 0x20 &&
+ x < vs->x + vs->w) {
+ ++numblanks;
+
+
+ ++x;
+ lastcolor = color;
+ color = colorscreen[x + y * CHARS_WIDTH];
+ c = screen[x + y * CHARS_WIDTH];
+ }
+
+ if(numblanks > 0) {
+
+ /* PRINTF(("Found %d blanks (%d:%d -> %d:%d)\n",
+ numblanks, x - numblanks, y, x, y));*/
+
+ /* There were one or more blank characters, so we send out a
+ single color rectangle with the right width. But first we
+ make sure that there is enough space in the current TCP
+ segment to put the rectangle. If there isn't we have to
+ backtrack the "x" variable to where we found the first
+ blank character so that the next TCP segment will be able
+ to update this area instead. */
+
+ msglen = sizeof(struct rfb_fb_update_rect_hdr) +
+ sizeof(struct rfb_rre_hdr);
+
+ if(msglen >= uip_mss() - len) {
+ /* PRINTF(("Not enouch space for blanks (%d, left %d)\n",
+ msglen, uip_mss() - len));*/
+ /* There is not enough space in the segment, so we remember
+ where we were ... */
+ vs->x2 = x - numblanks;
+ vs->y2 = y;
+
+ /* ... and we break out of the loop. */
+ goto loopend;
+ }
+
+ /* We construct a rectangle with the right width and color. */
+ recthdr = (struct rfb_fb_update_rect_hdr *)ptr;
+ rrehdr = (struct rfb_rre_hdr *)(ptr +
+ sizeof(struct rfb_fb_update_rect_hdr));
+
+ /* PRINTF(("Blankign (%d:%d) to (%d:%d)\n",
+ (x - numblanks) * FONT_WIDTH,
+ y * FONT_HEIGHT,
+ FONT_WIDTH * numblanks,
+ FONT_HEIGHT));*/
+ recthdr->rect.x = htons(SCREEN_X + (x - numblanks) *
+ FONT_WIDTH);
+ recthdr->rect.y = htons(SCREEN_Y + y * FONT_HEIGHT);
+ recthdr->rect.w = htons(FONT_WIDTH * numblanks);
+ recthdr->rect.h = HTONS(FONT_HEIGHT);
+ recthdr->encoding[0] =
+ recthdr->encoding[1] =
+ recthdr->encoding[2] = 0;
+ recthdr->encoding[3] = RFB_ENC_RRE;
+
+ rrehdr->subrects[0] =
+ rrehdr->subrects[1] = 0;
+ rrehdr->bgpixel = colortheme[lastcolor][0];
+
+ --x;
+ } else {
+
+ /* So there were no blank characters. */
+
+ /* PRINTF(("An char at (%d:%d)\n", x, y));*/
+ /* First we must make sure that there is enough space in the
+ outgoing TCP segment. */
+
+ msglen = sizeof(struct rfb_fb_update_rect_hdr) +
+ FONT_HEIGHT * FONT_WIDTH;
+ if(msglen >= uip_mss() - len) {
+ /* PRINTF(("Not enouch space for char (%d, left %d)\n",
+ msglen, uip_mss() - len));*/
+
+ /* There is not enough space in the segment, so we remember
+ where we were ... */
+ vs->x2 = x;
+ vs->y2 = y;
+
+ /* ... and we break out of the loop. */
+ goto loopend;
+ }
+
+ /* PRINTF(("ptr %p\n",ptr);*/
+ recthdr = (struct rfb_fb_update_rect_hdr *)ptr;
+
+ recthdr->rect.x = htons(SCREEN_X + x * FONT_WIDTH);
+ recthdr->rect.y = htons(SCREEN_Y + y * FONT_HEIGHT);
+ recthdr->rect.w = HTONS(FONT_WIDTH);
+ recthdr->rect.h = HTONS(FONT_HEIGHT);
+ recthdr->encoding[0] =
+ recthdr->encoding[1] =
+ recthdr->encoding[2] = 0;
+ recthdr->encoding[3] = RFB_ENC_RAW;
+
+ makechar((u8_t *)recthdr +
+ sizeof(struct rfb_fb_update_rect_hdr),
+ x, y);
+#if 0
+ c,
+ /* &ctk_vncfont[c * (FONT_WIDTH * FONT_HEIGHT)]*/
+ color);
+#endif /* 0 */
+ /* PRINTF(("Msglen %d (%d:%d)\n", msglen, x, y);*/
+ }
+ len += msglen;
+ ptr += msglen;
+ ++n;
+ }
+ x0 = vs->x;
+ }
+
+ loopend:
+
+ umsg->rects = htons(n);
+
+ if(y == vs->y + vs->h && x == vs->x + vs->w) {
+ vs->x2 = vs->y2 = 0;
+ }
+
+ if(n > 0) {
+ /* printf("Sending %d rects, %d bytes (%p, %p, %p)\n", n, len,
+ uip_appdata, umsg, ptr);*/
+ uip_send(uip_appdata, len);
+ }
+
+}
+/*-----------------------------------------------------------------------------------*/
+#define NUMKEYS 100
+static char keys[NUMKEYS];
+static int firstkey, lastkey;
+
+
+char
+vnc_out_keyavail(void)
+{
+ return firstkey != lastkey;
+}
+
+char
+vnc_out_getkey(void)
+{
+ char key;
+ key = keys[firstkey];
+
+ if(firstkey != lastkey) {
+ ++firstkey;
+ if(firstkey >= NUMKEYS) {
+ firstkey = 0;
+ }
+ }
+
+ return key;
+}
+
+void
+vnc_out_key_event(struct vnc_server_state *vs)
+{
+ struct rfb_key_event *ev;
+
+ ev = (struct rfb_key_event *)uip_appdata;
+
+ if(ev->down != 0) {
+ if(vs->sendmsg == SEND_NONE) {
+ vs->sendmsg = SEND_UPDATE;
+ }
+
+
+ if(ev->key[2] == 0 ||
+ (ev->key[2] == 0xff &&
+ (ev->key[3] == CH_HOME ||
+ ev->key[3] == CH_TAB ||
+ ev->key[3] == CH_ESC ||
+ ev->key[3] == CH_DEL ||
+ ev->key[3] == CH_ENTER ||
+ ev->key[3] == CH_CURS_LEFT ||
+ ev->key[3] == CH_CURS_UP ||
+ ev->key[3] == CH_CURS_RIGHT ||
+ ev->key[3] == CH_CURS_DOWN))) {
+
+ keys[lastkey] = ev->key[3];
+ ++lastkey;
+ if(lastkey >= NUMKEYS) {
+ lastkey = 0;
+ }
+ }
+ }
+
+ check_updates(vs);
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_out_pointer_event(struct vnc_server_state *vs)
+{
+ struct rfb_pointer_event *ev;
+ u16_t evx, evy;
+
+ ev = (struct rfb_pointer_event *)uip_appdata;
+
+ evx = htons(ev->x);
+ evy = htons(ev->y);
+
+ if(evx > SCREEN_X && evx < SCREEN_WIDTH - 2 * SCREEN_X &&
+ evy > SCREEN_Y && evy < SCREEN_HEIGHT - 2 * SCREEN_Y) {
+
+ mouse_button = ev->buttonmask & RFB_BUTTON_MASK1;
+
+ mouse_x = evx - SCREEN_X;
+ mouse_y = evy - SCREEN_Y;
+
+ check_updates(vs);
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_out_acked(struct vnc_server_state *vs)
+{
+ if(vs->state != VNC_RUNNING) {
+ return;
+ }
+ if(vs->sendmsg == SENT_BLANK) {
+ init_send_screen(vs);
+ } else if(vs->sendmsg == SEND_BLANK) {
+ /* Do nothing until sendmsg == SENT_BLANK. */
+ } else if(vs->sendmsg == SEND_SCREEN) {
+ /* When the screen has been fully drawn, ->x2 and ->y2 are both
+ set to 0 to indicate this.*/
+ if(vs->x2 == 0 && vs->y2 == 0) {
+ vs->sendmsg = SEND_NONE;
+
+ /* If there was an updaterequest for the entire screen, we can
+ clear that flag now. */
+ if(vs->updates_current != NULL) {
+ vnc_server_update_free(vs, vs->updates_current);
+ vs->updates_current = NULL;
+ }
+ check_updates(vs);
+ } else {
+ vs->x1 = vs->x2;
+ vs->y1 = vs->y2;
+ }
+
+ } else if(vs->sendmsg == SEND_UPDATE) {
+ if(vs->x2 == 0 && vs->y2 == 0) {
+ /* So, we have updated the area that we needed. We now check if
+ there have been any recent full screen update requests. If
+ so, we need to go to the SEND_SCREEN state. Else, we see if
+ there were more areas that needed to be updated and if so,
+ we'll continue with those. */
+
+ vs->sendmsg = SEND_NONE;
+
+ if(vs->updates_current != NULL) {
+ vnc_server_update_free(vs, vs->updates_current);
+ vs->updates_current = NULL;
+
+ }
+ check_updates(vs);
+#if 0
+ if(vs->updaterequest == VNC_SERVER_UPDATE_FULL) {
+ check_updates(vs);
+ } else {
+ vs->updatesptr2 = (vs->updatesptr2 + 1) %
+ VNC_SERVER_MAX_UPDATES;
+
+ /* If there are no more updates to do, we'll go back to the
+ SEND_NONE state. */
+ if(vs->updatesptr2 == vs->updatesptr) {
+ vs->updatetype = VNC_SERVER_UPDATE_NONE;
+ } else {
+ /* Otherwise, we continue to update the next area. */
+ vs->updaterequest = VNC_SERVER_UPDATE_PARTS;
+ check_updates(vs);
+ }
+ }
+#endif /* 0 */
+ } else {
+ vs->x1 = vs->x2;
+ vs->y1 = vs->y2;
+ }
+ } else {
+ vs->sendmsg = SEND_NONE;
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_out_poll(struct vnc_server_state *vs)
+{
+ /* PRINTF(("vs->state %d, sendmsg %d, updatetype %d, updatereq %d\n",
+ vs->state, vs->sendmsg, vs->updatetype, vs->updaterequest);*/
+
+ if(vs->state == VNC_RUNNING &&
+ vs->sendmsg == SEND_NONE) {
+ check_updates(vs);
+ vnc_server_send_data(vs);
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_mouse_init(void)
+{
+
+}
+/*-----------------------------------------------------------------------------------*/
+unsigned short
+ctk_mouse_x(void)
+{
+ return mouse_x;
+}
+/*-----------------------------------------------------------------------------------*/
+unsigned short
+ctk_mouse_y(void)
+{
+ return mouse_y;
+}
+/*-----------------------------------------------------------------------------------*/
+unsigned char
+ctk_mouse_xtoc(unsigned short x)
+{
+ return x / FONT_WIDTH;
+}
+/*-----------------------------------------------------------------------------------*/
+unsigned char
+ctk_mouse_ytoc(unsigned short y)
+{
+ return y / FONT_HEIGHT;
+}
+/*-----------------------------------------------------------------------------------*/
+unsigned char
+ctk_mouse_button(void)
+{
+ return mouse_button;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_mouse_hide(void)
+{
+}
+/*-----------------------------------------------------------------------------------*/
+void
+ctk_mouse_show(void)
+{
+}
+/*-----------------------------------------------------------------------------------*/
diff --git a/contiki/ctk/vnc-out.h b/contiki/ctk/vnc-out.h
new file mode 100644
index 0000000..3e43d6f
--- /dev/null
+++ b/contiki/ctk/vnc-out.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2001, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: vnc-out.h,v 1.1 2003/07/02 21:34:00 adamdunkels Exp $
+ *
+ */
+
+#ifndef __VNC_OUT_H__
+#define __VNC_OUT_H__
+
+
+void vnc_out_init(void);
+void vnc_out_new(struct vnc_server_state *vs);
+
+void vnc_out_send_blank(struct vnc_server_state *vs);
+void vnc_out_send_screen(struct vnc_server_state *vs);
+void vnc_out_send_update(struct vnc_server_state *vs);
+
+void vnc_out_key_event(struct vnc_server_state *vs);
+void vnc_out_pointer_event(struct vnc_server_state *vs);
+
+void vnc_out_acked(struct vnc_server_state *vs);
+
+void vnc_out_poll(struct vnc_server_state *vs);
+
+
+void vnc_out_update_screen(u8_t x, u8_t y, u8_t c, u8_t color);
+char vnc_out_getkey(void);
+char vnc_out_keyavail(void);
+
+void vnc_out_update_area(struct vnc_server_state *vs,
+ u8_t x, u8_t y, u8_t w, u8_t h);
+
+#include "ctk.h"
+
+unsigned char vnc_out_add_icon(struct ctk_icon *icon);
+
+#define VNC_OUT_BACKGROUNDCOLOR 0
+#define VNC_OUT_WINDOWCOLOR 1
+#define VNC_OUT_SEPARATORCOLOR (VNC_OUT_WINDOWCOLOR + 6)
+#define VNC_OUT_LABELCOLOR (VNC_OUT_SEPARATORCOLOR + 6)
+#define VNC_OUT_BUTTONCOLOR (VNC_OUT_LABELCOLOR + 6)
+#define VNC_OUT_HYPERLINKCOLOR (VNC_OUT_BUTTONCOLOR + 6)
+#define VNC_OUT_TEXTENTRYCOLOR (VNC_OUT_HYPERLINKCOLOR + 6)
+#define VNC_OUT_ICONCOLOR (VNC_OUT_TEXTENTRYCOLOR + 6)
+#define VNC_OUT_MENUCOLOR (VNC_OUT_ICONCOLOR + 6)
+#define VNC_OUT_OPENMENUCOLOR (VNC_OUT_MENUCOLOR + 1)
+#define VNC_OUT_ACTIVEMENUCOLOR (VNC_OUT_OPENMENUCOLOR + 1)
+
+#endif /* __VNC_OUT_H__ */
diff --git a/contiki/ctk/vnc-server.c b/contiki/ctk/vnc-server.c
new file mode 100644
index 0000000..4f5bf49
--- /dev/null
+++ b/contiki/ctk/vnc-server.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2001, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: vnc-server.c,v 1.1 2003/07/02 21:34:00 adamdunkels Exp $
+ *
+ */
+
+/* A micro implementation of a VNC server. VNC is a protocol for
+ remote network displays. See http://www.uk.research.att.com/vnc/
+ for information about VNC.
+
+ Initialization states:
+
+ VNC_VERSION (send version string)
+ VNC_AUTH (send auth message)
+ VNC_INIT (send init message)
+
+ Steady state:
+
+ VNC_RUNNING (send RFB updates, parse incoming messages)
+
+ What kind of message should be sent:
+
+ SEND_NONE (No message)
+ SEND_BLANK (Blank screen initially)
+ SEND_SCREEN (Send entire screen, initially)
+ SEND_UPDATE (Send incremental update)
+
+*/
+
+#include "uip.h"
+#include "vnc-server.h"
+#include "vnc-out.h"
+
+
+/* RFB server initial handshaking string. */
+#define RFB_SERVER_VERSION_STRING rfb_server_version_string
+
+/* "RFB 003.003" */
+static u8_t rfb_server_version_string[12] = {82,70,66,32,48,48,51,46,48,48,51,10};
+
+/* uVNC */
+static u8_t uvnc_name[4] = {117,86,78,67};
+#if 1
+#define PRINTF(x)
+#else
+#define PRINTF(x) printf x
+#endif
+
+/*-----------------------------------------------------------------------------------*/
+u8_t
+vnc_server_draw_rect(u8_t *ptr, u16_t x, u16_t y, u16_t w, u16_t h, u8_t c)
+{
+ struct rfb_fb_update_rect_hdr *recthdr;
+ struct rfb_rre_hdr *rrehdr;
+
+ recthdr = (struct rfb_fb_update_rect_hdr *)ptr;
+ rrehdr = (struct rfb_rre_hdr *)(ptr + sizeof(struct rfb_fb_update_rect_hdr));
+
+ recthdr->rect.x = x;
+ recthdr->rect.y = y;
+ recthdr->rect.w = w;
+ recthdr->rect.h = h;
+ recthdr->encoding[0] =
+ recthdr->encoding[1] =
+ recthdr->encoding[2] = 0;
+ recthdr->encoding[3] = RFB_ENC_RRE;
+
+ rrehdr->subrects[0] =
+ rrehdr->subrects[1] = 0;
+ rrehdr->bgpixel = c;
+
+ return sizeof(struct rfb_fb_update_rect_hdr) + sizeof(struct rfb_rre_hdr);
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_server_init(void)
+{
+ vnc_out_init();
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+vnc_send_blank(struct vnc_server_state *vs)
+{
+ switch(vs->type) {
+ case 0:
+ vnc_out_send_blank(vs);
+ break;
+ /* case 1:
+ vnc_stats_send_blank(vs);
+ break; */
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+vnc_send_screen(struct vnc_server_state *vs)
+{
+ switch(vs->type) {
+ case 0:
+ vnc_out_send_screen(vs);
+ break;
+ /* case 1:
+ vnc_stats_send_screen(vs);
+ break;*/
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+vnc_send_update(struct vnc_server_state *vs)
+{
+ switch(vs->type) {
+ case 0:
+ vnc_out_send_update(vs);
+ break;
+ /* case 1:
+ vnc_stats_send_update(vs);
+ break;*/
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_server_send_data(struct vnc_server_state *vs)
+{
+ struct rfb_server_init *initmsg;
+
+ switch(vs->state) {
+ case VNC_VERSION:
+ uip_send(RFB_SERVER_VERSION_STRING, sizeof(RFB_SERVER_VERSION_STRING));
+ break;
+ case VNC_AUTH:
+ uip_appdata[0] = 0;
+ uip_appdata[1] = 0;
+ uip_appdata[2] = 0;
+ uip_appdata[3] = RFB_AUTH_NONE;
+ uip_send(uip_appdata, 4);
+ break;
+ case VNC_INIT:
+ initmsg = (struct rfb_server_init *)uip_appdata;
+ initmsg->width = htons(vs->width);
+ initmsg->height = htons(vs->height);
+ /* BGR233 pixel format. */
+ initmsg->format.bps = 8;
+ initmsg->format.depth = 8;
+ initmsg->format.endian = 1;
+ initmsg->format.truecolor = 1;
+ initmsg->format.red_max = htons(7);
+ initmsg->format.green_max = htons(7);
+ initmsg->format.blue_max = htons(3);
+ initmsg->format.red_shift = 0;
+ initmsg->format.green_shift = 3;
+ initmsg->format.blue_shift = 6;
+ initmsg->namelength[0] = 0;
+ initmsg->namelength[1] = 0;
+ initmsg->namelength[2] = 0;
+ initmsg->namelength[3] = 4;
+ /* bcopy(uvnc_name, &uip_appdata[sizeof(struct rfb_server_init)], 4);*/
+ uip_appdata[sizeof(struct rfb_server_init)+0] = 'u';
+ uip_appdata[sizeof(struct rfb_server_init)+1] = 'V';
+ uip_appdata[sizeof(struct rfb_server_init)+2] = 'N';
+ uip_appdata[sizeof(struct rfb_server_init)+3] = 'C';
+ uip_send(uip_appdata, sizeof(struct rfb_server_init) + 4);
+ break;
+ case VNC_RUNNING:
+ switch(vs->sendmsg) {
+ case SEND_NONE:
+ PRINTF(("Sending none\n"));
+ break;
+
+ case SEND_BLANK:
+ case SENT_BLANK:
+ PRINTF(("Sending blank\n"));
+ vnc_send_blank(vs);
+ break;
+
+ case SEND_SCREEN:
+ PRINTF(("Sending screen\n"));
+ vnc_send_screen(vs);
+ break;
+
+ case SEND_UPDATE:
+ PRINTF(("Sending update\n"));
+ vnc_send_update(vs);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+vnc_key_event(struct vnc_server_state *vs)
+{
+ switch(vs->type) {
+ case 0:
+ vnc_out_key_event(vs);
+ break;
+ /* case 1:
+ vnc_stats_key_event(vs);
+ break;*/
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+vnc_pointer_event(struct vnc_server_state *vs)
+{
+ switch(vs->type) {
+ case 0:
+ vnc_out_pointer_event(vs);
+ break;
+ /* case 1:
+ vnc_stats_pointer_event(vs);
+ break;*/
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+static u8_t
+vnc_read_data(struct vnc_server_state *vs)
+{
+ u8_t *appdata;
+ u16_t len;
+ struct rfb_fb_update_request *req;
+ /* u8_t niter;*/
+
+ len = uip_datalen();
+ appdata = (u8_t *)uip_appdata;
+
+ /* First, check if there is data left to discard since last read. */
+ if(vs->readlen > 0) {
+ appdata += vs->readlen;
+ if(len > vs->readlen) {
+ len -= vs->readlen;
+ vs->readlen = 0;
+ } else {
+ vs->readlen -= len;
+ len = 0;
+ }
+ }
+
+ if(vs->readlen != 0) {
+ return 1;
+ }
+
+ /* All data read and ignored, parse next message. */
+ /* for(niter = 32; niter > 0 && len > 0; --niter) {*/
+ while(len > 0) {
+ switch(vs->state) {
+ case VNC_VERSION:
+ case VNC_VERSION2:
+ PRINTF(("Read in version\n"));
+ /* Receive and ignore client version string (12 bytes). */
+ vs->state = VNC_AUTH;
+ vs->readlen = 12;
+ break;
+
+ case VNC_AUTH:
+ case VNC_AUTH2:
+ PRINTF(("Read in auth \n"));
+ /* Read and discard initialization from client (1 byte). */
+ vs->readlen = 1;
+ vs->state = VNC_INIT;
+ break;
+
+ case VNC_INIT:
+ case VNC_INIT2:
+ PRINTF(("Read in init \n"));
+ vs->readlen = 0;
+ vs->state = VNC_RUNNING;
+
+ case VNC_RUNNING:
+ /* Handle all client events. */
+ switch(*appdata) {
+ case RFB_SET_PIXEL_FORMAT:
+ PRINTF(("Set pixel format\n"));
+ vs->readlen = sizeof(struct rfb_set_pixel_format);
+ /* Check if client runs with BGR233 format. If not, abort the
+ connection. */
+ /* XXX: not implemented yet. */
+ break;
+
+ case RFB_FIX_COLORMAP_ENTRIES:
+ PRINTF(("Fix colormap entries\n"));
+ return 0;
+
+ case RFB_SET_ENCODINGS:
+ PRINTF(("Set encodings\n"));
+ vs->readlen = sizeof(struct rfb_set_encoding);
+ vs->readlen += htons(((struct rfb_set_encoding *)appdata)->encodings) * 4;
+ /* Make sure that client supports the encodings we use. */
+ /* XXX: not implemented yet. */
+ break;
+
+ case RFB_FB_UPDATE_REQ:
+ PRINTF(("Update request\n"));
+ vs->update_requested = 1;
+ vs->readlen = sizeof(struct rfb_fb_update_request);
+ /* blank the screen initially */
+ req = (struct rfb_fb_update_request *)appdata;
+ if(req->incremental == 0) {
+ /* vs->sendmsg = SEND_BLANK;*/
+ vnc_out_update_area(vs, 0, 0, vs->w, vs->h);
+ }
+ break;
+
+ case RFB_KEY_EVENT:
+ vs->readlen = sizeof(struct rfb_key_event);
+ vnc_key_event(vs);
+ break;
+
+ case RFB_POINTER_EVENT:
+ vs->readlen = sizeof(struct rfb_pointer_event);
+ vnc_pointer_event(vs);
+ break;
+
+ case RFB_CLIENT_CUT_TEXT:
+ PRINTF(("Client cut text\n"));
+
+ if(((struct rfb_client_cut_text *)appdata)->len[0] != 0 ||
+ ((struct rfb_client_cut_text *)appdata)->len[1] != 0) {
+ return 0;
+
+ }
+ vs->readlen = sizeof(struct rfb_client_cut_text) +
+ (((struct rfb_client_cut_text *)appdata)->len[2] << 8) +
+ ((struct rfb_client_cut_text *)appdata)->len[3];
+ /* return 0;*/
+ break;
+
+ default:
+ PRINTF(("Unknown message %d\n", *appdata));
+ return 0;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ if(vs->readlen > 0) {
+ if(len > vs->readlen) {
+ len -= vs->readlen;
+ appdata += vs->readlen;
+ vs->readlen = 0;
+ } else {
+ vs->readlen -= len;
+ len = 0;
+ }
+ } else {
+ /* Lost data. */
+ break;
+ }
+
+ }
+
+ /* if(vs->readlen > 0) {
+ printf("More data %d\n", vs->readlen);
+ }*/
+
+ /* uip_appdata = appdata;*/
+
+ return 1;
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+vnc_new(struct vnc_server_state *vs)
+{
+ vs->counter = 0;
+ vs->readlen = 0;
+ vs->sendmsg = SEND_NONE;
+ vs->update_requested = 1;
+ switch(vs->type) {
+ case 0:
+ vnc_out_new(vs);
+ break;
+ /* case 1:
+ vnc_stats_new(vs);
+ break;*/
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+vnc_acked(struct vnc_server_state *vs)
+{
+ switch(vs->state) {
+ case VNC_VERSION:
+ vs->state = VNC_VERSION2;
+ break;
+
+ case VNC_AUTH:
+ vs->state = VNC_AUTH2;
+ break;
+
+ case VNC_INIT:
+ vs->state = VNC_INIT2;
+ break;
+
+ case VNC_RUNNING:
+ switch(vs->type) {
+ case 0:
+ vnc_out_acked(vs);
+ break;
+ /* case 1:
+ vnc_stats_acked(vs);
+ break;*/
+ }
+ break;
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+void
+vnc_server_appcall(struct vnc_server_state *vs)
+{
+
+ vs->type = htons(uip_conn->lport) - 5900;
+
+ if(uip_connected()) {
+ vnc_new(vs);
+ vs->state = VNC_VERSION;
+ vnc_server_send_data(vs);
+ return;
+ }
+ if(uip_acked()) {
+ PRINTF(("Acked\n"));
+ vnc_acked(vs);
+ }
+
+ if(uip_newdata()) {
+ PRINTF(("Newdata\n"));
+ vs->counter = 0;
+ if(vnc_read_data(vs) == 0) {
+ uip_abort();
+ return;
+ }
+ }
+
+ if(uip_rexmit()) {
+ PRINTF(("Rexmit\n"));
+ }
+
+
+ if(uip_newdata() ||
+ uip_rexmit() ||
+ uip_acked()) {
+ vnc_server_send_data(vs);
+ } else if(uip_poll()) {
+ ++vs->counter;
+ /* Abort connection after about 20 seconds of inactivity. */
+ if(vs->counter >= 40) {
+ uip_abort();
+ return;
+ }
+
+ vnc_out_poll(vs);
+ }
+
+}
+/*-----------------------------------------------------------------------------------*/
diff --git a/contiki/ctk/vnc-server.h b/contiki/ctk/vnc-server.h
new file mode 100644
index 0000000..eeb3f5d
--- /dev/null
+++ b/contiki/ctk/vnc-server.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2001, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: vnc-server.h,v 1.1 2003/07/02 21:34:00 adamdunkels Exp $
+ *
+ */
+
+#ifndef __VNC_SERVER_H__
+#define __VNC_SERVER_H__
+
+
+/*struct vnc_server_updatearea {
+ u8_t active;
+ u8_t x, y;
+ u8_t w, h;
+ };*/
+
+struct vnc_server_update {
+ struct vnc_server_update *next;
+
+#define VNC_SERVER_UPDATE_NONE 0
+#define VNC_SERVER_UPDATE_PARTS 1
+#define VNC_SERVER_UPDATE_FULL 2
+
+ u8_t type;
+
+ u8_t x, y;
+ u8_t w, h;
+};
+
+struct vnc_server_state {
+ u16_t counter;
+ u8_t type;
+ u8_t state;
+ u16_t height, width;
+
+ u8_t update_requested;
+
+ /* Variables used when sending screen updates. */
+ u8_t x, y, x1, y1, x2, y2;
+ u8_t w, h;
+
+
+
+ u16_t readlen;
+ u8_t sendmsg;
+ u8_t button;
+
+
+ struct vnc_server_update *updates_current;
+ struct vnc_server_update *updates_pending;
+ struct vnc_server_update *updates_free;
+
+#define VNC_SERVER_MAX_UPDATES 8
+ struct vnc_server_update updates_pool[VNC_SERVER_MAX_UPDATES];
+
+#if 0
+ /* The current update type. */
+ u8_t updatetype;
+
+ struct vnc_server_updatearea updates[VNC_SERVER_MAX_UPDATES];
+ u8_t updatesptr, updatesptr2;
+
+ u8_t updaterequest;
+#endif /* 0 */
+};
+
+struct vnc_server_update *
+ vnc_server_update_alloc(struct vnc_server_state *vs);
+void vnc_server_update_free(struct vnc_server_state *vs,
+ struct vnc_server_update *a);
+void vnc_server_update_remove(struct vnc_server_state *vs,
+ struct vnc_server_update *a);
+
+void vnc_server_update_add(struct vnc_server_state *vs,
+ struct vnc_server_update *a);
+struct vnc_server_update *
+ vnc_server_update_dequeue(struct vnc_server_state *vs);
+
+
+
+
+void vnc_server_init(void);
+void vnc_server_appcall(struct vnc_server_state *state);
+
+
+extern struct vnc_server_state *vs;
+
+enum {
+ VNC_DEALLOCATED,
+ VNC_VERSION,
+ VNC_VERSION2,
+ VNC_AUTH,
+ VNC_AUTH2,
+ VNC_INIT,
+ VNC_INIT2,
+ VNC_RUNNING
+};
+
+/* Sendmsg */
+enum {
+ SEND_NONE,
+ SEND_BLANK,
+ SENT_BLANK,
+ SEND_SCREEN,
+ SEND_UPDATE
+};
+
+
+/* Definitions of the RFB (Remote Frame Buffer) protocol
+ structures and constants. */
+
+#include "uipopt.h"
+
+void vnc_server_send_data(struct vnc_server_state *vs);
+u8_t vnc_server_draw_rect(u8_t *ptr, u16_t x, u16_t y, u16_t w, u16_t h, u8_t c);
+
+
+/* Generic rectangle - x, y coordinates, width and height. */
+struct rfb_rect {
+ u16_t x;
+ u16_t y;
+ u16_t w;
+ u16_t h;
+};
+
+/* Pixel format definition. */
+struct rfb_pixel_format {
+ u8_t bps; /* Bits per pixel: 8, 16 or 32. */
+ u8_t depth; /* Color depth: 8-32 */
+ u8_t endian; /* 1 - big endian (motorola), 0 - little endian
+ (x86) */
+ u8_t truecolor; /* 1 - true color is used, 0 - true color is not used. */
+
+ /* The following fields are only used if true color is used. */
+ u16_t red_max, green_max, blue_max;
+ u8_t red_shift, green_shift, blue_shift;
+ u8_t pad1;
+ u16_t pad2;
+};
+
+
+/* RFB authentication constants. */
+
+#define RFB_AUTH_FAILED 0
+#define RFB_AUTH_NONE 1
+#define RFB_AUTH_VNC 2
+
+#define RFB_VNC_AUTH_OK 0
+#define RFB_VNC_AUTH_FAILED 1
+#define RFB_VNC_AUTH_TOOMANY 2
+
+/* RFB message types. */
+
+/* From server to client: */
+#define RFB_FB_UPDATE 0
+#define RFB_SET_COLORMAP_ENTRIES 1
+#define RFB_BELL 2
+#define RFB_SERVER_CUT_TEXT 3
+
+/* From client to server. */
+#define RFB_SET_PIXEL_FORMAT 0
+#define RFB_FIX_COLORMAP_ENTRIES 1
+#define RFB_SET_ENCODINGS 2
+#define RFB_FB_UPDATE_REQ 3
+#define RFB_KEY_EVENT 4
+#define RFB_POINTER_EVENT 5
+#define RFB_CLIENT_CUT_TEXT 6
+
+/* Encoding types. */
+#define RFB_ENC_RAW 0
+#define RFB_ENC_COPYRECT 1
+#define RFB_ENC_RRE 2
+#define RFB_ENC_CORRE 3
+#define RFB_ENC_HEXTILE 4
+
+/* Message definitions. */
+
+/* Server to client messages. */
+
+struct rfb_server_init {
+ u16_t width;
+ u16_t height;
+ struct rfb_pixel_format format;
+ u8_t namelength[4];
+ /* Followed by name. */
+};
+
+struct rfb_fb_update {
+ u8_t type;
+ u8_t pad;
+ u16_t rects; /* Number of rectanges (struct rfb_fb_update_rect_hdr +
+ data) that follows. */
+};
+
+struct rfb_fb_update_rect_hdr {
+ struct rfb_rect rect;
+ u8_t encoding[4];
+};
+
+struct rfb_copy_rect {
+ u16_t srcx;
+ u16_t srcy;
+};
+
+struct rfb_rre_hdr {
+ u16_t subrects[2]; /* Number of subrectangles (struct
+ rfb_rre_subrect) to follow. */
+ u8_t bgpixel;
+};
+
+struct rfb_rre_subrect {
+ u8_t pixel;
+ struct rfb_rect rect;
+};
+
+struct rfb_corre_rect {
+ u8_t x;
+ u8_t y;
+ u8_t w;
+ u8_t h;
+};
+
+/* Client to server messages. */
+
+struct rfb_set_pixel_format {
+ u8_t type;
+ u8_t pad;
+ u16_t pad2;
+ struct rfb_pixel_format format;
+};
+
+struct rfb_fix_colormap_entries {
+ u8_t type;
+ u8_t pad;
+ u16_t firstcolor;
+ u16_t colors;
+};
+
+struct rfb_set_encoding {
+ u8_t type;
+ u8_t pad;
+ u16_t encodings;
+};
+
+struct rfb_fb_update_request {
+ u8_t type;
+ u8_t incremental;
+ u16_t x;
+ u16_t y;
+ u16_t w;
+ u16_t h;
+};
+
+struct rfb_key_event {
+ u8_t type;
+ u8_t down;
+ u16_t pad;
+ u8_t key[4];
+};
+
+#define RFB_BUTTON_MASK1 1
+#define RFB_BUTTON_MASK2 2
+#define RFB_BUTTON_MASK3 4
+struct rfb_pointer_event {
+ u8_t type;
+ u8_t buttonmask;
+ u16_t x;
+ u16_t y;
+};
+
+struct rfb_client_cut_text {
+ u8_t type;
+ u8_t pad[3];
+ u8_t len[4];
+};
+
+#endif /* __VNC_SERVER_H__ */