[NTOSKRNL]
[reactos.git] / base / applications / mstsc / uimain.c
1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Main ui file
4 Copyright (C) Jay Sorg 2006
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 along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "precomp.h"
22
23 char g_username[256] = "";
24 char g_hostname[256] = "";
25 char g_servername[256] = "";
26 char g_password[256] = "";
27 char g_shell[256] = "";
28 char g_directory[256] = "";
29 char g_domain[256] = "";
30 BOOL g_desktop_save = False; /* desktop save order */
31 BOOL g_polygon_ellipse_orders = False; /* polygon / ellipse orders */
32 BOOL g_bitmap_compression = True;
33 uint32 g_rdp5_performanceflags =
34 RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
35 BOOL g_bitmap_cache_persist_enable = False;
36 BOOL g_bitmap_cache_precache = True;
37 BOOL g_bitmap_cache = True;
38 BOOL g_encryption = True;
39 int g_server_depth = 8;
40 BOOL g_use_rdp5 = False;
41 int g_width = 800;
42 int g_height = 600;
43 uint32 g_keylayout = 0x409; /* Defaults to US keyboard layout */
44 int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */
45 int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */
46 int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */
47 BOOL g_console_session = False;
48
49 /* can't be static, hardware file or bsops need these */
50 int g_tcp_sck = 0;
51 int pal_entries[256];
52
53 /* Session Directory redirection */
54 BOOL g_redirect = False;
55 char g_redirect_server[64];
56 char g_redirect_domain[16];
57 char g_redirect_password[64];
58 char g_redirect_username[64];
59 char g_redirect_cookie[128];
60 uint32 g_redirect_flags = 0;
61
62 extern int g_tcp_port_rdp;
63
64 static int g_deactivated = 0;
65 static uint32 g_ext_disc_reason = 0;
66
67 struct bitmap
68 {
69 uint8 * data;
70 uint32 width;
71 uint32 height;
72 };
73
74 /* in ui specific file eg win32.c, qt.c, df.c, ... */
75 int
76 mi_create_window(void);
77 int
78 mi_main_loop(void);
79 void
80 mi_error(char * msg);
81 void
82 mi_warning(char * msg);
83 void
84 mi_paint_rect(char * data, int width, int height, int x, int y, int cx, int cy);
85 void
86 mi_begin_update(void);
87 void
88 mi_end_update(void);
89 void
90 mi_fill_rect(int x, int y, int cx, int cy, int colour);
91 void
92 mi_screen_copy(int x, int y, int cx, int cy, int srcx, int srcy);
93 void
94 mi_set_clip(int x, int y, int cx, int cy);
95 void
96 mi_reset_clip(void);
97 void
98 mi_line(int x1, int y1, int x2, int y2, int colour);
99 void*
100 mi_create_cursor(unsigned int x, unsigned int y,
101 int width, int height,
102 unsigned char * andmask, unsigned char * xormask);
103
104
105 void
106 mi_destroy_cursor(void * cursor);
107 void
108 mi_set_cursor(void * cursor);
109 void
110 mi_set_null_cursor(void);
111 int
112 mi_read_keyboard_state(void);
113
114 /*****************************************************************************/
115 /* put part of the screen from the backing store to the display */
116 void
117 ui_invalidate(int x, int y, int cx, int cy)
118 {
119 char * data;
120
121 if (cx < 1 || cy < 1)
122 {
123 return;
124 }
125 if (bs_warp_coords(&x, &y, &cx, &cy, 0, 0))
126 {
127 cx = (cx + 3) & ~3;
128 data = (char *) xmalloc(cx * cy * 4);
129 bs_copy_box(data, x, y, cx, cy, cx * ((g_server_depth + 7) / 8));
130 mi_paint_rect(data, cx, cy, x, y, cx, cy);
131 xfree(data);
132 }
133 }
134
135 /*****************************************************************************/
136 void
137 ui_bell(void)
138 {
139 }
140
141 /*****************************************************************************/
142 int
143 ui_select(int in)
144 {
145 if (g_tcp_sck == 0)
146 {
147 g_tcp_sck = in;
148 }
149 return 1;
150 }
151
152 /*****************************************************************************/
153 void *
154 ui_create_cursor(uint32 x, uint32 y,
155 int width, int height,
156 uint8 * andmask, uint8 * xormask)
157 {
158 int i;
159 int j;
160 char am[32 * 4];
161 char xm[32 * 4];
162
163 if (width != 32 || height != 32)
164 {
165 return 0;
166 }
167 memset(am, 0, 32 * 4);
168 memset(xm, 0, 32 * 4);
169 for (i = 0; i < 32; i++)
170 {
171 for (j = 0; j < 32; j++)
172 {
173 if (bs_is_pixel_on((char *)andmask, j, i, 32, 1))
174 {
175 bs_set_pixel_on(am, j, 31 - i, 32, 1, 1);
176 }
177 if (bs_is_pixel_on((char *)xormask, j, i, 32, 24))
178 {
179 bs_set_pixel_on(xm, j, 31 - i, 32, 1, 1);
180 }
181 }
182 }
183 return (void *) mi_create_cursor(x, y, width, height, (unsigned char *)am, (unsigned char *)xm);
184 }
185
186 /*****************************************************************************/
187 void
188 ui_destroy_cursor(void * cursor)
189 {
190 mi_destroy_cursor(cursor);
191 }
192
193 /*****************************************************************************/
194 void
195 ui_set_cursor(void * cursor)
196 {
197 mi_set_cursor(cursor);
198 }
199
200 /*****************************************************************************/
201 void
202 ui_set_null_cursor(void)
203 {
204 mi_set_null_cursor();
205 }
206
207 /*****************************************************************************/
208 void *
209 ui_create_glyph(int width, int height, uint8 * data)
210 {
211 int i;
212 int j;
213 char * glyph_data;
214 struct bitmap * the_glyph;
215
216 glyph_data = (char *) xmalloc(width * height);
217 memset(glyph_data, 0, width * height);
218 the_glyph = (struct bitmap *) xmalloc(sizeof(struct bitmap));
219 memset(the_glyph, 0, sizeof(struct bitmap));
220 the_glyph->width = width;
221 the_glyph->height = height;
222 the_glyph->data = (uint8 *)glyph_data;
223 for (i = 0; i < height; i++)
224 {
225 for (j = 0; j < width; j++)
226 {
227 if (bs_is_pixel_on((char *)data, j, i, width, 1))
228 {
229 bs_set_pixel_on(glyph_data, j, i, width, 8, 255);
230 }
231 }
232 }
233 return the_glyph;
234 }
235
236 /*****************************************************************************/
237 void
238 ui_destroy_glyph(void * glyph)
239 {
240 struct bitmap * the_glyph;
241
242 the_glyph = glyph;
243 if (the_glyph != 0)
244 {
245 xfree(the_glyph->data);
246 }
247 xfree(the_glyph);
248 }
249
250 /*****************************************************************************/
251 void *
252 ui_create_bitmap(int width, int height, uint8 * data)
253 {
254 struct bitmap * b;
255 int size;
256
257 size = width * height * ((g_server_depth + 7) / 8);
258 b = (struct bitmap *) xmalloc(sizeof(struct bitmap));
259 b->data = (uint8 *) xmalloc(size);
260 memcpy(b->data, data, size);
261 b->width = width;
262 b->height = height;
263 return b;
264 }
265
266 /*****************************************************************************/
267 void
268 ui_destroy_bitmap(void * bmp)
269 {
270 struct bitmap * b;
271
272 b = (struct bitmap *) bmp;
273 if (b != 0)
274 {
275 xfree(b->data);
276 }
277 xfree(b);
278 }
279
280 /*****************************************************************************/
281 void
282 ui_paint_bitmap(int x, int y, int cx, int cy,
283 int width, int height, uint8 * data)
284 {
285 struct bitmap b;
286
287 b.width = width;
288 b.height = height;
289 b.data = data;
290 ui_memblt(12, x, y, cx, cy, &b, 0, 0);
291 }
292
293 /*****************************************************************************/
294 void
295 ui_set_clip(int x, int y, int cx, int cy)
296 {
297 bs_set_clip(x, y, cx, cy);
298 mi_set_clip(x, y, cx, cy);
299 }
300
301 /*****************************************************************************/
302 void
303 ui_reset_clip(void)
304 {
305 bs_reset_clip();
306 mi_reset_clip();
307 }
308
309 /*****************************************************************************/
310 void *
311 ui_create_colourmap(COLOURMAP * colours)
312 {
313 int i;
314 int n;
315
316 n = MIN(256, colours->ncolours);
317 memset(pal_entries, 0, sizeof(pal_entries));
318 for (i = 0; i < n; i++)
319 {
320 pal_entries[i] = (colours->colours[i].red << 16) |
321 (colours->colours[i].green << 8) |
322 colours->colours[i].blue;
323 }
324 return 0;
325 }
326
327 /*****************************************************************************/
328 void
329 ui_set_colourmap(void * map)
330 {
331 }
332
333 /*****************************************************************************/
334 static void
335 draw_glyph(int x, int y, void * glyph, int fgcolor)
336 {
337 struct bitmap * b;
338
339 b = glyph;
340 bs_draw_glyph(x, y, (char *)b->data, b->width, b->height, fgcolor);
341 }
342
343 /*****************************************************************************/
344 #define DO_GLYPH(ttext,idx) \
345 { \
346 glyph = cache_get_font(font, ttext[idx]); \
347 if (!(flags & TEXT2_IMPLICIT_X)) \
348 { \
349 xyoffset = ttext[++idx]; \
350 if (xyoffset & 0x80) \
351 { \
352 if (flags & TEXT2_VERTICAL) \
353 { \
354 y += ttext[idx + 1] | (ttext[idx + 2] << 8); \
355 } \
356 else \
357 { \
358 x += ttext[idx + 1] | (ttext[idx + 2] << 8); \
359 } \
360 idx += 2; \
361 } \
362 else \
363 { \
364 if (flags & TEXT2_VERTICAL) \
365 { \
366 y += xyoffset; \
367 } \
368 else \
369 { \
370 x += xyoffset; \
371 } \
372 } \
373 } \
374 if (glyph != NULL) \
375 { \
376 draw_glyph(x + glyph->offset, y + glyph->baseline, glyph->pixmap, \
377 fgcolour); \
378 if (flags & TEXT2_IMPLICIT_X) \
379 { \
380 x += glyph->width; \
381 } \
382 } \
383 }
384
385 /*****************************************************************************/
386 void
387 ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode,
388 int x, int y,
389 int clipx, int clipy, int clipcx, int clipcy,
390 int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
391 int bgcolour, int fgcolour, uint8 * text, uint8 length)
392 {
393 int i;
394 int j;
395 int xyoffset;
396 DATABLOB * entry;
397 FONTGLYPH * glyph;
398
399 if (boxx + boxcx > g_width)
400 {
401 boxcx = g_width - boxx;
402 }
403 if (boxcx > 1)
404 {
405 bs_rect(boxx, boxy, boxcx, boxcy, bgcolour, 0xc);
406 }
407 else
408 {
409 if (mixmode == MIX_OPAQUE)
410 {
411 bs_rect(clipx, clipy, clipcx, clipcy, bgcolour, 0xc);
412 }
413 }
414 /* Paint text, character by character */
415 for (i = 0; i < length;)
416 {
417 switch (text[i])
418 {
419 case 0xff:
420 if (i + 2 < length)
421 {
422 cache_put_text(text[i + 1], text, text[i + 2]);
423 }
424 else
425 {
426 error("this shouldn't be happening\n");
427 exit(1);
428 }
429 /* this will move pointer from start to first character after */
430 /* FF command */
431 length -= i + 3;
432 text = &(text[i + 3]);
433 i = 0;
434 break;
435 case 0xfe:
436 entry = cache_get_text(text[i + 1]);
437 if (entry != NULL)
438 {
439 if ((((uint8 *) (entry->data))[1] == 0) &&
440 (!(flags & TEXT2_IMPLICIT_X)))
441 {
442 if (flags & TEXT2_VERTICAL)
443 {
444 y += text[i + 2];
445 }
446 else
447 {
448 x += text[i + 2];
449 }
450 }
451 for (j = 0; j < entry->size; j++)
452 {
453 DO_GLYPH(((uint8 *) (entry->data)), j);
454 }
455 }
456 if (i + 2 < length)
457 {
458 i += 3;
459 }
460 else
461 {
462 i += 2;
463 }
464 length -= i;
465 /* this will move pointer from start to first character after */
466 /* FE command */
467 text = &(text[i]);
468 i = 0;
469 break;
470 default:
471 DO_GLYPH(text, i);
472 i++;
473 break;
474 }
475 }
476 if (boxcx > 1)
477 {
478 ui_invalidate(boxx, boxy, boxcx, boxcy);
479 }
480 else
481 {
482 ui_invalidate(clipx, clipy, clipcx, clipcy);
483 }
484 }
485
486 /*****************************************************************************/
487 void
488 ui_line(uint8 opcode, int startx, int starty, int endx, int endy,
489 PEN * pen)
490 {
491 int x;
492 int y;
493 int cx;
494 int cy;
495
496 bs_line(opcode, startx, starty, endx, endy, pen->width, pen->style,
497 pen->colour);
498 if (pen->style == 0 && pen->width < 2 && opcode == 12)
499 {
500 mi_line(startx, starty, endx, endy, pen->colour);
501 }
502 else
503 {
504 x = MIN(startx, endx);
505 y = MIN(starty, endy);
506 cx = (MAX(startx, endx) + 1) - x;
507 cy = (MAX(starty, endy) + 1) - y;
508 ui_invalidate(x, y, cx, cy);
509 }
510 }
511
512 /*****************************************************************************/
513 void
514 ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
515 void * src, int srcx, int srcy,
516 BRUSH* brush, int bgcolour, int fgcolour)
517 {
518 /* not used */
519 }
520
521 /*****************************************************************************/
522 void
523 ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
524 void * src, int srcx, int srcy)
525 {
526 struct bitmap* b;
527
528 b = (struct bitmap*)src;
529 bs_memblt(opcode, x, y, cx, cy, b->data, b->width, b->height,
530 srcx, srcy);
531 ui_invalidate(x, y, cx, cy);
532 }
533
534 /*****************************************************************************/
535 void
536 ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
537 {
538 }
539
540 /*****************************************************************************/
541 void
542 ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
543 {
544 }
545
546 /*****************************************************************************/
547 void
548 ui_rect(int x, int y, int cx, int cy, int colour)
549 {
550 bs_rect(x, y, cx, cy, colour, 12);
551 mi_fill_rect(x, y, cx, cy, colour);
552 }
553
554 /*****************************************************************************/
555 void
556 ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
557 int srcx, int srcy)
558 {
559 bs_screenblt(opcode, x, y, cx, cy, srcx, srcy);
560 if (opcode == 12)
561 {
562 mi_screen_copy(x, y, cx, cy, srcx, srcy);
563 }
564 else
565 {
566 ui_invalidate(x, y, cx, cy);
567 }
568 }
569
570 /*****************************************************************************/
571 void
572 ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
573 BRUSH * brush, int bgcolour, int fgcolour)
574 {
575 bs_patblt(opcode, x, y, cx, cy, brush->style, (char *)brush->pattern,
576 brush->xorigin, brush->yorigin, bgcolour, fgcolour);
577 ui_invalidate(x, y, cx, cy);
578 }
579
580 /*****************************************************************************/
581 void
582 ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
583 {
584 bs_rect(x, y, cx, cy, 0, opcode);
585 ui_invalidate(x, y, cx, cy);
586 /* todo */
587 }
588
589 /*****************************************************************************/
590 void
591 ui_move_pointer(int x, int y)
592 {
593 }
594
595 /*****************************************************************************/
596 uint16
597 ui_get_numlock_state(uint32 state)
598 {
599 return (uint16) state;
600 }
601
602 /*****************************************************************************/
603 /* get the num, caps, and scroll lock state */
604 /* scroll lock is 1, num lock is 2 and caps lock is 4 */
605 /* just returning 0, the hardware specific file is responsable for this */
606 uint32
607 read_keyboard_state(void)
608 {
609 return (uint32) mi_read_keyboard_state();
610 }
611
612 /*****************************************************************************/
613 void
614 ui_set_modifier_state(int code)
615
616 {
617
618 //error("%8.8x", code);
619
620 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, (uint16) code, 0);
621
622 }
623
624 /*****************************************************************************/
625 void
626 ui_resize_window(void)
627 {
628 }
629
630 /*****************************************************************************/
631 void
632 ui_begin_update(void)
633 {
634 mi_begin_update();
635 }
636
637 /*****************************************************************************/
638 void
639 ui_end_update(void)
640 {
641 mi_end_update();
642 }
643
644 /*****************************************************************************/
645 void
646 ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
647 BRUSH * brush, int bgcolour, int fgcolour)
648 {
649 /* not used */
650 }
651
652 /*****************************************************************************/
653 void
654 ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
655 {
656 int i, x, y, dx, dy;
657 if (npoints > 0)
658 {
659 x = points[0].x;
660 y = points[0].y;
661 for (i = 1; i < npoints; i++)
662 {
663 dx = points[i].x;
664 dy = points[i].y;
665 ui_line(opcode, x, y, x + dx, y + dy, pen);
666 x = x + dx;
667 y = y + dy;
668 }
669 }
670 }
671
672 /*****************************************************************************/
673 void
674 ui_ellipse(uint8 opcode, uint8 fillmode,
675 int x, int y, int cx, int cy,
676 BRUSH * brush, int bgcolour, int fgcolour)
677 {
678 /* not used */
679 }
680
681 /*****************************************************************************/
682 /* get a 32 byte random */
683 void
684 generate_random(uint8 * random)
685 {
686 int i;
687
688 rand();
689 rand();
690 for (i = 0; i < 32; i++)
691 {
692 random[i] = rand() >> 16; /* higher bits are more random */
693 }
694 }
695
696 /*****************************************************************************/
697 void
698 save_licence(uint8 * data, int length)
699 {
700 }
701
702 /*****************************************************************************/
703 int
704 load_licence(uint8 ** data)
705 {
706 return 0;
707 }
708
709 /*****************************************************************************/
710 void *
711 xrealloc(void * in, int size)
712 {
713 if (size < 1)
714 {
715 size = 1;
716 }
717 return realloc(in, size);
718 }
719
720 /*****************************************************************************/
721 void *
722 xmalloc(int size)
723 {
724 if (size < 1)
725 {
726 size = 1;
727 }
728 return malloc(size);
729 }
730
731 /*****************************************************************************/
732 void
733 xfree(void * in)
734 {
735 if (in != 0)
736 {
737 free(in);
738 }
739 }
740
741 /*****************************************************************************/
742 char *
743 xstrdup(const char * s)
744 {
745 int len;
746 char * p;
747
748 if (s == 0)
749 {
750 return 0;
751 }
752 len = strlen(s);
753 p = (char *) xmalloc(len + 1);
754 strcpy(p, s);
755 return p;
756 }
757
758 /*****************************************************************************/
759 void
760 warning(char * format, ...)
761 {
762 va_list ap;
763 char text[512];
764 char text1[512];
765
766 sprintf(text1, "WARNING: ");
767 va_start(ap, format);
768 vsprintf(text, format, ap);
769 va_end(ap);
770 strcat(text1, text);
771 mi_warning(text1);
772 }
773
774 /*****************************************************************************/
775 void
776 unimpl(char * format, ...)
777 {
778 va_list ap;
779 char text[512];
780 char text1[512];
781
782 sprintf(text1, "UNIMPL: ");
783 va_start(ap, format);
784 vsprintf(text, format, ap);
785 va_end(ap);
786 strcat(text1, text);
787 mi_warning(text1);
788 }
789
790 /*****************************************************************************/
791 void
792 error(char * format, ...)
793 {
794 va_list ap;
795 char text[512];
796 char text1[512];
797
798 sprintf(text1, "ERROR: ");
799 va_start(ap, format);
800 vsprintf(text, format, ap);
801 va_end(ap);
802 strcat(text1, text);
803 mi_error(text1);
804 }
805
806 /*****************************************************************************/
807 BOOL
808 rd_pstcache_mkdir(void)
809 {
810 return 0;
811 }
812
813 /*****************************************************************************/
814 int
815 rd_open_file(char * filename)
816 {
817 return 0;
818 }
819
820 /*****************************************************************************/
821 void
822 rd_close_file(int fd)
823 {
824 return;
825 }
826
827 /*****************************************************************************/
828 int
829 rd_read_file(int fd, void * ptr, int len)
830 {
831 return 0;
832 }
833
834 /*****************************************************************************/
835 int
836 rd_write_file(int fd, void * ptr, int len)
837 {
838 return 0;
839 }
840
841 /*****************************************************************************/
842 int
843 rd_lseek_file(int fd, int offset)
844 {
845 return 0;
846 }
847
848 /*****************************************************************************/
849 BOOL
850 rd_lock_file(int fd, int start, int len)
851 {
852 return False;
853 }
854
855
856 /*****************************************************************************/
857 void
858 ui_mouse_move(int x, int y)
859 {
860 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, (uint16) x, (uint16) y);
861 }
862
863
864 /*****************************************************************************/
865 void
866 ui_mouse_button(int button, int x, int y, int down)
867 {
868 uint16 flags;
869
870 flags = 0;
871 if (down)
872 {
873 flags |= MOUSE_FLAG_DOWN;
874 }
875 switch (button)
876 {
877 case 1:
878 flags |= MOUSE_FLAG_BUTTON1;
879 break;
880 case 2:
881 flags |= MOUSE_FLAG_BUTTON2;
882 break;
883 case 3:
884 flags |= MOUSE_FLAG_BUTTON3;
885 break;
886 case 4:
887 flags |= MOUSE_FLAG_BUTTON4;
888 break;
889 case 5:
890 flags |= MOUSE_FLAG_BUTTON5;
891 break;
892 }
893 rdp_send_input(0, RDP_INPUT_MOUSE, flags, (uint16) x, (uint16) y);
894 }
895
896
897 /*****************************************************************************/
898 void
899 ui_key_down(int key, int ext)
900
901 {
902 rdp_send_input(0, RDP_INPUT_SCANCODE, (uint16) (RDP_KEYPRESS | ext),
903 (uint16) key, 0);
904 }
905
906 /*****************************************************************************/
907 void
908 ui_key_up(int key, int ext)
909 {
910 rdp_send_input(0, RDP_INPUT_SCANCODE, (uint16) (RDP_KEYRELEASE | ext),
911 (uint16) key, 0);
912 }
913
914 /*****************************************************************************/
915 /* returns boolean, non zero is good */
916 int
917 ui_read_wire(void)
918 {
919 return rdp_loop(&g_deactivated, &g_ext_disc_reason);
920 }
921
922 /*****************************************************************************/
923 /* called after the command line parameters are processed */
924 /* returns boolean, non zero is ok */
925 int
926 ui_main(void)
927 {
928 uint32 flags;
929
930 /* try to connect */
931 flags = RDP_LOGON_NORMAL;
932 if (g_password[0] != 0)
933 {
934 flags |= RDP_LOGON_AUTO;
935 }
936 if (!rdp_connect(g_servername, flags, g_domain, g_password,
937 g_shell, g_directory))
938 {
939 return 0;
940 }
941 /* init backingstore */
942 bs_init(g_width, g_height, g_server_depth);
943 /* create the window */
944 if (!mi_create_window())
945 {
946 return 0;
947 }
948 /* if all ok, enter main loop */
949 return mi_main_loop();
950 }
951
952 /*****************************************************************************/
953 /* produce a hex dump */
954 void
955 hexdump(uint8 * p, uint32 len)
956 {
957 uint8 * line = p;
958 int i, thisline, offset = 0;
959
960 while (offset < (int)len)
961 {
962 printf("%04x ", offset);
963 thisline = len - offset;
964 if (thisline > 16)
965 thisline = 16;
966
967 for (i = 0; i < thisline; i++)
968 printf("%02x ", line[i]);
969
970 for (; i < 16; i++)
971 printf(" ");
972
973 for (i = 0; i < thisline; i++)
974 printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
975
976 printf("\n");
977 offset += thisline;
978 line += thisline;
979 }
980 }
981