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