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 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
;
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
;
51 /* can't be static, hardware file or bsops need these */
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;
70 extern int g_tcp_port_rdp
;
72 static int g_deactivated
= 0;
73 static uint32 g_ext_disc_reason
= 0;
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
;
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
;
96 /* in ui specific file eg win32.c, qt.c, df.c, ... */
98 mi_create_window(void);
102 mi_error(char * msg
);
104 mi_warning(char * msg
);
106 mi_paint_rect(char * data
, int width
, int height
, int x
, int y
, int cx
, int cy
);
108 mi_begin_update(void);
112 mi_fill_rect(int x
, int y
, int cx
, int cy
, int colour
);
114 mi_screen_copy(int x
, int y
, int cx
, int cy
, int srcx
, int srcy
);
116 mi_set_clip(int x
, int y
, int cx
, int cy
);
120 mi_line(int x1
, int y1
, int x2
, int y2
, int colour
);
122 mi_create_cursor(unsigned int x
, unsigned int y
,
123 int width
, int height
,
124 unsigned char * andmask
, unsigned char * xormask
);
128 mi_destroy_cursor(void * cursor
);
130 mi_set_cursor(void * cursor
);
132 mi_set_null_cursor(void);
134 mi_read_keyboard_state(void);
136 /*****************************************************************************/
137 /* put part of the screen from the backing store to the display */
139 ui_invalidate(int x
, int y
, int cx
, int cy
)
143 if (cx
< 1 || cy
< 1)
147 if (bs_warp_coords(&x
, &y
, &cx
, &cy
, 0, 0))
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
);
157 /*****************************************************************************/
163 /*****************************************************************************/
174 /*****************************************************************************/
176 ui_create_cursor(unsigned int x
, unsigned int y
,
177 int width
, int height
,
178 uint8
* andmask
, uint8
* xormask
, int xor_bpp
)
185 if (width
!= 32 || height
!= 32)
191 return (void *) mi_create_cursor(x
, y
, width
, height
, (unsigned char *)andmask
, (unsigned char *)xormask
);
193 memset(am
, 0, 32 * 4);
194 memset(xm
, 0, 32 * 4);
195 for (i
= 0; i
< 32; i
++)
197 for (j
= 0; j
< 32; j
++)
199 if (bs_is_pixel_on((char *)andmask
, j
, i
, 32, 1))
201 bs_set_pixel_on(am
, j
, 31 - i
, 32, 1, 1);
203 if (bs_is_pixel_on((char *)xormask
, j
, i
, 32, 24))
205 bs_set_pixel_on(xm
, j
, 31 - i
, 32, 1, 1);
209 return (void *) mi_create_cursor(x
, y
, width
, height
, (unsigned char *)am
, (unsigned char *)xm
);
212 /*****************************************************************************/
214 ui_destroy_cursor(void * cursor
)
216 mi_destroy_cursor(cursor
);
219 /*****************************************************************************/
221 ui_set_cursor(void * cursor
)
223 mi_set_cursor(cursor
);
226 /*****************************************************************************/
228 ui_set_null_cursor(void)
230 mi_set_null_cursor();
233 /*****************************************************************************/
235 ui_create_glyph(int width
, int height
, uint8
* data
)
240 struct bitmap
* the_glyph
;
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
++)
251 for (j
= 0; j
< width
; j
++)
253 if (bs_is_pixel_on((char *)data
, j
, i
, width
, 1))
255 bs_set_pixel_on(glyph_data
, j
, i
, width
, 8, 255);
262 /*****************************************************************************/
264 ui_destroy_glyph(void * glyph
)
266 struct bitmap
* the_glyph
;
271 xfree(the_glyph
->data
);
276 /*****************************************************************************/
278 ui_create_bitmap(int width
, int height
, uint8
* data
)
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
);
292 /*****************************************************************************/
294 ui_destroy_bitmap(void * bmp
)
298 b
= (struct bitmap
*) bmp
;
306 /*****************************************************************************/
308 ui_paint_bitmap(int x
, int y
, int cx
, int cy
,
309 int width
, int height
, uint8
* data
)
316 ui_memblt(12, x
, y
, cx
, cy
, &b
, 0, 0);
319 /*****************************************************************************/
321 ui_set_clip(int x
, int y
, int cx
, int cy
)
323 bs_set_clip(x
, y
, cx
, cy
);
324 mi_set_clip(x
, y
, cx
, cy
);
327 /*****************************************************************************/
335 /*****************************************************************************/
337 ui_create_colourmap(COLOURMAP
* colours
)
342 n
= MIN(256, colours
->ncolours
);
343 memset(pal_entries
, 0, sizeof(pal_entries
));
344 for (i
= 0; i
< n
; i
++)
346 pal_entries
[i
] = (colours
->colours
[i
].red
<< 16) |
347 (colours
->colours
[i
].green
<< 8) |
348 colours
->colours
[i
].blue
;
353 /*****************************************************************************/
355 ui_set_colourmap(void * map
)
359 /*****************************************************************************/
361 draw_glyph(int x
, int y
, void * glyph
, int fgcolor
)
366 bs_draw_glyph(x
, y
, (char *)b
->data
, b
->width
, b
->height
, fgcolor
);
369 /*****************************************************************************/
370 #define DO_GLYPH(ttext,idx) \
372 glyph = cache_get_font(font, ttext[idx]); \
373 if (!(flags & TEXT2_IMPLICIT_X)) \
375 xyoffset = ttext[++idx]; \
376 if (xyoffset & 0x80) \
378 if (flags & TEXT2_VERTICAL) \
380 y += ttext[idx + 1] | (ttext[idx + 2] << 8); \
384 x += ttext[idx + 1] | (ttext[idx + 2] << 8); \
390 if (flags & TEXT2_VERTICAL) \
402 draw_glyph(x + glyph->offset, y + glyph->baseline, glyph->pixmap, \
404 if (flags & TEXT2_IMPLICIT_X) \
411 /*****************************************************************************/
413 ui_draw_text(uint8 font
, uint8 flags
, uint8 opcode
, int mixmode
,
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
)
425 if (boxx
+ boxcx
> g_width
)
427 boxcx
= g_width
- boxx
;
431 bs_rect(boxx
, boxy
, boxcx
, boxcy
, bgcolour
, 0xc);
435 if (mixmode
== MIX_OPAQUE
)
437 bs_rect(clipx
, clipy
, clipcx
, clipcy
, bgcolour
, 0xc);
440 /* Paint text, character by character */
441 for (i
= 0; i
< length
;)
448 cache_put_text(text
[i
+ 1], text
, text
[i
+ 2]);
452 error("this shouldn't be happening\n");
455 /* this will move pointer from start to first character after */
458 text
= &(text
[i
+ 3]);
462 entry
= cache_get_text(text
[i
+ 1]);
465 if ((((uint8
*) (entry
->data
))[1] == 0) &&
466 (!(flags
& TEXT2_IMPLICIT_X
)))
468 if (flags
& TEXT2_VERTICAL
)
477 for (j
= 0; j
< entry
->size
; j
++)
479 DO_GLYPH(((uint8
*) (entry
->data
)), j
);
491 /* this will move pointer from start to first character after */
504 ui_invalidate(boxx
, boxy
, boxcx
, boxcy
);
508 ui_invalidate(clipx
, clipy
, clipcx
, clipcy
);
512 /*****************************************************************************/
514 ui_line(uint8 opcode
, int startx
, int starty
, int endx
, int endy
,
522 bs_line(opcode
, startx
, starty
, endx
, endy
, pen
->width
, pen
->style
,
524 if (pen
->style
== 0 && pen
->width
< 2 && opcode
== 12)
526 mi_line(startx
, starty
, endx
, endy
, pen
->colour
);
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
);
538 /*****************************************************************************/
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
)
547 /*****************************************************************************/
549 ui_memblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
550 void * src
, int srcx
, int srcy
)
554 b
= (struct bitmap
*)src
;
555 bs_memblt(opcode
, x
, y
, cx
, cy
, b
->data
, b
->width
, b
->height
,
557 ui_invalidate(x
, y
, cx
, cy
);
560 /*****************************************************************************/
562 ui_desktop_restore(uint32 offset
, int x
, int y
, int cx
, int cy
)
566 /*****************************************************************************/
568 ui_desktop_save(uint32 offset
, int x
, int y
, int cx
, int cy
)
572 /*****************************************************************************/
574 ui_rect(int x
, int y
, int cx
, int cy
, int colour
)
576 bs_rect(x
, y
, cx
, cy
, colour
, 12);
577 mi_fill_rect(x
, y
, cx
, cy
, colour
);
580 /*****************************************************************************/
582 ui_screenblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
585 bs_screenblt(opcode
, x
, y
, cx
, cy
, srcx
, srcy
);
588 mi_screen_copy(x
, y
, cx
, cy
, srcx
, srcy
);
592 ui_invalidate(x
, y
, cx
, cy
);
596 /*****************************************************************************/
598 ui_patblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
599 BRUSH
* brush
, int bgcolour
, int fgcolour
)
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
);
606 /*****************************************************************************/
608 ui_destblt(uint8 opcode
, int x
, int y
, int cx
, int cy
)
610 bs_rect(x
, y
, cx
, cy
, 0, opcode
);
611 ui_invalidate(x
, y
, cx
, cy
);
615 /*****************************************************************************/
617 ui_move_pointer(int x
, int y
)
621 /*****************************************************************************/
623 ui_get_numlock_state(uint32 state
)
625 return (uint16
) state
;
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 */
633 read_keyboard_state(void)
635 return (uint32
) mi_read_keyboard_state();
638 /*****************************************************************************/
640 ui_set_modifier_state(int code
)
644 //error("%8.8x", code);
646 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE
, 0, (uint16
) code
, 0);
650 /*****************************************************************************/
652 ui_resize_window(void)
656 /*****************************************************************************/
658 ui_begin_update(void)
663 /*****************************************************************************/
670 /*****************************************************************************/
672 ui_polygon(uint8 opcode
, uint8 fillmode
, RD_POINT
* point
, int npoints
,
673 BRUSH
* brush
, int bgcolour
, int fgcolour
)
678 /*****************************************************************************/
680 ui_polyline(uint8 opcode
, RD_POINT
* points
, int npoints
, PEN
* pen
)
687 for (i
= 1; i
< npoints
; i
++)
691 ui_line(opcode
, x
, y
, x
+ dx
, y
+ dy
, pen
);
698 /*****************************************************************************/
700 ui_ellipse(uint8 opcode
, uint8 fillmode
,
701 int x
, int y
, int cx
, int cy
,
702 BRUSH
* brush
, int bgcolour
, int fgcolour
)
707 /*****************************************************************************/
708 /* get a 32 byte random */
710 generate_random(uint8
* random
)
716 for (i
= 0; i
< 32; i
++)
718 random
[i
] = rand(); /* higher bits are more random */
722 /*****************************************************************************/
724 save_licence(uint8
* data
, int length
)
728 /*****************************************************************************/
730 load_licence(uint8
** data
)
735 /*****************************************************************************/
737 xrealloc(void * in
, size_t size
)
743 return realloc(in
, size
);
746 /*****************************************************************************/
757 /*****************************************************************************/
767 /*****************************************************************************/
769 xstrdup(const char * s
)
779 p
= (char *) xmalloc(len
+ 1);
784 /*****************************************************************************/
786 warning(char * format
, ...)
792 sprintf(text1
, "WARNING: ");
793 va_start(ap
, format
);
794 vsprintf(text
, format
, ap
);
800 /*****************************************************************************/
802 unimpl(char * format
, ...)
808 sprintf(text1
, "UNIMPL: ");
809 va_start(ap
, format
);
810 vsprintf(text
, format
, ap
);
816 /*****************************************************************************/
818 error(char * format
, ...)
824 sprintf(text1
, "ERROR: ");
825 va_start(ap
, format
);
826 vsprintf(text
, format
, ap
);
832 /*****************************************************************************/
834 rd_pstcache_mkdir(void)
839 /*****************************************************************************/
841 rd_open_file(char * filename
)
846 /*****************************************************************************/
848 rd_close_file(int fd
)
853 /*****************************************************************************/
855 rd_read_file(int fd
, void * ptr
, int len
)
860 /*****************************************************************************/
862 rd_write_file(int fd
, void * ptr
, int len
)
867 /*****************************************************************************/
869 rd_lseek_file(int fd
, int offset
)
874 /*****************************************************************************/
876 rd_lock_file(int fd
, int start
, int len
)
882 /*****************************************************************************/
884 ui_mouse_move(int x
, int y
)
886 rdp_send_input(0, RDP_INPUT_MOUSE
, MOUSE_FLAG_MOVE
, (uint16
) x
, (uint16
) y
);
890 /*****************************************************************************/
892 ui_mouse_button(int button
, int x
, int y
, int down
)
899 flags
|= MOUSE_FLAG_DOWN
;
904 flags
|= MOUSE_FLAG_BUTTON1
;
907 flags
|= MOUSE_FLAG_BUTTON2
;
910 flags
|= MOUSE_FLAG_BUTTON3
;
913 flags
|= MOUSE_FLAG_BUTTON4
;
916 flags
|= MOUSE_FLAG_BUTTON5
;
919 rdp_send_input(0, RDP_INPUT_MOUSE
, flags
, (uint16
) x
, (uint16
) y
);
923 /*****************************************************************************/
925 ui_key_down(int key
, int ext
)
928 rdp_send_input(0, RDP_INPUT_SCANCODE
, (uint16
) (RDP_KEYPRESS
| ext
),
932 /*****************************************************************************/
934 ui_key_up(int key
, int ext
)
936 rdp_send_input(0, RDP_INPUT_SCANCODE
, (uint16
) (RDP_KEYRELEASE
| ext
),
940 /*****************************************************************************/
941 /* returns boolean, non zero is good */
945 return rdp_loop(&g_deactivated
, &g_ext_disc_reason
);
948 /*****************************************************************************/
949 /* called after the command line parameters are processed */
950 /* returns boolean, non zero is ok */
957 flags
= RDP_LOGON_NORMAL
;
958 if (g_password
[0] != 0)
960 flags
|= RDP_INFO_AUTOLOGON
;
962 if (!rdp_connect(g_servername
, flags
, g_domain
, g_password
,
963 g_shell
, g_directory
, FALSE
))
967 /* init backingstore */
968 bs_init(g_width
, g_height
, g_server_depth
);
969 /* create the window */
970 if (!mi_create_window())
974 /* if all ok, enter main loop */
975 return mi_main_loop();
978 /*****************************************************************************/
979 /* produce a hex dump */
981 hexdump(uint8
* p
, uint32 len
)
984 int i
, thisline
, offset
= 0;
986 while (offset
< (int)len
)
988 printf("%04x ", offset
);
989 thisline
= len
- offset
;
993 for (i
= 0; i
< thisline
; i
++)
994 printf("%02x ", line
[i
]);
999 for (i
= 0; i
< thisline
; i
++)
1000 printf("%c", (line
[i
] >= 0x20 && line
[i
] < 0x7f) ? line
[i
] : '.');