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