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 BOOL g_desktop_save
= False
; /* desktop save order */
33 BOOL g_polygon_ellipse_orders
= False
; /* polygon / ellipse orders */
34 BOOL g_bitmap_compression
= True
;
35 uint32 g_rdp5_performanceflags
=
36 RDP5_NO_WALLPAPER
| RDP5_NO_FULLWINDOWDRAG
| RDP5_NO_MENUANIMATIONS
;
37 BOOL g_bitmap_cache_persist_enable
= False
;
38 BOOL g_bitmap_cache_precache
= True
;
39 BOOL g_bitmap_cache
= True
;
40 BOOL g_encryption
= True
;
41 int g_server_depth
= 8;
42 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 BOOL g_console_session
= False
;
51 /* can't be static, hardware file or bsops need these */
55 /* Session Directory redirection */
56 BOOL g_redirect
= False
;
57 char g_redirect_server
[64];
58 char g_redirect_domain
[16];
59 char g_redirect_password
[64];
60 char g_redirect_username
[64];
61 char g_redirect_cookie
[128];
62 uint32 g_redirect_flags
= 0;
64 extern int g_tcp_port_rdp
;
66 static int g_deactivated
= 0;
67 static uint32 g_ext_disc_reason
= 0;
76 /* in ui specific file eg win32.c, qt.c, df.c, ... */
78 mi_create_window(void);
84 mi_warning(char * msg
);
86 mi_paint_rect(char * data
, int width
, int height
, int x
, int y
, int cx
, int cy
);
88 mi_begin_update(void);
92 mi_fill_rect(int x
, int y
, int cx
, int cy
, int colour
);
94 mi_screen_copy(int x
, int y
, int cx
, int cy
, int srcx
, int srcy
);
96 mi_set_clip(int x
, int y
, int cx
, int cy
);
100 mi_line(int x1
, int y1
, int x2
, int y2
, int colour
);
102 mi_create_cursor(unsigned int x
, unsigned int y
,
103 int width
, int height
,
104 unsigned char * andmask
, unsigned char * xormask
);
108 mi_destroy_cursor(void * cursor
);
110 mi_set_cursor(void * cursor
);
112 mi_set_null_cursor(void);
114 mi_read_keyboard_state(void);
116 /*****************************************************************************/
117 /* put part of the screen from the backing store to the display */
119 ui_invalidate(int x
, int y
, int cx
, int cy
)
123 if (cx
< 1 || cy
< 1)
127 if (bs_warp_coords(&x
, &y
, &cx
, &cy
, 0, 0))
130 data
= (char *) xmalloc(cx
* cy
* 4);
131 bs_copy_box(data
, x
, y
, cx
, cy
, cx
* ((g_server_depth
+ 7) / 8));
132 mi_paint_rect(data
, cx
, cy
, x
, y
, cx
, cy
);
137 /*****************************************************************************/
143 /*****************************************************************************/
154 /*****************************************************************************/
156 ui_create_cursor(uint32 x
, uint32 y
,
157 int width
, int height
,
158 uint8
* andmask
, uint8
* xormask
)
165 if (width
!= 32 || height
!= 32)
169 memset(am
, 0, 32 * 4);
170 memset(xm
, 0, 32 * 4);
171 for (i
= 0; i
< 32; i
++)
173 for (j
= 0; j
< 32; j
++)
175 if (bs_is_pixel_on((char *)andmask
, j
, i
, 32, 1))
177 bs_set_pixel_on(am
, j
, 31 - i
, 32, 1, 1);
179 if (bs_is_pixel_on((char *)xormask
, j
, i
, 32, 24))
181 bs_set_pixel_on(xm
, j
, 31 - i
, 32, 1, 1);
185 return (void *) mi_create_cursor(x
, y
, width
, height
, (unsigned char *)am
, (unsigned char *)xm
);
188 /*****************************************************************************/
190 ui_destroy_cursor(void * cursor
)
192 mi_destroy_cursor(cursor
);
195 /*****************************************************************************/
197 ui_set_cursor(void * cursor
)
199 mi_set_cursor(cursor
);
202 /*****************************************************************************/
204 ui_set_null_cursor(void)
206 mi_set_null_cursor();
209 /*****************************************************************************/
211 ui_create_glyph(int width
, int height
, uint8
* data
)
216 struct bitmap
* the_glyph
;
218 glyph_data
= (char *) xmalloc(width
* height
);
219 memset(glyph_data
, 0, width
* height
);
220 the_glyph
= (struct bitmap
*) xmalloc(sizeof(struct bitmap
));
221 memset(the_glyph
, 0, sizeof(struct bitmap
));
222 the_glyph
->width
= width
;
223 the_glyph
->height
= height
;
224 the_glyph
->data
= (uint8
*)glyph_data
;
225 for (i
= 0; i
< height
; i
++)
227 for (j
= 0; j
< width
; j
++)
229 if (bs_is_pixel_on((char *)data
, j
, i
, width
, 1))
231 bs_set_pixel_on(glyph_data
, j
, i
, width
, 8, 255);
238 /*****************************************************************************/
240 ui_destroy_glyph(void * glyph
)
242 struct bitmap
* the_glyph
;
247 xfree(the_glyph
->data
);
252 /*****************************************************************************/
254 ui_create_bitmap(int width
, int height
, uint8
* data
)
259 size
= width
* height
* ((g_server_depth
+ 7) / 8);
260 b
= (struct bitmap
*) xmalloc(sizeof(struct bitmap
));
261 b
->data
= (uint8
*) xmalloc(size
);
262 memcpy(b
->data
, data
, size
);
268 /*****************************************************************************/
270 ui_destroy_bitmap(void * bmp
)
274 b
= (struct bitmap
*) bmp
;
282 /*****************************************************************************/
284 ui_paint_bitmap(int x
, int y
, int cx
, int cy
,
285 int width
, int height
, uint8
* data
)
292 ui_memblt(12, x
, y
, cx
, cy
, &b
, 0, 0);
295 /*****************************************************************************/
297 ui_set_clip(int x
, int y
, int cx
, int cy
)
299 bs_set_clip(x
, y
, cx
, cy
);
300 mi_set_clip(x
, y
, cx
, cy
);
303 /*****************************************************************************/
311 /*****************************************************************************/
313 ui_create_colourmap(COLOURMAP
* colours
)
318 n
= MIN(256, colours
->ncolours
);
319 memset(pal_entries
, 0, sizeof(pal_entries
));
320 for (i
= 0; i
< n
; i
++)
322 pal_entries
[i
] = (colours
->colours
[i
].red
<< 16) |
323 (colours
->colours
[i
].green
<< 8) |
324 colours
->colours
[i
].blue
;
329 /*****************************************************************************/
331 ui_set_colourmap(void * map
)
335 /*****************************************************************************/
337 draw_glyph(int x
, int y
, void * glyph
, int fgcolor
)
342 bs_draw_glyph(x
, y
, (char *)b
->data
, b
->width
, b
->height
, fgcolor
);
345 /*****************************************************************************/
346 #define DO_GLYPH(ttext,idx) \
348 glyph = cache_get_font(font, ttext[idx]); \
349 if (!(flags & TEXT2_IMPLICIT_X)) \
351 xyoffset = ttext[++idx]; \
352 if (xyoffset & 0x80) \
354 if (flags & TEXT2_VERTICAL) \
356 y += ttext[idx + 1] | (ttext[idx + 2] << 8); \
360 x += ttext[idx + 1] | (ttext[idx + 2] << 8); \
366 if (flags & TEXT2_VERTICAL) \
378 draw_glyph(x + glyph->offset, y + glyph->baseline, glyph->pixmap, \
380 if (flags & TEXT2_IMPLICIT_X) \
387 /*****************************************************************************/
389 ui_draw_text(uint8 font
, uint8 flags
, uint8 opcode
, int mixmode
,
391 int clipx
, int clipy
, int clipcx
, int clipcy
,
392 int boxx
, int boxy
, int boxcx
, int boxcy
, BRUSH
* brush
,
393 int bgcolour
, int fgcolour
, uint8
* text
, uint8 length
)
401 if (boxx
+ boxcx
> g_width
)
403 boxcx
= g_width
- boxx
;
407 bs_rect(boxx
, boxy
, boxcx
, boxcy
, bgcolour
, 0xc);
411 if (mixmode
== MIX_OPAQUE
)
413 bs_rect(clipx
, clipy
, clipcx
, clipcy
, bgcolour
, 0xc);
416 /* Paint text, character by character */
417 for (i
= 0; i
< length
;)
424 cache_put_text(text
[i
+ 1], text
, text
[i
+ 2]);
428 error("this shouldn't be happening\n");
431 /* this will move pointer from start to first character after */
434 text
= &(text
[i
+ 3]);
438 entry
= cache_get_text(text
[i
+ 1]);
441 if ((((uint8
*) (entry
->data
))[1] == 0) &&
442 (!(flags
& TEXT2_IMPLICIT_X
)))
444 if (flags
& TEXT2_VERTICAL
)
453 for (j
= 0; j
< entry
->size
; j
++)
455 DO_GLYPH(((uint8
*) (entry
->data
)), j
);
467 /* this will move pointer from start to first character after */
480 ui_invalidate(boxx
, boxy
, boxcx
, boxcy
);
484 ui_invalidate(clipx
, clipy
, clipcx
, clipcy
);
488 /*****************************************************************************/
490 ui_line(uint8 opcode
, int startx
, int starty
, int endx
, int endy
,
498 bs_line(opcode
, startx
, starty
, endx
, endy
, pen
->width
, pen
->style
,
500 if (pen
->style
== 0 && pen
->width
< 2 && opcode
== 12)
502 mi_line(startx
, starty
, endx
, endy
, pen
->colour
);
506 x
= MIN(startx
, endx
);
507 y
= MIN(starty
, endy
);
508 cx
= (MAX(startx
, endx
) + 1) - x
;
509 cy
= (MAX(starty
, endy
) + 1) - y
;
510 ui_invalidate(x
, y
, cx
, cy
);
514 /*****************************************************************************/
516 ui_triblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
517 void * src
, int srcx
, int srcy
,
518 BRUSH
* brush
, int bgcolour
, int fgcolour
)
523 /*****************************************************************************/
525 ui_memblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
526 void * src
, int srcx
, int srcy
)
530 b
= (struct bitmap
*)src
;
531 bs_memblt(opcode
, x
, y
, cx
, cy
, b
->data
, b
->width
, b
->height
,
533 ui_invalidate(x
, y
, cx
, cy
);
536 /*****************************************************************************/
538 ui_desktop_restore(uint32 offset
, int x
, int y
, int cx
, int cy
)
542 /*****************************************************************************/
544 ui_desktop_save(uint32 offset
, int x
, int y
, int cx
, int cy
)
548 /*****************************************************************************/
550 ui_rect(int x
, int y
, int cx
, int cy
, int colour
)
552 bs_rect(x
, y
, cx
, cy
, colour
, 12);
553 mi_fill_rect(x
, y
, cx
, cy
, colour
);
556 /*****************************************************************************/
558 ui_screenblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
561 bs_screenblt(opcode
, x
, y
, cx
, cy
, srcx
, srcy
);
564 mi_screen_copy(x
, y
, cx
, cy
, srcx
, srcy
);
568 ui_invalidate(x
, y
, cx
, cy
);
572 /*****************************************************************************/
574 ui_patblt(uint8 opcode
, int x
, int y
, int cx
, int cy
,
575 BRUSH
* brush
, int bgcolour
, int fgcolour
)
577 bs_patblt(opcode
, x
, y
, cx
, cy
, brush
->style
, (char *)brush
->pattern
,
578 brush
->xorigin
, brush
->yorigin
, bgcolour
, fgcolour
);
579 ui_invalidate(x
, y
, cx
, cy
);
582 /*****************************************************************************/
584 ui_destblt(uint8 opcode
, int x
, int y
, int cx
, int cy
)
586 bs_rect(x
, y
, cx
, cy
, 0, opcode
);
587 ui_invalidate(x
, y
, cx
, cy
);
591 /*****************************************************************************/
593 ui_move_pointer(int x
, int y
)
597 /*****************************************************************************/
599 ui_get_numlock_state(uint32 state
)
601 return (uint16
) state
;
604 /*****************************************************************************/
605 /* get the num, caps, and scroll lock state */
606 /* scroll lock is 1, num lock is 2 and caps lock is 4 */
607 /* just returning 0, the hardware specific file is responsable for this */
609 read_keyboard_state(void)
611 return (uint32
) mi_read_keyboard_state();
614 /*****************************************************************************/
616 ui_set_modifier_state(int code
)
620 //error("%8.8x", code);
622 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE
, 0, (uint16
) code
, 0);
626 /*****************************************************************************/
628 ui_resize_window(void)
632 /*****************************************************************************/
634 ui_begin_update(void)
639 /*****************************************************************************/
646 /*****************************************************************************/
648 ui_polygon(uint8 opcode
, uint8 fillmode
, POINT
* point
, int npoints
,
649 BRUSH
* brush
, int bgcolour
, int fgcolour
)
654 /*****************************************************************************/
656 ui_polyline(uint8 opcode
, POINT
* points
, int npoints
, PEN
* pen
)
663 for (i
= 1; i
< npoints
; i
++)
667 ui_line(opcode
, x
, y
, x
+ dx
, y
+ dy
, pen
);
674 /*****************************************************************************/
676 ui_ellipse(uint8 opcode
, uint8 fillmode
,
677 int x
, int y
, int cx
, int cy
,
678 BRUSH
* brush
, int bgcolour
, int fgcolour
)
683 /*****************************************************************************/
684 /* get a 32 byte random */
686 generate_random(uint8
* random
)
692 for (i
= 0; i
< 32; i
++)
694 random
[i
] = rand() >> 16; /* higher bits are more random */
698 /*****************************************************************************/
700 save_licence(uint8
* data
, int length
)
704 /*****************************************************************************/
706 load_licence(uint8
** data
)
711 /*****************************************************************************/
713 xrealloc(void * in
, int size
)
719 return realloc(in
, size
);
722 /*****************************************************************************/
733 /*****************************************************************************/
743 /*****************************************************************************/
745 xstrdup(const char * s
)
755 p
= (char *) xmalloc(len
+ 1);
760 /*****************************************************************************/
762 warning(char * format
, ...)
768 sprintf(text1
, "WARNING: ");
769 va_start(ap
, format
);
770 vsprintf(text
, format
, ap
);
776 /*****************************************************************************/
778 unimpl(char * format
, ...)
784 sprintf(text1
, "UNIMPL: ");
785 va_start(ap
, format
);
786 vsprintf(text
, format
, ap
);
792 /*****************************************************************************/
794 error(char * format
, ...)
800 sprintf(text1
, "ERROR: ");
801 va_start(ap
, format
);
802 vsprintf(text
, format
, ap
);
808 /*****************************************************************************/
810 rd_pstcache_mkdir(void)
815 /*****************************************************************************/
817 rd_open_file(char * filename
)
822 /*****************************************************************************/
824 rd_close_file(int fd
)
829 /*****************************************************************************/
831 rd_read_file(int fd
, void * ptr
, int len
)
836 /*****************************************************************************/
838 rd_write_file(int fd
, void * ptr
, int len
)
843 /*****************************************************************************/
845 rd_lseek_file(int fd
, int offset
)
850 /*****************************************************************************/
852 rd_lock_file(int fd
, int start
, int len
)
858 /*****************************************************************************/
860 ui_mouse_move(int x
, int y
)
862 rdp_send_input(0, RDP_INPUT_MOUSE
, MOUSE_FLAG_MOVE
, (uint16
) x
, (uint16
) y
);
866 /*****************************************************************************/
868 ui_mouse_button(int button
, int x
, int y
, int down
)
875 flags
|= MOUSE_FLAG_DOWN
;
880 flags
|= MOUSE_FLAG_BUTTON1
;
883 flags
|= MOUSE_FLAG_BUTTON2
;
886 flags
|= MOUSE_FLAG_BUTTON3
;
889 flags
|= MOUSE_FLAG_BUTTON4
;
892 flags
|= MOUSE_FLAG_BUTTON5
;
895 rdp_send_input(0, RDP_INPUT_MOUSE
, flags
, (uint16
) x
, (uint16
) y
);
899 /*****************************************************************************/
901 ui_key_down(int key
, int ext
)
904 rdp_send_input(0, RDP_INPUT_SCANCODE
, (uint16
) (RDP_KEYPRESS
| ext
),
908 /*****************************************************************************/
910 ui_key_up(int key
, int ext
)
912 rdp_send_input(0, RDP_INPUT_SCANCODE
, (uint16
) (RDP_KEYRELEASE
| ext
),
916 /*****************************************************************************/
917 /* returns boolean, non zero is good */
921 return rdp_loop(&g_deactivated
, &g_ext_disc_reason
);
924 /*****************************************************************************/
925 /* called after the command line parameters are processed */
926 /* returns boolean, non zero is ok */
933 flags
= RDP_LOGON_NORMAL
;
934 if (g_password
[0] != 0)
936 flags
|= RDP_LOGON_AUTO
;
938 if (!rdp_connect(g_servername
, flags
, g_domain
, g_password
,
939 g_shell
, g_directory
))
943 /* init backingstore */
944 bs_init(g_width
, g_height
, g_server_depth
);
945 /* create the window */
946 if (!mi_create_window())
950 /* if all ok, enter main loop */
951 return mi_main_loop();
954 /*****************************************************************************/
955 /* produce a hex dump */
957 hexdump(uint8
* p
, uint32 len
)
960 int i
, thisline
, offset
= 0;
962 while (offset
< (int)len
)
964 printf("%04x ", offset
);
965 thisline
= len
- offset
;
969 for (i
= 0; i
< thisline
; i
++)
970 printf("%02x ", line
[i
]);
975 for (i
= 0; i
< thisline
; i
++)
976 printf("%c", (line
[i
] >= 0x20 && line
[i
] < 0x7f) ? line
[i
] : '.');