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