1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
4 Copyright (C) Jay Sorg 2006
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.
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.
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.
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;
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
;
50 /* can't be static, hardware file or bsops need these */
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;
69 extern int g_tcp_port_rdp
;
71 static int g_deactivated
= 0;
72 static uint32 g_ext_disc_reason
= 0;
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
;
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
;
95 /* in ui specific file eg win32.c, qt.c, df.c, ... */
97 mi_create_window(void);
101 mi_error(char * msg
);
103 mi_warning(char * msg
);
105 mi_paint_rect(char * data
, int width
, int height
, int x
, int y
, int cx
, int cy
);
107 mi_begin_update(void);
111 mi_fill_rect(int x
, int y
, int cx
, int cy
, int colour
);
113 mi_screen_copy(int x
, int y
, int cx
, int cy
, int srcx
, int srcy
);
115 mi_set_clip(int x
, int y
, int cx
, int cy
);
119 mi_line(int x1
, int y1
, int x2
, int y2
, int colour
);
121 mi_create_cursor(unsigned int x
, unsigned int y
,
122 int width
, int height
,
123 unsigned char * andmask
, unsigned char * xormask
);
127 mi_destroy_cursor(void * cursor
);
129 mi_set_cursor(void * cursor
);
131 mi_set_null_cursor(void);
133 mi_read_keyboard_state(void);
135 /*****************************************************************************/
136 /* put part of the screen from the backing store to the display */
138 ui_invalidate(int x
, int y
, int cx
, int cy
)
142 if (cx
< 1 || cy
< 1)
146 if (bs_warp_coords(&x
, &y
, &cx
, &cy
, 0, 0))
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
);
156 /*****************************************************************************/
162 /*****************************************************************************/
173 /*****************************************************************************/
175 ui_create_cursor(unsigned int x
, unsigned int y
,
176 int width
, int height
,
177 uint8
* andmask
, uint8
* xormask
, int xor_bpp
)
184 if (width
!= 32 || height
!= 32)
190 return (void *) mi_create_cursor(x
, y
, width
, height
, (unsigned char *)andmask
, (unsigned char *)xormask
);
192 memset(am
, 0, 32 * 4);
193 memset(xm
, 0, 32 * 4);
194 for (i
= 0; i
< 32; i
++)
196 for (j
= 0; j
< 32; j
++)
198 if (bs_is_pixel_on((char *)andmask
, j
, i
, 32, 1))
200 bs_set_pixel_on(am
, j
, 31 - i
, 32, 1, 1);
202 if (bs_is_pixel_on((char *)xormask
, j
, i
, 32, 24))
204 bs_set_pixel_on(xm
, j
, 31 - i
, 32, 1, 1);
208 return (void *) mi_create_cursor(x
, y
, width
, height
, (unsigned char *)am
, (unsigned char *)xm
);
211 /*****************************************************************************/
213 ui_destroy_cursor(void * cursor
)
215 mi_destroy_cursor(cursor
);
218 /*****************************************************************************/
220 ui_set_cursor(void * cursor
)
222 mi_set_cursor(cursor
);
225 /*****************************************************************************/
227 ui_set_null_cursor(void)
229 mi_set_null_cursor();
232 /*****************************************************************************/
234 ui_create_glyph(int width
, int height
, uint8
* data
)
239 struct bitmap
* the_glyph
;
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
++)
250 for (j
= 0; j
< width
; j
++)
252 if (bs_is_pixel_on((char *)data
, j
, i
, width
, 1))
254 bs_set_pixel_on(glyph_data
, j
, i
, width
, 8, 255);
261 /*****************************************************************************/
263 ui_destroy_glyph(void * glyph
)
265 struct bitmap
* the_glyph
;
270 xfree(the_glyph
->data
);
275 /*****************************************************************************/
277 ui_create_bitmap(int width
, int height
, uint8
* data
)
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
);
291 /*****************************************************************************/
293 ui_destroy_bitmap(void * bmp
)
297 b
= (struct bitmap
*) bmp
;
305 /*****************************************************************************/
307 ui_paint_bitmap(int x
, int y
, int cx
, int cy
,
308 int width
, int height
, uint8
* data
)
315 ui_memblt(12, x
, y
, cx
, cy
, &b
, 0, 0);
318 /*****************************************************************************/
320 ui_set_clip(int x
, int y
, int cx
, int cy
)
322 bs_set_clip(x
, y
, cx
, cy
);
323 mi_set_clip(x
, y
, cx
, cy
);
326 /*****************************************************************************/
334 /*****************************************************************************/
336 ui_create_colourmap(COLOURMAP
* colours
)
341 n
= MIN(256, colours
->ncolours
);
342 memset(pal_entries
, 0, sizeof(pal_entries
));
343 for (i
= 0; i
< n
; i
++)
345 pal_entries
[i
] = (colours
->colours
[i
].red
<< 16) |
346 (colours
->colours
[i
].green
<< 8) |
347 colours
->colours
[i
].blue
;
352 /*****************************************************************************/
354 ui_set_colourmap(void * map
)
358 /*****************************************************************************/
360 draw_glyph(int x
, int y
, void * glyph
, int fgcolor
)
365 bs_draw_glyph(x
, y
, (char *)b
->data
, b
->width
, b
->height
, fgcolor
);
368 /*****************************************************************************/
369 #define DO_GLYPH(ttext,idx) \
371 glyph = cache_get_font(font, ttext[idx]); \
372 if (!(flags & TEXT2_IMPLICIT_X)) \
374 xyoffset = ttext[++idx]; \
375 if (xyoffset & 0x80) \
377 if (flags & TEXT2_VERTICAL) \
379 y += ttext[idx + 1] | (ttext[idx + 2] << 8); \
383 x += ttext[idx + 1] | (ttext[idx + 2] << 8); \
389 if (flags & TEXT2_VERTICAL) \
401 draw_glyph(x + glyph->offset, y + glyph->baseline, glyph->pixmap, \
403 if (flags & TEXT2_IMPLICIT_X) \
410 /*****************************************************************************/
412 ui_draw_text(uint8 font
, uint8 flags
, uint8 opcode
, int mixmode
,
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
)
424 if (boxx
+ boxcx
> g_width
)
426 boxcx
= g_width
- boxx
;
430 bs_rect(boxx
, boxy
, boxcx
, boxcy
, bgcolour
, 0xc);
434 if (mixmode
== MIX_OPAQUE
)
436 bs_rect(clipx
, clipy
, clipcx
, clipcy
, bgcolour
, 0xc);
439 /* Paint text, character by character */
440 for (i
= 0; i
< length
;)
447 cache_put_text(text
[i
+ 1], text
, text
[i
+ 2]);
451 error("this shouldn't be happening\n");
454 /* this will move pointer from start to first character after */
457 text
= &(text
[i
+ 3]);
461 entry
= cache_get_text(text
[i
+ 1]);
464 if ((((uint8
*) (entry
->data
))[1] == 0) &&
465 (!(flags
& TEXT2_IMPLICIT_X
)))
467 if (flags
& TEXT2_VERTICAL
)
476 for (j
= 0; j
< entry
->size
; j
++)
478 DO_GLYPH(((uint8
*) (entry
->data
)), j
);
490 /* this will move pointer from start to first character after */
503 ui_invalidate(boxx
, boxy
, boxcx
, boxcy
);
507 ui_invalidate(clipx
, clipy
, clipcx
, clipcy
);
511 /*****************************************************************************/
513 ui_line(uint8 opcode
, int startx
, int starty
, int endx
, int endy
,
521 bs_line(opcode
, startx
, starty
, endx
, endy
, pen
->width
, pen
->style
,
523 if (pen
->style
== 0 && pen
->width
< 2 && opcode
== 12)
525 mi_line(startx
, starty
, endx
, endy
, pen
->colour
);
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
);
537 /*****************************************************************************/
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
)
546 /*****************************************************************************/
548 ui_memblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
549 void * src
, int srcx
, int srcy
)
553 b
= (struct bitmap
*)src
;
554 bs_memblt(opcode
, x
, y
, cx
, cy
, b
->data
, b
->width
, b
->height
,
556 ui_invalidate(x
, y
, cx
, cy
);
559 /*****************************************************************************/
561 ui_desktop_restore(uint32 offset
, int x
, int y
, int cx
, int cy
)
565 /*****************************************************************************/
567 ui_desktop_save(uint32 offset
, int x
, int y
, int cx
, int cy
)
571 /*****************************************************************************/
573 ui_rect(int x
, int y
, int cx
, int cy
, int colour
)
575 bs_rect(x
, y
, cx
, cy
, colour
, 12);
576 mi_fill_rect(x
, y
, cx
, cy
, colour
);
579 /*****************************************************************************/
581 ui_screenblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
584 bs_screenblt(opcode
, x
, y
, cx
, cy
, srcx
, srcy
);
587 mi_screen_copy(x
, y
, cx
, cy
, srcx
, srcy
);
591 ui_invalidate(x
, y
, cx
, cy
);
595 /*****************************************************************************/
597 ui_patblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
598 BRUSH
* brush
, int bgcolour
, int fgcolour
)
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
);
605 /*****************************************************************************/
607 ui_destblt(uint8 opcode
, int x
, int y
, int cx
, int cy
)
609 bs_rect(x
, y
, cx
, cy
, 0, opcode
);
610 ui_invalidate(x
, y
, cx
, cy
);
614 /*****************************************************************************/
616 ui_move_pointer(int x
, int y
)
620 /*****************************************************************************/
622 ui_get_numlock_state(uint32 state
)
624 return (uint16
) state
;
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 */
632 read_keyboard_state(void)
634 return (uint32
) mi_read_keyboard_state();
637 /*****************************************************************************/
639 ui_set_modifier_state(int code
)
643 //error("%8.8x", code);
645 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE
, 0, (uint16
) code
, 0);
649 /*****************************************************************************/
651 ui_resize_window(void)
655 /*****************************************************************************/
657 ui_begin_update(void)
662 /*****************************************************************************/
669 /*****************************************************************************/
671 ui_polygon(uint8 opcode
, uint8 fillmode
, RD_POINT
* point
, int npoints
,
672 BRUSH
* brush
, int bgcolour
, int fgcolour
)
677 /*****************************************************************************/
679 ui_polyline(uint8 opcode
, RD_POINT
* points
, int npoints
, PEN
* pen
)
686 for (i
= 1; i
< npoints
; i
++)
690 ui_line(opcode
, x
, y
, x
+ dx
, y
+ dy
, pen
);
697 /*****************************************************************************/
699 ui_ellipse(uint8 opcode
, uint8 fillmode
,
700 int x
, int y
, int cx
, int cy
,
701 BRUSH
* brush
, int bgcolour
, int fgcolour
)
706 /*****************************************************************************/
707 /* get a 32 byte random */
709 generate_random(uint8
* random
)
715 for (i
= 0; i
< 32; i
++)
717 random
[i
] = rand(); /* higher bits are more random */
721 /*****************************************************************************/
723 save_licence(uint8
* data
, int length
)
727 /*****************************************************************************/
729 load_licence(uint8
** data
)
734 /*****************************************************************************/
736 xrealloc(void * in
, size_t size
)
742 return realloc(in
, size
);
745 /*****************************************************************************/
756 /*****************************************************************************/
766 /*****************************************************************************/
768 xstrdup(const char * s
)
778 p
= (char *) xmalloc(len
+ 1);
783 /*****************************************************************************/
785 warning(char * format
, ...)
791 sprintf(text1
, "WARNING: ");
792 va_start(ap
, format
);
793 vsprintf(text
, format
, ap
);
799 /*****************************************************************************/
801 unimpl(char * format
, ...)
807 sprintf(text1
, "UNIMPL: ");
808 va_start(ap
, format
);
809 vsprintf(text
, format
, ap
);
815 /*****************************************************************************/
817 error(char * format
, ...)
823 sprintf(text1
, "ERROR: ");
824 va_start(ap
, format
);
825 vsprintf(text
, format
, ap
);
831 /*****************************************************************************/
833 rd_pstcache_mkdir(void)
838 /*****************************************************************************/
840 rd_open_file(char * filename
)
845 /*****************************************************************************/
847 rd_close_file(int fd
)
852 /*****************************************************************************/
854 rd_read_file(int fd
, void * ptr
, int len
)
859 /*****************************************************************************/
861 rd_write_file(int fd
, void * ptr
, int len
)
866 /*****************************************************************************/
868 rd_lseek_file(int fd
, int offset
)
873 /*****************************************************************************/
875 rd_lock_file(int fd
, int start
, int len
)
881 /*****************************************************************************/
883 ui_mouse_move(int x
, int y
)
885 rdp_send_input(0, RDP_INPUT_MOUSE
, MOUSE_FLAG_MOVE
, (uint16
) x
, (uint16
) y
);
889 /*****************************************************************************/
891 ui_mouse_button(int button
, int x
, int y
, int down
)
898 flags
|= MOUSE_FLAG_DOWN
;
903 flags
|= MOUSE_FLAG_BUTTON1
;
906 flags
|= MOUSE_FLAG_BUTTON2
;
909 flags
|= MOUSE_FLAG_BUTTON3
;
912 flags
|= MOUSE_FLAG_BUTTON4
;
915 flags
|= MOUSE_FLAG_BUTTON5
;
918 rdp_send_input(0, RDP_INPUT_MOUSE
, flags
, (uint16
) x
, (uint16
) y
);
922 /*****************************************************************************/
924 ui_key_down(int key
, int ext
)
927 rdp_send_input(0, RDP_INPUT_SCANCODE
, (uint16
) (RDP_KEYPRESS
| ext
),
931 /*****************************************************************************/
933 ui_key_up(int key
, int ext
)
935 rdp_send_input(0, RDP_INPUT_SCANCODE
, (uint16
) (RDP_KEYRELEASE
| ext
),
939 /*****************************************************************************/
940 /* returns boolean, non zero is good */
944 return rdp_loop(&g_deactivated
, &g_ext_disc_reason
);
947 /*****************************************************************************/
948 /* called after the command line parameters are processed */
949 /* returns boolean, non zero is ok */
956 flags
= RDP_LOGON_NORMAL
;
957 if (g_password
[0] != 0)
959 flags
|= RDP_INFO_AUTOLOGON
;
961 if (!rdp_connect(g_servername
, flags
, g_domain
, g_password
,
962 g_shell
, g_directory
, FALSE
))
966 /* init backingstore */
967 bs_init(g_width
, g_height
, g_server_depth
);
968 /* create the window */
969 if (!mi_create_window())
973 /* if all ok, enter main loop */
974 return mi_main_loop();
977 /*****************************************************************************/
978 /* produce a hex dump */
980 hexdump(uint8
* p
, uint32 len
)
983 int i
, thisline
, offset
= 0;
985 while (offset
< (int)len
)
987 printf("%04x ", offset
);
988 thisline
= len
- offset
;
992 for (i
= 0; i
< thisline
; i
++)
993 printf("%02x ", line
[i
]);
998 for (i
= 0; i
< thisline
; i
++)
999 printf("%c", (line
[i
] >= 0x20 && line
[i
] < 0x7f) ? line
[i
] : '.');