1c2c66affSColin Finck /* -*- c-basic-offset: 8 -*-
2c2c66affSColin Finck    rdesktop: A Remote Desktop Protocol client.
3c2c66affSColin Finck    User interface services - NanoX(microwindows)
4c2c66affSColin Finck    Copyright (C) Jay Sorg 2004-2005
5c2c66affSColin Finck 
6c2c66affSColin Finck    This program is free software; you can redistribute it and/or modify
7c2c66affSColin Finck    it under the terms of the GNU General Public License as published by
8c2c66affSColin Finck    the Free Software Foundation; either version 2 of the License, or
9c2c66affSColin Finck    (at your option) any later version.
10c2c66affSColin Finck 
11c2c66affSColin Finck    This program is distributed in the hope that it will be useful,
12c2c66affSColin Finck    but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14c2c66affSColin Finck    GNU General Public License for more details.
15c2c66affSColin Finck 
16c2c66affSColin Finck    You should have received a copy of the GNU General Public License along
17c2c66affSColin Finck    with this program; if not, write to the Free Software Foundation, Inc.,
18c2c66affSColin Finck    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19c2c66affSColin Finck */
20c2c66affSColin Finck /*
21c2c66affSColin Finck   problems with nanox lib
22c2c66affSColin Finck     opcodes don't work, can only rely on copy
23c2c66affSColin Finck     stipple orgins don't work
24c2c66affSColin Finck     clip seems to affect source too, it should only affect dest
25c2c66affSColin Finck       in copyarea functions
26c2c66affSColin Finck */
27c2c66affSColin Finck 
28c2c66affSColin Finck #include "../rdesktop.h"
29c2c66affSColin Finck 
30c2c66affSColin Finck #include <stdarg.h>  /* va_list va_start va_end */
31c2c66affSColin Finck #include <unistd.h> /* gethostname */
32c2c66affSColin Finck #include <pwd.h> /* getpwuid */
33c2c66affSColin Finck 
34c2c66affSColin Finck #include <nano-X.h>
35c2c66affSColin Finck 
36c2c66affSColin Finck extern int g_tcp_port_rdp;
37c2c66affSColin Finck int g_use_rdp5 = 1;
38c2c66affSColin Finck char g_hostname[16];
39c2c66affSColin Finck char g_username[64];
40c2c66affSColin Finck int g_width = 800;
41c2c66affSColin Finck int g_height = 600;
42c2c66affSColin Finck int g_server_bpp = 16;
43c2c66affSColin Finck int g_encryption = 1;
44c2c66affSColin Finck int g_desktop_save = 0; /* todo */
45c2c66affSColin Finck int g_polygon_ellipse_orders = 0;
46c2c66affSColin Finck int g_bitmap_cache = 1;
47c2c66affSColin Finck int g_bitmap_cache_persist_enable = 0;
48c2c66affSColin Finck int g_bitmap_cache_precache = 1;
49c2c66affSColin Finck int g_bitmap_compression = 1;
50c2c66affSColin Finck uint32 g_rdp5_performanceflags =
51c2c66affSColin Finck   RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
52c2c66affSColin Finck int g_console_session = 0;
53c2c66affSColin Finck int g_keylayout = 0x409; /* Defaults to US keyboard layout */
54c2c66affSColin Finck int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */
55c2c66affSColin Finck int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */
56c2c66affSColin Finck int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */
57c2c66affSColin Finck 
58c2c66affSColin Finck static int g_sck = 0;
59c2c66affSColin Finck static char g_servername[256] = "";
60c2c66affSColin Finck static char g_password[64] = "";
61c2c66affSColin Finck static char g_domain[64] = "";
62c2c66affSColin Finck static char g_shell[64] = "";
63c2c66affSColin Finck static char g_directory[64] = "";
64c2c66affSColin Finck static GR_WINDOW_ID g_wnd = 0;
65c2c66affSColin Finck static GR_GC_ID g_gc = 0;
66c2c66affSColin Finck static GR_GC_ID g_gc_clean = 0;
67c2c66affSColin Finck static int g_deactivated = 0;
68c2c66affSColin Finck static int g_ext_disc_reason = 0;
69c2c66affSColin Finck static GR_SCREEN_INFO g_screen_info;
70c2c66affSColin Finck static int g_bpp = 0;
71c2c66affSColin Finck static int g_Bpp = 0;
72c2c66affSColin Finck static GR_RECT g_clip; /* set in main */
73c2c66affSColin Finck static GR_CURSOR_ID g_null_cursor; /* set in main */
74c2c66affSColin Finck static int g_flags = RDP_LOGON_NORMAL;
75c2c66affSColin Finck 
76c2c66affSColin Finck struct key
77c2c66affSColin Finck {
78c2c66affSColin Finck   int ch1;
79c2c66affSColin Finck   int ch2;
80c2c66affSColin Finck   int ch3;
81c2c66affSColin Finck   int chs; /* shift char */
82c2c66affSColin Finck };
83c2c66affSColin Finck 
84c2c66affSColin Finck static struct key g_keys[256];
85c2c66affSColin Finck 
86c2c66affSColin Finck /* Session Directory redirection */
87c2c66affSColin Finck BOOL g_redirect = False;
88c2c66affSColin Finck char g_redirect_server[64];
89c2c66affSColin Finck char g_redirect_domain[16];
90c2c66affSColin Finck char g_redirect_password[64];
91c2c66affSColin Finck char g_redirect_username[64];
92c2c66affSColin Finck char g_redirect_cookie[128];
93c2c66affSColin Finck uint32 g_redirect_flags = 0;
94c2c66affSColin Finck 
95c2c66affSColin Finck #define COLOR16TO32(color) \
96c2c66affSColin Finck ( \
97c2c66affSColin Finck   ((((color >> 8) & 0xf8) | ((color >> 13) & 0x7)) <<  0) | \
98c2c66affSColin Finck   ((((color >> 3) & 0xfc) | ((color >>  9) & 0x3)) <<  8) | \
99c2c66affSColin Finck   ((((color << 3) & 0xf8) | ((color >>  2) & 0x7)) << 16) \
100c2c66affSColin Finck )
101c2c66affSColin Finck 
102c2c66affSColin Finck static uint32 g_ops[16] =
103c2c66affSColin Finck {
104c2c66affSColin Finck   GR_MODE_CLEAR,         /* 0 */
105c2c66affSColin Finck   GR_MODE_NOR,           /* ~(src | dst) */
106c2c66affSColin Finck   GR_MODE_ANDINVERTED,   /* (~src) & dst */
107c2c66affSColin Finck   GR_MODE_COPYINVERTED,  /* ~src */
108c2c66affSColin Finck   GR_MODE_ANDREVERSE,    /* src & (~dst) */
109c2c66affSColin Finck   GR_MODE_INVERT,        /* ~(dst) */
110c2c66affSColin Finck   GR_MODE_XOR,           /* src ^ dst */
111c2c66affSColin Finck   GR_MODE_NAND,          /* ~(src & dst) */
112c2c66affSColin Finck   GR_MODE_AND,           /* src & dst */
113c2c66affSColin Finck   GR_MODE_EQUIV,         /* ~(src) ^ dst or is it ~(src ^ dst) */
114c2c66affSColin Finck   GR_MODE_NOOP,          /* dst */
115c2c66affSColin Finck   GR_MODE_ORINVERTED,    /* (~src) | dst */
116c2c66affSColin Finck   GR_MODE_COPY,          /* src */
117c2c66affSColin Finck   GR_MODE_ORREVERSE,     /* src | (~dst) */
118c2c66affSColin Finck   GR_MODE_OR,            /* src | dst */
119c2c66affSColin Finck   GR_MODE_SETTO1         /* ~0 */
120c2c66affSColin Finck };
121c2c66affSColin Finck 
122c2c66affSColin Finck /*****************************************************************************/
123c2c66affSColin Finck /* do a raster op */
rop(int rop,int src,int dst)124c2c66affSColin Finck static int rop(int rop, int src, int dst)
125c2c66affSColin Finck {
126c2c66affSColin Finck   switch (rop)
127c2c66affSColin Finck   {
128c2c66affSColin Finck     case 0x0: return 0;
129c2c66affSColin Finck     case 0x1: return ~(src | dst);
130c2c66affSColin Finck     case 0x2: return (~src) & dst;
131c2c66affSColin Finck     case 0x3: return ~src;
132c2c66affSColin Finck     case 0x4: return src & (~dst);
133c2c66affSColin Finck     case 0x5: return ~(dst);
134c2c66affSColin Finck     case 0x6: return src ^ dst;
135c2c66affSColin Finck     case 0x7: return ~(src & dst);
136c2c66affSColin Finck     case 0x8: return src & dst;
137c2c66affSColin Finck     case 0x9: return ~(src) ^ dst;
138c2c66affSColin Finck     case 0xa: return dst;
139c2c66affSColin Finck     case 0xb: return (~src) | dst;
140c2c66affSColin Finck     case 0xc: return src;
141c2c66affSColin Finck     case 0xd: return src | (~dst);
142c2c66affSColin Finck     case 0xe: return src | dst;
143c2c66affSColin Finck     case 0xf: return ~0;
144c2c66affSColin Finck   }
145c2c66affSColin Finck   return dst;
146c2c66affSColin Finck }
147c2c66affSColin Finck 
148c2c66affSColin Finck /*****************************************************************************/
get_pixel32(uint8 * data,int x,int y,int width,int height)149c2c66affSColin Finck static int get_pixel32(uint8 * data, int x, int y,
150c2c66affSColin Finck                        int width, int height)
151c2c66affSColin Finck {
152c2c66affSColin Finck   if (x >= 0 && y >= 0 && x < width && y < height)
153c2c66affSColin Finck   {
154c2c66affSColin Finck     return *(((int*)data) + (y * width + x));
155c2c66affSColin Finck   }
156c2c66affSColin Finck   else
157c2c66affSColin Finck   {
158c2c66affSColin Finck     return 0;
159c2c66affSColin Finck   }
160c2c66affSColin Finck }
161c2c66affSColin Finck 
162c2c66affSColin Finck /*****************************************************************************/
set_pixel32(uint8 * data,int x,int y,int width,int height,int pixel)163c2c66affSColin Finck static void set_pixel32(uint8 * data, int x, int y,
164c2c66affSColin Finck                         int width, int height, int pixel)
165c2c66affSColin Finck {
166c2c66affSColin Finck   if (x >= 0 && y >= 0 && x < width && y < height)
167c2c66affSColin Finck   {
168c2c66affSColin Finck     *(((int*)data) + (y * width + x)) = pixel;
169c2c66affSColin Finck   }
170c2c66affSColin Finck }
171c2c66affSColin Finck 
172c2c66affSColin Finck /*****************************************************************************/
warp_coords(int * x,int * y,int * cx,int * cy,int * srcx,int * srcy)173c2c66affSColin Finck static int warp_coords(int * x, int * y, int * cx, int * cy,
174c2c66affSColin Finck                        int * srcx, int * srcy)
175c2c66affSColin Finck {
176c2c66affSColin Finck   int dx;
177c2c66affSColin Finck   int dy;
178c2c66affSColin Finck 
179c2c66affSColin Finck   if (g_clip.x > *x)
180c2c66affSColin Finck   {
181c2c66affSColin Finck     dx = g_clip.x - *x;
182c2c66affSColin Finck   }
183c2c66affSColin Finck   else
184c2c66affSColin Finck   {
185c2c66affSColin Finck     dx = 0;
186c2c66affSColin Finck   }
187c2c66affSColin Finck   if (g_clip.y > *y)
188c2c66affSColin Finck   {
189c2c66affSColin Finck     dy = g_clip.y - *y;
190c2c66affSColin Finck   }
191c2c66affSColin Finck   else
192c2c66affSColin Finck   {
193c2c66affSColin Finck     dy = 0;
194c2c66affSColin Finck   }
195c2c66affSColin Finck   if (*x + *cx > g_clip.x + g_clip.width)
196c2c66affSColin Finck   {
197c2c66affSColin Finck     *cx = (*cx - ((*x + *cx) - (g_clip.x + g_clip.width)));
198c2c66affSColin Finck   }
199c2c66affSColin Finck   if (*y + *cy > g_clip.y + g_clip.height)
200c2c66affSColin Finck   {
201c2c66affSColin Finck     *cy = (*cy - ((*y + *cy) - (g_clip.y + g_clip.height)));
202c2c66affSColin Finck   }
203c2c66affSColin Finck   *cx = *cx - dx;
204c2c66affSColin Finck   *cy = *cy - dy;
205c2c66affSColin Finck   if (*cx <= 0)
206c2c66affSColin Finck   {
207c2c66affSColin Finck     return 0;
208c2c66affSColin Finck   }
209c2c66affSColin Finck   if (*cy <= 0)
210c2c66affSColin Finck   {
211c2c66affSColin Finck     return 0;
212c2c66affSColin Finck   }
213c2c66affSColin Finck   *x = *x + dx;
214c2c66affSColin Finck   *y = *y + dy;
215c2c66affSColin Finck   if (srcx != 0)
216c2c66affSColin Finck   {
217c2c66affSColin Finck     *srcx = *srcx + dx;
218c2c66affSColin Finck   }
219c2c66affSColin Finck   if (srcy != 0)
220c2c66affSColin Finck   {
221c2c66affSColin Finck     *srcy = *srcy + dy;
222c2c66affSColin Finck   }
223c2c66affSColin Finck   return 1;
224c2c66affSColin Finck }
225c2c66affSColin Finck 
226c2c66affSColin Finck /******************************************************************************/
227c2c66affSColin Finck /* check if a certain pixel is set in a bitmap */
is_pixel_on(uint8 * data,int x,int y,int width,int bpp)228c2c66affSColin Finck static int is_pixel_on(uint8 * data, int x, int y, int width, int bpp)
229c2c66affSColin Finck {
230c2c66affSColin Finck   int start;
231c2c66affSColin Finck   int shift;
232c2c66affSColin Finck 
233c2c66affSColin Finck   if (bpp == 1)
234c2c66affSColin Finck   {
235c2c66affSColin Finck     width = (width + 7) / 8;
236c2c66affSColin Finck     start = (y * width) + x / 8;
237c2c66affSColin Finck     shift = x % 8;
238c2c66affSColin Finck     return (data[start] & (0x80 >> shift)) != 0;
239c2c66affSColin Finck   }
240c2c66affSColin Finck   else
241c2c66affSColin Finck     return 0;
242c2c66affSColin Finck }
243c2c66affSColin Finck 
244c2c66affSColin Finck /*****************************************************************************/
ui_select(int in)245c2c66affSColin Finck int ui_select(int in)
246c2c66affSColin Finck {
247c2c66affSColin Finck   if (g_sck == 0)
248c2c66affSColin Finck   {
249c2c66affSColin Finck     g_sck = in;
250c2c66affSColin Finck   }
251c2c66affSColin Finck   return 1;
252c2c66affSColin Finck }
253c2c66affSColin Finck 
254c2c66affSColin Finck /*****************************************************************************/
ui_set_clip(int x,int y,int cx,int cy)255c2c66affSColin Finck void ui_set_clip(int x, int y, int cx, int cy)
256c2c66affSColin Finck {
257c2c66affSColin Finck   GR_REGION_ID region;
258c2c66affSColin Finck 
259c2c66affSColin Finck   g_clip.x = x;
260c2c66affSColin Finck   g_clip.y = y;
261c2c66affSColin Finck   g_clip.width = cx;
262c2c66affSColin Finck   g_clip.height = cy;
263c2c66affSColin Finck   region = GrNewRegion();
264c2c66affSColin Finck   GrUnionRectWithRegion(region, &g_clip);
265c2c66affSColin Finck   GrSetGCRegion(g_gc, region); /* can't destroy region here, i guess gc */
266c2c66affSColin Finck                                /* takes owership, if you destroy it */
267c2c66affSColin Finck                                /* clip is reset, hum */
268c2c66affSColin Finck }
269c2c66affSColin Finck 
270c2c66affSColin Finck /*****************************************************************************/
ui_reset_clip(void)271c2c66affSColin Finck void ui_reset_clip(void)
272c2c66affSColin Finck {
273c2c66affSColin Finck   GrSetGCRegion(g_gc, 0);
274c2c66affSColin Finck   g_clip.x = 0;
275c2c66affSColin Finck   g_clip.y = 0;
276c2c66affSColin Finck   g_clip.width = g_width;
277c2c66affSColin Finck   g_clip.height = g_height;
278c2c66affSColin Finck }
279c2c66affSColin Finck 
280c2c66affSColin Finck /*****************************************************************************/
ui_bell(void)281c2c66affSColin Finck void ui_bell(void)
282c2c66affSColin Finck {
283c2c66affSColin Finck   GrBell();
284c2c66affSColin Finck }
285c2c66affSColin Finck 
286c2c66affSColin Finck /*****************************************************************************/
287c2c66affSColin Finck /* gota convert the rdp glyph to nanox glyph */
ui_create_glyph(int width,int height,uint8 * data)288c2c66affSColin Finck void * ui_create_glyph(int width, int height, uint8 * data)
289c2c66affSColin Finck {
290c2c66affSColin Finck   char * p, * q, * r;
291c2c66affSColin Finck   int datasize, i, j;
292c2c66affSColin Finck 
293c2c66affSColin Finck   datasize = GR_BITMAP_SIZE(width, height) * sizeof(GR_BITMAP);
294c2c66affSColin Finck   p = xmalloc(datasize);
295c2c66affSColin Finck   q = p;
296c2c66affSColin Finck   r = data;
297c2c66affSColin Finck   memset(p, 0, datasize);
298c2c66affSColin Finck   for (i = 0; i < height; i++)
299c2c66affSColin Finck   {
300c2c66affSColin Finck     j = 0;
301c2c66affSColin Finck     while (j + 8 < width)
302c2c66affSColin Finck     {
303c2c66affSColin Finck       *q = *(r + 1);
304c2c66affSColin Finck       q++;
305c2c66affSColin Finck       r++;
306c2c66affSColin Finck       *q = *(r - 1);
307c2c66affSColin Finck       q++;
308c2c66affSColin Finck       r++;
309c2c66affSColin Finck       j += 16;
310c2c66affSColin Finck     }
311c2c66affSColin Finck     if ((width % 16) <= 8 && (width % 16) > 0)
312c2c66affSColin Finck     {
313c2c66affSColin Finck       q++;
314c2c66affSColin Finck       *q = *r;
315c2c66affSColin Finck       q++;
316c2c66affSColin Finck       r++;
317c2c66affSColin Finck       j += 8;
318c2c66affSColin Finck     }
319c2c66affSColin Finck   }
320c2c66affSColin Finck   return p;
321c2c66affSColin Finck }
322c2c66affSColin Finck 
323c2c66affSColin Finck /*****************************************************************************/
ui_destroy_glyph(void * glyph)324c2c66affSColin Finck void ui_destroy_glyph(void * glyph)
325c2c66affSColin Finck {
326c2c66affSColin Finck   xfree(glyph);
327c2c66affSColin Finck }
328c2c66affSColin Finck 
329c2c66affSColin Finck /*****************************************************************************/
ui_create_colourmap(COLOURMAP * colors)330c2c66affSColin Finck void * ui_create_colourmap(COLOURMAP * colors)
331c2c66affSColin Finck {
332c2c66affSColin Finck   return 0;
333c2c66affSColin Finck }
334c2c66affSColin Finck 
335c2c66affSColin Finck /*****************************************************************************/
ui_set_colourmap(void * map)336c2c66affSColin Finck void ui_set_colourmap(void * map)
337c2c66affSColin Finck {
338c2c66affSColin Finck }
339c2c66affSColin Finck 
340c2c66affSColin Finck /*****************************************************************************/
ui_create_bitmap(int width,int height,uint8 * data)341c2c66affSColin Finck void * ui_create_bitmap(int width, int height, uint8 * data)
342c2c66affSColin Finck {
343c2c66affSColin Finck   GR_WINDOW_ID pixmap;
344c2c66affSColin Finck   uint8 * p;
345c2c66affSColin Finck   uint32 i, j, pixel;
346c2c66affSColin Finck 
347c2c66affSColin Finck   p = data;
348c2c66affSColin Finck   pixmap = GrNewPixmap(width, height, 0);
349c2c66affSColin Finck   if (g_server_bpp == 16 && g_bpp == 32)
350c2c66affSColin Finck   {
351c2c66affSColin Finck     p = xmalloc(width * height * g_Bpp);
352c2c66affSColin Finck     for (i = 0; i < height; i++)
353c2c66affSColin Finck     {
354c2c66affSColin Finck       for (j = 0; j < width; j++)
355c2c66affSColin Finck       {
356c2c66affSColin Finck         pixel = *(((uint16 *) data) + (i * width + j));
357c2c66affSColin Finck         pixel = COLOR16TO32(pixel);
358c2c66affSColin Finck         *(((uint32 *) p) + (i * width + j)) = pixel;
359c2c66affSColin Finck       }
360c2c66affSColin Finck     }
361c2c66affSColin Finck   }
362c2c66affSColin Finck   GrArea(pixmap, g_gc_clean, 0, 0, width, height, p, MWPF_RGB);
363c2c66affSColin Finck   if (p != data)
364c2c66affSColin Finck   {
365c2c66affSColin Finck     xfree(p);
366c2c66affSColin Finck   }
367c2c66affSColin Finck   return (void *) pixmap;
368c2c66affSColin Finck }
369c2c66affSColin Finck 
370c2c66affSColin Finck /*****************************************************************************/
ui_destroy_bitmap(void * bmp)371c2c66affSColin Finck void ui_destroy_bitmap(void * bmp)
372c2c66affSColin Finck {
373c2c66affSColin Finck   GrDestroyWindow((GR_WINDOW_ID)bmp);
374c2c66affSColin Finck }
375c2c66affSColin Finck 
376c2c66affSColin Finck /*****************************************************************************/
377c2c66affSColin Finck #define DO_GLYPH(ttext,idx) \
378c2c66affSColin Finck { \
379c2c66affSColin Finck   glyph = cache_get_font (font, ttext[idx]); \
380c2c66affSColin Finck   if (!(flags & TEXT2_IMPLICIT_X)) \
381c2c66affSColin Finck   { \
382c2c66affSColin Finck     xyoffset = ttext[++idx]; \
383c2c66affSColin Finck     if ((xyoffset & 0x80)) \
384c2c66affSColin Finck     { \
385c2c66affSColin Finck       if (flags & TEXT2_VERTICAL) \
386c2c66affSColin Finck       { \
387c2c66affSColin Finck         y += ttext[idx+1] | (ttext[idx+2] << 8); \
388c2c66affSColin Finck       } \
389c2c66affSColin Finck       else \
390c2c66affSColin Finck       { \
391c2c66affSColin Finck         x += ttext[idx+1] | (ttext[idx+2] << 8); \
392c2c66affSColin Finck       } \
393c2c66affSColin Finck       idx += 2; \
394c2c66affSColin Finck     } \
395c2c66affSColin Finck     else \
396c2c66affSColin Finck     { \
397c2c66affSColin Finck       if (flags & TEXT2_VERTICAL) \
398c2c66affSColin Finck       { \
399c2c66affSColin Finck         y += xyoffset; \
400c2c66affSColin Finck       } \
401c2c66affSColin Finck       else \
402c2c66affSColin Finck       { \
403c2c66affSColin Finck         x += xyoffset; \
404c2c66affSColin Finck       } \
405c2c66affSColin Finck     } \
406c2c66affSColin Finck   } \
407c2c66affSColin Finck   if (glyph != NULL) \
408c2c66affSColin Finck   { \
409c2c66affSColin Finck     x1 = x + glyph->offset; \
410c2c66affSColin Finck     y1 = y + glyph->baseline; \
411c2c66affSColin Finck     GrBitmap(g_wnd, g_gc, x1, y1, glyph->width, glyph->height, glyph->pixmap); \
412c2c66affSColin Finck     if (flags & TEXT2_IMPLICIT_X) \
413c2c66affSColin Finck     { \
414c2c66affSColin Finck       x += glyph->width; \
415c2c66affSColin Finck     } \
416c2c66affSColin Finck   } \
417c2c66affSColin Finck }
418c2c66affSColin Finck 
419c2c66affSColin Finck /*****************************************************************************/
ui_draw_text(uint8 font,uint8 flags,uint8 opcode,int mixmode,int x,int y,int clipx,int clipy,int clipcx,int clipcy,int boxx,int boxy,int boxcx,int boxcy,BRUSH * brush,int bgcolor,int fgcolor,uint8 * text,uint8 length)420c2c66affSColin Finck void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode,
421c2c66affSColin Finck                   int x, int y,
422c2c66affSColin Finck                   int clipx, int clipy, int clipcx, int clipcy,
423c2c66affSColin Finck                   int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
424c2c66affSColin Finck                   int bgcolor, int fgcolor, uint8 * text, uint8 length)
425c2c66affSColin Finck {
426c2c66affSColin Finck   FONTGLYPH * glyph;
427c2c66affSColin Finck   int i, j, xyoffset, x1, y1;
428c2c66affSColin Finck   DATABLOB * entry;
429c2c66affSColin Finck 
430c2c66affSColin Finck   GrSetGCMode(g_gc, GR_MODE_COPY);
431c2c66affSColin Finck   GrSetGCUseBackground(g_gc, 0); /* this can be set when gc is created */
432c2c66affSColin Finck   if (g_server_bpp == 16 && g_bpp == 32)
433c2c66affSColin Finck   {
434c2c66affSColin Finck     fgcolor = COLOR16TO32(fgcolor);
435c2c66affSColin Finck     bgcolor = COLOR16TO32(bgcolor);
436c2c66affSColin Finck   }
437c2c66affSColin Finck   GrSetGCForeground(g_gc, bgcolor);
438c2c66affSColin Finck   if (boxx + boxcx > g_width)
439c2c66affSColin Finck   {
440c2c66affSColin Finck     boxcx = g_width - boxx;
441c2c66affSColin Finck   }
442c2c66affSColin Finck   if (boxcx > 1)
443c2c66affSColin Finck   {
444c2c66affSColin Finck     GrFillRect(g_wnd, g_gc, boxx, boxy, boxcx, boxcy);
445c2c66affSColin Finck   }
446c2c66affSColin Finck   else if (mixmode == MIX_OPAQUE)
447c2c66affSColin Finck   {
448c2c66affSColin Finck     GrFillRect(g_wnd, g_gc, clipx, clipy, clipcx, clipcy);
449c2c66affSColin Finck   }
450c2c66affSColin Finck   GrSetGCForeground(g_gc, fgcolor);
451c2c66affSColin Finck   /* Paint text, character by character */
452c2c66affSColin Finck   for (i = 0; i < length;)
453c2c66affSColin Finck   {
454c2c66affSColin Finck     switch (text[i])
455c2c66affSColin Finck     {
456c2c66affSColin Finck       case 0xff:
457c2c66affSColin Finck         if (i + 2 < length)
458c2c66affSColin Finck         {
459c2c66affSColin Finck           cache_put_text(text[i + 1], text, text[i + 2]);
460c2c66affSColin Finck         }
461c2c66affSColin Finck         else
462c2c66affSColin Finck         {
463c2c66affSColin Finck           error("this shouldn't be happening\n");
464c2c66affSColin Finck           exit(1);
465c2c66affSColin Finck         }
466c2c66affSColin Finck         /* this will move pointer from start to first character after */
467c2c66affSColin Finck         /* FF command */
468c2c66affSColin Finck         length -= i + 3;
469c2c66affSColin Finck         text = &(text[i + 3]);
470c2c66affSColin Finck         i = 0;
471c2c66affSColin Finck         break;
472c2c66affSColin Finck       case 0xfe:
473c2c66affSColin Finck         entry = cache_get_text(text[i + 1]);
474c2c66affSColin Finck         if (entry != NULL)
475c2c66affSColin Finck         {
476c2c66affSColin Finck           if ((((uint8 *) (entry->data))[1] == 0) &&
477c2c66affSColin Finck                                 (!(flags & TEXT2_IMPLICIT_X)))
478c2c66affSColin Finck           {
479c2c66affSColin Finck             if (flags & TEXT2_VERTICAL)
480c2c66affSColin Finck             {
481c2c66affSColin Finck               y += text[i + 2];
482c2c66affSColin Finck             }
483c2c66affSColin Finck             else
484c2c66affSColin Finck             {
485c2c66affSColin Finck               x += text[i + 2];
486c2c66affSColin Finck             }
487c2c66affSColin Finck           }
488c2c66affSColin Finck           for (j = 0; j < entry->size; j++)
489c2c66affSColin Finck           {
490c2c66affSColin Finck             DO_GLYPH(((uint8 *) (entry->data)), j);
491c2c66affSColin Finck           }
492c2c66affSColin Finck         }
493c2c66affSColin Finck         if (i + 2 < length)
494c2c66affSColin Finck         {
495c2c66affSColin Finck           i += 3;
496c2c66affSColin Finck         }
497c2c66affSColin Finck         else
498c2c66affSColin Finck         {
499c2c66affSColin Finck           i += 2;
500c2c66affSColin Finck         }
501c2c66affSColin Finck         length -= i;
502c2c66affSColin Finck         /* this will move pointer from start to first character after */
503c2c66affSColin Finck         /* FE command */
504c2c66affSColin Finck         text = &(text[i]);
505c2c66affSColin Finck         i = 0;
506c2c66affSColin Finck         break;
507c2c66affSColin Finck       default:
508c2c66affSColin Finck         DO_GLYPH(text, i);
509c2c66affSColin Finck         i++;
510c2c66affSColin Finck         break;
511c2c66affSColin Finck     }
512c2c66affSColin Finck   }
513c2c66affSColin Finck }
514c2c66affSColin Finck 
515c2c66affSColin Finck /*****************************************************************************/
ui_line(uint8 opcode,int startx,int starty,int endx,int endy,PEN * pen)516c2c66affSColin Finck void ui_line(uint8 opcode, int startx, int starty, int endx, int endy,
517c2c66affSColin Finck              PEN * pen)
518c2c66affSColin Finck {
519c2c66affSColin Finck   uint32 op;
520c2c66affSColin Finck   uint32 color;
521c2c66affSColin Finck 
522c2c66affSColin Finck   color = pen->colour;
523c2c66affSColin Finck   if (opcode == 5) /* GR_MODE_INVERT, not supported so convert it */
524c2c66affSColin Finck   {                /* i think x ^ -1 = ~x */
525c2c66affSColin Finck     color = 0xffffffff;
526c2c66affSColin Finck     opcode = 6; /* GR_MODE_XOR */
527c2c66affSColin Finck   }
528c2c66affSColin Finck   if (opcode == 12 || opcode == 6) /* nanox only supports these 2 opcode */
529c2c66affSColin Finck   {
530c2c66affSColin Finck     op = g_ops[opcode];
531c2c66affSColin Finck     GrSetGCMode(g_gc, op);
532c2c66affSColin Finck     if (g_server_bpp == 16 && g_bpp == 32)
533c2c66affSColin Finck     {
534c2c66affSColin Finck       color = COLOR16TO32(color);
535c2c66affSColin Finck     }
536c2c66affSColin Finck     GrSetGCForeground(g_gc, color);
537c2c66affSColin Finck     GrLine(g_wnd, g_gc, startx, starty, endx, endy);
538c2c66affSColin Finck     GrSetGCMode(g_gc, GR_MODE_COPY);
539c2c66affSColin Finck   }
540c2c66affSColin Finck   else
541c2c66affSColin Finck   {
542c2c66affSColin Finck     unimpl("opcode %d in ui_line\n", opcode);
543c2c66affSColin Finck   }
544c2c66affSColin Finck }
545c2c66affSColin Finck 
546c2c66affSColin Finck /*****************************************************************************/
ui_triblt(uint8 opcode,int x,int y,int cx,int cy,void * src,int srcx,int srcy,BRUSH * brush,int bgcolor,int fgcolor)547c2c66affSColin Finck void ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
548c2c66affSColin Finck                void * src, int srcx, int srcy,
549c2c66affSColin Finck                BRUSH * brush, int bgcolor, int fgcolor)
550c2c66affSColin Finck {
551c2c66affSColin Finck /* not used, turned off */
552c2c66affSColin Finck }
553c2c66affSColin Finck 
554c2c66affSColin Finck /*****************************************************************************/
ui_memblt(uint8 opcode,int x,int y,int cx,int cy,void * src,int srcx,int srcy)555c2c66affSColin Finck void ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
556c2c66affSColin Finck                void * src, int srcx, int srcy)
557c2c66affSColin Finck {
558c2c66affSColin Finck   uint8 * dest;
559c2c66affSColin Finck   uint8 * source;
560c2c66affSColin Finck   uint8 * final;
561c2c66affSColin Finck   GR_WINDOW_INFO wi;
562c2c66affSColin Finck   int i, j, s, d;
563c2c66affSColin Finck   GR_WINDOW_ID pixmap;
564c2c66affSColin Finck 
565c2c66affSColin Finck   if (opcode == 12)
566c2c66affSColin Finck   {
567c2c66affSColin Finck     GrCopyArea(g_wnd, g_gc, x, y, cx, cy, (GR_DRAW_ID)src, srcx, srcy,
568c2c66affSColin Finck                GR_MODE_COPY);
569c2c66affSColin Finck   }
570c2c66affSColin Finck   else /* do opcodes ourself */
571c2c66affSColin Finck   {    /* slow but its correct, ok to be slow here, these are rare */
572c2c66affSColin Finck     GrGetWindowInfo((GR_DRAW_ID)src, &wi);
573c2c66affSColin Finck     dest = xmalloc(cx * cy * g_Bpp);
574c2c66affSColin Finck     source = xmalloc(wi.width * wi.height * g_Bpp);
575c2c66affSColin Finck     final = xmalloc(cx * cy * g_Bpp);
576c2c66affSColin Finck     memset(final, 0, cx * cy * g_Bpp);
577c2c66affSColin Finck     /* dest */
578c2c66affSColin Finck     GrReadArea(g_wnd, x, y, cx, cy, (GR_PIXELVAL*)dest);
579c2c66affSColin Finck     /* source */
580c2c66affSColin Finck     GrReadArea((GR_DRAW_ID)src, 0, 0,
581c2c66affSColin Finck                wi.width, wi.height, (GR_PIXELVAL*)source);
582c2c66affSColin Finck     for (i = 0; i < cy; i++)
583c2c66affSColin Finck     {
584c2c66affSColin Finck       for (j = 0; j < cx; j++)
585c2c66affSColin Finck       {
586c2c66affSColin Finck         s = get_pixel32(source, j + srcx, i + srcy, wi.width, wi.height);
587c2c66affSColin Finck         d = get_pixel32(dest, j, i, cx ,cy);
588c2c66affSColin Finck         set_pixel32(final, j, i, cx, cy, rop(opcode, s, d));
589c2c66affSColin Finck       }
590c2c66affSColin Finck     }
591c2c66affSColin Finck     pixmap = GrNewPixmap(cx, cy, 0);
592c2c66affSColin Finck     GrArea(pixmap, g_gc_clean, 0, 0, cx, cy, final, MWPF_TRUECOLOR0888);
593c2c66affSColin Finck     GrCopyArea(g_wnd, g_gc, x, y, cx, cy, pixmap, 0, 0, GR_MODE_COPY);
594c2c66affSColin Finck     GrDestroyWindow(pixmap);
595c2c66affSColin Finck     xfree(dest);
596c2c66affSColin Finck     xfree(source);
597c2c66affSColin Finck     xfree(final);
598c2c66affSColin Finck   }
599c2c66affSColin Finck }
600c2c66affSColin Finck 
601c2c66affSColin Finck /*****************************************************************************/
ui_desktop_restore(uint32 offset,int x,int y,int cx,int cy)602c2c66affSColin Finck void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
603c2c66affSColin Finck {
604c2c66affSColin Finck /* not used, turned off */
605c2c66affSColin Finck }
606c2c66affSColin Finck 
607c2c66affSColin Finck /*****************************************************************************/
ui_desktop_save(uint32 offset,int x,int y,int cx,int cy)608c2c66affSColin Finck void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
609c2c66affSColin Finck {
610c2c66affSColin Finck /* not used, turned off */
611c2c66affSColin Finck }
612c2c66affSColin Finck 
613c2c66affSColin Finck /*****************************************************************************/
ui_rect(int x,int y,int cx,int cy,int color)614c2c66affSColin Finck void ui_rect(int x, int y, int cx, int cy, int color)
615c2c66affSColin Finck {
616c2c66affSColin Finck   if (g_server_bpp == 16 && g_bpp == 32)
617c2c66affSColin Finck   {
618c2c66affSColin Finck     color = COLOR16TO32(color);
619c2c66affSColin Finck   }
620c2c66affSColin Finck   GrSetGCForeground(g_gc, color);
621c2c66affSColin Finck   GrFillRect(g_wnd, g_gc, x, y, cx, cy);
622c2c66affSColin Finck }
623c2c66affSColin Finck 
624c2c66affSColin Finck /*****************************************************************************/
625c2c66affSColin Finck /* using warp_coords cause clip seems to affect source in GrCopyArea */
ui_screenblt(uint8 opcode,int x,int y,int cx,int cy,int srcx,int srcy)626c2c66affSColin Finck void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
627c2c66affSColin Finck                   int srcx, int srcy)
628c2c66affSColin Finck {
629c2c66affSColin Finck   if (opcode == 12)
630c2c66affSColin Finck   {
631c2c66affSColin Finck     if (warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
632c2c66affSColin Finck     {
633c2c66affSColin Finck       GrCopyArea(g_wnd, g_gc_clean, x, y, cx, cy, g_wnd, srcx, srcy,
634c2c66affSColin Finck                  GR_MODE_COPY);
635c2c66affSColin Finck     }
636c2c66affSColin Finck   }
637c2c66affSColin Finck   else
638c2c66affSColin Finck   {
639c2c66affSColin Finck     unimpl("opcode %d in ui_screenblt\n", opcode);
640c2c66affSColin Finck   }
641c2c66affSColin Finck }
642c2c66affSColin Finck 
643c2c66affSColin Finck /******************************************************************************/
644c2c66affSColin Finck /* can't use stipple cause tsorigin don't work, GrPoint too slow,
645c2c66affSColin Finck    GrPoints too slow but better, using a copy from the screen,
646c2c66affSColin Finck    do the pattern and copy it back */
ui_patblt(uint8 opcode,int x,int y,int cx,int cy,BRUSH * brush,int bgcolor,int fgcolor)647c2c66affSColin Finck void ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
648c2c66affSColin Finck                BRUSH * brush, int bgcolor, int fgcolor)
649c2c66affSColin Finck {
650c2c66affSColin Finck   uint8 ipattern[8], * dest, * final;
651c2c66affSColin Finck   uint32 op;
652c2c66affSColin Finck   int i, j, s, d;
653c2c66affSColin Finck   GR_WINDOW_ID pixmap;
654c2c66affSColin Finck 
655c2c66affSColin Finck   if (g_server_bpp == 16 && g_bpp == 32)
656c2c66affSColin Finck   {
657c2c66affSColin Finck     fgcolor = COLOR16TO32(fgcolor);
658c2c66affSColin Finck     bgcolor = COLOR16TO32(bgcolor);
659c2c66affSColin Finck   }
660c2c66affSColin Finck   switch (brush->style)
661c2c66affSColin Finck   {
662c2c66affSColin Finck     case 0: /* Solid */
663c2c66affSColin Finck       if (opcode == 12 || opcode == 6)
664c2c66affSColin Finck       {
665c2c66affSColin Finck         op = g_ops[opcode];
666c2c66affSColin Finck         GrSetGCMode(g_gc, op);
667c2c66affSColin Finck         GrSetGCForeground(g_gc, fgcolor);
668c2c66affSColin Finck         GrFillRect(g_wnd, g_gc, x, y, cx, cy);
669c2c66affSColin Finck         GrSetGCMode(g_gc, GR_MODE_COPY);
670c2c66affSColin Finck       }
671c2c66affSColin Finck       else
672c2c66affSColin Finck       {
673c2c66affSColin Finck         unimpl("opcode %d in ui_patblt solid brush\n", opcode);
674c2c66affSColin Finck       }
675c2c66affSColin Finck       break;
676c2c66affSColin Finck     case 3: /* Pattern - all opcodes ok */
677c2c66affSColin Finck       for (i = 0; i != 8; i++)
678c2c66affSColin Finck       {
679c2c66affSColin Finck         ipattern[7 - i] = brush->pattern[i];
680c2c66affSColin Finck       }
681c2c66affSColin Finck       dest = xmalloc(cx * cy * g_Bpp);
682c2c66affSColin Finck       final = xmalloc(cx * cy * g_Bpp);
683c2c66affSColin Finck       memset(final, 0, cx * cy * g_Bpp);
684c2c66affSColin Finck       /* dest */
685c2c66affSColin Finck       if (opcode != 12)
686c2c66affSColin Finck       {
687c2c66affSColin Finck         GrReadArea(g_wnd, x, y, cx, cy, (GR_PIXELVAL*)dest);
688c2c66affSColin Finck       }
689c2c66affSColin Finck       for (i = 0; i < cy; i++)
690c2c66affSColin Finck       {
691c2c66affSColin Finck         for (j = 0; j < cx; j++)
692c2c66affSColin Finck         {
693c2c66affSColin Finck           if (is_pixel_on(ipattern, (x + j + brush->xorigin) % 8,
694c2c66affSColin Finck                           (y + i + brush->yorigin) % 8, 8, 1))
695c2c66affSColin Finck           {
696c2c66affSColin Finck             s = fgcolor;
697c2c66affSColin Finck           }
698c2c66affSColin Finck           else
699c2c66affSColin Finck           {
700c2c66affSColin Finck             s = bgcolor;
701c2c66affSColin Finck           }
702c2c66affSColin Finck           d = get_pixel32(dest, j, i, cx ,cy);
703c2c66affSColin Finck           set_pixel32(final, j, i, cx, cy, rop(opcode, s, d));
704c2c66affSColin Finck         }
705c2c66affSColin Finck       }
706c2c66affSColin Finck       pixmap = GrNewPixmap(cx, cy, 0);
707c2c66affSColin Finck       GrArea(pixmap, g_gc_clean, 0, 0, cx, cy, final, MWPF_TRUECOLOR0888);
708c2c66affSColin Finck       GrCopyArea(g_wnd, g_gc, x, y, cx, cy, pixmap, 0, 0, GR_MODE_COPY);
709c2c66affSColin Finck       GrDestroyWindow(pixmap);
710c2c66affSColin Finck       xfree(dest);
711c2c66affSColin Finck       xfree(final);
712c2c66affSColin Finck       break;
713c2c66affSColin Finck   }
714c2c66affSColin Finck }
715c2c66affSColin Finck 
716c2c66affSColin Finck /*****************************************************************************/
ui_destblt(uint8 opcode,int x,int y,int cx,int cy)717c2c66affSColin Finck void ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
718c2c66affSColin Finck {
719c2c66affSColin Finck   uint32 op;
720c2c66affSColin Finck 
721c2c66affSColin Finck   if (opcode == 0) /* black */
722c2c66affSColin Finck   {
723c2c66affSColin Finck     GrSetGCForeground(g_gc, 0);
724c2c66affSColin Finck     opcode = 12;
725c2c66affSColin Finck   }
726c2c66affSColin Finck   else if (opcode == 5) /* invert */
727c2c66affSColin Finck   {
728c2c66affSColin Finck     GrSetGCForeground(g_gc, 0xffffffff);
729c2c66affSColin Finck     opcode = 6;
730c2c66affSColin Finck   }
731c2c66affSColin Finck   else if (opcode == 15) /* white */
732c2c66affSColin Finck   {
733c2c66affSColin Finck     GrSetGCForeground(g_gc, 0xffffffff);
734c2c66affSColin Finck     opcode = 12;
735c2c66affSColin Finck   }
736c2c66affSColin Finck   if (opcode == 12 || opcode == 6)
737c2c66affSColin Finck   {
738c2c66affSColin Finck     op = g_ops[opcode];
739c2c66affSColin Finck     GrSetGCMode(g_gc, op);
740c2c66affSColin Finck     GrFillRect(g_wnd, g_gc, x, y, cx, cy);
741c2c66affSColin Finck     GrSetGCMode(g_gc, GR_MODE_COPY);
742c2c66affSColin Finck   }
743c2c66affSColin Finck   else
744c2c66affSColin Finck   {
745c2c66affSColin Finck     unimpl("opcode %d in ui_destblt\n", opcode);
746c2c66affSColin Finck   }
747c2c66affSColin Finck }
748c2c66affSColin Finck 
749c2c66affSColin Finck /*****************************************************************************/
ui_paint_bitmap(int x,int y,int cx,int cy,int width,int height,uint8 * data)750c2c66affSColin Finck void ui_paint_bitmap(int x, int y, int cx, int cy,
751c2c66affSColin Finck                      int width, int height, uint8 * data)
752c2c66affSColin Finck {
753c2c66affSColin Finck   void * b;
754c2c66affSColin Finck 
755c2c66affSColin Finck   b = ui_create_bitmap(width, height, data);
756c2c66affSColin Finck   ui_memblt(12, x, y, cx, cy, b, 0, 0);
757c2c66affSColin Finck   ui_destroy_bitmap(b);
758c2c66affSColin Finck }
759c2c66affSColin Finck 
760c2c66affSColin Finck /*****************************************************************************/
ui_move_pointer(int x,int y)761c2c66affSColin Finck void ui_move_pointer(int x, int y)
762c2c66affSColin Finck {
763c2c66affSColin Finck   GrMoveCursor(x, y);
764c2c66affSColin Finck }
765c2c66affSColin Finck 
766c2c66affSColin Finck /*****************************************************************************/
ui_set_null_cursor(void)767c2c66affSColin Finck void ui_set_null_cursor(void)
768c2c66affSColin Finck {
769c2c66affSColin Finck   GrSetWindowCursor(g_wnd, g_null_cursor);
770c2c66affSColin Finck }
771c2c66affSColin Finck 
772c2c66affSColin Finck /*****************************************************************************/
ui_set_cursor(void * cursor)773c2c66affSColin Finck void ui_set_cursor(void * cursor)
774c2c66affSColin Finck {
775c2c66affSColin Finck   GrSetWindowCursor(g_wnd, (GR_CURSOR_ID)cursor);
776c2c66affSColin Finck }
777c2c66affSColin Finck 
778c2c66affSColin Finck //******************************************************************************
is24on(uint8 * data,int x,int y)779c2c66affSColin Finck static int is24on(uint8 * data, int x, int y)
780c2c66affSColin Finck {
781c2c66affSColin Finck   uint8 r, g, b;
782c2c66affSColin Finck   int start;
783c2c66affSColin Finck 
784c2c66affSColin Finck   if (data == 0)
785c2c66affSColin Finck   {
786c2c66affSColin Finck     return 0;
787c2c66affSColin Finck   }
788c2c66affSColin Finck   start = y * 32 * 3 + x * 3;
789c2c66affSColin Finck   r = data[start];
790c2c66affSColin Finck   g = data[start + 1];
791c2c66affSColin Finck   b = data[start + 2];
792c2c66affSColin Finck   return !((r == 0) && (g == 0) && (b == 0));
793c2c66affSColin Finck }
794c2c66affSColin Finck 
795c2c66affSColin Finck //******************************************************************************
is1on(uint8 * data,int x,int y)796c2c66affSColin Finck static int is1on(uint8 * data, int x, int y)
797c2c66affSColin Finck {
798c2c66affSColin Finck   int start;
799c2c66affSColin Finck   int shift;
800c2c66affSColin Finck 
801c2c66affSColin Finck   if (data == 0)
802c2c66affSColin Finck   {
803c2c66affSColin Finck     return 0;
804c2c66affSColin Finck   }
805c2c66affSColin Finck   start = (y * 32) / 8 + x / 8;
806c2c66affSColin Finck   shift = x % 8;
807c2c66affSColin Finck   return (data[start] & (0x80 >> shift)) == 0;
808c2c66affSColin Finck }
809c2c66affSColin Finck 
810c2c66affSColin Finck //******************************************************************************
set1(uint8 * data,int x,int y)811c2c66affSColin Finck static void set1(uint8 * data, int x, int y)
812c2c66affSColin Finck {
813c2c66affSColin Finck   int start;
814c2c66affSColin Finck   int shift;
815c2c66affSColin Finck 
816c2c66affSColin Finck   if (data == 0)
817c2c66affSColin Finck   {
818c2c66affSColin Finck     return;
819c2c66affSColin Finck   }
820c2c66affSColin Finck   start = (y * 32) / 8 + x / 8;
821c2c66affSColin Finck   shift = x % 8;
822c2c66affSColin Finck   data[start] = data[start] | (0x80 >> shift);
823c2c66affSColin Finck }
824c2c66affSColin Finck 
825c2c66affSColin Finck //******************************************************************************
flipover(uint8 * data)826c2c66affSColin Finck static void flipover(uint8 * data)
827c2c66affSColin Finck {
828c2c66affSColin Finck   uint8 adata[128];
829c2c66affSColin Finck   int index;
830c2c66affSColin Finck 
831c2c66affSColin Finck   if (data == 0)
832c2c66affSColin Finck   {
833c2c66affSColin Finck     return;
834c2c66affSColin Finck   }
835c2c66affSColin Finck   memcpy(adata, data, 128);
836c2c66affSColin Finck   for (index = 0; index <= 31; index++)
837c2c66affSColin Finck   {
838c2c66affSColin Finck     data[127 - (index * 4 + 3)] = adata[index * 4];
839c2c66affSColin Finck     data[127 - (index * 4 + 2)] = adata[index * 4 + 1];
840c2c66affSColin Finck     data[127 - (index * 4 + 1)] = adata[index * 4 + 2];
841c2c66affSColin Finck     data[127 - index * 4] = adata[index * 4 + 3];
842c2c66affSColin Finck   }
843c2c66affSColin Finck }
844c2c66affSColin Finck 
845c2c66affSColin Finck /*****************************************************************************/
ui_create_cursor(uint32 x,uint32 y,int width,int height,uint8 * andmask,uint8 * xormask)846c2c66affSColin Finck void * ui_create_cursor(uint32 x, uint32 y,
847c2c66affSColin Finck                         int width, int height,
848c2c66affSColin Finck                         uint8 * andmask, uint8 * xormask)
849c2c66affSColin Finck {
850c2c66affSColin Finck   uint8 adata[128];
851c2c66affSColin Finck   uint8 amask[128];
852c2c66affSColin Finck   GR_BITMAP * databitmap;
853c2c66affSColin Finck   GR_BITMAP * maskbitmap;
854c2c66affSColin Finck   GR_CURSOR_ID cursor;
855c2c66affSColin Finck   int i1, i2, bon, mon;
856c2c66affSColin Finck 
857c2c66affSColin Finck   if (width != 32 || height != 32)
858c2c66affSColin Finck   {
859c2c66affSColin Finck     return 0;
860c2c66affSColin Finck   }
861c2c66affSColin Finck   memset(adata, 0, 128);
862c2c66affSColin Finck   memset(amask, 0, 128);
863c2c66affSColin Finck   for (i1 = 0; i1 <= 31; i1++)
864c2c66affSColin Finck   {
865c2c66affSColin Finck     for (i2 = 0; i2 <= 31; i2++)
866c2c66affSColin Finck     {
867c2c66affSColin Finck       mon = is24on(xormask, i1, i2);
868c2c66affSColin Finck       bon = is1on(andmask, i1, i2);
869c2c66affSColin Finck       if (bon ^ mon) // xor
870c2c66affSColin Finck       {
871c2c66affSColin Finck         set1(adata, i1, i2);
872c2c66affSColin Finck         if (!mon)
873c2c66affSColin Finck         {
874c2c66affSColin Finck           set1(amask, i1, i2);
875c2c66affSColin Finck         }
876c2c66affSColin Finck       }
877c2c66affSColin Finck       if (mon)
878c2c66affSColin Finck       {
879c2c66affSColin Finck         set1(amask, i1, i2);
880c2c66affSColin Finck       }
881c2c66affSColin Finck     }
882c2c66affSColin Finck   }
883c2c66affSColin Finck   flipover(adata);
884c2c66affSColin Finck   flipover(amask);
885c2c66affSColin Finck   databitmap = ui_create_glyph(32, 32, adata);
886c2c66affSColin Finck   maskbitmap = ui_create_glyph(32, 32, amask);
887c2c66affSColin Finck   cursor = GrNewCursor(32, 32, x, y, 0xffffff, 0, databitmap, maskbitmap);
888c2c66affSColin Finck   ui_destroy_glyph(databitmap);
889c2c66affSColin Finck   ui_destroy_glyph(maskbitmap);
890c2c66affSColin Finck   return (void*)cursor;
891c2c66affSColin Finck }
892c2c66affSColin Finck 
893c2c66affSColin Finck /*****************************************************************************/
ui_destroy_cursor(void * cursor)894c2c66affSColin Finck void ui_destroy_cursor(void * cursor)
895c2c66affSColin Finck {
896c2c66affSColin Finck   GrDestroyCursor((GR_CURSOR_ID)cursor);
897c2c66affSColin Finck }
898c2c66affSColin Finck 
899c2c66affSColin Finck /*****************************************************************************/
ui_get_numlock_state(uint32 state)900c2c66affSColin Finck uint16 ui_get_numlock_state(uint32 state)
901c2c66affSColin Finck {
902c2c66affSColin Finck   return 0;
903c2c66affSColin Finck }
904c2c66affSColin Finck 
905c2c66affSColin Finck /*****************************************************************************/
read_keyboard_state(void)906c2c66affSColin Finck uint32 read_keyboard_state(void)
907c2c66affSColin Finck {
908c2c66affSColin Finck   return 0;
909c2c66affSColin Finck }
910c2c66affSColin Finck 
911c2c66affSColin Finck /*****************************************************************************/
ui_resize_window(void)912c2c66affSColin Finck void ui_resize_window(void)
913c2c66affSColin Finck {
914c2c66affSColin Finck }
915c2c66affSColin Finck 
916c2c66affSColin Finck /*****************************************************************************/
ui_begin_update(void)917c2c66affSColin Finck void ui_begin_update(void)
918c2c66affSColin Finck {
919c2c66affSColin Finck }
920c2c66affSColin Finck 
921c2c66affSColin Finck /*****************************************************************************/
ui_end_update(void)922c2c66affSColin Finck void ui_end_update(void)
923c2c66affSColin Finck {
924c2c66affSColin Finck }
925c2c66affSColin Finck 
926c2c66affSColin Finck /*****************************************************************************/
ui_polygon(uint8 opcode,uint8 fillmode,POINT * point,int npoints,BRUSH * brush,int bgcolor,int fgcolor)927c2c66affSColin Finck void ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
928c2c66affSColin Finck                 BRUSH * brush, int bgcolor, int fgcolor)
929c2c66affSColin Finck {
930c2c66affSColin Finck /* not used, turned off */
931c2c66affSColin Finck }
932c2c66affSColin Finck 
933c2c66affSColin Finck /*****************************************************************************/
ui_polyline(uint8 opcode,POINT * points,int npoints,PEN * pen)934c2c66affSColin Finck void ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
935c2c66affSColin Finck {
936c2c66affSColin Finck   int i, x, y, dx, dy;
937c2c66affSColin Finck 
938c2c66affSColin Finck   if (npoints > 0)
939c2c66affSColin Finck   {
940c2c66affSColin Finck     x = points[0].x;
941c2c66affSColin Finck     y = points[0].y;
942c2c66affSColin Finck     for (i = 1; i < npoints; i++)
943c2c66affSColin Finck     {
944c2c66affSColin Finck       dx = points[i].x;
945c2c66affSColin Finck       dy = points[i].y;
946c2c66affSColin Finck       ui_line(opcode, x, y, x + dx, y + dy, pen);
947c2c66affSColin Finck       x = x + dx;
948c2c66affSColin Finck       y = y + dy;
949c2c66affSColin Finck     }
950c2c66affSColin Finck   }
951c2c66affSColin Finck }
952c2c66affSColin Finck 
953c2c66affSColin Finck /*****************************************************************************/
ui_ellipse(uint8 opcode,uint8 fillmode,int x,int y,int cx,int cy,BRUSH * brush,int bgcolor,int fgcolor)954c2c66affSColin Finck void ui_ellipse(uint8 opcode, uint8 fillmode,
955c2c66affSColin Finck                 int x, int y, int cx, int cy,
956c2c66affSColin Finck                 BRUSH * brush, int bgcolor, int fgcolor)
957c2c66affSColin Finck {
958c2c66affSColin Finck /* not used, turned off */
959c2c66affSColin Finck }
960c2c66affSColin Finck 
961c2c66affSColin Finck /*****************************************************************************/
generate_random(uint8 * random)962c2c66affSColin Finck void generate_random(uint8 * random)
963c2c66affSColin Finck {
964c2c66affSColin Finck   memcpy(random, "12345678901234567890123456789012", 32);
965c2c66affSColin Finck }
966c2c66affSColin Finck 
967c2c66affSColin Finck /*****************************************************************************/
save_licence(uint8 * data,int length)968c2c66affSColin Finck void save_licence(uint8 * data, int length)
969c2c66affSColin Finck {
970c2c66affSColin Finck }
971c2c66affSColin Finck 
972c2c66affSColin Finck /*****************************************************************************/
load_licence(uint8 ** data)973c2c66affSColin Finck int load_licence(uint8 ** data)
974c2c66affSColin Finck {
975c2c66affSColin Finck   return 0;
976c2c66affSColin Finck }
977c2c66affSColin Finck 
978c2c66affSColin Finck /*****************************************************************************/
xrealloc(void * in,int size)979c2c66affSColin Finck void * xrealloc(void * in, int size)
980c2c66affSColin Finck {
981c2c66affSColin Finck   if (size < 1)
982c2c66affSColin Finck   {
983c2c66affSColin Finck     size = 1;
984c2c66affSColin Finck   }
985c2c66affSColin Finck   return realloc(in, size);
986c2c66affSColin Finck }
987c2c66affSColin Finck 
988c2c66affSColin Finck /*****************************************************************************/
xmalloc(int size)989c2c66affSColin Finck void * xmalloc(int size)
990c2c66affSColin Finck {
991c2c66affSColin Finck   return malloc(size);
992c2c66affSColin Finck }
993c2c66affSColin Finck 
994c2c66affSColin Finck /*****************************************************************************/
xfree(void * in)995c2c66affSColin Finck void xfree(void * in)
996c2c66affSColin Finck {
997c2c66affSColin Finck   if (in != 0)
998c2c66affSColin Finck   {
999c2c66affSColin Finck     free(in);
1000c2c66affSColin Finck   }
1001c2c66affSColin Finck }
1002c2c66affSColin Finck 
1003c2c66affSColin Finck /*****************************************************************************/
xstrdup(const char * s)1004c2c66affSColin Finck char * xstrdup(const char * s)
1005c2c66affSColin Finck {
1006c2c66affSColin Finck   char * mem = strdup(s);
1007c2c66affSColin Finck   if (mem == NULL)
1008c2c66affSColin Finck   {
1009c2c66affSColin Finck     perror("strdup");
1010c2c66affSColin Finck     exit(1);
1011c2c66affSColin Finck   }
1012c2c66affSColin Finck   return mem;
1013c2c66affSColin Finck }
1014c2c66affSColin Finck 
1015c2c66affSColin Finck /*****************************************************************************/
warning(char * format,...)1016c2c66affSColin Finck void warning(char * format, ...)
1017c2c66affSColin Finck {
1018c2c66affSColin Finck   va_list ap;
1019c2c66affSColin Finck 
1020c2c66affSColin Finck   fprintf(stderr, "WARNING: ");
1021c2c66affSColin Finck   va_start(ap, format);
1022c2c66affSColin Finck   vfprintf(stderr, format, ap);
1023c2c66affSColin Finck   va_end(ap);
1024c2c66affSColin Finck }
1025c2c66affSColin Finck 
1026c2c66affSColin Finck /*****************************************************************************/
unimpl(char * format,...)1027c2c66affSColin Finck void unimpl(char * format, ...)
1028c2c66affSColin Finck {
1029c2c66affSColin Finck   va_list ap;
1030c2c66affSColin Finck 
1031c2c66affSColin Finck   fprintf(stderr, "NOT IMPLEMENTED: ");
1032c2c66affSColin Finck   va_start(ap, format);
1033c2c66affSColin Finck   vfprintf(stderr, format, ap);
1034c2c66affSColin Finck   va_end(ap);
1035c2c66affSColin Finck }
1036c2c66affSColin Finck 
1037c2c66affSColin Finck /*****************************************************************************/
error(char * format,...)1038c2c66affSColin Finck void error(char * format, ...)
1039c2c66affSColin Finck {
1040c2c66affSColin Finck   va_list ap;
1041c2c66affSColin Finck 
1042c2c66affSColin Finck   fprintf(stderr, "ERROR: ");
1043c2c66affSColin Finck   va_start(ap, format);
1044c2c66affSColin Finck   vfprintf(stderr, format, ap);
1045c2c66affSColin Finck   va_end(ap);
1046c2c66affSColin Finck }
1047c2c66affSColin Finck 
1048c2c66affSColin Finck /*****************************************************************************/
rd_pstcache_mkdir(void)1049c2c66affSColin Finck int rd_pstcache_mkdir(void)
1050c2c66affSColin Finck {
1051c2c66affSColin Finck   return 0;
1052c2c66affSColin Finck }
1053c2c66affSColin Finck 
1054c2c66affSColin Finck /*****************************************************************************/
rd_open_file(char * filename)1055c2c66affSColin Finck int rd_open_file(char * filename)
1056c2c66affSColin Finck {
1057c2c66affSColin Finck   return 0;
1058c2c66affSColin Finck }
1059c2c66affSColin Finck 
1060c2c66affSColin Finck /*****************************************************************************/
rd_close_file(int fd)1061c2c66affSColin Finck void rd_close_file(int fd)
1062c2c66affSColin Finck {
1063c2c66affSColin Finck   return;
1064c2c66affSColin Finck }
1065c2c66affSColin Finck 
1066c2c66affSColin Finck /*****************************************************************************/
rd_read_file(int fd,void * ptr,int len)1067c2c66affSColin Finck int rd_read_file(int fd, void * ptr, int len)
1068c2c66affSColin Finck {
1069c2c66affSColin Finck   return 0;
1070c2c66affSColin Finck }
1071c2c66affSColin Finck 
1072c2c66affSColin Finck /*****************************************************************************/
rd_write_file(int fd,void * ptr,int len)1073c2c66affSColin Finck int rd_write_file(int fd, void * ptr, int len)
1074c2c66affSColin Finck {
1075c2c66affSColin Finck   return 0;
1076c2c66affSColin Finck }
1077c2c66affSColin Finck 
1078c2c66affSColin Finck /*****************************************************************************/
rd_lseek_file(int fd,int offset)1079c2c66affSColin Finck int rd_lseek_file(int fd, int offset)
1080c2c66affSColin Finck {
1081c2c66affSColin Finck   return 0;
1082c2c66affSColin Finck }
1083c2c66affSColin Finck 
1084c2c66affSColin Finck /*****************************************************************************/
rd_lock_file(int fd,int start,int len)1085c2c66affSColin Finck int rd_lock_file(int fd, int start, int len)
1086c2c66affSColin Finck {
1087c2c66affSColin Finck   return False;
1088c2c66affSColin Finck }
1089c2c66affSColin Finck 
1090c2c66affSColin Finck /*****************************************************************************/
1091c2c66affSColin Finck /*static int key(int ch, int flags)
1092c2c66affSColin Finck {
1093c2c66affSColin Finck   return (ch & 0xffff) | ((flags & 0xffff) << 16);
1094c2c66affSColin Finck }*/
1095c2c66affSColin Finck 
1096c2c66affSColin Finck /*****************************************************************************/
init_keys(void)1097c2c66affSColin Finck static void init_keys(void)
1098c2c66affSColin Finck {
1099c2c66affSColin Finck   memset(&g_keys, 0, sizeof(g_keys));
1100c2c66affSColin Finck   g_keys[0x01].ch1 = 27; /* esc */
1101c2c66affSColin Finck   g_keys[0x02].ch1 = '1';
1102c2c66affSColin Finck   g_keys[0x02].chs = '!';
1103c2c66affSColin Finck   g_keys[0x03].ch1 = '2';
1104c2c66affSColin Finck   g_keys[0x03].chs = '@';
1105c2c66affSColin Finck   g_keys[0x04].ch1 = '3';
1106c2c66affSColin Finck   g_keys[0x04].chs = '#';
1107c2c66affSColin Finck   g_keys[0x05].ch1 = '4';
1108c2c66affSColin Finck   g_keys[0x05].chs = '$';
1109c2c66affSColin Finck   g_keys[0x06].ch1 = '5';
1110c2c66affSColin Finck   g_keys[0x06].chs = '%';
1111c2c66affSColin Finck   g_keys[0x07].ch1 = '6';
1112c2c66affSColin Finck   g_keys[0x07].chs = '^';
1113c2c66affSColin Finck   g_keys[0x08].ch1 = '7';
1114c2c66affSColin Finck   g_keys[0x08].chs = '&';
1115c2c66affSColin Finck   g_keys[0x09].ch1 = '8';
1116c2c66affSColin Finck   g_keys[0x09].chs = '*';
1117c2c66affSColin Finck   g_keys[0x0a].ch1 = '9';
1118c2c66affSColin Finck   g_keys[0x0a].chs = '(';
1119c2c66affSColin Finck   g_keys[0x0b].ch1 = '0';
1120c2c66affSColin Finck   g_keys[0x0b].chs = ')';
1121c2c66affSColin Finck   g_keys[0x0c].ch1 = '-';
1122c2c66affSColin Finck   g_keys[0x0c].chs = '_';
1123c2c66affSColin Finck   g_keys[0x0d].ch1 = '=';
1124c2c66affSColin Finck   g_keys[0x0d].chs = '+';
1125c2c66affSColin Finck   g_keys[0x0e].ch1 = 8; /* backspace */
1126c2c66affSColin Finck   g_keys[0x0f].ch1 = 9; /* tab */
1127c2c66affSColin Finck   g_keys[0x10].ch1 = 'q';
1128c2c66affSColin Finck   g_keys[0x10].chs = 'Q';
1129c2c66affSColin Finck   g_keys[0x11].ch1 = 'w';
1130c2c66affSColin Finck   g_keys[0x11].chs = 'W';
1131c2c66affSColin Finck   g_keys[0x12].ch1 = 'e';
1132c2c66affSColin Finck   g_keys[0x12].chs = 'E';
1133c2c66affSColin Finck   g_keys[0x13].ch1 = 'r';
1134c2c66affSColin Finck   g_keys[0x13].chs = 'R';
1135c2c66affSColin Finck   g_keys[0x14].ch1 = 't';
1136c2c66affSColin Finck   g_keys[0x14].chs = 'T';
1137c2c66affSColin Finck   g_keys[0x15].ch1 = 'y';
1138c2c66affSColin Finck   g_keys[0x15].chs = 'Y';
1139c2c66affSColin Finck   g_keys[0x16].ch1 = 'u';
1140c2c66affSColin Finck   g_keys[0x16].chs = 'U';
1141c2c66affSColin Finck   g_keys[0x17].ch1 = 'i';
1142c2c66affSColin Finck   g_keys[0x17].chs = 'I';
1143c2c66affSColin Finck   g_keys[0x18].ch1 = 'o';
1144c2c66affSColin Finck   g_keys[0x18].chs = 'O';
1145c2c66affSColin Finck   g_keys[0x19].ch1 = 'p';
1146c2c66affSColin Finck   g_keys[0x19].chs = 'P';
1147c2c66affSColin Finck   g_keys[0x1a].ch1 = '[';
1148c2c66affSColin Finck   g_keys[0x1a].chs = '{';
1149c2c66affSColin Finck   g_keys[0x1b].ch1 = ']';
1150c2c66affSColin Finck   g_keys[0x1b].chs = '}';
1151c2c66affSColin Finck   g_keys[0x1c].ch2 = 13; /* enter */
1152c2c66affSColin Finck   g_keys[0x1d].ch1 = 63533; /* left control */
1153c2c66affSColin Finck   g_keys[0x1d].ch2 = 63534; /* right control */
1154c2c66affSColin Finck   g_keys[0x1e].ch1 = 'a';
1155c2c66affSColin Finck   g_keys[0x1e].chs = 'A';
1156c2c66affSColin Finck   g_keys[0x1f].ch1 = 's';
1157c2c66affSColin Finck   g_keys[0x1f].chs = 'S';
1158c2c66affSColin Finck   g_keys[0x20].ch1 = 'd';
1159c2c66affSColin Finck   g_keys[0x20].chs = 'D';
1160c2c66affSColin Finck   g_keys[0x21].ch1 = 'f';
1161c2c66affSColin Finck   g_keys[0x21].chs = 'F';
1162c2c66affSColin Finck   g_keys[0x22].ch1 = 'g';
1163c2c66affSColin Finck   g_keys[0x22].chs = 'G';
1164c2c66affSColin Finck   g_keys[0x23].ch1 = 'h';
1165c2c66affSColin Finck   g_keys[0x23].chs = 'H';
1166c2c66affSColin Finck   g_keys[0x24].ch1 = 'j';
1167c2c66affSColin Finck   g_keys[0x24].chs = 'J';
1168c2c66affSColin Finck   g_keys[0x25].ch1 = 'k';
1169c2c66affSColin Finck   g_keys[0x25].chs = 'K';
1170c2c66affSColin Finck   g_keys[0x26].ch1 = 'l';
1171c2c66affSColin Finck   g_keys[0x26].chs = 'L';
1172c2c66affSColin Finck   g_keys[0x27].ch1 = ';';
1173c2c66affSColin Finck   g_keys[0x27].chs = ':';
1174c2c66affSColin Finck   g_keys[0x28].ch1 = '\'';
1175c2c66affSColin Finck   g_keys[0x28].chs = '"';
1176c2c66affSColin Finck   g_keys[0x29].ch1 = '`';
1177c2c66affSColin Finck   g_keys[0x29].chs = '~';
1178c2c66affSColin Finck   g_keys[0x2a].ch1 = 63531; /* left shift */
1179c2c66affSColin Finck   g_keys[0x2b].ch1 = '\\';
1180c2c66affSColin Finck   g_keys[0x2c].ch1 = 'z';
1181c2c66affSColin Finck   g_keys[0x2c].chs = 'Z';
1182c2c66affSColin Finck   g_keys[0x2d].ch1 = 'x';
1183c2c66affSColin Finck   g_keys[0x2d].chs = 'X';
1184c2c66affSColin Finck   g_keys[0x2e].ch1 = 'c';
1185c2c66affSColin Finck   g_keys[0x2e].chs = 'C';
1186c2c66affSColin Finck   g_keys[0x2f].ch1 = 'v';
1187c2c66affSColin Finck   g_keys[0x2f].chs = 'V';
1188c2c66affSColin Finck   g_keys[0x30].ch1 = 'b';
1189c2c66affSColin Finck   g_keys[0x30].chs = 'B';
1190c2c66affSColin Finck   g_keys[0x31].ch1 = 'n';
1191c2c66affSColin Finck   g_keys[0x31].chs = 'N';
1192c2c66affSColin Finck   g_keys[0x32].ch1 = 'm';
1193c2c66affSColin Finck   g_keys[0x32].chs = 'M';
1194c2c66affSColin Finck   g_keys[0x33].ch1 = ',';
1195c2c66affSColin Finck   g_keys[0x33].chs = '<';
1196c2c66affSColin Finck   g_keys[0x34].ch1 = '.';
1197c2c66affSColin Finck   g_keys[0x34].chs = '>';
1198c2c66affSColin Finck   g_keys[0x35].ch1 = '/';
1199c2c66affSColin Finck   g_keys[0x35].ch2 = 63509;
1200c2c66affSColin Finck   g_keys[0x35].chs = '?';
1201c2c66affSColin Finck   g_keys[0x36].ch1 = 63532; /* right shift */
1202c2c66affSColin Finck   g_keys[0x37].ch1 = '*'; /* star on keypad */
1203c2c66affSColin Finck   g_keys[0x37].ch2 = 63510; /* star on keypad */
1204c2c66affSColin Finck   g_keys[0x38].ch1 = 63535; /* alt */
1205c2c66affSColin Finck   g_keys[0x38].ch2 = 63536; /* alt */
1206c2c66affSColin Finck   g_keys[0x39].ch1 = ' ';
1207c2c66affSColin Finck   g_keys[0x3a].ch1 = 0; /* caps lock */
1208c2c66affSColin Finck   g_keys[0x3b].ch1 = 63515; /* f1 */
1209c2c66affSColin Finck   g_keys[0x3c].ch1 = 63516; /* f2 */
1210c2c66affSColin Finck   g_keys[0x3d].ch1 = 63517; /* f3 */
1211c2c66affSColin Finck   g_keys[0x3e].ch1 = 63518; /* f4 */
1212c2c66affSColin Finck   g_keys[0x3f].ch1 = 63519; /* f5 */
1213c2c66affSColin Finck   g_keys[0x40].ch1 = 63520; /* f6 */
1214c2c66affSColin Finck   g_keys[0x41].ch1 = 63521; /* f7 */
1215c2c66affSColin Finck   g_keys[0x42].ch1 = 63522; /* f8 */
1216c2c66affSColin Finck   g_keys[0x43].ch1 = 63523; /* f9 */
1217c2c66affSColin Finck   g_keys[0x44].ch1 = 63524; /* f10 */
1218c2c66affSColin Finck   g_keys[0x45].ch1 = 0; /* num lock */
1219c2c66affSColin Finck   g_keys[0x46].ch1 = 0; /* scroll lock */
1220c2c66affSColin Finck   g_keys[0x47].ch1 = 63505; /* home */
1221c2c66affSColin Finck   g_keys[0x47].ch2 = 63494; /* home */
1222c2c66affSColin Finck   g_keys[0x48].ch1 = 63490; /* arrow up */
1223c2c66affSColin Finck   g_keys[0x48].ch2 = 63506; /* arrow up */
1224c2c66affSColin Finck   g_keys[0x49].ch1 = 63507; /* page up */
1225c2c66affSColin Finck   g_keys[0x49].ch2 = 63496; /* page up */
1226c2c66affSColin Finck   g_keys[0x4a].ch1 = '-'; /* -(minus) on keypad */
1227c2c66affSColin Finck   g_keys[0x4a].ch2 = 63511; /* -(minus) on keypad */
1228c2c66affSColin Finck   g_keys[0x4b].ch1 = 63502; /* arrow left */
1229c2c66affSColin Finck   g_keys[0x4b].ch2 = 63488; /* arrow left */
1230c2c66affSColin Finck   g_keys[0x4c].ch1 = 63503; /* middle(5 key) on keypad */
1231c2c66affSColin Finck   g_keys[0x4d].ch1 = 63504; /* arrow right */
1232c2c66affSColin Finck   g_keys[0x4d].ch2 = 63489; /* arrow right */
1233c2c66affSColin Finck   g_keys[0x4e].ch1 = '+'; /* +(plus) on keypad */
1234c2c66affSColin Finck   g_keys[0x4e].ch2 = 63512; /* +(plus) on keypad */
1235c2c66affSColin Finck   g_keys[0x4f].ch1 = 63499; /* end */
1236c2c66affSColin Finck   g_keys[0x4f].ch2 = 63495; /* end */
1237c2c66affSColin Finck   g_keys[0x50].ch1 = 63500; /* arrow down */
1238c2c66affSColin Finck   g_keys[0x50].ch2 = 63491; /* arrow down */
1239c2c66affSColin Finck   g_keys[0x51].ch1 = 63501; /* page down */
1240c2c66affSColin Finck   g_keys[0x51].ch2 = 63497; /* page down */
1241c2c66affSColin Finck   g_keys[0x52].ch1 = 63498; /* insert */
1242c2c66affSColin Finck   g_keys[0x52].ch2 = 63492; /* insert */
1243c2c66affSColin Finck   g_keys[0x53].ch1 = 63508; /* delete */
1244c2c66affSColin Finck   g_keys[0x53].ch2 = 63493; /* delete */
1245c2c66affSColin Finck   g_keys[0x54].ch1 = 63525; /* f11 */
1246*782bf0e3SRafał Mikrut   g_keys[0x55].ch1 = 63527; /* f12 */
1247c2c66affSColin Finck }
1248c2c66affSColin Finck 
1249c2c66affSColin Finck /*****************************************************************************/
1250c2c66affSColin Finck /* returns 0 if found key */
get_sc(GR_EVENT_KEYSTROKE * event_keystroke,int * sc,int * ec)1251c2c66affSColin Finck static int get_sc(GR_EVENT_KEYSTROKE * event_keystroke, int * sc, int * ec)
1252c2c66affSColin Finck {
1253c2c66affSColin Finck   int i;
1254c2c66affSColin Finck 
1255c2c66affSColin Finck   //printf("%d %d\n", event_keystroke->ch, event_keystroke->modifiers);
1256c2c66affSColin Finck   *sc = 0;
1257c2c66affSColin Finck   *ec = 0;
1258c2c66affSColin Finck   for (i = 0; i < 256; i++)
1259c2c66affSColin Finck   {
1260c2c66affSColin Finck     if (event_keystroke->modifiers & 1) /* shift is down */
1261c2c66affSColin Finck     {
1262c2c66affSColin Finck       if (event_keystroke->ch == g_keys[i].chs)
1263c2c66affSColin Finck       {
1264c2c66affSColin Finck         *sc = i;
1265c2c66affSColin Finck         break;
1266c2c66affSColin Finck       }
1267c2c66affSColin Finck     }
1268c2c66affSColin Finck     if (event_keystroke->ch == g_keys[i].ch1 ||
1269c2c66affSColin Finck         event_keystroke->ch == g_keys[i].ch2 ||
1270c2c66affSColin Finck         event_keystroke->ch == g_keys[i].ch3)
1271c2c66affSColin Finck     {
1272c2c66affSColin Finck       *sc = i;
1273c2c66affSColin Finck       break;
1274c2c66affSColin Finck     }
1275c2c66affSColin Finck   }
1276c2c66affSColin Finck   if (*sc == 0)
1277c2c66affSColin Finck   {
1278c2c66affSColin Finck     return 1;
1279c2c66affSColin Finck   }
1280c2c66affSColin Finck   else
1281c2c66affSColin Finck   {
1282c2c66affSColin Finck     return 0;
1283c2c66affSColin Finck   }
1284c2c66affSColin Finck }
1285c2c66affSColin Finck 
1286c2c66affSColin Finck /*****************************************************************************/
process_keystroke(GR_EVENT_KEYSTROKE * event_keystroke,int down)1287c2c66affSColin Finck void static process_keystroke(GR_EVENT_KEYSTROKE * event_keystroke, int down)
1288c2c66affSColin Finck {
1289c2c66affSColin Finck   int sc, ec;
1290c2c66affSColin Finck 
1291c2c66affSColin Finck   if (get_sc(event_keystroke, &sc, &ec) == 0)
1292c2c66affSColin Finck   {
1293c2c66affSColin Finck     if (down)
1294c2c66affSColin Finck     {
1295c2c66affSColin Finck       rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS, sc, ec);
1296c2c66affSColin Finck     }
1297c2c66affSColin Finck     else
1298c2c66affSColin Finck     {
1299c2c66affSColin Finck       rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, sc, ec);
1300c2c66affSColin Finck     }
1301c2c66affSColin Finck   }
1302c2c66affSColin Finck }
1303c2c66affSColin Finck 
1304c2c66affSColin Finck /*****************************************************************************/
nanox_event(GR_EVENT * ev)1305c2c66affSColin Finck void nanox_event(GR_EVENT * ev)
1306c2c66affSColin Finck {
1307c2c66affSColin Finck   GR_EVENT_MOUSE * event_mouse;
1308c2c66affSColin Finck   GR_EVENT_BUTTON * event_button;
1309c2c66affSColin Finck   GR_EVENT_FDINPUT * event_fdinput;
1310c2c66affSColin Finck   GR_EVENT_KEYSTROKE * event_keystroke;
1311c2c66affSColin Finck 
1312c2c66affSColin Finck   do
1313c2c66affSColin Finck   {
1314c2c66affSColin Finck     if (ev->type == GR_EVENT_TYPE_FDINPUT) /* 12 */
1315c2c66affSColin Finck     {
1316c2c66affSColin Finck       event_fdinput = (GR_EVENT_FDINPUT *) ev;
1317c2c66affSColin Finck       if (event_fdinput->fd == g_sck)
1318c2c66affSColin Finck       {
1319c2c66affSColin Finck         if (!rdp_loop(&g_deactivated, &g_ext_disc_reason))
1320c2c66affSColin Finck         {
1321c2c66affSColin Finck           fprintf(stderr, "rdp_loop in nanox_event exit codes %d %d\n",
1322c2c66affSColin Finck                   g_deactivated, g_ext_disc_reason);
1323c2c66affSColin Finck           exit(1);
1324c2c66affSColin Finck         }
1325c2c66affSColin Finck       }
1326c2c66affSColin Finck     }
1327c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_BUTTON_DOWN) /* 2 */
1328c2c66affSColin Finck     {
1329c2c66affSColin Finck       event_button = (GR_EVENT_BUTTON *) ev;
1330c2c66affSColin Finck       if (event_button->changebuttons & 4) /* left */
1331c2c66affSColin Finck       {
1332c2c66affSColin Finck         rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
1333c2c66affSColin Finck                        event_button->x, event_button->y);
1334c2c66affSColin Finck       }
1335c2c66affSColin Finck       else if (event_button->changebuttons & 1) /* right */
1336c2c66affSColin Finck       {
1337c2c66affSColin Finck         rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
1338c2c66affSColin Finck                        event_button->x, event_button->y);
1339c2c66affSColin Finck       }
1340c2c66affSColin Finck     }
1341c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_BUTTON_UP) /* 3 */
1342c2c66affSColin Finck     {
1343c2c66affSColin Finck       event_button = (GR_EVENT_BUTTON *) ev;
1344c2c66affSColin Finck       if (event_button->changebuttons & 4) /* left */
1345c2c66affSColin Finck       {
1346c2c66affSColin Finck         rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
1347c2c66affSColin Finck                        event_button->x, event_button->y);
1348c2c66affSColin Finck       }
1349c2c66affSColin Finck       else if (event_button->changebuttons & 1) /* right */
1350c2c66affSColin Finck       {
1351c2c66affSColin Finck         rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2,
1352c2c66affSColin Finck                        event_button->x, event_button->y);
1353c2c66affSColin Finck       }
1354c2c66affSColin Finck     }
1355c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_MOUSE_MOTION) /* 6 */
1356c2c66affSColin Finck     {
1357c2c66affSColin Finck       event_mouse = (GR_EVENT_MOUSE *) ev;
1358c2c66affSColin Finck       rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE,
1359c2c66affSColin Finck                      event_mouse->x, event_mouse->y);
1360c2c66affSColin Finck     }
1361c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_MOUSE_POSITION) /* 7 */
1362c2c66affSColin Finck     {
1363c2c66affSColin Finck       /* use GR_EVENT_TYPE_MOUSE_MOTION */
1364c2c66affSColin Finck     }
1365c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_KEY_DOWN) /* 8 */
1366c2c66affSColin Finck     {
1367c2c66affSColin Finck       event_keystroke = (GR_EVENT_KEYSTROKE *) ev;
1368c2c66affSColin Finck       process_keystroke(event_keystroke, 1);
1369c2c66affSColin Finck     }
1370c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_KEY_UP) /* 9 */
1371c2c66affSColin Finck     {
1372c2c66affSColin Finck       event_keystroke = (GR_EVENT_KEYSTROKE *) ev;
1373c2c66affSColin Finck       process_keystroke(event_keystroke, 0);
1374c2c66affSColin Finck     }
1375c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_FOCUS_IN) /* 10 */
1376c2c66affSColin Finck     {
1377c2c66affSColin Finck     }
1378c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_FOCUS_OUT) /* 11 */
1379c2c66affSColin Finck     {
1380c2c66affSColin Finck     }
1381c2c66affSColin Finck     else if (ev->type == GR_EVENT_TYPE_UPDATE) /* 13 */
1382c2c66affSColin Finck     {
1383c2c66affSColin Finck     }
1384c2c66affSColin Finck     GrCheckNextEvent(ev);
1385c2c66affSColin Finck   } while (ev->type != GR_EVENT_TYPE_NONE);
1386c2c66affSColin Finck }
1387c2c66affSColin Finck 
1388c2c66affSColin Finck /*****************************************************************************/
get_username_and_hostname(void)1389c2c66affSColin Finck static void get_username_and_hostname(void)
1390c2c66affSColin Finck {
1391c2c66affSColin Finck   char fullhostname[64];
1392c2c66affSColin Finck   char * p;
1393c2c66affSColin Finck   struct passwd * pw;
1394c2c66affSColin Finck 
1395c2c66affSColin Finck   STRNCPY(g_username, "unknown", sizeof(g_username));
1396c2c66affSColin Finck   STRNCPY(g_hostname, "unknown", sizeof(g_hostname));
1397c2c66affSColin Finck   pw = getpwuid(getuid());
1398c2c66affSColin Finck   if (pw != NULL && pw->pw_name != NULL)
1399c2c66affSColin Finck   {
1400c2c66affSColin Finck     STRNCPY(g_username, pw->pw_name, sizeof(g_username));
1401c2c66affSColin Finck   }
1402c2c66affSColin Finck   if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
1403c2c66affSColin Finck   {
1404c2c66affSColin Finck     p = strchr(fullhostname, '.');
1405c2c66affSColin Finck     if (p != NULL)
1406c2c66affSColin Finck     {
1407c2c66affSColin Finck       *p = 0;
1408c2c66affSColin Finck     }
1409c2c66affSColin Finck     STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
1410c2c66affSColin Finck   }
1411c2c66affSColin Finck }
1412c2c66affSColin Finck /*****************************************************************************/
out_params(void)1413c2c66affSColin Finck static void out_params(void)
1414c2c66affSColin Finck {
1415c2c66affSColin Finck   fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
1416c2c66affSColin Finck   fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
1417c2c66affSColin Finck   fprintf(stderr, "nanox uiport by Jay Sorg\n");
1418c2c66affSColin Finck   fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
1419c2c66affSColin Finck   fprintf(stderr, "Usage: nanoxrdesktop [options] server\n");
1420c2c66affSColin Finck   fprintf(stderr, "   -u: user name\n");
1421c2c66affSColin Finck   fprintf(stderr, "   -n: client hostname\n");
1422c2c66affSColin Finck   fprintf(stderr, "   -p: password\n");
1423c2c66affSColin Finck   fprintf(stderr, "   -d: domain\n");
1424c2c66affSColin Finck   fprintf(stderr, "   -s: shell\n");
1425c2c66affSColin Finck   fprintf(stderr, "   -c: working directory\n");
1426c2c66affSColin Finck   fprintf(stderr, "\n");
1427c2c66affSColin Finck }
1428c2c66affSColin Finck 
1429c2c66affSColin Finck /*****************************************************************************/
parse_parameters(int in_argc,char ** in_argv)1430c2c66affSColin Finck static int parse_parameters(int in_argc, char ** in_argv)
1431c2c66affSColin Finck {
1432c2c66affSColin Finck   int i;
1433c2c66affSColin Finck 
1434c2c66affSColin Finck   if (in_argc <= 1)
1435c2c66affSColin Finck   {
1436c2c66affSColin Finck     out_params();
1437c2c66affSColin Finck     return 0;
1438c2c66affSColin Finck   }
1439c2c66affSColin Finck   for (i = 1; i < in_argc; i++)
1440c2c66affSColin Finck   {
1441c2c66affSColin Finck     strcpy(g_servername, in_argv[i]);
1442c2c66affSColin Finck     if (strcmp(in_argv[i], "-h") == 0)
1443c2c66affSColin Finck     {
1444c2c66affSColin Finck       out_params();
1445c2c66affSColin Finck       return 0;
1446c2c66affSColin Finck     }
1447c2c66affSColin Finck     else if (strcmp(in_argv[i], "-n") == 0)
1448c2c66affSColin Finck     {
1449c2c66affSColin Finck       STRNCPY(g_hostname, in_argv[i + 1], sizeof(g_hostname));
1450c2c66affSColin Finck     }
1451c2c66affSColin Finck     else if (strcmp(in_argv[i], "-u") == 0)
1452c2c66affSColin Finck     {
1453c2c66affSColin Finck       STRNCPY(g_username, in_argv[i + 1], sizeof(g_username));
1454c2c66affSColin Finck     }
1455c2c66affSColin Finck     else if (strcmp(in_argv[i], "-p") == 0)
1456c2c66affSColin Finck     {
1457c2c66affSColin Finck       STRNCPY(g_password, in_argv[i + 1], sizeof(g_password));
1458c2c66affSColin Finck       g_flags |= RDP_LOGON_AUTO;
1459c2c66affSColin Finck       i++;
1460c2c66affSColin Finck     }
1461c2c66affSColin Finck     else if (strcmp(in_argv[i], "-d") == 0)
1462c2c66affSColin Finck     {
1463c2c66affSColin Finck       STRNCPY(g_domain, in_argv[i + 1], sizeof(g_domain));
1464c2c66affSColin Finck       i++;
1465c2c66affSColin Finck     }
1466c2c66affSColin Finck     else if (strcmp(in_argv[i], "-s") == 0)
1467c2c66affSColin Finck     {
1468c2c66affSColin Finck       STRNCPY(g_shell, in_argv[i + 1], sizeof(g_shell));
1469c2c66affSColin Finck       i++;
1470c2c66affSColin Finck     }
1471c2c66affSColin Finck     else if (strcmp(in_argv[i], "-c") == 0)
1472c2c66affSColin Finck     {
1473c2c66affSColin Finck       STRNCPY(g_directory, in_argv[i + 1], sizeof(g_directory));
1474c2c66affSColin Finck       i++;
1475c2c66affSColin Finck     }
1476c2c66affSColin Finck   }
1477c2c66affSColin Finck   return 1;
1478c2c66affSColin Finck }
1479c2c66affSColin Finck 
1480c2c66affSColin Finck /*****************************************************************************/
main(int in_argc,char ** in_argv)1481c2c66affSColin Finck int main(int in_argc, char ** in_argv)
1482c2c66affSColin Finck {
1483c2c66affSColin Finck   get_username_and_hostname();
1484c2c66affSColin Finck   /* read command line options */
1485c2c66affSColin Finck   if (!parse_parameters(in_argc, in_argv))
1486c2c66affSColin Finck   {
1487c2c66affSColin Finck     exit(0);
1488c2c66affSColin Finck   }
1489c2c66affSColin Finck   /* connect to server */
1490c2c66affSColin Finck   if (GrOpen() < 0)
1491c2c66affSColin Finck   {
1492c2c66affSColin Finck     fprintf(stderr, "Couldn't connect to Nano-X server\n");
1493c2c66affSColin Finck     exit(1);
1494c2c66affSColin Finck   }
1495c2c66affSColin Finck   GrGetScreenInfo(&g_screen_info);
1496c2c66affSColin Finck   g_bpp = g_screen_info.bpp;
1497c2c66affSColin Finck   g_Bpp = (g_screen_info.bpp + 7) / 8;
1498c2c66affSColin Finck   g_width = g_screen_info.vs_width;
1499c2c66affSColin Finck   g_height = g_screen_info.vs_height;
1500c2c66affSColin Finck   g_clip.x = 0;
1501c2c66affSColin Finck   g_clip.y = 0;
1502c2c66affSColin Finck   g_clip.width = g_width;
1503c2c66affSColin Finck   g_clip.height = g_height;
1504c2c66affSColin Finck   if (!((g_bpp == 32 && g_server_bpp == 16) ||
1505c2c66affSColin Finck         (g_bpp == 16 && g_server_bpp == 16)))
1506c2c66affSColin Finck   {
1507c2c66affSColin Finck     fprintf(stderr, "unsupported bpp, server = %d, client = %d\n",
1508c2c66affSColin Finck             g_server_bpp, g_bpp);
1509c2c66affSColin Finck     GrClose();
1510c2c66affSColin Finck     exit(0);
1511c2c66affSColin Finck   }
1512c2c66affSColin Finck   init_keys();
1513c2c66affSColin Finck   /* connect to server */
1514c2c66affSColin Finck   if (!rdp_connect(g_servername, g_flags, g_domain, g_password, g_shell,
1515c2c66affSColin Finck                    g_directory))
1516c2c66affSColin Finck   {
1517c2c66affSColin Finck     fprintf(stderr, "Error connecting\n");
1518c2c66affSColin Finck     GrClose();
1519c2c66affSColin Finck     exit(1);
1520c2c66affSColin Finck   }
1521c2c66affSColin Finck   /* create window */
1522c2c66affSColin Finck   g_wnd = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, g_width, g_height, 0, 0, 0);
1523c2c66affSColin Finck   /* show window */
1524c2c66affSColin Finck   GrMapWindow(g_wnd);
1525c2c66affSColin Finck   /* create graphic context */
1526c2c66affSColin Finck   g_gc = GrNewGC();
1527c2c66affSColin Finck   g_gc_clean = GrNewGC();
1528c2c66affSColin Finck   /* clear screen */
1529c2c66affSColin Finck   GrSetGCForeground(g_gc, 0);
1530c2c66affSColin Finck   GrFillRect(g_wnd, g_gc, 0, 0, g_width, g_height);
1531c2c66affSColin Finck   /* create null cursor */
1532c2c66affSColin Finck   g_null_cursor = (GR_CURSOR_ID)ui_create_cursor(0, 0, 32, 32, 0, 0);
1533c2c66affSColin Finck   /* register callbacks, set mask, and run main loop */
1534c2c66affSColin Finck   GrSelectEvents(g_wnd, -1); /* all events */
1535c2c66affSColin Finck   GrRegisterInput(g_sck);
1536c2c66affSColin Finck   GrMainLoop(nanox_event);
1537c2c66affSColin Finck   /* free null cursor */
1538c2c66affSColin Finck   ui_destroy_cursor((void*)g_null_cursor);
1539c2c66affSColin Finck   /* free graphic context */
1540c2c66affSColin Finck   GrDestroyGC(g_gc);
1541c2c66affSColin Finck   GrDestroyGC(g_gc_clean);
1542c2c66affSColin Finck   /* free window */
1543c2c66affSColin Finck   GrDestroyWindow(g_wnd);
1544c2c66affSColin Finck   /* close connection */
1545c2c66affSColin Finck   GrClose();
1546c2c66affSColin Finck   return 0;
1547c2c66affSColin Finck }
1548