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