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.
23 char g_username
[256] = "";
24 char g_hostname
[256] = "";
25 char g_servername
[256] = "";
26 char g_password
[256] = "";
27 char g_shell
[256] = "";
28 char g_directory
[256] = "";
29 char g_domain
[256] = "";
30 BOOL g_desktop_save
= False
; /* desktop save order */
31 BOOL g_polygon_ellipse_orders
= False
; /* polygon / ellipse orders */
32 BOOL g_bitmap_compression
= True
;
33 uint32 g_rdp5_performanceflags
=
34 RDP5_NO_WALLPAPER
| RDP5_NO_FULLWINDOWDRAG
| RDP5_NO_MENUANIMATIONS
;
35 BOOL g_bitmap_cache_persist_enable
= False
;
36 BOOL g_bitmap_cache_precache
= True
;
37 BOOL g_bitmap_cache
= True
;
38 BOOL g_encryption
= True
;
39 int g_server_depth
= 8;
40 BOOL g_use_rdp5
= False
;
43 uint32 g_keylayout
= 0x409; /* Defaults to US keyboard layout */
44 int g_keyboard_type
= 0x4; /* Defaults to US keyboard layout */
45 int g_keyboard_subtype
= 0x0; /* Defaults to US keyboard layout */
46 int g_keyboard_functionkeys
= 0xc; /* Defaults to US keyboard layout */
47 BOOL g_console_session
= False
;
49 /* can't be static, hardware file or bsops need these */
53 /* Session Directory redirection */
54 BOOL g_redirect
= False
;
55 char g_redirect_server
[64];
56 char g_redirect_domain
[16];
57 char g_redirect_password
[64];
58 char g_redirect_username
[64];
59 char g_redirect_cookie
[128];
60 uint32 g_redirect_flags
= 0;
62 extern int g_tcp_port_rdp
;
64 static int g_deactivated
= 0;
65 static uint32 g_ext_disc_reason
= 0;
74 /* in ui specific file eg win32.c, qt.c, df.c, ... */
76 mi_create_window(void);
82 mi_warning(char * msg
);
84 mi_paint_rect(char * data
, int width
, int height
, int x
, int y
, int cx
, int cy
);
86 mi_begin_update(void);
90 mi_fill_rect(int x
, int y
, int cx
, int cy
, int colour
);
92 mi_screen_copy(int x
, int y
, int cx
, int cy
, int srcx
, int srcy
);
94 mi_set_clip(int x
, int y
, int cx
, int cy
);
98 mi_line(int x1
, int y1
, int x2
, int y2
, int colour
);
100 mi_create_cursor(unsigned int x
, unsigned int y
,
101 int width
, int height
,
102 unsigned char * andmask
, unsigned char * xormask
);
106 mi_destroy_cursor(void * cursor
);
108 mi_set_cursor(void * cursor
);
110 mi_set_null_cursor(void);
112 mi_read_keyboard_state(void);
114 /*****************************************************************************/
115 /* put part of the screen from the backing store to the display */
117 ui_invalidate(int x
, int y
, int cx
, int cy
)
121 if (cx
< 1 || cy
< 1)
125 if (bs_warp_coords(&x
, &y
, &cx
, &cy
, 0, 0))
128 data
= (char *) xmalloc(cx
* cy
* 4);
129 bs_copy_box(data
, x
, y
, cx
, cy
, cx
* ((g_server_depth
+ 7) / 8));
130 mi_paint_rect(data
, cx
, cy
, x
, y
, cx
, cy
);
135 /*****************************************************************************/
141 /*****************************************************************************/
152 /*****************************************************************************/
154 ui_create_cursor(uint32 x
, uint32 y
,
155 int width
, int height
,
156 uint8
* andmask
, uint8
* xormask
)
163 if (width
!= 32 || height
!= 32)
167 memset(am
, 0, 32 * 4);
168 memset(xm
, 0, 32 * 4);
169 for (i
= 0; i
< 32; i
++)
171 for (j
= 0; j
< 32; j
++)
173 if (bs_is_pixel_on((char *)andmask
, j
, i
, 32, 1))
175 bs_set_pixel_on(am
, j
, 31 - i
, 32, 1, 1);
177 if (bs_is_pixel_on((char *)xormask
, j
, i
, 32, 24))
179 bs_set_pixel_on(xm
, j
, 31 - i
, 32, 1, 1);
183 return (void *) mi_create_cursor(x
, y
, width
, height
, (unsigned char *)am
, (unsigned char *)xm
);
186 /*****************************************************************************/
188 ui_destroy_cursor(void * cursor
)
190 mi_destroy_cursor(cursor
);
193 /*****************************************************************************/
195 ui_set_cursor(void * cursor
)
197 mi_set_cursor(cursor
);
200 /*****************************************************************************/
202 ui_set_null_cursor(void)
204 mi_set_null_cursor();
207 /*****************************************************************************/
209 ui_create_glyph(int width
, int height
, uint8
* data
)
214 struct bitmap
* the_glyph
;
216 glyph_data
= (char *) xmalloc(width
* height
);
217 memset(glyph_data
, 0, width
* height
);
218 the_glyph
= (struct bitmap
*) xmalloc(sizeof(struct bitmap
));
219 memset(the_glyph
, 0, sizeof(struct bitmap
));
220 the_glyph
->width
= width
;
221 the_glyph
->height
= height
;
222 the_glyph
->data
= (uint8
*)glyph_data
;
223 for (i
= 0; i
< height
; i
++)
225 for (j
= 0; j
< width
; j
++)
227 if (bs_is_pixel_on((char *)data
, j
, i
, width
, 1))
229 bs_set_pixel_on(glyph_data
, j
, i
, width
, 8, 255);
236 /*****************************************************************************/
238 ui_destroy_glyph(void * glyph
)
240 struct bitmap
* the_glyph
;
245 xfree(the_glyph
->data
);
250 /*****************************************************************************/
252 ui_create_bitmap(int width
, int height
, uint8
* data
)
257 size
= width
* height
* ((g_server_depth
+ 7) / 8);
258 b
= (struct bitmap
*) xmalloc(sizeof(struct bitmap
));
259 b
->data
= (uint8
*) xmalloc(size
);
260 memcpy(b
->data
, data
, size
);
266 /*****************************************************************************/
268 ui_destroy_bitmap(void * bmp
)
272 b
= (struct bitmap
*) bmp
;
280 /*****************************************************************************/
282 ui_paint_bitmap(int x
, int y
, int cx
, int cy
,
283 int width
, int height
, uint8
* data
)
290 ui_memblt(12, x
, y
, cx
, cy
, &b
, 0, 0);
293 /*****************************************************************************/
295 ui_set_clip(int x
, int y
, int cx
, int cy
)
297 bs_set_clip(x
, y
, cx
, cy
);
298 mi_set_clip(x
, y
, cx
, cy
);
301 /*****************************************************************************/
309 /*****************************************************************************/
311 ui_create_colourmap(COLOURMAP
* colours
)
316 n
= MIN(256, colours
->ncolours
);
317 memset(pal_entries
, 0, sizeof(pal_entries
));
318 for (i
= 0; i
< n
; i
++)
320 pal_entries
[i
] = (colours
->colours
[i
].red
<< 16) |
321 (colours
->colours
[i
].green
<< 8) |
322 colours
->colours
[i
].blue
;
327 /*****************************************************************************/
329 ui_set_colourmap(void * map
)
333 /*****************************************************************************/
335 draw_glyph(int x
, int y
, void * glyph
, int fgcolor
)
340 bs_draw_glyph(x
, y
, (char *)b
->data
, b
->width
, b
->height
, fgcolor
);
343 /*****************************************************************************/
344 #define DO_GLYPH(ttext,idx) \
346 glyph = cache_get_font(font, ttext[idx]); \
347 if (!(flags & TEXT2_IMPLICIT_X)) \
349 xyoffset = ttext[++idx]; \
350 if (xyoffset & 0x80) \
352 if (flags & TEXT2_VERTICAL) \
354 y += ttext[idx + 1] | (ttext[idx + 2] << 8); \
358 x += ttext[idx + 1] | (ttext[idx + 2] << 8); \
364 if (flags & TEXT2_VERTICAL) \
376 draw_glyph(x + glyph->offset, y + glyph->baseline, glyph->pixmap, \
378 if (flags & TEXT2_IMPLICIT_X) \
385 /*****************************************************************************/
387 ui_draw_text(uint8 font
, uint8 flags
, uint8 opcode
, int mixmode
,
389 int clipx
, int clipy
, int clipcx
, int clipcy
,
390 int boxx
, int boxy
, int boxcx
, int boxcy
, BRUSH
* brush
,
391 int bgcolour
, int fgcolour
, uint8
* text
, uint8 length
)
399 if (boxx
+ boxcx
> g_width
)
401 boxcx
= g_width
- boxx
;
405 bs_rect(boxx
, boxy
, boxcx
, boxcy
, bgcolour
, 0xc);
409 if (mixmode
== MIX_OPAQUE
)
411 bs_rect(clipx
, clipy
, clipcx
, clipcy
, bgcolour
, 0xc);
414 /* Paint text, character by character */
415 for (i
= 0; i
< length
;)
422 cache_put_text(text
[i
+ 1], text
, text
[i
+ 2]);
426 error("this shouldn't be happening\n");
429 /* this will move pointer from start to first character after */
432 text
= &(text
[i
+ 3]);
436 entry
= cache_get_text(text
[i
+ 1]);
439 if ((((uint8
*) (entry
->data
))[1] == 0) &&
440 (!(flags
& TEXT2_IMPLICIT_X
)))
442 if (flags
& TEXT2_VERTICAL
)
451 for (j
= 0; j
< entry
->size
; j
++)
453 DO_GLYPH(((uint8
*) (entry
->data
)), j
);
465 /* this will move pointer from start to first character after */
478 ui_invalidate(boxx
, boxy
, boxcx
, boxcy
);
482 ui_invalidate(clipx
, clipy
, clipcx
, clipcy
);
486 /*****************************************************************************/
488 ui_line(uint8 opcode
, int startx
, int starty
, int endx
, int endy
,
496 bs_line(opcode
, startx
, starty
, endx
, endy
, pen
->width
, pen
->style
,
498 if (pen
->style
== 0 && pen
->width
< 2 && opcode
== 12)
500 mi_line(startx
, starty
, endx
, endy
, pen
->colour
);
504 x
= MIN(startx
, endx
);
505 y
= MIN(starty
, endy
);
506 cx
= (MAX(startx
, endx
) + 1) - x
;
507 cy
= (MAX(starty
, endy
) + 1) - y
;
508 ui_invalidate(x
, y
, cx
, cy
);
512 /*****************************************************************************/
514 ui_triblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
515 void * src
, int srcx
, int srcy
,
516 BRUSH
* brush
, int bgcolour
, int fgcolour
)
521 /*****************************************************************************/
523 ui_memblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
524 void * src
, int srcx
, int srcy
)
528 b
= (struct bitmap
*)src
;
529 bs_memblt(opcode
, x
, y
, cx
, cy
, b
->data
, b
->width
, b
->height
,
531 ui_invalidate(x
, y
, cx
, cy
);
534 /*****************************************************************************/
536 ui_desktop_restore(uint32 offset
, int x
, int y
, int cx
, int cy
)
540 /*****************************************************************************/
542 ui_desktop_save(uint32 offset
, int x
, int y
, int cx
, int cy
)
546 /*****************************************************************************/
548 ui_rect(int x
, int y
, int cx
, int cy
, int colour
)
550 bs_rect(x
, y
, cx
, cy
, colour
, 12);
551 mi_fill_rect(x
, y
, cx
, cy
, colour
);
554 /*****************************************************************************/
556 ui_screenblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
559 bs_screenblt(opcode
, x
, y
, cx
, cy
, srcx
, srcy
);
562 mi_screen_copy(x
, y
, cx
, cy
, srcx
, srcy
);
566 ui_invalidate(x
, y
, cx
, cy
);
570 /*****************************************************************************/
572 ui_patblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
573 BRUSH
* brush
, int bgcolour
, int fgcolour
)
575 bs_patblt(opcode
, x
, y
, cx
, cy
, brush
->style
, (char *)brush
->pattern
,
576 brush
->xorigin
, brush
->yorigin
, bgcolour
, fgcolour
);
577 ui_invalidate(x
, y
, cx
, cy
);
580 /*****************************************************************************/
582 ui_destblt(uint8 opcode
, int x
, int y
, int cx
, int cy
)
584 bs_rect(x
, y
, cx
, cy
, 0, opcode
);
585 ui_invalidate(x
, y
, cx
, cy
);
589 /*****************************************************************************/
591 ui_move_pointer(int x
, int y
)
595 /*****************************************************************************/
597 ui_get_numlock_state(uint32 state
)
599 return (uint16
) state
;
602 /*****************************************************************************/
603 /* get the num, caps, and scroll lock state */
604 /* scroll lock is 1, num lock is 2 and caps lock is 4 */
605 /* just returning 0, the hardware specific file is responsable for this */
607 read_keyboard_state(void)
609 return (uint32
) mi_read_keyboard_state();
612 /*****************************************************************************/
614 ui_set_modifier_state(int code
)
618 //error("%8.8x", code);
620 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE
, 0, (uint16
) code
, 0);
624 /*****************************************************************************/
626 ui_resize_window(void)
630 /*****************************************************************************/
632 ui_begin_update(void)
637 /*****************************************************************************/
644 /*****************************************************************************/
646 ui_polygon(uint8 opcode
, uint8 fillmode
, POINT
* point
, int npoints
,
647 BRUSH
* brush
, int bgcolour
, int fgcolour
)
652 /*****************************************************************************/
654 ui_polyline(uint8 opcode
, POINT
* points
, int npoints
, PEN
* pen
)
661 for (i
= 1; i
< npoints
; i
++)
665 ui_line(opcode
, x
, y
, x
+ dx
, y
+ dy
, pen
);
672 /*****************************************************************************/
674 ui_ellipse(uint8 opcode
, uint8 fillmode
,
675 int x
, int y
, int cx
, int cy
,
676 BRUSH
* brush
, int bgcolour
, int fgcolour
)
681 /*****************************************************************************/
682 /* get a 32 byte random */
684 generate_random(uint8
* random
)
690 for (i
= 0; i
< 32; i
++)
692 random
[i
] = rand() >> 16; /* higher bits are more random */
696 /*****************************************************************************/
698 save_licence(uint8
* data
, int length
)
702 /*****************************************************************************/
704 load_licence(uint8
** data
)
709 /*****************************************************************************/
711 xrealloc(void * in
, int size
)
717 return realloc(in
, size
);
720 /*****************************************************************************/
731 /*****************************************************************************/
741 /*****************************************************************************/
743 xstrdup(const char * s
)
753 p
= (char *) xmalloc(len
+ 1);
758 /*****************************************************************************/
760 warning(char * format
, ...)
766 sprintf(text1
, "WARNING: ");
767 va_start(ap
, format
);
768 vsprintf(text
, format
, ap
);
774 /*****************************************************************************/
776 unimpl(char * format
, ...)
782 sprintf(text1
, "UNIMPL: ");
783 va_start(ap
, format
);
784 vsprintf(text
, format
, ap
);
790 /*****************************************************************************/
792 error(char * format
, ...)
798 sprintf(text1
, "ERROR: ");
799 va_start(ap
, format
);
800 vsprintf(text
, format
, ap
);
806 /*****************************************************************************/
808 rd_pstcache_mkdir(void)
813 /*****************************************************************************/
815 rd_open_file(char * filename
)
820 /*****************************************************************************/
822 rd_close_file(int fd
)
827 /*****************************************************************************/
829 rd_read_file(int fd
, void * ptr
, int len
)
834 /*****************************************************************************/
836 rd_write_file(int fd
, void * ptr
, int len
)
841 /*****************************************************************************/
843 rd_lseek_file(int fd
, int offset
)
848 /*****************************************************************************/
850 rd_lock_file(int fd
, int start
, int len
)
856 /*****************************************************************************/
858 ui_mouse_move(int x
, int y
)
860 rdp_send_input(0, RDP_INPUT_MOUSE
, MOUSE_FLAG_MOVE
, (uint16
) x
, (uint16
) y
);
864 /*****************************************************************************/
866 ui_mouse_button(int button
, int x
, int y
, int down
)
873 flags
|= MOUSE_FLAG_DOWN
;
878 flags
|= MOUSE_FLAG_BUTTON1
;
881 flags
|= MOUSE_FLAG_BUTTON2
;
884 flags
|= MOUSE_FLAG_BUTTON3
;
887 flags
|= MOUSE_FLAG_BUTTON4
;
890 flags
|= MOUSE_FLAG_BUTTON5
;
893 rdp_send_input(0, RDP_INPUT_MOUSE
, flags
, (uint16
) x
, (uint16
) y
);
897 /*****************************************************************************/
899 ui_key_down(int key
, int ext
)
902 rdp_send_input(0, RDP_INPUT_SCANCODE
, (uint16
) (RDP_KEYPRESS
| ext
),
906 /*****************************************************************************/
908 ui_key_up(int key
, int ext
)
910 rdp_send_input(0, RDP_INPUT_SCANCODE
, (uint16
) (RDP_KEYRELEASE
| ext
),
914 /*****************************************************************************/
915 /* returns boolean, non zero is good */
919 return rdp_loop(&g_deactivated
, &g_ext_disc_reason
);
922 /*****************************************************************************/
923 /* called after the command line parameters are processed */
924 /* returns boolean, non zero is ok */
931 flags
= RDP_LOGON_NORMAL
;
932 if (g_password
[0] != 0)
934 flags
|= RDP_LOGON_AUTO
;
936 if (!rdp_connect(g_servername
, flags
, g_domain
, g_password
,
937 g_shell
, g_directory
))
941 /* init backingstore */
942 bs_init(g_width
, g_height
, g_server_depth
);
943 /* create the window */
944 if (!mi_create_window())
948 /* if all ok, enter main loop */
949 return mi_main_loop();
952 /*****************************************************************************/
953 /* produce a hex dump */
955 hexdump(uint8
* p
, uint32 len
)
958 int i
, thisline
, offset
= 0;
960 while (offset
< (int)len
)
962 printf("%04x ", offset
);
963 thisline
= len
- offset
;
967 for (i
= 0; i
< thisline
; i
++)
968 printf("%02x ", line
[i
]);
973 for (i
= 0; i
< thisline
; i
++)
974 printf("%c", (line
[i
] >= 0x20 && line
[i
] < 0x7f) ? line
[i
] : '.');