/[rdesktop]/sourceforge.net/trunk/rdesktop/uiports/svgawin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/uiports/svgawin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 849 - (show annotations)
Sun Mar 13 03:45:27 2005 UTC (19 years, 3 months ago) by jsorg71
File MIME type: text/plain
File size: 47446 byte(s)
some new orders

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 User interface services - SVGA lib
4 Copyright (C) Jay Sorg 2004-2005
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
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "../rdesktop.h"
22
23 #include <vga.h>
24 #include <vgakeyboard.h>
25 #include <vgamouse.h>
26 #include <vgagl.h>
27
28 #include <unistd.h> // gethostname
29 #include <pwd.h> // getpwuid
30 #include <stdarg.h> // va_list va_start va_end
31
32 #include <sys/ioctl.h>
33 #include <linux/keyboard.h>
34 #include <linux/kd.h>
35 #include <fcntl.h>
36
37 extern int g_tcp_port_rdp;
38 int g_use_rdp5 = 0;
39 char g_hostname[16] = "";
40 char g_username[64] = "";
41 int g_height = 600;
42 int g_width = 800;
43 int g_server_bpp = 8;
44 int g_encryption = 1;
45 int g_desktop_save = 1;
46 int g_polygon_ellipse_orders = 0;
47 int g_bitmap_cache = 1;
48 int g_bitmap_cache_persist_enable = False;
49 int g_bitmap_cache_precache = True;
50 int g_bitmap_compression = 1;
51 int g_rdp5_performanceflags = 0;
52 int g_console_session = 0;
53 int g_keylayout = 0x409; /* Defaults to US keyboard layout */
54
55 /* hack globals */
56 int g_argc = 0;
57 char** g_argv = 0;
58 int UpAndRunning = 0;
59 int g_sock = 0;
60 int deactivated = 0;
61 uint32 ext_disc_reason = 0;
62 char g_servername[128] = "";
63 static uint32* colmap = 0;
64 static uint8* desk_save = 0;
65 static int g_server_Bpp = 1;
66
67 /* Keyboard LEDS */
68 static int numlock;
69 static int capslock;
70 static int scrolllock;
71
72 // this is non null if vgalib has non accel functions available
73 // reading from video memory is sooo slow
74 static uint8* sdata = 0;
75 static int g_save_mem = 0; // for video memory use eg sdata == 0
76
77 // video acceleration
78 static int use_accel = 1;
79 static int has_fill_box = 0;
80 static int has_screen_copy = 0;
81 static int has_put_image = 0;
82
83 // clip
84 int clip_startx;
85 int clip_starty;
86 int clip_endx;
87 int clip_endy;
88
89 // mouse
90 uint8 mouse_under[32 * 32 * 4]; // save area under mouse
91 int mousex = 0;
92 int mousey = 0;
93 int mouseb = 0;
94
95 // mouse info
96 typedef struct
97 {
98 uint8 andmask[32 * 32];
99 uint8 xormask[32 * 32];
100 int x;
101 int y;
102 int w;
103 int h;
104 } tcursor;
105
106 // mouse global
107 static tcursor mcursor;
108
109 static int g_draw_mouse = 1;
110
111 // bitmap
112 typedef struct
113 {
114 int width;
115 int height;
116 uint8* data;
117 uint8 Bpp;
118 } bitmap;
119
120 typedef struct
121 {
122 int x;
123 int y;
124 int cx;
125 int cy;
126 void* prev;
127 void* next;
128 } myrect;
129
130 myrect* head_rect = 0;
131
132 //*****************************************************************************
133 // Keyboard stuff - PeterS
134 static void setled(int mask, int state)
135 {
136 int fd;
137 long int leds;
138
139 if (( fd=open("/dev/console", O_NOCTTY)) != -1 )
140 {
141 if (ioctl (fd, KDGETLED, &leds) != -1)
142 {
143 leds &= 7;
144 if (state)
145 leds |= mask;
146 else
147 leds &= ~mask;
148 ioctl (fd, KDSETLED, leds);
149 }
150 close(fd);
151 }
152 }
153
154
155 //*****************************************************************************
156 // do a raster op
157 int rop(int rop, int src, int dst)
158 {
159 switch (rop)
160 {
161 case 0x0: return 0;
162 case 0x1: return ~(src | dst);
163 case 0x2: return (~src) & dst;
164 case 0x3: return ~src;
165 case 0x4: return src & (~dst);
166 case 0x5: return ~(dst);
167 case 0x6: return src ^ dst;
168 case 0x7: return ~(src & dst);
169 case 0x8: return src & dst;
170 case 0x9: return ~(src) ^ dst;
171 case 0xa: return dst;
172 case 0xb: return (~src) | dst;
173 case 0xc: return src;
174 case 0xd: return src | (~dst);
175 case 0xe: return src | dst;
176 case 0xf: return ~0;
177 }
178 return dst;
179 }
180
181 //*****************************************************************************
182 // get a screen pixel
183 int get_pixel(int x, int y)
184 {
185 if (x >= 0 && x < g_width && y >= 0 && y < g_height)
186 {
187 if (sdata != 0)
188 {
189 if (g_server_Bpp == 1)
190 return sdata[y * g_width + x];
191 else if (g_server_Bpp == 2)
192 return ((uint16*)sdata)[y * g_width + x];
193 else
194 return 0;
195 }
196 else
197 return vga_getpixel(x, y);
198 }
199 else
200 return 0;
201 }
202
203 //*****************************************************************************
204 // set a screen pixel
205 void set_pixel(int x, int y, int pixel, int op)
206 {
207 if (x >= clip_startx && x < clip_endx && y >= clip_starty && y < clip_endy)
208 {
209 if (x >= 0 && x < g_width && y >= 0 && y < g_height)
210 {
211 if (op == 0x0)
212 pixel = 0;
213 else if (op == 0xf)
214 pixel = -1;
215 else if (op != 0xc)
216 pixel = rop(op, pixel, get_pixel(x, y));
217 if (sdata != 0)
218 {
219 if (g_server_Bpp == 1)
220 sdata[y * g_width + x] = pixel;
221 else if (g_server_Bpp == 2)
222 ((uint16*)sdata)[y * g_width + x] = pixel;
223 }
224 else
225 {
226 vga_setcolor(pixel);
227 vga_drawpixel(x, y);
228 }
229 }
230 }
231 }
232
233 //*****************************************************************************
234 // get a pixel from a bitmap
235 int get_pixel2(int x, int y, uint8* data, int width, int bpp)
236 {
237 if (bpp == 8)
238 return data[y * width + x];
239 else if (bpp == 16)
240 return ((uint16*)data)[y * width + x];
241 else
242 return 0;
243 }
244
245 //*****************************************************************************
246 // set a pixel in a bitmap
247 void set_pixel2(int x, int y, int pixel, uint8* data, int width, int bpp)
248 {
249 if (bpp == 8)
250 data[y * width + x] = pixel;
251 else if (bpp == 16)
252 ((uint16*)data)[y * width + x] = pixel;
253 }
254
255 //*****************************************************************************
256 // get a pointer into a bitmap
257 uint8* get_ptr(int x, int y, uint8* data, int width, int bpp)
258 {
259 if (bpp == 8)
260 return data + (y * width + x);
261 else if (bpp == 16)
262 return data + (y * width + x) * 2;
263 else
264 return 0;
265 }
266
267 //*****************************************************************************
268 // check if a certain pixel is set in a bitmap
269 BOOL is_pixel_on(uint8* data, int x, int y, int width, int bpp)
270 {
271 int start;
272 int shift;
273
274 if (bpp == 1)
275 {
276 width = (width + 7) / 8;
277 start = (y * width) + x / 8;
278 shift = x % 8;
279 return (data[start] & (0x80 >> shift)) != 0;
280 }
281 else if (bpp == 8)
282 {
283 return data[y * width + x] != 0;
284 }
285 else if (bpp == 24)
286 {
287 return data[(y * 3) * width + (x * 3)] != 0 &&
288 data[(y * 3) * width + (x * 3) + 1] != 0 &&
289 data[(y * 3) * width + (x * 3) + 2] != 0;
290 }
291 else
292 return False;
293 }
294
295 //*****************************************************************************
296 void set_pixel_on(uint8* data, int x, int y, int width, int bpp, int pixel)
297 {
298 if (bpp == 8)
299 {
300 data[y * width + x] = pixel;
301 }
302 }
303
304 /*****************************************************************************/
305 int warp_coords(int* x, int* y, int* cx, int* cy, int* srcx, int* srcy)
306 {
307 int dx;
308 int dy;
309 // int lx = *x, ly = *y, lcx = *cx, lcy = *cy;
310
311 if (clip_startx > *x)
312 dx = clip_startx - *x;
313 else
314 dx = 0;
315 if (clip_starty > *y)
316 dy = clip_starty - *y;
317 else
318 dy = 0;
319 if (*x + *cx > clip_endx)
320 *cx = (*cx - ((*x + *cx) - clip_endx)) /*+ 1*/;
321 if (*y + *cy > clip_endy)
322 *cy = (*cy - ((*y + *cy) - clip_endy)) /*+ 1*/;
323 *cx = *cx - dx;
324 *cy = *cy - dy;
325 if (*cx <= 0)
326 return False;
327 if (*cy <= 0)
328 return False;
329 *x = *x + dx;
330 *y = *y + dy;
331 if (srcx != NULL)
332 *srcx = *srcx + dx;
333 if (srcy != NULL)
334 *srcy = *srcy + dy;
335
336 // if (*x != lx || *y != ly || *cx != lcx || *cy != lcy)
337 // printf("%d %d %d %d to %d %d %d %d\n", lx, ly, lcx, lcy, *x, *y, *cx, *cy);
338
339 return True;
340 }
341
342 //*****************************************************************************
343 void copy_mem(uint8* d, uint8* s, int n)
344 {
345 while (n & (~7))
346 {
347 *(d++) = *(s++);
348 *(d++) = *(s++);
349 *(d++) = *(s++);
350 *(d++) = *(s++);
351 *(d++) = *(s++);
352 *(d++) = *(s++);
353 *(d++) = *(s++);
354 *(d++) = *(s++);
355 n = n - 8;
356 }
357 while (n > 0)
358 {
359 *(d++) = *(s++);
360 n--;
361 }
362 }
363
364 //*****************************************************************************
365 void copy_memb(uint8* d, uint8* s, int n)
366 {
367 d = (d + n) - 1;
368 s = (s + n) - 1;
369 while (n & (~7))
370 {
371 *(d--) = *(s--);
372 *(d--) = *(s--);
373 *(d--) = *(s--);
374 *(d--) = *(s--);
375 *(d--) = *(s--);
376 *(d--) = *(s--);
377 *(d--) = *(s--);
378 *(d--) = *(s--);
379 n = n - 8;
380 }
381 while (n > 0)
382 {
383 *(d--) = *(s--);
384 n--;
385 }
386 }
387
388 //*****************************************************************************
389 // all in pixel except line_size is in bytes
390 void accel_draw_box(int x, int y, int cx, int cy, uint8* data, int line_size)
391 {
392 int i;
393 uint8* s;
394 uint8* d;
395
396 if (sdata != 0)
397 {
398 s = data;
399 d = get_ptr(x, y, sdata, g_width, g_server_bpp);
400 for (i = 0; i < cy; i++)
401 {
402 copy_mem(d, s, cx * g_server_Bpp);
403 s = s + line_size;
404 d = d + g_width * g_server_Bpp;
405 }
406 }
407 else if (has_put_image && line_size == cx * g_server_Bpp)
408 {
409 vga_accel(ACCEL_PUTIMAGE, x, y, cx, cy, data);
410 }
411 else
412 {
413 s = data;
414 for (i = 0; i < cy; i++)
415 {
416 vga_drawscansegment(s, x, y + i, cx * g_server_Bpp);
417 s = s + line_size;
418 }
419 }
420 }
421
422 //*****************************************************************************
423 void accel_fill_rect(int x, int y, int cx, int cy, int color)
424 {
425 int i;
426 uint8* temp;
427 uint8* d;
428
429 if (sdata != 0)
430 {
431 temp = xmalloc(cx * g_server_Bpp);
432 if (g_server_Bpp == 1)
433 for (i = 0; i < cx; i++)
434 temp[i] = color;
435 else if (g_server_Bpp == 2)
436 for (i = 0; i < cx; i++)
437 ((uint16*)temp)[i] = color;
438 d = get_ptr(x, y, sdata, g_width, g_server_bpp);
439 for (i = 0; i < cy; i++)
440 {
441 copy_mem(d, temp, cx * g_server_Bpp);
442 d = d + g_width * g_server_Bpp;
443 }
444 xfree(temp);
445 }
446 else if (has_fill_box)
447 {
448 vga_accel(ACCEL_SETFGCOLOR, color);
449 vga_accel(ACCEL_FILLBOX, x, y, cx, cy);
450 }
451 else
452 {
453 temp = xmalloc(cx * g_server_Bpp);
454 if (g_server_Bpp == 1)
455 for (i = 0; i < cx; i++)
456 temp[i] = color;
457 else if (g_server_Bpp == 2)
458 for (i = 0; i < cx; i++)
459 ((uint16*)temp)[i] = color;
460 for (i = 0; i < cy; i++)
461 vga_drawscansegment(temp, x, y + i, cx * g_server_Bpp);
462 xfree(temp);
463 }
464 }
465
466 //*****************************************************************************
467 void accel_screen_copy(int x, int y, int cx, int cy, int srcx, int srcy)
468 {
469 uint8* temp;
470 uint8* s;
471 uint8* d;
472 int i;
473
474 if (sdata != 0)
475 {
476 if (srcy < y)
477 { // bottom to top
478 s = get_ptr(srcx, (srcy + cy) - 1, sdata, g_width, g_server_bpp);
479 d = get_ptr(x, (y + cy) - 1, sdata, g_width, g_server_bpp);
480 for (i = 0; i < cy; i++) // copy down
481 {
482 copy_mem(d, s, cx * g_server_Bpp);
483 s = s - g_width * g_server_Bpp;
484 d = d - g_width * g_server_Bpp;
485 }
486 }
487 else if (srcy > y || srcx > x) // copy up or left
488 { // top to bottom
489 s = get_ptr(srcx, srcy, sdata, g_width, g_server_bpp);
490 d = get_ptr(x, y, sdata, g_width, g_server_bpp);
491 for (i = 0; i < cy; i++)
492 {
493 copy_mem(d, s, cx * g_server_Bpp);
494 s = s + g_width * g_server_Bpp;
495 d = d + g_width * g_server_Bpp;
496 }
497 }
498 else // copy straight right
499 {
500 s = get_ptr(srcx, srcy, sdata, g_width, g_server_bpp);
501 d = get_ptr(x, y, sdata, g_width, g_server_bpp);
502 for (i = 0; i < cy; i++)
503 {
504 copy_memb(d, s, cx * g_server_Bpp);
505 s = s + g_width * g_server_Bpp;
506 d = d + g_width * g_server_Bpp;
507 }
508 }
509 }
510 else if (has_screen_copy)
511 {
512 vga_accel(ACCEL_SCREENCOPY, srcx, srcy, x, y, cx, cy);
513 }
514 else
515 {
516 // slow
517 temp = (uint8*)xmalloc(cx * cy * g_server_Bpp);
518 for (i = 0; i < cy; i++)
519 vga_getscansegment(get_ptr(0, i, temp, cx, g_server_bpp), srcx, srcy + i, cx * g_server_Bpp);
520 for (i = 0; i < cy; i++)
521 vga_drawscansegment(get_ptr(0, i, temp, cx, g_server_bpp), x, y + i, cx * g_server_Bpp);
522 xfree(temp);
523 }
524 }
525
526 //*****************************************************************************
527 // return bool
528 int contains_mouse(int x, int y, int cx, int cy)
529 {
530 if (mousex + 32 >= x &&
531 mousey + 32 >= y &&
532 mousex <= x + cx &&
533 mousey <= y + cy)
534 return 1;
535 else
536 return 0;
537 }
538
539 //*****************************************************************************
540 void fill_rect(int x, int y, int cx, int cy, int colour, int opcode)
541 {
542 int i;
543 int j;
544
545 if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
546 {
547 if (opcode == 0xc)
548 accel_fill_rect(x, y, cx, cy, colour);
549 else if (opcode == 0xf)
550 accel_fill_rect(x, y, cx, cy, -1);
551 else if (opcode == 0x0)
552 accel_fill_rect(x, y, cx, cy, 0);
553 else
554 {
555 for (i = 0; i < cy; i++)
556 for (j = 0; j < cx; j++)
557 set_pixel(x + j, y + i, colour, opcode);
558 }
559 }
560 }
561
562 //*****************************************************************************
563 void get_rect(int x, int y, int cx, int cy, uint8* p)
564 {
565 int i;
566
567 if (x < 0)
568 {
569 cx = cx + x;
570 x = 0;
571 }
572 if (y < 0)
573 {
574 cy = cy + y;
575 y = 0;
576 }
577 if (sdata != 0)
578 {
579 for (i = 0; i < cy; i++)
580 {
581 copy_mem(p, get_ptr(x, y + i, sdata, g_width, g_server_bpp), cx * g_server_Bpp);
582 p = p + cx * g_server_Bpp;
583 }
584 }
585 else
586 {
587 for (i = 0; i < cy; i++)
588 {
589 vga_getscansegment(p, x, y + i, cx * g_server_Bpp);
590 p = p + cx * g_server_Bpp;
591 }
592 }
593 }
594
595 /*****************************************************************************/
596 // return true if r1 is contained by r2
597 int is_contained_by(myrect* r1, myrect* r2)
598 {
599 if (r1->x >= r2->x &&
600 r1->y >= r2->y &&
601 r1->x + r1->cx <= r2->x + r2->cx &&
602 r1->y + r1->cy <= r2->y + r2->cy)
603 return 1;
604 else
605 return 0;
606 }
607
608 /*****************************************************************************/
609 void draw_cursor_under(int ox, int oy)
610 {
611 int i;
612 int j;
613 int k;
614 uint8* ptr;
615 int len;
616
617 if (ox < 0)
618 k = -ox;
619 else
620 k = 0;
621 j = g_width - ox;
622 if (j > 32)
623 j = 32;
624 if (j > 0)
625 {
626 for (i = 0; i < 32; i++)
627 {
628 ptr = get_ptr(k, i, mouse_under, 32, g_server_bpp);
629 len = (j - k) * g_server_Bpp;
630 if (ox + k >= 0 && oy + i >= 0 && ox + k < g_width && oy + i < g_height)
631 vga_drawscansegment(ptr, ox + k, oy + i, len);
632 }
633 }
634 g_draw_mouse = 1;
635 }
636
637 /*****************************************************************************/
638 void draw_cursor(void)
639 {
640 int i;
641 int j;
642 int k;
643 int pixel;
644 uint8 mouse_a[32 * 32 * 4];
645 uint8* ptr;
646 int len;
647
648 if (!g_draw_mouse)
649 return;
650 memset(mouse_under, 0, sizeof(mouse_under));
651 for (i = 0; i < 32; i++)
652 {
653 for (j = 0; j < 32; j++)
654 {
655 pixel = get_pixel(mousex + j, mousey + i);
656 set_pixel2(j, i, pixel, mouse_under, 32, g_server_bpp);
657 if (mcursor.andmask[i * 32 + j] == 0)
658 k = 0;
659 else
660 k = ~0;
661 pixel = rop(0x8, k, pixel);
662 if (mcursor.xormask[i * 32 + j] == 0)
663 k = 0;
664 else
665 k = ~0;
666 pixel = rop(0x6, k, pixel);
667 set_pixel2(j, i, pixel, mouse_a, 32, g_server_bpp);
668 }
669 }
670 if (mousex < 0)
671 k = -mousex;
672 else
673 k = 0;
674 j = g_width - mousex;
675 if (j > 32)
676 j = 32;
677 if (j > 0)
678 {
679 for (i = mousey; i < mousey + 32; i++)
680 if (i < g_height && i >= 0)
681 {
682 ptr = get_ptr(k, i - mousey, mouse_a, 32, g_server_bpp);
683 len = (j - k) * g_server_Bpp;
684 vga_drawscansegment(ptr, mousex + k, i, len);
685 }
686 }
687 g_draw_mouse = 0;
688 }
689
690 /*****************************************************************************/
691 // add a rect to cache
692 void cache_rect(int x, int y, int cx, int cy, int do_warp)
693 {
694 myrect* rect;
695 myrect* walk_rect;
696
697 if (sdata == 0)
698 {
699 draw_cursor();
700 return;
701 }
702 if (do_warp)
703 if (!warp_coords(&x, &y, &cx, &cy, NULL, NULL))
704 return;
705 rect = (myrect*)xmalloc(sizeof(myrect));
706 rect->x = x;
707 rect->y = y;
708 rect->cx = cx;
709 rect->cy = cy;
710 rect->next = 0;
711 rect->prev = 0;
712 if (head_rect == 0)
713 head_rect = rect;
714 else
715 {
716 walk_rect = 0;
717 do
718 {
719 if (walk_rect == 0)
720 walk_rect = head_rect;
721 else
722 walk_rect = walk_rect->next;
723 if (is_contained_by(rect, walk_rect))
724 {
725 xfree(rect);
726 return;
727 }
728 }
729 while (walk_rect->next != 0);
730 walk_rect->next = rect;
731 rect->prev = walk_rect;
732 }
733 }
734
735 //*****************************************************************************
736 void draw_cache_rects(void)
737 {
738 int i;
739 myrect* rect;
740 myrect* rect1;
741 uint8* p;
742
743 // draw all the rects
744 rect = head_rect;
745 while (rect != 0)
746 {
747 p = get_ptr(rect->x, rect->y, sdata, g_width, g_server_bpp);
748 for (i = 0; i < rect->cy; i++)
749 {
750 vga_drawscansegment(p, rect->x, rect->y + i, rect->cx * g_server_Bpp);
751 p = p + g_width * g_server_Bpp;
752 }
753 rect1 = rect;
754 rect = rect->next;
755 xfree(rect1);
756 }
757 head_rect = 0;
758 }
759
760 /*****************************************************************************/
761 void key_event(int scancode, int pressed)
762 {
763 int rdpkey;
764 int ext;
765
766 if (!UpAndRunning)
767 return;
768 rdpkey = scancode;
769 ext = 0;
770
771 // Keyboard LEDS
772 if ((scancode == SCANCODE_CAPSLOCK) && pressed)
773 {
774 capslock = !capslock;
775 setled(LED_CAP, capslock);
776 }
777 if ((scancode == SCANCODE_SCROLLLOCK) && pressed)
778 {
779 scrolllock = !scrolllock;
780 setled(LED_SCR, scrolllock);
781 }
782
783 if ((scancode == SCANCODE_NUMLOCK) && pressed)
784 {
785 numlock = !numlock;
786 setled(LED_NUM, numlock);
787 }
788
789 switch (scancode)
790 {
791 case SCANCODE_CURSORBLOCKUP: rdpkey = 0xc8; ext = KBD_FLAG_EXT; break; // up arrow
792 case SCANCODE_CURSORBLOCKDOWN: rdpkey = 0xd0; ext = KBD_FLAG_EXT; break; // down arrow
793 case SCANCODE_CURSORBLOCKRIGHT: rdpkey = 0xcd; ext = KBD_FLAG_EXT; break; // right arrow
794 case SCANCODE_CURSORBLOCKLEFT: rdpkey = 0xcb; ext = KBD_FLAG_EXT; break; // left arrow
795 case SCANCODE_PAGEDOWN: rdpkey = 0xd1; ext = KBD_FLAG_EXT; break; // page down
796 case SCANCODE_PAGEUP: rdpkey = 0xc9; ext = KBD_FLAG_EXT; break; // page up
797 case SCANCODE_HOME: rdpkey = 0xc7; ext = KBD_FLAG_EXT; break; // home
798 case SCANCODE_END: rdpkey = 0xcf; ext = KBD_FLAG_EXT; break; // end
799 case SCANCODE_INSERT: rdpkey = 0xd2; ext = KBD_FLAG_EXT; break; // insert
800 case SCANCODE_REMOVE: rdpkey = 0xd3; ext = KBD_FLAG_EXT; break; // delete
801 case SCANCODE_KEYPADDIVIDE: rdpkey = 0x35; break; // /
802 case SCANCODE_KEYPADENTER: rdpkey = 0x1c; break; // enter
803 case SCANCODE_RIGHTCONTROL: rdpkey = 0x1d; break; // right ctrl
804 case SCANCODE_RIGHTALT: rdpkey = 0x38; break; // right alt
805 case SCANCODE_LEFTWIN: rdpkey = 0x5b; ext = KBD_FLAG_EXT; break; // left win
806 case SCANCODE_RIGHTWIN: rdpkey = 0x5c; ext = KBD_FLAG_EXT; break; // right win
807 case 127: rdpkey = 0x5d; ext = KBD_FLAG_EXT; break; // menu key
808 case SCANCODE_PRINTSCREEN: rdpkey = 0x37; ext = KBD_FLAG_EXT; break; // print screen
809 case SCANCODE_BREAK: //rdpkey = 0; break; // break
810 {
811 if (pressed)
812 {
813 ext = KBD_FLAG_EXT;
814 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS | ext, 0x46, 0);
815 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS | ext, 0xc6, 0);
816 }
817 rdpkey = 0;
818 }
819 case SCANCODE_SCROLLLOCK: rdpkey = 0x46; break; // scroll lock
820 case 112: // mouse down
821 {
822 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON4,
823 mouse_getx(), mouse_gety());
824 return;
825 }
826 case 113: // mouse up
827 {
828 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON5,
829 mouse_getx(), mouse_gety());
830 return;
831 }
832 }
833 // printf("%d %d\n", scancode, pressed);
834 if (pressed)
835 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS | ext, rdpkey, 0);
836 else
837 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE | ext, rdpkey, 0);
838
839
840 }
841
842 /*****************************************************************************/
843 int ui_init(void)
844 {
845 vga_init();
846 memset(&mcursor, 0, sizeof(tcursor));
847 desk_save = (uint8*)xmalloc(0x38400 * g_server_Bpp);
848 return 1;
849 }
850
851 /*****************************************************************************/
852 void ui_deinit(void)
853 {
854 xfree(desk_save);
855 }
856
857 /*****************************************************************************/
858 int ui_create_window(void)
859 {
860 int vgamode;
861 int i;
862
863 vgamode = G800x600x256;
864 if (g_width == 640 && g_height == 480)
865 {
866 if (g_server_Bpp == 1)
867 vgamode = G640x480x256;
868 else if (g_server_Bpp == 2)
869 vgamode = G640x480x64K;
870 }
871 else if (g_width == 800 && g_height == 600)
872 {
873 if (g_server_Bpp == 1)
874 vgamode = G800x600x256;
875 else if (g_server_Bpp == 2)
876 vgamode = G800x600x64K;
877 }
878 else if (g_width == 1024 && g_height == 768)
879 {
880 if (g_server_Bpp == 1)
881 vgamode = G1024x768x256;
882 else if (g_server_Bpp == 2)
883 vgamode = G1024x768x64K;
884 }
885 else
886 {
887 error("Invalid width / height");
888 return 0;
889 }
890 ui_reset_clip();
891 if (!vga_hasmode(vgamode))
892 {
893 error("Graphics unavailable");
894 return 0;
895 }
896 vga_setmousesupport(1);
897 mouse_setposition(g_width / 2, g_height / 2);
898 vga_setmode(vgamode);
899 if (keyboard_init())
900 {
901 error("Keyboard unavailable");
902 return 0;
903 }
904 keyboard_seteventhandler(key_event);
905 if (use_accel)
906 {
907 i = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL);
908 if (i & ACCELFLAG_PUTIMAGE)
909 has_put_image = 1;
910 if (i & ACCELFLAG_SCREENCOPY)
911 has_screen_copy = 1;
912 if (i & ACCELFLAG_FILLBOX)
913 has_fill_box = 1;
914 printf("accel %d\n", i);
915 }
916 if (!has_screen_copy && !g_save_mem)
917 sdata = xmalloc(g_width * g_height * g_server_Bpp);
918 return 1;
919 }
920
921 /*****************************************************************************/
922 void ui_destroy_window(void)
923 {
924 keyboard_close(); /* Don't forget this! */
925 vga_setmode(TEXT);
926 if (sdata != 0)
927 xfree(sdata);
928 }
929
930 /*****************************************************************************/
931 void process_mouse(void)
932 {
933 int ox = mousex;
934 int oy = mousey;
935 int ob = mouseb;
936
937 if (!UpAndRunning)
938 return;
939 mousex = mouse_getx() - mcursor.x;
940 mousey = mouse_gety() - mcursor.y;
941 mouseb = mouse_getbutton();
942
943 if (mouseb != ob) // button
944 {
945 // right button
946 if (mouseb & 1)
947 if (!(ob & 1))
948 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
949 mousex + mcursor.x, mousey + mcursor.y);
950 if (ob & 1)
951 if (!(mouseb & 1))
952 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2,
953 mousex + mcursor.x, mousey + mcursor.y);
954 // middle button
955 if (mouseb & 2)
956 if (!(ob & 2))
957 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON3,
958 mousex + mcursor.x, mousey + mcursor.y);
959 if (ob & 2)
960 if (!(mouseb & 2))
961 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3,
962 mousex + mcursor.x, mousey + mcursor.y);
963 // left button
964 if (mouseb & 4)
965 if (!(ob & 4))
966 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
967 mousex + mcursor.x, mousey + mcursor.y);
968 if (ob & 4)
969 if (!(mouseb & 4))
970 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
971 mousex + mcursor.x, mousey + mcursor.y);
972 }
973 if (mousex != ox || mousey != oy) // movement
974 {
975 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE,
976 mousex + mcursor.x, mousey + mcursor.y);
977 draw_cursor_under(ox, oy);
978 draw_cursor();
979 }
980 }
981
982 /*****************************************************************************/
983 void process_keyboard(void)
984 {
985 if (!UpAndRunning)
986 return;
987 }
988
989 /*****************************************************************************/
990 BOOL ui_main_loop(void)
991 {
992 int sel;
993 fd_set rfds;
994
995 if (!rdp_connect(g_servername, RDP_LOGON_NORMAL, "", "", "", ""))
996 return False;
997 UpAndRunning = 1;
998 FD_ZERO(&rfds);
999 FD_SET(g_sock, &rfds);
1000 sel = vga_waitevent(3, &rfds, NULL, NULL, NULL);
1001 while (sel >= 0)
1002 {
1003 if (sel & 1) /* mouse */
1004 {
1005 process_mouse();
1006 }
1007 else if (sel & 2) /* keyboard */
1008 {
1009 process_keyboard();
1010 }
1011 else
1012 {
1013 if (!rdp_loop(&deactivated, &ext_disc_reason))
1014 return True; /* ok */
1015 }
1016 FD_ZERO(&rfds);
1017 FD_SET(g_sock, &rfds);
1018 sel = vga_waitevent(3, &rfds, NULL, NULL, NULL);
1019 }
1020 return True;
1021 }
1022
1023 /*****************************************************************************/
1024 void ui_bell(void)
1025 {
1026 }
1027
1028 /*****************************************************************************/
1029 int ui_select(int in)
1030 {
1031 g_sock = in;
1032 return 1;
1033 }
1034
1035 /*****************************************************************************/
1036 void* ui_create_glyph(int width, int height, uint8* data)
1037 {
1038 int i, j;
1039 uint8* glyph_data;
1040 bitmap* the_glyph;
1041
1042 glyph_data = (uint8*)xmalloc(width * height);
1043 the_glyph = (bitmap*)xmalloc(sizeof(bitmap));
1044 the_glyph->width = width;
1045 the_glyph->height = height;
1046 the_glyph->data = glyph_data;
1047 memset(glyph_data, 0, width * height);
1048 for (i = 0; i < height; i++)
1049 for (j = 0; j < width; j++)
1050 if (is_pixel_on(data, j, i, width, 1))
1051 set_pixel_on(glyph_data, j, i, width, 8, 255);
1052 return the_glyph;
1053 }
1054
1055 /*****************************************************************************/
1056 void ui_destroy_glyph(void* glyph)
1057 {
1058 bitmap* the_glyph;
1059
1060 the_glyph = (bitmap*)glyph;
1061 if (the_glyph != NULL)
1062 {
1063 if (the_glyph->data != NULL)
1064 xfree(the_glyph->data);
1065 xfree(the_glyph);
1066 }
1067 }
1068
1069 /*****************************************************************************/
1070 void ui_destroy_bitmap(void* bmp)
1071 {
1072 bitmap* b;
1073
1074 b = (bitmap*)bmp;
1075 xfree(b->data);
1076 xfree(b);
1077 }
1078
1079 /*****************************************************************************/
1080 void ui_reset_clip(void)
1081 {
1082 clip_startx = 0;
1083 clip_starty = 0;
1084 clip_endx = g_width;
1085 clip_endy = g_height;
1086 }
1087
1088 /*****************************************************************************/
1089 void ui_set_clip(int x, int y, int cx, int cy)
1090 {
1091 clip_startx = x;
1092 clip_starty = y;
1093 clip_endx = x + cx;
1094 clip_endy = y + cy;
1095 }
1096
1097 /*****************************************************************************/
1098 void* ui_create_colourmap(COLOURMAP * colours)
1099 {
1100 int i = 0;
1101 int n = colours->ncolours;
1102 COLOURENTRY* c = colours->colours;
1103 int* cmap = (int*)xmalloc(3 * 256 * sizeof (int));
1104 if (n > 256)
1105 n = 256;
1106 bzero(cmap, 256 * 3 * sizeof (int));
1107 for (i = 0; i < (3 * n); c++)
1108 {
1109 cmap[i++] = (c->red) >> 2;
1110 cmap[i++] = (c->green) >> 2;
1111 cmap[i++] = (c->blue) >> 2;
1112 }
1113 return cmap;
1114 }
1115
1116 /*****************************************************************************/
1117 void ui_destroy_colourmap(HCOLOURMAP map)
1118 {
1119 if (colmap == map)
1120 colmap = 0;
1121 xfree(map);
1122 }
1123
1124 /*****************************************************************************/
1125 void ui_set_colourmap(void* map)
1126 {
1127 if (colmap != 0)
1128 xfree(colmap);
1129 vga_setpalvec(0, 256, (int*)map);
1130 colmap = map;
1131 }
1132
1133 /*****************************************************************************/
1134 HBITMAP ui_create_bitmap(int width, int height, uint8* data)
1135 {
1136 bitmap* b;
1137
1138 b = (bitmap*)xmalloc(sizeof(bitmap));
1139 b->data = (uint8*)xmalloc(width * height * g_server_Bpp);
1140 b->width = width;
1141 b->height = height;
1142 b->Bpp = g_server_Bpp;
1143 copy_mem(b->data, data, width * height * g_server_Bpp);
1144 return (void*)b;
1145 }
1146
1147 //*****************************************************************************
1148 void draw_glyph (int x, int y, HGLYPH glyph, int fgcolour)
1149 {
1150 bitmap* the_glyph;
1151 int i, j;
1152
1153 the_glyph = (bitmap*)glyph;
1154 if (the_glyph == NULL)
1155 return;
1156 for (i = 0; i < the_glyph->height; i++)
1157 for (j = 0; j < the_glyph->width; j++)
1158 if (is_pixel_on(the_glyph->data, j, i, the_glyph->width, 8))
1159 set_pixel(x + j, y + i, fgcolour, 0xc);
1160 }
1161
1162 #define DO_GLYPH(ttext,idx) \
1163 {\
1164 glyph = cache_get_font (font, ttext[idx]);\
1165 if (!(flags & TEXT2_IMPLICIT_X))\
1166 {\
1167 xyoffset = ttext[++idx];\
1168 if ((xyoffset & 0x80))\
1169 {\
1170 if (flags & TEXT2_VERTICAL) \
1171 y += ttext[idx+1] | (ttext[idx+2] << 8);\
1172 else\
1173 x += ttext[idx+1] | (ttext[idx+2] << 8);\
1174 idx += 2;\
1175 }\
1176 else\
1177 {\
1178 if (flags & TEXT2_VERTICAL) \
1179 y += xyoffset;\
1180 else\
1181 x += xyoffset;\
1182 }\
1183 }\
1184 if (glyph != NULL)\
1185 {\
1186 draw_glyph (x + glyph->offset, y + glyph->baseline, glyph->pixmap, fgcolour);\
1187 if (flags & TEXT2_IMPLICIT_X)\
1188 x += glyph->width;\
1189 }\
1190 }
1191
1192 /*****************************************************************************/
1193 void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode,
1194 int x, int y,
1195 int clipx, int clipy, int clipcx, int clipcy,
1196 int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
1197 int bgcolour, int fgcolour, uint8* text, uint8 length)
1198 {
1199 int i;
1200 int j;
1201 int xyoffset;
1202 DATABLOB* entry;
1203 FONTGLYPH* glyph;
1204
1205 if (boxcx > 1)
1206 {
1207 if (contains_mouse(boxx, boxy, boxcx, boxcy))
1208 draw_cursor_under(mousex, mousey);
1209 fill_rect(boxx, boxy, boxcx, boxcy, bgcolour, 0xc);
1210 }
1211 else
1212 {
1213 if (contains_mouse(clipx, clipy, clipcx, clipcy))
1214 draw_cursor_under(mousex, mousey);
1215 if (mixmode == MIX_OPAQUE)
1216 fill_rect(clipx, clipy, clipcx, clipcy, bgcolour, 0xc);
1217 }
1218
1219 /* Paint text, character by character */
1220 for (i = 0; i < length;)
1221 {
1222 switch (text[i])
1223 {
1224 case 0xff:
1225 if (i + 2 < length)
1226 cache_put_text(text[i + 1], text, text[i + 2]);
1227 else
1228 {
1229 error("this shouldn't be happening\n");
1230 exit(1);
1231 }
1232 /* this will move pointer from start to first character after FF command */
1233 length -= i + 3;
1234 text = &(text[i + 3]);
1235 i = 0;
1236 break;
1237
1238 case 0xfe:
1239 entry = cache_get_text(text[i + 1]);
1240 if (entry != NULL)
1241 {
1242 if ((((uint8 *) (entry->data))[1] == 0) && (!(flags & TEXT2_IMPLICIT_X)))
1243 {
1244 if (flags & TEXT2_VERTICAL)
1245 y += text[i + 2];
1246 else
1247 x += text[i + 2];
1248 }
1249 for (j = 0; j < entry->size; j++)
1250 DO_GLYPH(((uint8 *) (entry->data)), j);
1251 }
1252 if (i + 2 < length)
1253 i += 3;
1254 else
1255 i += 2;
1256 length -= i;
1257 /* this will move pointer from start to first character after FE command */
1258 text = &(text[i]);
1259 i = 0;
1260 break;
1261
1262 default:
1263 DO_GLYPH(text, i);
1264 i++;
1265 break;
1266 }
1267 }
1268 if (boxcx > 1)
1269 cache_rect(boxx, boxy, boxcx, boxcy, True);
1270 else
1271 cache_rect(clipx, clipy, clipcx, clipcy, True);
1272 }
1273
1274 //*****************************************************************************
1275 // Bresenham's line drawing algorithm
1276 void ui_line(uint8 opcode, int startx, int starty, int endx,
1277 int endy, PEN* pen)
1278 {
1279 int dx;
1280 int dy;
1281 int incx;
1282 int incy;
1283 int dpr;
1284 int dpru;
1285 int p;
1286 int left;
1287 int top;
1288 int right;
1289 int bottom;
1290
1291 if (startx > endx)
1292 {
1293 dx = startx - endx;
1294 incx = -1;
1295 left = endx;
1296 right = startx;
1297 }
1298 else
1299 {
1300 dx = endx - startx;
1301 incx = 1;
1302 left = startx;
1303 right = endx;
1304 }
1305 if (starty > endy)
1306 {
1307 dy = starty - endy;
1308 incy = -1;
1309 top = endy;
1310 bottom = starty;
1311 }
1312 else
1313 {
1314 dy = endy - starty;
1315 incy = 1;
1316 top = starty;
1317 bottom = endy;
1318 }
1319 if (contains_mouse(left, top, (right - left) + 1, (bottom - top) + 1))
1320 draw_cursor_under(mousex, mousey);
1321 if (dx >= dy)
1322 {
1323 dpr = dy << 1;
1324 dpru = dpr - (dx << 1);
1325 p = dpr - dx;
1326 for (; dx >= 0; dx--)
1327 {
1328 set_pixel(startx, starty, pen->colour, opcode);
1329 if (p > 0)
1330 {
1331 startx += incx;
1332 starty += incy;
1333 p += dpru;
1334 }
1335 else
1336 {
1337 startx += incx;
1338 p += dpr;
1339 }
1340 }
1341 }
1342 else
1343 {
1344 dpr = dx << 1;
1345 dpru = dpr - (dy << 1);
1346 p = dpr - dy;
1347 for (; dy >= 0; dy--)
1348 {
1349 set_pixel(startx, starty, pen->colour, opcode);
1350 if (p > 0)
1351 {
1352 startx += incx;
1353 starty += incy;
1354 p += dpru;
1355 }
1356 else
1357 {
1358 starty += incy;
1359 p += dpr;
1360 }
1361 }
1362 }
1363 cache_rect(left, top, (right - left) + 1, (bottom - top) + 1, True);
1364 }
1365
1366 /*****************************************************************************/
1367 void ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
1368 HBITMAP src, int srcx, int srcy,
1369 BRUSH* brush, int bgcolour, int fgcolour)
1370 {
1371 // non used
1372 }
1373
1374 /*****************************************************************************/
1375 void ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
1376 HBITMAP src, int srcx, int srcy)
1377 {
1378 bitmap* b;
1379 int i;
1380 int j;
1381 int pixel;
1382
1383 if (warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
1384 {
1385 if (contains_mouse(x, y, cx, cy))
1386 draw_cursor_under(mousex, mousey);
1387 b = (bitmap*)src;
1388 if (opcode == 0xc)
1389 accel_draw_box(x, y, cx, cy, get_ptr(srcx, srcy, b->data, b->width, g_server_bpp),
1390 b->width * g_server_Bpp);
1391 else
1392 {
1393 for (i = 0; i < cy; i++)
1394 {
1395 for (j = 0; j < cx; j++)
1396 {
1397 pixel = get_pixel2(srcx + j, srcy + i, b->data, b->width, g_server_bpp);
1398 set_pixel(x + j, y + i, pixel, opcode);
1399 }
1400 }
1401 }
1402 cache_rect(x, y, cx, cy, False);
1403 }
1404 }
1405
1406 /*****************************************************************************/
1407 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
1408 {
1409 uint8* p;
1410
1411 if (offset > 0x38400)
1412 offset = 0;
1413 if (offset + cx * cy > 0x38400)
1414 return;
1415 p = desk_save + offset * g_server_Bpp;
1416 ui_paint_bitmap(x, y, cx, cy, cx, cy, p);
1417 }
1418
1419 /*****************************************************************************/
1420 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
1421 {
1422 uint8* p;
1423
1424 if (offset > 0x38400)
1425 offset = 0;
1426 if (offset + cx * cy > 0x38400)
1427 return;
1428 if (contains_mouse(x, y, cx, cy))
1429 draw_cursor_under(mousex, mousey);
1430 p = desk_save + offset * g_server_Bpp;
1431 get_rect(x, y, cx, cy, p);
1432 }
1433
1434 /*****************************************************************************/
1435 void ui_rect(int x, int y, int cx, int cy, int colour)
1436 {
1437 if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
1438 {
1439 if (contains_mouse(x, y, cx, cy))
1440 draw_cursor_under(mousex, mousey);
1441 accel_fill_rect(x, y, cx, cy, colour);
1442 cache_rect(x, y, cx, cy, False);
1443 }
1444 }
1445
1446 /*****************************************************************************/
1447 void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
1448 int srcx, int srcy)
1449 {
1450 int i;
1451 int j;
1452 uint8* temp;
1453
1454 if (x == srcx && y == srcy)
1455 return;
1456 if (warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
1457 {
1458 if (contains_mouse(x, y, cx, cy) || contains_mouse(srcx, srcy, cx, cy))
1459 draw_cursor_under(mousex, mousey);
1460 if (opcode == 0xc) /* copy */
1461 accel_screen_copy(x, y, cx, cy, srcx, srcy);
1462 else
1463 {
1464 temp = (uint8*)xmalloc(cx * cy * g_server_Bpp);
1465 for (i = 0; i < cy; i++)
1466 for (j = 0; j < cx; j++)
1467 set_pixel2(j, i, get_pixel(srcx + j, srcy + i), temp, cx, g_server_bpp);
1468 for (i = 0; i < cy; i++)
1469 for (j = 0; j < cx; j++)
1470 set_pixel(x + j, y + i, get_pixel2(j, i, temp, cx, g_server_bpp), opcode);
1471 xfree(temp);
1472 }
1473 cache_rect(x, y, cx, cy, False);
1474 draw_cache_rects(); // draw them all so screen is not jumpy
1475 }
1476 }
1477
1478 /*****************************************************************************/
1479 void ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
1480 BRUSH * brush, int bgcolour, int fgcolour)
1481 {
1482 int i;
1483 int j;
1484 uint8 ipattern[8];
1485
1486 if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
1487 {
1488 if (contains_mouse(x, y, cx, cy))
1489 draw_cursor_under(mousex, mousey);
1490 switch (brush->style)
1491 {
1492 case 0:
1493 fill_rect(x, y, cx, cy, fgcolour, opcode);
1494 break;
1495 case 3:
1496 for (i = 0; i < 8; i++)
1497 ipattern[i] = ~brush->pattern[7 - i];
1498 for (i = 0; i < cy; i++)
1499 for (j = 0; j < cx; j++)
1500 if (is_pixel_on(ipattern, (x + j + brush->xorigin) % 8,
1501 (y + i + brush->yorigin) % 8, 8, 1))
1502 set_pixel(x + j, y + i, fgcolour, opcode);
1503 else
1504 set_pixel(x + j, y + i, bgcolour, opcode);
1505 break;
1506 }
1507 cache_rect(x, y, cx, cy, False);
1508 }
1509 }
1510
1511 /*****************************************************************************/
1512 void ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
1513 {
1514 if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
1515 {
1516 if (contains_mouse(x, y, cx, cy))
1517 draw_cursor_under(mousex, mousey);
1518 fill_rect(x, y, cx, cy, -1, opcode);
1519 cache_rect(x, y, cx, cy, False);
1520 }
1521 }
1522
1523 /*****************************************************************************/
1524 void ui_move_pointer(int x, int y)
1525 {
1526 }
1527
1528 /*****************************************************************************/
1529 void ui_set_null_cursor(void)
1530 {
1531 draw_cursor_under(mousex, mousey);
1532 mousex = mousex - mcursor.x;
1533 mousey = mousey - mcursor.y;
1534 memset(&mcursor, 0, sizeof(mcursor));
1535 memset(mcursor.andmask, 255, sizeof(mcursor.andmask));
1536 memset(mcursor.xormask, 0, sizeof(mcursor.xormask));
1537 draw_cursor();
1538 }
1539
1540 /*****************************************************************************/
1541 void ui_paint_bitmap(int x, int y, int cx, int cy,
1542 int width, int height, uint8* data)
1543 {
1544 if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
1545 {
1546 if (contains_mouse(x, y, cx, cy))
1547 draw_cursor_under(mousex, mousey);
1548 accel_draw_box(x, y, cx, cy, data, width * g_server_Bpp);
1549 cache_rect(x, y, cx, cy, False);
1550 }
1551 }
1552
1553 /*****************************************************************************/
1554 void* ui_create_cursor(unsigned int x, unsigned int y,
1555 int width, int height,
1556 uint8* andmask, uint8* xormask)
1557 {
1558 tcursor* c;
1559 int i;
1560 int j;
1561
1562 c = (tcursor*)xmalloc(sizeof(tcursor));
1563 memset(c, 0, sizeof(tcursor));
1564 c->w = width;
1565 c->h = height;
1566 c->x = x;
1567 c->y = y;
1568 for (i = 0; i < 32; i++)
1569 {
1570 for (j = 0; j < 32; j++)
1571 {
1572 if (is_pixel_on(andmask, j, i, 32, 1))
1573 set_pixel_on(c->andmask, j, 31 - i, 32, 8, 255);
1574 if (is_pixel_on(xormask, j, i, 32, 24))
1575 set_pixel_on(c->xormask, j, 31 - i, 32, 8, 255);
1576 }
1577 }
1578 return (void*)c;
1579 }
1580
1581 /*****************************************************************************/
1582 void ui_destroy_cursor(void* cursor)
1583 {
1584 if (cursor != NULL)
1585 xfree(cursor);
1586 }
1587
1588 /*****************************************************************************/
1589 void ui_set_cursor(void* cursor)
1590 {
1591 int x;
1592 int y;
1593 int ox;
1594 int oy;
1595
1596 ox = mousex;
1597 oy = mousey;
1598 x = mousex + mcursor.x;
1599 y = mousey + mcursor.y;
1600 memcpy(&mcursor, cursor, sizeof(tcursor));
1601 mousex = x - mcursor.x;
1602 mousey = y - mcursor.y;
1603 draw_cursor_under(ox, oy);
1604 draw_cursor();
1605 }
1606
1607 /*****************************************************************************/
1608 uint16 ui_get_numlock_state(unsigned int state)
1609 {
1610 return 0;
1611 }
1612
1613 /*****************************************************************************/
1614 unsigned int read_keyboard_state(void)
1615 {
1616 return 0;
1617 }
1618
1619 /*****************************************************************************/
1620 void ui_resize_window(void)
1621 {
1622 }
1623
1624 /*****************************************************************************/
1625 void ui_begin_update(void)
1626 {
1627 }
1628
1629 /*****************************************************************************/
1630 void ui_end_update(void)
1631 {
1632 draw_cache_rects();
1633 draw_cursor();
1634 }
1635
1636 /*****************************************************************************/
1637 void ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
1638 BRUSH * brush, int bgcolour, int fgcolour)
1639 {
1640 }
1641
1642 /*****************************************************************************/
1643 void ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
1644 {
1645 }
1646
1647 /*****************************************************************************/
1648 void ui_ellipse(uint8 opcode, uint8 fillmode,
1649 int x, int y, int cx, int cy,
1650 BRUSH * brush, int bgcolour, int fgcolour)
1651 {
1652 }
1653
1654 /*****************************************************************************/
1655 void generate_random(uint8* random)
1656 {
1657 memcpy(random, "12345678901234567890123456789012", 32);
1658 }
1659
1660 /*****************************************************************************/
1661 void save_licence(uint8* data, int length)
1662 {
1663 }
1664
1665 /*****************************************************************************/
1666 int load_licence(uint8** data)
1667 {
1668 return 0;
1669 }
1670
1671 /*****************************************************************************/
1672 void* xrealloc(void* in_val, int size)
1673 {
1674 return realloc(in_val, size);
1675 }
1676
1677 /*****************************************************************************/
1678 void* xmalloc(int size)
1679 {
1680 return malloc(size);
1681 }
1682
1683 /*****************************************************************************/
1684 void xfree(void* in_val)
1685 {
1686 free(in_val);
1687 }
1688
1689 /*****************************************************************************/
1690 void warning(char* format, ...)
1691 {
1692 va_list ap;
1693
1694 fprintf(stderr, "WARNING: ");
1695 va_start(ap, format);
1696 vfprintf(stderr, format, ap);
1697 va_end(ap);
1698 }
1699
1700 /*****************************************************************************/
1701 void unimpl(char* format, ...)
1702 {
1703 va_list ap;
1704
1705 fprintf(stderr, "NOT IMPLEMENTED: ");
1706 va_start(ap, format);
1707 vfprintf(stderr, format, ap);
1708 va_end(ap);
1709 }
1710
1711 /*****************************************************************************/
1712 void error(char* format, ...)
1713 {
1714 va_list ap;
1715
1716 fprintf(stderr, "ERROR: ");
1717 va_start(ap, format);
1718 vfprintf(stderr, format, ap);
1719 va_end(ap);
1720 }
1721
1722 BOOL rd_pstcache_mkdir(void)
1723 {
1724 return 0;
1725 }
1726
1727 /*****************************************************************************/
1728 int rd_open_file(char *filename)
1729 {
1730 return 0;
1731 }
1732
1733 /*****************************************************************************/
1734 void rd_close_file(int fd)
1735 {
1736 return;
1737 }
1738
1739 /*****************************************************************************/
1740 int rd_read_file(int fd, void *ptr, int len)
1741 {
1742 return 0;
1743 }
1744
1745 /*****************************************************************************/
1746 int rd_write_file(int fd, void* ptr, int len)
1747 {
1748 return 0;
1749 }
1750
1751 /*****************************************************************************/
1752 int rd_lseek_file(int fd, int offset)
1753 {
1754 return 0;
1755 }
1756
1757 /*****************************************************************************/
1758 BOOL rd_lock_file(int fd, int start, int len)
1759 {
1760 return False;
1761 }
1762
1763 /*****************************************************************************/
1764 void get_username_and_hostname(void)
1765 {
1766 char fullhostname[64];
1767 char* p;
1768 struct passwd* pw;
1769
1770 STRNCPY(g_username, "unknown", sizeof(g_username));
1771 STRNCPY(g_hostname, "unknown", sizeof(g_hostname));
1772 pw = getpwuid(getuid());
1773 if (pw != NULL && pw->pw_name != NULL)
1774 {
1775 STRNCPY(g_username, pw->pw_name, sizeof(g_username));
1776 }
1777 if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
1778 {
1779 p = strchr(fullhostname, '.');
1780 if (p != NULL)
1781 *p = 0;
1782 STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
1783 }
1784 }
1785
1786 /*****************************************************************************/
1787 void out_params(void)
1788 {
1789 fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
1790 fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
1791 fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
1792 fprintf(stderr, "Usage: svgardesktop [options] server\n");
1793 fprintf(stderr, " -g: desktop geometry (WxH)\n");
1794 fprintf(stderr, " -4: use RDP version 4\n");
1795 fprintf(stderr, " -5: use RDP version 5 (default)\n");
1796 fprintf(stderr, " -t: tcp port\n");
1797 fprintf(stderr, " -u: user name\n");
1798 fprintf(stderr, " -n: client hostname\n");
1799 fprintf(stderr, " -d: disable accel funcs\n");
1800 fprintf(stderr, " -a: connection colour depth\n");
1801 fprintf(stderr, " -l: low memory\n");
1802 fprintf(stderr, "\n");
1803 }
1804
1805 /* produce a hex dump */
1806 void hexdump(uint8* p, uint32 len)
1807 {
1808 uint8* line;
1809 int i;
1810 int thisline;
1811 int offset;
1812
1813 line = p;
1814 offset = 0;
1815 while (offset < len)
1816 {
1817 printf("%04x ", offset);
1818 thisline = len - offset;
1819 if (thisline > 16)
1820 thisline = 16;
1821
1822 for (i = 0; i < thisline; i++)
1823 printf("%02x ", line[i]);
1824
1825 for (; i < 16; i++)
1826 printf(" ");
1827
1828 for (i = 0; i < thisline; i++)
1829 printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
1830
1831 printf("\n");
1832 offset += thisline;
1833 line += thisline;
1834 }
1835 }
1836
1837 /*****************************************************************************/
1838 int parse_parameters(int in_argc, char** in_argv)
1839 {
1840 int i;
1841 char* p;
1842
1843 if (in_argc <= 1)
1844 {
1845 out_params();
1846 return 0;
1847 }
1848 g_argc = in_argc;
1849 g_argv = in_argv;
1850 for (i = 1; i < in_argc; i++)
1851 {
1852 strcpy(g_servername, in_argv[i]);
1853 if (strcmp(in_argv[i], "-g") == 0)
1854 {
1855 g_width = strtol(in_argv[i + 1], &p, 10);
1856 if (g_width <= 0)
1857 {
1858 error("invalid geometry\n");
1859 return 0;
1860 }
1861 if (*p == 'x')
1862 g_height = strtol(p + 1, NULL, 10);
1863 if (g_height <= 0)
1864 {
1865 error("invalid geometry\n");
1866 return 0;
1867 }
1868 g_width = (g_width + 3) & ~3;
1869 }
1870 else if (strcmp(in_argv[i], "-4") == 0)
1871 g_use_rdp5 = 0;
1872 else if (strcmp(in_argv[i], "-5") == 0)
1873 g_use_rdp5 = 1;
1874 else if (strcmp(in_argv[i], "-t") == 0)
1875 g_tcp_port_rdp = strtol(in_argv[i + 1], &p, 10);
1876 else if (strcmp(in_argv[i], "-h") == 0)
1877 {
1878 out_params();
1879 return 0;
1880 }
1881 else if (strcmp(in_argv[i], "-n") == 0)
1882 {
1883 STRNCPY(g_hostname, in_argv[i + 1], sizeof(g_hostname));
1884 }
1885 else if (strcmp(in_argv[i], "-u") == 0)
1886 {
1887 STRNCPY(g_username, in_argv[i + 1], sizeof(g_username));
1888 }
1889 else if (strcmp(in_argv[i], "-d") == 0)
1890 {
1891 use_accel = 0;
1892 }
1893 else if (strcmp(in_argv[i], "-a") == 0)
1894 {
1895 g_server_bpp = strtol(in_argv[i + 1], NULL, 10);
1896 if (g_server_bpp != 8 && g_server_bpp != 16)
1897 {
1898 error("invalid server bpp\n");
1899 return 0;
1900 }
1901 g_server_Bpp = (g_server_bpp + 7) / 8;
1902 }
1903 else if (strcmp(in_argv[i], "-l") == 0)
1904 g_save_mem = 1;
1905 }
1906 return 1;
1907 }
1908
1909 /*****************************************************************************/
1910 int main(int in_argc, char** in_argv)
1911 {
1912 get_username_and_hostname();
1913 if (!parse_parameters(in_argc, in_argv))
1914 return 0;
1915 if (!ui_init())
1916 return 1;
1917 if (!ui_create_window())
1918 return 1;
1919 ui_main_loop();
1920 ui_destroy_window();
1921 ui_deinit();
1922 return 0;
1923 }

  ViewVC Help
Powered by ViewVC 1.1.26