2 * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this software; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * Microwindows interface by George Harvey
21 * 07/03/00 GH created nanox.c to replace x.c, development
22 * being done using Microwindows 0.88pre3
23 * 16/03/00 GH try to match the VNC palette to the current
24 * palette using a lookup table
25 * 06/05/00 GH update for mwin 0.88pre7, use GrSetSystemPalette()
26 * instead of lookup table
27 * 27/05/00 GH update for mwin 0.88pre8
28 * 03/06/00 GH remove colour lookup code
32 * nanox.c - functions to deal with nano-X display.
35 #include <vncviewer.h>
38 #define VW_WIDTH 1024 /* VNC window width */
39 #define VW_HEIGHT 768 /* VNC window height */
40 #define VW_X 0 /* VNC window origin */
41 #define VW_Y 0 /* VNC window origin */
43 #define SCROLLBAR_SIZE 10
44 #define SCROLLBAR_BG_SIZE (SCROLLBAR_SIZE + 2)
46 #define INVALID_PIXEL 0xffffffff
47 #define COLORMAP_SIZE 256
59 /* BGR233ToPixel array */
60 unsigned long BGR233ToPixel[COLORMAP_SIZE] = { \
61 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, \
62 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \
63 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \
64 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \
65 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \
66 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \
67 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \
68 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \
69 0xf7, 0xc7, 0x87, 0x47, 0x07, 0xc6, 0x86, 0x46, \
70 0x0c, 0x4c, 0x8c, 0xcc, 0x0d, 0x4d, 0x8d, 0xcd, \
74 /* colour palette for 8-bit displays */
75 static GR_PALETTE srv_pal; /* VNC server palette */
78 /* temporary keyboard mapping array */
79 /* ^T = up, ^F = left, ^G = right, ^V = down
81 CARD32 kmap[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0xff51, 0xff53, \
82 0xff08, 0xff09, 0x0a, 0x0b, 0x0c, 0xff0d, 0x0e, 0x0f, \
83 0x10, 0x11, 0x12, 0x13, 0xff52, 0x15, 0xff54, 0x17, \
84 0x18, 0x19, 0x1a, 0xff1b, 0x1c, 0x1d, 0x1e, 0x1f, \
85 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, \
86 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, \
87 '0', '1', '2', '3', '4', '5', '6', '7', \
88 '8', '9', 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, \
89 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G', \
90 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', \
91 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', \
92 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, \
93 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', \
94 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', \
95 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', \
96 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f };
98 static Display nx_dpy;
99 static GR_WINDOW_ID wid;
100 static int pixtype; /* format of pixel value */
102 static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height);
104 extern MWPIXELVAL gr_foreground; /* for debugging only */
107 * Initialize graphics and open a window for the viewer
116 if ((fd = GrOpen()) < 0)
121 GrGetScreenInfo(&si);
122 /* pass screen details to RFB handler */
123 myFormat.bitsPerPixel = si.bpp;
124 myFormat.depth = si.bpp; /* is this right? */
125 myFormat.bigEndian = 0; /* how do I find this out? */
126 myFormat.trueColour = (myFormat.depth == 8 && !useBGR233) ? 0 : 1;
127 if (myFormat.trueColour) {
128 myFormat.redMax = myFormat.greenMax = 7;
129 myFormat.blueMax = 3;
130 myFormat.redShift = 0;
131 myFormat.greenShift = 3;
132 myFormat.blueShift = 6;
134 pixtype = si.pixtype;
135 /* get the initial server palette */
136 GrGetSystemPalette(&srv_pal);
139 for (i = 0; i < srv_pal.count; i++) {
140 printf("0x%02x %03d %03d %03d\n", i, \
141 srv_pal.palette[i].r, srv_pal.palette[i].g, \
142 srv_pal.palette[i].b );
145 /* create the top-level window */
146 w = (VW_WIDTH > (si.cols - VW_X)) ? (si.cols - VW_X) : VW_WIDTH;
147 h = (VW_HEIGHT > (si.rows - VW_Y)) ? (si.rows - VW_Y) : VW_HEIGHT;
148 if ((wid = GrNewWindow(GR_ROOT_WINDOW_ID, VW_X, VW_Y, w, h,
149 2, LTGRAY, BLACK)) == 0) {
150 fprintf(stderr, "Unable to create top-level window\n");
154 /* select events to receive */
155 GrSelectEvents(wid, GR_EVENT_MASK_BUTTON_DOWN |
156 GR_EVENT_MASK_BUTTON_UP | GR_EVENT_MASK_KEY_DOWN |
157 GR_EVENT_MASK_KEY_UP | GR_EVENT_MASK_MOUSE_POSITION);
158 /* make thw window visible */
161 /* create the graphics contexts */
170 * set the server palette to the requested colour
171 * NOTE: this has only been tested for 8-bit colour!
174 XStoreColor(Display *dpy, Colormap cmap, XColor *xc)
178 ind = xc->pixel & 0xff; /* colour map index */
180 * the colours are passed as 16-bit values so divide by 256 to
181 * get 8-bit RGB values
183 srv_pal.palette[0].r = (xc->red / 256) & 0xff;
184 srv_pal.palette[0].g = (xc->green / 256) & 0xff;
185 srv_pal.palette[0].b = (xc->blue / 256) & 0xff;
189 printf("XStoreColor: ind=%d, r=%02x, g=%02x, b=%02x\n", ind, \
190 srv_pal.palette[0].r, srv_pal.palette[0].g, \
191 srv_pal.palette[0].b);
193 GrSetSystemPalette(ind, &srv_pal);
199 * Copy a rectangular block of pixels
202 XCopyArea(Display *dpy, Window src, Window dst, GR_GC_ID gc,
203 int x1, int y1, int w, int h, int x2, int y2)
205 /* printf("XCopyArea: src=%d, dst=%d, w=%d, h=%d\n",src, dst, w, h); */
206 GrCopyArea(dst, gc, x2, y2, w, h, src, x1, y1, MWROP_SRCCOPY);
211 * Fill a rectangular block
214 XFillRectangle(Display *dpy, Window canvas, GR_GC_ID gc,
215 int x, int y, int w, int h)
217 GrFillRect(canvas, gc, x, y, w, h);
218 /* printf("XFillRectangle: gr_foreground=%08x\n", (int)gr_foreground); */
223 * get the X display name
226 XDisplayName(char *display)
228 return((char *)NULL);
232 * Change the graphics context.
233 * VNC only uses this to set the foreground colour.
236 XChangeGC(Display *dpy, GR_GC_ID gc, unsigned long vmask, GR_GC_INFO *gcv)
239 /* all we need is the foreground colour */
240 /* printf("XChangeGC: foreground=%08x\n", gcv->foreground); */
241 if (pixtype == MWPF_PALETTE) {
243 * The MWF_PALINDEX bit tells GdFindColor() to skip the palette
244 * lookup. This is OK because we have already set the palette.
246 GrSetGCForeground(gc, gcv->foreground | MWF_PALINDEX);
248 GrSetGCForeground(gc, gcv->foreground);
257 XBell(Display *dpy, int pc)
266 XSync(Display *dpy, Bool disc)
275 XSelectInput(Display *dpy, Window win, long evmask)
284 XStoreBytes(Display *dpy, char *bytes, int nbytes)
293 XSetSelectionOwner(Display *dpy, Atom sel, Window own, Time t)
299 * Copy raw pixel data to the screen
302 CopyDataToScreen(CARD8 *buf, int x, int y, int width, int height)
311 XFillRectangle(dpy, canvas, DefaultGC(dpy,DefaultScreen(dpy)),
312 x, y, width, height);
315 usleep(rawDelay * 1000);
318 GrArea(canvas, gc, x, y, width, height, buf, MWPF_PALETTE);
320 CopyBGR233ToScreen(buf, x, y, width, height);
325 * Copy BGR233 data to the screen.
328 CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height)
334 * Handle all X events (keyboard and mouse).
337 HandleXEvents(GR_EVENT *ev)
339 GR_BOOL ret = GR_TRUE;
347 case GR_EVENT_TYPE_NONE:
350 case GR_EVENT_TYPE_MOUSE_POSITION:
351 buttons = (ev->mouse.buttons & GR_BUTTON_R) << 2;
352 buttons |= ev->mouse.buttons & GR_BUTTON_M;
353 buttons |= (ev->mouse.buttons & GR_BUTTON_L) >> 2;
354 ret = SendPointerEvent(ev->mouse.x, ev->mouse.y,
357 case GR_EVENT_TYPE_BUTTON_DOWN:
358 case GR_EVENT_TYPE_BUTTON_UP:
359 buttons = (ev->button.buttons & GR_BUTTON_R) << 2;
360 buttons |= ev->button.buttons & GR_BUTTON_M;
361 buttons |= (ev->button.buttons & GR_BUTTON_L) >> 2;
362 ret = SendPointerEvent(ev->button.x, ev->button.y,
365 case GR_EVENT_TYPE_KEY_DOWN:
366 case GR_EVENT_TYPE_KEY_UP:
367 ret = SendKeyEvent(kmap[ev->keystroke.ch & 0x7f],
368 (ev->type == GR_EVENT_TYPE_KEY_DOWN));
377 * Close everything down before exiting.