/[rdesktop]/sourceforge.net/trunk/rdesktop/uiports/nanoxwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/uiports/nanoxwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 892 - (show annotations)
Sat Apr 23 20:52:51 2005 UTC (19 years, 1 month ago) by jsorg71
File MIME type: text/plain
File size: 39611 byte(s)
much work on nanox port

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26