ReactOS  0.4.14-dev-41-g31d7680
nanoxwin.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 8 -*-
2  rdesktop: A Remote Desktop Protocol client.
3  User interface services - NanoX(microwindows)
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 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.
19 */
20 /*
21  problems with nanox lib
22  opcodes don't work, can only rely on copy
23  stipple orgins don't work
24  clip seems to affect source too, it should only affect dest
25  in copyarea functions
26 */
27 
28 #include "../rdesktop.h"
29 
30 #include <stdarg.h> /* va_list va_start va_end */
31 #include <unistd.h> /* gethostname */
32 #include <pwd.h> /* getpwuid */
33 
34 #include <nano-X.h>
35 
36 extern int g_tcp_port_rdp;
37 int g_use_rdp5 = 1;
38 char g_hostname[16];
39 char g_username[64];
40 int g_width = 800;
41 int g_height = 600;
42 int g_server_bpp = 16;
43 int g_encryption = 1;
44 int g_desktop_save = 0; /* todo */
53 int g_keylayout = 0x409; /* Defaults to US keyboard layout */
54 int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */
55 int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */
56 int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */
57 
58 static int g_sck = 0;
59 static char g_servername[256] = "";
60 static char g_password[64] = "";
61 static char g_domain[64] = "";
62 static char g_shell[64] = "";
63 static char g_directory[64] = "";
64 static GR_WINDOW_ID g_wnd = 0;
65 static GR_GC_ID g_gc = 0;
66 static GR_GC_ID g_gc_clean = 0;
67 static int g_deactivated = 0;
68 static int g_ext_disc_reason = 0;
69 static GR_SCREEN_INFO g_screen_info;
70 static int g_bpp = 0;
71 static int g_Bpp = 0;
72 static GR_RECT g_clip; /* set in main */
73 static GR_CURSOR_ID g_null_cursor; /* set in main */
75 
76 struct key
77 {
78  int ch1;
79  int ch2;
80  int ch3;
81  int chs; /* shift char */
82 };
83 
84 static struct key g_keys[256];
85 
86 /* Session Directory redirection */
94 
95 #define COLOR16TO32(color) \
96 ( \
97  ((((color >> 8) & 0xf8) | ((color >> 13) & 0x7)) << 0) | \
98  ((((color >> 3) & 0xfc) | ((color >> 9) & 0x3)) << 8) | \
99  ((((color << 3) & 0xf8) | ((color >> 2) & 0x7)) << 16) \
100 )
101 
102 static uint32 g_ops[16] =
103 {
104  GR_MODE_CLEAR, /* 0 */
105  GR_MODE_NOR, /* ~(src | dst) */
106  GR_MODE_ANDINVERTED, /* (~src) & dst */
107  GR_MODE_COPYINVERTED, /* ~src */
108  GR_MODE_ANDREVERSE, /* src & (~dst) */
109  GR_MODE_INVERT, /* ~(dst) */
110  GR_MODE_XOR, /* src ^ dst */
111  GR_MODE_NAND, /* ~(src & dst) */
112  GR_MODE_AND, /* src & dst */
113  GR_MODE_EQUIV, /* ~(src) ^ dst or is it ~(src ^ dst) */
114  GR_MODE_NOOP, /* dst */
115  GR_MODE_ORINVERTED, /* (~src) | dst */
116  GR_MODE_COPY, /* src */
117  GR_MODE_ORREVERSE, /* src | (~dst) */
118  GR_MODE_OR, /* src | dst */
119  GR_MODE_SETTO1 /* ~0 */
120 };
121 
122 /*****************************************************************************/
123 /* do a raster op */
124 static int rop(int rop, int src, int dst)
125 {
126  switch (rop)
127  {
128  case 0x0: return 0;
129  case 0x1: return ~(src | dst);
130  case 0x2: return (~src) & dst;
131  case 0x3: return ~src;
132  case 0x4: return src & (~dst);
133  case 0x5: return ~(dst);
134  case 0x6: return src ^ dst;
135  case 0x7: return ~(src & dst);
136  case 0x8: return src & dst;
137  case 0x9: return ~(src) ^ dst;
138  case 0xa: return dst;
139  case 0xb: return (~src) | dst;
140  case 0xc: return src;
141  case 0xd: return src | (~dst);
142  case 0xe: return src | dst;
143  case 0xf: return ~0;
144  }
145  return dst;
146 }
147 
148 /*****************************************************************************/
149 static int get_pixel32(uint8 * data, int x, int y,
150  int width, int height)
151 {
152  if (x >= 0 && y >= 0 && x < width && y < height)
153  {
154  return *(((int*)data) + (y * width + x));
155  }
156  else
157  {
158  return 0;
159  }
160 }
161 
162 /*****************************************************************************/
163 static void set_pixel32(uint8 * data, int x, int y,
164  int width, int height, int pixel)
165 {
166  if (x >= 0 && y >= 0 && x < width && y < height)
167  {
168  *(((int*)data) + (y * width + x)) = pixel;
169  }
170 }
171 
172 /*****************************************************************************/
173 static int warp_coords(int * x, int * y, int * cx, int * cy,
174  int * srcx, int * srcy)
175 {
176  int dx;
177  int dy;
178 
179  if (g_clip.x > *x)
180  {
181  dx = g_clip.x - *x;
182  }
183  else
184  {
185  dx = 0;
186  }
187  if (g_clip.y > *y)
188  {
189  dy = g_clip.y - *y;
190  }
191  else
192  {
193  dy = 0;
194  }
195  if (*x + *cx > g_clip.x + g_clip.width)
196  {
197  *cx = (*cx - ((*x + *cx) - (g_clip.x + g_clip.width)));
198  }
199  if (*y + *cy > g_clip.y + g_clip.height)
200  {
201  *cy = (*cy - ((*y + *cy) - (g_clip.y + g_clip.height)));
202  }
203  *cx = *cx - dx;
204  *cy = *cy - dy;
205  if (*cx <= 0)
206  {
207  return 0;
208  }
209  if (*cy <= 0)
210  {
211  return 0;
212  }
213  *x = *x + dx;
214  *y = *y + dy;
215  if (srcx != 0)
216  {
217  *srcx = *srcx + dx;
218  }
219  if (srcy != 0)
220  {
221  *srcy = *srcy + dy;
222  }
223  return 1;
224 }
225 
226 /******************************************************************************/
227 /* check if a certain pixel is set in a bitmap */
228 static int is_pixel_on(uint8 * data, int x, int y, int width, int bpp)
229 {
230  int start;
231  int shift;
232 
233  if (bpp == 1)
234  {
235  width = (width + 7) / 8;
236  start = (y * width) + x / 8;
237  shift = x % 8;
238  return (data[start] & (0x80 >> shift)) != 0;
239  }
240  else
241  return 0;
242 }
243 
244 /*****************************************************************************/
245 int ui_select(int in)
246 {
247  if (g_sck == 0)
248  {
249  g_sck = in;
250  }
251  return 1;
252 }
253 
254 /*****************************************************************************/
255 void ui_set_clip(int x, int y, int cx, int cy)
256 {
257  GR_REGION_ID region;
258 
259  g_clip.x = x;
260  g_clip.y = y;
261  g_clip.width = cx;
262  g_clip.height = cy;
263  region = GrNewRegion();
264  GrUnionRectWithRegion(region, &g_clip);
265  GrSetGCRegion(g_gc, region); /* can't destroy region here, i guess gc */
266  /* takes owership, if you destroy it */
267  /* clip is reset, hum */
268 }
269 
270 /*****************************************************************************/
271 void ui_reset_clip(void)
272 {
273  GrSetGCRegion(g_gc, 0);
274  g_clip.x = 0;
275  g_clip.y = 0;
276  g_clip.width = g_width;
277  g_clip.height = g_height;
278 }
279 
280 /*****************************************************************************/
281 void ui_bell(void)
282 {
283  GrBell();
284 }
285 
286 /*****************************************************************************/
287 /* gota convert the rdp glyph to nanox glyph */
288 void * ui_create_glyph(int width, int height, uint8 * data)
289 {
290  char * p, * q, * r;
291  int datasize, i, j;
292 
293  datasize = GR_BITMAP_SIZE(width, height) * sizeof(GR_BITMAP);
294  p = xmalloc(datasize);
295  q = p;
296  r = data;
297  memset(p, 0, datasize);
298  for (i = 0; i < height; i++)
299  {
300  j = 0;
301  while (j + 8 < width)
302  {
303  *q = *(r + 1);
304  q++;
305  r++;
306  *q = *(r - 1);
307  q++;
308  r++;
309  j += 16;
310  }
311  if ((width % 16) <= 8 && (width % 16) > 0)
312  {
313  q++;
314  *q = *r;
315  q++;
316  r++;
317  j += 8;
318  }
319  }
320  return p;
321 }
322 
323 /*****************************************************************************/
324 void ui_destroy_glyph(void * glyph)
325 {
326  xfree(glyph);
327 }
328 
329 /*****************************************************************************/
331 {
332  return 0;
333 }
334 
335 /*****************************************************************************/
336 void ui_set_colourmap(void * map)
337 {
338 }
339 
340 /*****************************************************************************/
342 {
343  GR_WINDOW_ID pixmap;
344  uint8 * p;
345  uint32 i, j, pixel;
346 
347  p = data;
348  pixmap = GrNewPixmap(width, height, 0);
349  if (g_server_bpp == 16 && g_bpp == 32)
350  {
351  p = xmalloc(width * height * g_Bpp);
352  for (i = 0; i < height; i++)
353  {
354  for (j = 0; j < width; j++)
355  {
356  pixel = *(((uint16 *) data) + (i * width + j));
357  pixel = COLOR16TO32(pixel);
358  *(((uint32 *) p) + (i * width + j)) = pixel;
359  }
360  }
361  }
362  GrArea(pixmap, g_gc_clean, 0, 0, width, height, p, MWPF_RGB);
363  if (p != data)
364  {
365  xfree(p);
366  }
367  return (void *) pixmap;
368 }
369 
370 /*****************************************************************************/
371 void ui_destroy_bitmap(void * bmp)
372 {
373  GrDestroyWindow((GR_WINDOW_ID)bmp);
374 }
375 
376 /*****************************************************************************/
377 #define DO_GLYPH(ttext,idx) \
378 { \
379  glyph = cache_get_font (font, ttext[idx]); \
380  if (!(flags & TEXT2_IMPLICIT_X)) \
381  { \
382  xyoffset = ttext[++idx]; \
383  if ((xyoffset & 0x80)) \
384  { \
385  if (flags & TEXT2_VERTICAL) \
386  { \
387  y += ttext[idx+1] | (ttext[idx+2] << 8); \
388  } \
389  else \
390  { \
391  x += ttext[idx+1] | (ttext[idx+2] << 8); \
392  } \
393  idx += 2; \
394  } \
395  else \
396  { \
397  if (flags & TEXT2_VERTICAL) \
398  { \
399  y += xyoffset; \
400  } \
401  else \
402  { \
403  x += xyoffset; \
404  } \
405  } \
406  } \
407  if (glyph != NULL) \
408  { \
409  x1 = x + glyph->offset; \
410  y1 = y + glyph->baseline; \
411  GrBitmap(g_wnd, g_gc, x1, y1, glyph->width, glyph->height, glyph->pixmap); \
412  if (flags & TEXT2_IMPLICIT_X) \
413  { \
414  x += glyph->width; \
415  } \
416  } \
417 }
418 
419 /*****************************************************************************/
420 void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode,
421  int x, int y,
422  int clipx, int clipy, int clipcx, int clipcy,
423  int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
424  int bgcolor, int fgcolor, uint8 * text, uint8 length)
425 {
426  FONTGLYPH * glyph;
427  int i, j, xyoffset, x1, y1;
428  DATABLOB * entry;
429 
430  GrSetGCMode(g_gc, GR_MODE_COPY);
431  GrSetGCUseBackground(g_gc, 0); /* this can be set when gc is created */
432  if (g_server_bpp == 16 && g_bpp == 32)
433  {
434  fgcolor = COLOR16TO32(fgcolor);
435  bgcolor = COLOR16TO32(bgcolor);
436  }
437  GrSetGCForeground(g_gc, bgcolor);
438  if (boxx + boxcx > g_width)
439  {
440  boxcx = g_width - boxx;
441  }
442  if (boxcx > 1)
443  {
444  GrFillRect(g_wnd, g_gc, boxx, boxy, boxcx, boxcy);
445  }
446  else if (mixmode == MIX_OPAQUE)
447  {
448  GrFillRect(g_wnd, g_gc, clipx, clipy, clipcx, clipcy);
449  }
450  GrSetGCForeground(g_gc, fgcolor);
451  /* Paint text, character by character */
452  for (i = 0; i < length;)
453  {
454  switch (text[i])
455  {
456  case 0xff:
457  if (i + 2 < length)
458  {
459  cache_put_text(text[i + 1], text, text[i + 2]);
460  }
461  else
462  {
463  error("this shouldn't be happening\n");
464  exit(1);
465  }
466  /* this will move pointer from start to first character after */
467  /* FF command */
468  length -= i + 3;
469  text = &(text[i + 3]);
470  i = 0;
471  break;
472  case 0xfe:
473  entry = cache_get_text(text[i + 1]);
474  if (entry != NULL)
475  {
476  if ((((uint8 *) (entry->data))[1] == 0) &&
477  (!(flags & TEXT2_IMPLICIT_X)))
478  {
479  if (flags & TEXT2_VERTICAL)
480  {
481  y += text[i + 2];
482  }
483  else
484  {
485  x += text[i + 2];
486  }
487  }
488  for (j = 0; j < entry->size; j++)
489  {
490  DO_GLYPH(((uint8 *) (entry->data)), j);
491  }
492  }
493  if (i + 2 < length)
494  {
495  i += 3;
496  }
497  else
498  {
499  i += 2;
500  }
501  length -= i;
502  /* this will move pointer from start to first character after */
503  /* FE command */
504  text = &(text[i]);
505  i = 0;
506  break;
507  default:
508  DO_GLYPH(text, i);
509  i++;
510  break;
511  }
512  }
513 }
514 
515 /*****************************************************************************/
516 void ui_line(uint8 opcode, int startx, int starty, int endx, int endy,
517  PEN * pen)
518 {
519  uint32 op;
520  uint32 color;
521 
522  color = pen->colour;
523  if (opcode == 5) /* GR_MODE_INVERT, not supported so convert it */
524  { /* i think x ^ -1 = ~x */
525  color = 0xffffffff;
526  opcode = 6; /* GR_MODE_XOR */
527  }
528  if (opcode == 12 || opcode == 6) /* nanox only supports these 2 opcode */
529  {
530  op = g_ops[opcode];
531  GrSetGCMode(g_gc, op);
532  if (g_server_bpp == 16 && g_bpp == 32)
533  {
535  }
536  GrSetGCForeground(g_gc, color);
537  GrLine(g_wnd, g_gc, startx, starty, endx, endy);
538  GrSetGCMode(g_gc, GR_MODE_COPY);
539  }
540  else
541  {
542  unimpl("opcode %d in ui_line\n", opcode);
543  }
544 }
545 
546 /*****************************************************************************/
547 void ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
548  void * src, int srcx, int srcy,
549  BRUSH * brush, int bgcolor, int fgcolor)
550 {
551 /* not used, turned off */
552 }
553 
554 /*****************************************************************************/
555 void ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
556  void * src, int srcx, int srcy)
557 {
558  uint8 * dest;
559  uint8 * source;
560  uint8 * final;
561  GR_WINDOW_INFO wi;
562  int i, j, s, d;
563  GR_WINDOW_ID pixmap;
564 
565  if (opcode == 12)
566  {
567  GrCopyArea(g_wnd, g_gc, x, y, cx, cy, (GR_DRAW_ID)src, srcx, srcy,
568  GR_MODE_COPY);
569  }
570  else /* do opcodes ourself */
571  { /* slow but its correct, ok to be slow here, these are rare */
572  GrGetWindowInfo((GR_DRAW_ID)src, &wi);
573  dest = xmalloc(cx * cy * g_Bpp);
574  source = xmalloc(wi.width * wi.height * g_Bpp);
575  final = xmalloc(cx * cy * g_Bpp);
576  memset(final, 0, cx * cy * g_Bpp);
577  /* dest */
578  GrReadArea(g_wnd, x, y, cx, cy, (GR_PIXELVAL*)dest);
579  /* source */
580  GrReadArea((GR_DRAW_ID)src, 0, 0,
581  wi.width, wi.height, (GR_PIXELVAL*)source);
582  for (i = 0; i < cy; i++)
583  {
584  for (j = 0; j < cx; j++)
585  {
586  s = get_pixel32(source, j + srcx, i + srcy, wi.width, wi.height);
587  d = get_pixel32(dest, j, i, cx ,cy);
588  set_pixel32(final, j, i, cx, cy, rop(opcode, s, d));
589  }
590  }
591  pixmap = GrNewPixmap(cx, cy, 0);
592  GrArea(pixmap, g_gc_clean, 0, 0, cx, cy, final, MWPF_TRUECOLOR0888);
593  GrCopyArea(g_wnd, g_gc, x, y, cx, cy, pixmap, 0, 0, GR_MODE_COPY);
594  GrDestroyWindow(pixmap);
595  xfree(dest);
596  xfree(source);
597  xfree(final);
598  }
599 }
600 
601 /*****************************************************************************/
602 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
603 {
604 /* not used, turned off */
605 }
606 
607 /*****************************************************************************/
608 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
609 {
610 /* not used, turned off */
611 }
612 
613 /*****************************************************************************/
614 void ui_rect(int x, int y, int cx, int cy, int color)
615 {
616  if (g_server_bpp == 16 && g_bpp == 32)
617  {
619  }
620  GrSetGCForeground(g_gc, color);
621  GrFillRect(g_wnd, g_gc, x, y, cx, cy);
622 }
623 
624 /*****************************************************************************/
625 /* using warp_coords cause clip seems to affect source in GrCopyArea */
626 void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
627  int srcx, int srcy)
628 {
629  if (opcode == 12)
630  {
631  if (warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
632  {
633  GrCopyArea(g_wnd, g_gc_clean, x, y, cx, cy, g_wnd, srcx, srcy,
634  GR_MODE_COPY);
635  }
636  }
637  else
638  {
639  unimpl("opcode %d in ui_screenblt\n", opcode);
640  }
641 }
642 
643 /******************************************************************************/
644 /* can't use stipple cause tsorigin don't work, GrPoint too slow,
645  GrPoints too slow but better, using a copy from the screen,
646  do the pattern and copy it back */
647 void ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
648  BRUSH * brush, int bgcolor, int fgcolor)
649 {
650  uint8 ipattern[8], * dest, * final;
651  uint32 op;
652  int i, j, s, d;
653  GR_WINDOW_ID pixmap;
654 
655  if (g_server_bpp == 16 && g_bpp == 32)
656  {
657  fgcolor = COLOR16TO32(fgcolor);
658  bgcolor = COLOR16TO32(bgcolor);
659  }
660  switch (brush->style)
661  {
662  case 0: /* Solid */
663  if (opcode == 12 || opcode == 6)
664  {
665  op = g_ops[opcode];
666  GrSetGCMode(g_gc, op);
667  GrSetGCForeground(g_gc, fgcolor);
668  GrFillRect(g_wnd, g_gc, x, y, cx, cy);
669  GrSetGCMode(g_gc, GR_MODE_COPY);
670  }
671  else
672  {
673  unimpl("opcode %d in ui_patblt solid brush\n", opcode);
674  }
675  break;
676  case 3: /* Pattern - all opcodes ok */
677  for (i = 0; i != 8; i++)
678  {
679  ipattern[7 - i] = brush->pattern[i];
680  }
681  dest = xmalloc(cx * cy * g_Bpp);
682  final = xmalloc(cx * cy * g_Bpp);
683  memset(final, 0, cx * cy * g_Bpp);
684  /* dest */
685  if (opcode != 12)
686  {
687  GrReadArea(g_wnd, x, y, cx, cy, (GR_PIXELVAL*)dest);
688  }
689  for (i = 0; i < cy; i++)
690  {
691  for (j = 0; j < cx; j++)
692  {
693  if (is_pixel_on(ipattern, (x + j + brush->xorigin) % 8,
694  (y + i + brush->yorigin) % 8, 8, 1))
695  {
696  s = fgcolor;
697  }
698  else
699  {
700  s = bgcolor;
701  }
702  d = get_pixel32(dest, j, i, cx ,cy);
703  set_pixel32(final, j, i, cx, cy, rop(opcode, s, d));
704  }
705  }
706  pixmap = GrNewPixmap(cx, cy, 0);
707  GrArea(pixmap, g_gc_clean, 0, 0, cx, cy, final, MWPF_TRUECOLOR0888);
708  GrCopyArea(g_wnd, g_gc, x, y, cx, cy, pixmap, 0, 0, GR_MODE_COPY);
709  GrDestroyWindow(pixmap);
710  xfree(dest);
711  xfree(final);
712  break;
713  }
714 }
715 
716 /*****************************************************************************/
717 void ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
718 {
719  uint32 op;
720 
721  if (opcode == 0) /* black */
722  {
723  GrSetGCForeground(g_gc, 0);
724  opcode = 12;
725  }
726  else if (opcode == 5) /* invert */
727  {
728  GrSetGCForeground(g_gc, 0xffffffff);
729  opcode = 6;
730  }
731  else if (opcode == 15) /* white */
732  {
733  GrSetGCForeground(g_gc, 0xffffffff);
734  opcode = 12;
735  }
736  if (opcode == 12 || opcode == 6)
737  {
738  op = g_ops[opcode];
739  GrSetGCMode(g_gc, op);
740  GrFillRect(g_wnd, g_gc, x, y, cx, cy);
741  GrSetGCMode(g_gc, GR_MODE_COPY);
742  }
743  else
744  {
745  unimpl("opcode %d in ui_destblt\n", opcode);
746  }
747 }
748 
749 /*****************************************************************************/
750 void ui_paint_bitmap(int x, int y, int cx, int cy,
751  int width, int height, uint8 * data)
752 {
753  void * b;
754 
756  ui_memblt(12, x, y, cx, cy, b, 0, 0);
758 }
759 
760 /*****************************************************************************/
761 void ui_move_pointer(int x, int y)
762 {
763  GrMoveCursor(x, y);
764 }
765 
766 /*****************************************************************************/
768 {
769  GrSetWindowCursor(g_wnd, g_null_cursor);
770 }
771 
772 /*****************************************************************************/
773 void ui_set_cursor(void * cursor)
774 {
775  GrSetWindowCursor(g_wnd, (GR_CURSOR_ID)cursor);
776 }
777 
778 //******************************************************************************
779 static int is24on(uint8 * data, int x, int y)
780 {
781  uint8 r, g, b;
782  int start;
783 
784  if (data == 0)
785  {
786  return 0;
787  }
788  start = y * 32 * 3 + x * 3;
789  r = data[start];
790  g = data[start + 1];
791  b = data[start + 2];
792  return !((r == 0) && (g == 0) && (b == 0));
793 }
794 
795 //******************************************************************************
796 static int is1on(uint8 * data, int x, int y)
797 {
798  int start;
799  int shift;
800 
801  if (data == 0)
802  {
803  return 0;
804  }
805  start = (y * 32) / 8 + x / 8;
806  shift = x % 8;
807  return (data[start] & (0x80 >> shift)) == 0;
808 }
809 
810 //******************************************************************************
811 static void set1(uint8 * data, int x, int y)
812 {
813  int start;
814  int shift;
815 
816  if (data == 0)
817  {
818  return;
819  }
820  start = (y * 32) / 8 + x / 8;
821  shift = x % 8;
822  data[start] = data[start] | (0x80 >> shift);
823 }
824 
825 //******************************************************************************
826 static void flipover(uint8 * data)
827 {
828  uint8 adata[128];
829  int index;
830 
831  if (data == 0)
832  {
833  return;
834  }
835  memcpy(adata, data, 128);
836  for (index = 0; index <= 31; index++)
837  {
838  data[127 - (index * 4 + 3)] = adata[index * 4];
839  data[127 - (index * 4 + 2)] = adata[index * 4 + 1];
840  data[127 - (index * 4 + 1)] = adata[index * 4 + 2];
841  data[127 - index * 4] = adata[index * 4 + 3];
842  }
843 }
844 
845 /*****************************************************************************/
847  int width, int height,
848  uint8 * andmask, uint8 * xormask)
849 {
850  uint8 adata[128];
851  uint8 amask[128];
852  GR_BITMAP * databitmap;
853  GR_BITMAP * maskbitmap;
854  GR_CURSOR_ID cursor;
855  int i1, i2, bon, mon;
856 
857  if (width != 32 || height != 32)
858  {
859  return 0;
860  }
861  memset(adata, 0, 128);
862  memset(amask, 0, 128);
863  for (i1 = 0; i1 <= 31; i1++)
864  {
865  for (i2 = 0; i2 <= 31; i2++)
866  {
867  mon = is24on(xormask, i1, i2);
868  bon = is1on(andmask, i1, i2);
869  if (bon ^ mon) // xor
870  {
871  set1(adata, i1, i2);
872  if (!mon)
873  {
874  set1(amask, i1, i2);
875  }
876  }
877  if (mon)
878  {
879  set1(amask, i1, i2);
880  }
881  }
882  }
883  flipover(adata);
884  flipover(amask);
885  databitmap = ui_create_glyph(32, 32, adata);
886  maskbitmap = ui_create_glyph(32, 32, amask);
887  cursor = GrNewCursor(32, 32, x, y, 0xffffff, 0, databitmap, maskbitmap);
888  ui_destroy_glyph(databitmap);
889  ui_destroy_glyph(maskbitmap);
890  return (void*)cursor;
891 }
892 
893 /*****************************************************************************/
895 {
896  GrDestroyCursor((GR_CURSOR_ID)cursor);
897 }
898 
899 /*****************************************************************************/
901 {
902  return 0;
903 }
904 
905 /*****************************************************************************/
907 {
908  return 0;
909 }
910 
911 /*****************************************************************************/
913 {
914 }
915 
916 /*****************************************************************************/
917 void ui_begin_update(void)
918 {
919 }
920 
921 /*****************************************************************************/
922 void ui_end_update(void)
923 {
924 }
925 
926 /*****************************************************************************/
927 void ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
928  BRUSH * brush, int bgcolor, int fgcolor)
929 {
930 /* not used, turned off */
931 }
932 
933 /*****************************************************************************/
934 void ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
935 {
936  int i, x, y, dx, dy;
937 
938  if (npoints > 0)
939  {
940  x = points[0].x;
941  y = points[0].y;
942  for (i = 1; i < npoints; i++)
943  {
944  dx = points[i].x;
945  dy = points[i].y;
946  ui_line(opcode, x, y, x + dx, y + dy, pen);
947  x = x + dx;
948  y = y + dy;
949  }
950  }
951 }
952 
953 /*****************************************************************************/
954 void ui_ellipse(uint8 opcode, uint8 fillmode,
955  int x, int y, int cx, int cy,
956  BRUSH * brush, int bgcolor, int fgcolor)
957 {
958 /* not used, turned off */
959 }
960 
961 /*****************************************************************************/
963 {
964  memcpy(random, "12345678901234567890123456789012", 32);
965 }
966 
967 /*****************************************************************************/
969 {
970 }
971 
972 /*****************************************************************************/
974 {
975  return 0;
976 }
977 
978 /*****************************************************************************/
979 void * xrealloc(void * in, int size)
980 {
981  if (size < 1)
982  {
983  size = 1;
984  }
985  return realloc(in, size);
986 }
987 
988 /*****************************************************************************/
989 void * xmalloc(int size)
990 {
991  return malloc(size);
992 }
993 
994 /*****************************************************************************/
995 void xfree(void * in)
996 {
997  if (in != 0)
998  {
999  free(in);
1000  }
1001 }
1002 
1003 /*****************************************************************************/
1004 char * xstrdup(const char * s)
1005 {
1006  char * mem = strdup(s);
1007  if (mem == NULL)
1008  {
1009  perror("strdup");
1010  exit(1);
1011  }
1012  return mem;
1013 }
1014 
1015 /*****************************************************************************/
1016 void warning(char * format, ...)
1017 {
1018  va_list ap;
1019 
1020  fprintf(stderr, "WARNING: ");
1021  va_start(ap, format);
1022  vfprintf(stderr, format, ap);
1023  va_end(ap);
1024 }
1025 
1026 /*****************************************************************************/
1027 void unimpl(char * format, ...)
1028 {
1029  va_list ap;
1030 
1031  fprintf(stderr, "NOT IMPLEMENTED: ");
1032  va_start(ap, format);
1033  vfprintf(stderr, format, ap);
1034  va_end(ap);
1035 }
1036 
1037 /*****************************************************************************/
1038 void error(char * format, ...)
1039 {
1040  va_list ap;
1041 
1042  fprintf(stderr, "ERROR: ");
1043  va_start(ap, format);
1044  vfprintf(stderr, format, ap);
1045  va_end(ap);
1046 }
1047 
1048 /*****************************************************************************/
1050 {
1051  return 0;
1052 }
1053 
1054 /*****************************************************************************/
1056 {
1057  return 0;
1058 }
1059 
1060 /*****************************************************************************/
1062 {
1063  return;
1064 }
1065 
1066 /*****************************************************************************/
1067 int rd_read_file(int fd, void * ptr, int len)
1068 {
1069  return 0;
1070 }
1071 
1072 /*****************************************************************************/
1073 int rd_write_file(int fd, void * ptr, int len)
1074 {
1075  return 0;
1076 }
1077 
1078 /*****************************************************************************/
1079 int rd_lseek_file(int fd, int offset)
1080 {
1081  return 0;
1082 }
1083 
1084 /*****************************************************************************/
1085 int rd_lock_file(int fd, int start, int len)
1086 {
1087  return False;
1088 }
1089 
1090 /*****************************************************************************/
1091 /*static int key(int ch, int flags)
1092 {
1093  return (ch & 0xffff) | ((flags & 0xffff) << 16);
1094 }*/
1095 
1096 /*****************************************************************************/
1097 static void init_keys(void)
1098 {
1099  memset(&g_keys, 0, sizeof(g_keys));
1100  g_keys[0x01].ch1 = 27; /* esc */
1101  g_keys[0x02].ch1 = '1';
1102  g_keys[0x02].chs = '!';
1103  g_keys[0x03].ch1 = '2';
1104  g_keys[0x03].chs = '@';
1105  g_keys[0x04].ch1 = '3';
1106  g_keys[0x04].chs = '#';
1107  g_keys[0x05].ch1 = '4';
1108  g_keys[0x05].chs = '$';
1109  g_keys[0x06].ch1 = '5';
1110  g_keys[0x06].chs = '%';
1111  g_keys[0x07].ch1 = '6';
1112  g_keys[0x07].chs = '^';
1113  g_keys[0x08].ch1 = '7';
1114  g_keys[0x08].chs = '&';
1115  g_keys[0x09].ch1 = '8';
1116  g_keys[0x09].chs = '*';
1117  g_keys[0x0a].ch1 = '9';
1118  g_keys[0x0a].chs = '(';
1119  g_keys[0x0b].ch1 = '0';
1120  g_keys[0x0b].chs = ')';
1121  g_keys[0x0c].ch1 = '-';
1122  g_keys[0x0c].chs = '_';
1123  g_keys[0x0d].ch1 = '=';
1124  g_keys[0x0d].chs = '+';
1125  g_keys[0x0e].ch1 = 8; /* backspace */
1126  g_keys[0x0f].ch1 = 9; /* tab */
1127  g_keys[0x10].ch1 = 'q';
1128  g_keys[0x10].chs = 'Q';
1129  g_keys[0x11].ch1 = 'w';
1130  g_keys[0x11].chs = 'W';
1131  g_keys[0x12].ch1 = 'e';
1132  g_keys[0x12].chs = 'E';
1133  g_keys[0x13].ch1 = 'r';
1134  g_keys[0x13].chs = 'R';
1135  g_keys[0x14].ch1 = 't';
1136  g_keys[0x14].chs = 'T';
1137  g_keys[0x15].ch1 = 'y';
1138  g_keys[0x15].chs = 'Y';
1139  g_keys[0x16].ch1 = 'u';
1140  g_keys[0x16].chs = 'U';
1141  g_keys[0x17].ch1 = 'i';
1142  g_keys[0x17].chs = 'I';
1143  g_keys[0x18].ch1 = 'o';
1144  g_keys[0x18].chs = 'O';
1145  g_keys[0x19].ch1 = 'p';
1146  g_keys[0x19].chs = 'P';
1147  g_keys[0x1a].ch1 = '[';
1148  g_keys[0x1a].chs = '{';
1149  g_keys[0x1b].ch1 = ']';
1150  g_keys[0x1b].chs = '}';
1151  g_keys[0x1c].ch2 = 13; /* enter */
1152  g_keys[0x1d].ch1 = 63533; /* left control */
1153  g_keys[0x1d].ch2 = 63534; /* right control */
1154  g_keys[0x1e].ch1 = 'a';
1155  g_keys[0x1e].chs = 'A';
1156  g_keys[0x1f].ch1 = 's';
1157  g_keys[0x1f].chs = 'S';
1158  g_keys[0x20].ch1 = 'd';
1159  g_keys[0x20].chs = 'D';
1160  g_keys[0x21].ch1 = 'f';
1161  g_keys[0x21].chs = 'F';
1162  g_keys[0x22].ch1 = 'g';
1163  g_keys[0x22].chs = 'G';
1164  g_keys[0x23].ch1 = 'h';
1165  g_keys[0x23].chs = 'H';
1166  g_keys[0x24].ch1 = 'j';
1167  g_keys[0x24].chs = 'J';
1168  g_keys[0x25].ch1 = 'k';
1169  g_keys[0x25].chs = 'K';
1170  g_keys[0x26].ch1 = 'l';
1171  g_keys[0x26].chs = 'L';
1172  g_keys[0x27].ch1 = ';';
1173  g_keys[0x27].chs = ':';
1174  g_keys[0x28].ch1 = '\'';
1175  g_keys[0x28].chs = '"';
1176  g_keys[0x29].ch1 = '`';
1177  g_keys[0x29].chs = '~';
1178  g_keys[0x2a].ch1 = 63531; /* left shift */
1179  g_keys[0x2b].ch1 = '\\';
1180  g_keys[0x2c].ch1 = 'z';
1181  g_keys[0x2c].chs = 'Z';
1182  g_keys[0x2d].ch1 = 'x';
1183  g_keys[0x2d].chs = 'X';
1184  g_keys[0x2e].ch1 = 'c';
1185  g_keys[0x2e].chs = 'C';
1186  g_keys[0x2f].ch1 = 'v';
1187  g_keys[0x2f].chs = 'V';
1188  g_keys[0x30].ch1 = 'b';
1189  g_keys[0x30].chs = 'B';
1190  g_keys[0x31].ch1 = 'n';
1191  g_keys[0x31].chs = 'N';
1192  g_keys[0x32].ch1 = 'm';
1193  g_keys[0x32].chs = 'M';
1194  g_keys[0x33].ch1 = ',';
1195  g_keys[0x33].chs = '<';
1196  g_keys[0x34].ch1 = '.';
1197  g_keys[0x34].chs = '>';
1198  g_keys[0x35].ch1 = '/';
1199  g_keys[0x35].ch2 = 63509;
1200  g_keys[0x35].chs = '?';
1201  g_keys[0x36].ch1 = 63532; /* right shift */
1202  g_keys[0x37].ch1 = '*'; /* star on keypad */
1203  g_keys[0x37].ch2 = 63510; /* star on keypad */
1204  g_keys[0x38].ch1 = 63535; /* alt */
1205  g_keys[0x38].ch2 = 63536; /* alt */
1206  g_keys[0x39].ch1 = ' ';
1207  g_keys[0x3a].ch1 = 0; /* caps lock */
1208  g_keys[0x3b].ch1 = 63515; /* f1 */
1209  g_keys[0x3c].ch1 = 63516; /* f2 */
1210  g_keys[0x3d].ch1 = 63517; /* f3 */
1211  g_keys[0x3e].ch1 = 63518; /* f4 */
1212  g_keys[0x3f].ch1 = 63519; /* f5 */
1213  g_keys[0x40].ch1 = 63520; /* f6 */
1214  g_keys[0x41].ch1 = 63521; /* f7 */
1215  g_keys[0x42].ch1 = 63522; /* f8 */
1216  g_keys[0x43].ch1 = 63523; /* f9 */
1217  g_keys[0x44].ch1 = 63524; /* f10 */
1218  g_keys[0x45].ch1 = 0; /* num lock */
1219  g_keys[0x46].ch1 = 0; /* scroll lock */
1220  g_keys[0x47].ch1 = 63505; /* home */
1221  g_keys[0x47].ch2 = 63494; /* home */
1222  g_keys[0x48].ch1 = 63490; /* arrow up */
1223  g_keys[0x48].ch2 = 63506; /* arrow up */
1224  g_keys[0x49].ch1 = 63507; /* page up */
1225  g_keys[0x49].ch2 = 63496; /* page up */
1226  g_keys[0x4a].ch1 = '-'; /* -(minus) on keypad */
1227  g_keys[0x4a].ch2 = 63511; /* -(minus) on keypad */
1228  g_keys[0x4b].ch1 = 63502; /* arrow left */
1229  g_keys[0x4b].ch2 = 63488; /* arrow left */
1230  g_keys[0x4c].ch1 = 63503; /* middle(5 key) on keypad */
1231  g_keys[0x4d].ch1 = 63504; /* arrow right */
1232  g_keys[0x4d].ch2 = 63489; /* arrow right */
1233  g_keys[0x4e].ch1 = '+'; /* +(plus) on keypad */
1234  g_keys[0x4e].ch2 = 63512; /* +(plus) on keypad */
1235  g_keys[0x4f].ch1 = 63499; /* end */
1236  g_keys[0x4f].ch2 = 63495; /* end */
1237  g_keys[0x50].ch1 = 63500; /* arrow down */
1238  g_keys[0x50].ch2 = 63491; /* arrow down */
1239  g_keys[0x51].ch1 = 63501; /* page down */
1240  g_keys[0x51].ch2 = 63497; /* page down */
1241  g_keys[0x52].ch1 = 63498; /* insert */
1242  g_keys[0x52].ch2 = 63492; /* insert */
1243  g_keys[0x53].ch1 = 63508; /* delete */
1244  g_keys[0x53].ch2 = 63493; /* delete */
1245  g_keys[0x54].ch1 = 63525; /* f11 */
1246  g_keys[0x54].ch1 = 63527; /* f12 */
1247 }
1248 
1249 /*****************************************************************************/
1250 /* returns 0 if found key */
1251 static int get_sc(GR_EVENT_KEYSTROKE * event_keystroke, int * sc, int * ec)
1252 {
1253  int i;
1254 
1255  //printf("%d %d\n", event_keystroke->ch, event_keystroke->modifiers);
1256  *sc = 0;
1257  *ec = 0;
1258  for (i = 0; i < 256; i++)
1259  {
1260  if (event_keystroke->modifiers & 1) /* shift is down */
1261  {
1262  if (event_keystroke->ch == g_keys[i].chs)
1263  {
1264  *sc = i;
1265  break;
1266  }
1267  }
1268  if (event_keystroke->ch == g_keys[i].ch1 ||
1269  event_keystroke->ch == g_keys[i].ch2 ||
1270  event_keystroke->ch == g_keys[i].ch3)
1271  {
1272  *sc = i;
1273  break;
1274  }
1275  }
1276  if (*sc == 0)
1277  {
1278  return 1;
1279  }
1280  else
1281  {
1282  return 0;
1283  }
1284 }
1285 
1286 /*****************************************************************************/
1287 void static process_keystroke(GR_EVENT_KEYSTROKE * event_keystroke, int down)
1288 {
1289  int sc, ec;
1290 
1291  if (get_sc(event_keystroke, &sc, &ec) == 0)
1292  {
1293  if (down)
1294  {
1296  }
1297  else
1298  {
1300  }
1301  }
1302 }
1303 
1304 /*****************************************************************************/
1305 void nanox_event(GR_EVENT * ev)
1306 {
1307  GR_EVENT_MOUSE * event_mouse;
1308  GR_EVENT_BUTTON * event_button;
1309  GR_EVENT_FDINPUT * event_fdinput;
1310  GR_EVENT_KEYSTROKE * event_keystroke;
1311 
1312  do
1313  {
1314  if (ev->type == GR_EVENT_TYPE_FDINPUT) /* 12 */
1315  {
1316  event_fdinput = (GR_EVENT_FDINPUT *) ev;
1317  if (event_fdinput->fd == g_sck)
1318  {
1320  {
1321  fprintf(stderr, "rdp_loop in nanox_event exit codes %d %d\n",
1323  exit(1);
1324  }
1325  }
1326  }
1327  else if (ev->type == GR_EVENT_TYPE_BUTTON_DOWN) /* 2 */
1328  {
1329  event_button = (GR_EVENT_BUTTON *) ev;
1330  if (event_button->changebuttons & 4) /* left */
1331  {
1333  event_button->x, event_button->y);
1334  }
1335  else if (event_button->changebuttons & 1) /* right */
1336  {
1338  event_button->x, event_button->y);
1339  }
1340  }
1341  else if (ev->type == GR_EVENT_TYPE_BUTTON_UP) /* 3 */
1342  {
1343  event_button = (GR_EVENT_BUTTON *) ev;
1344  if (event_button->changebuttons & 4) /* left */
1345  {
1347  event_button->x, event_button->y);
1348  }
1349  else if (event_button->changebuttons & 1) /* right */
1350  {
1352  event_button->x, event_button->y);
1353  }
1354  }
1355  else if (ev->type == GR_EVENT_TYPE_MOUSE_MOTION) /* 6 */
1356  {
1357  event_mouse = (GR_EVENT_MOUSE *) ev;
1359  event_mouse->x, event_mouse->y);
1360  }
1361  else if (ev->type == GR_EVENT_TYPE_MOUSE_POSITION) /* 7 */
1362  {
1363  /* use GR_EVENT_TYPE_MOUSE_MOTION */
1364  }
1365  else if (ev->type == GR_EVENT_TYPE_KEY_DOWN) /* 8 */
1366  {
1367  event_keystroke = (GR_EVENT_KEYSTROKE *) ev;
1368  process_keystroke(event_keystroke, 1);
1369  }
1370  else if (ev->type == GR_EVENT_TYPE_KEY_UP) /* 9 */
1371  {
1372  event_keystroke = (GR_EVENT_KEYSTROKE *) ev;
1373  process_keystroke(event_keystroke, 0);
1374  }
1375  else if (ev->type == GR_EVENT_TYPE_FOCUS_IN) /* 10 */
1376  {
1377  }
1378  else if (ev->type == GR_EVENT_TYPE_FOCUS_OUT) /* 11 */
1379  {
1380  }
1381  else if (ev->type == GR_EVENT_TYPE_UPDATE) /* 13 */
1382  {
1383  }
1384  GrCheckNextEvent(ev);
1385  } while (ev->type != GR_EVENT_TYPE_NONE);
1386 }
1387 
1388 /*****************************************************************************/
1389 static void get_username_and_hostname(void)
1390 {
1391  char fullhostname[64];
1392  char * p;
1393  struct passwd * pw;
1394 
1395  STRNCPY(g_username, "unknown", sizeof(g_username));
1396  STRNCPY(g_hostname, "unknown", sizeof(g_hostname));
1397  pw = getpwuid(getuid());
1398  if (pw != NULL && pw->pw_name != NULL)
1399  {
1400  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
1401  }
1402  if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
1403  {
1404  p = strchr(fullhostname, '.');
1405  if (p != NULL)
1406  {
1407  *p = 0;
1408  }
1409  STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
1410  }
1411 }
1412 /*****************************************************************************/
1413 static void out_params(void)
1414 {
1415  fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
1416  fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
1417  fprintf(stderr, "nanox uiport by Jay Sorg\n");
1418  fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
1419  fprintf(stderr, "Usage: nanoxrdesktop [options] server\n");
1420  fprintf(stderr, " -u: user name\n");
1421  fprintf(stderr, " -n: client hostname\n");
1422  fprintf(stderr, " -p: password\n");
1423  fprintf(stderr, " -d: domain\n");
1424  fprintf(stderr, " -s: shell\n");
1425  fprintf(stderr, " -c: working directory\n");
1426  fprintf(stderr, "\n");
1427 }
1428 
1429 /*****************************************************************************/
1430 static int parse_parameters(int in_argc, char ** in_argv)
1431 {
1432  int i;
1433 
1434  if (in_argc <= 1)
1435  {
1436  out_params();
1437  return 0;
1438  }
1439  for (i = 1; i < in_argc; i++)
1440  {
1441  strcpy(g_servername, in_argv[i]);
1442  if (strcmp(in_argv[i], "-h") == 0)
1443  {
1444  out_params();
1445  return 0;
1446  }
1447  else if (strcmp(in_argv[i], "-n") == 0)
1448  {
1449  STRNCPY(g_hostname, in_argv[i + 1], sizeof(g_hostname));
1450  }
1451  else if (strcmp(in_argv[i], "-u") == 0)
1452  {
1453  STRNCPY(g_username, in_argv[i + 1], sizeof(g_username));
1454  }
1455  else if (strcmp(in_argv[i], "-p") == 0)
1456  {
1457  STRNCPY(g_password, in_argv[i + 1], sizeof(g_password));
1459  i++;
1460  }
1461  else if (strcmp(in_argv[i], "-d") == 0)
1462  {
1463  STRNCPY(g_domain, in_argv[i + 1], sizeof(g_domain));
1464  i++;
1465  }
1466  else if (strcmp(in_argv[i], "-s") == 0)
1467  {
1468  STRNCPY(g_shell, in_argv[i + 1], sizeof(g_shell));
1469  i++;
1470  }
1471  else if (strcmp(in_argv[i], "-c") == 0)
1472  {
1473  STRNCPY(g_directory, in_argv[i + 1], sizeof(g_directory));
1474  i++;
1475  }
1476  }
1477  return 1;
1478 }
1479 
1480 /*****************************************************************************/
1481 int main(int in_argc, char ** in_argv)
1482 {
1484  /* read command line options */
1485  if (!parse_parameters(in_argc, in_argv))
1486  {
1487  exit(0);
1488  }
1489  /* connect to server */
1490  if (GrOpen() < 0)
1491  {
1492  fprintf(stderr, "Couldn't connect to Nano-X server\n");
1493  exit(1);
1494  }
1495  GrGetScreenInfo(&g_screen_info);
1496  g_bpp = g_screen_info.bpp;
1497  g_Bpp = (g_screen_info.bpp + 7) / 8;
1498  g_width = g_screen_info.vs_width;
1499  g_height = g_screen_info.vs_height;
1500  g_clip.x = 0;
1501  g_clip.y = 0;
1502  g_clip.width = g_width;
1503  g_clip.height = g_height;
1504  if (!((g_bpp == 32 && g_server_bpp == 16) ||
1505  (g_bpp == 16 && g_server_bpp == 16)))
1506  {
1507  fprintf(stderr, "unsupported bpp, server = %d, client = %d\n",
1508  g_server_bpp, g_bpp);
1509  GrClose();
1510  exit(0);
1511  }
1512  init_keys();
1513  /* connect to server */
1515  g_directory))
1516  {
1517  fprintf(stderr, "Error connecting\n");
1518  GrClose();
1519  exit(1);
1520  }
1521  /* create window */
1522  g_wnd = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, g_width, g_height, 0, 0, 0);
1523  /* show window */
1524  GrMapWindow(g_wnd);
1525  /* create graphic context */
1526  g_gc = GrNewGC();
1527  g_gc_clean = GrNewGC();
1528  /* clear screen */
1529  GrSetGCForeground(g_gc, 0);
1530  GrFillRect(g_wnd, g_gc, 0, 0, g_width, g_height);
1531  /* create null cursor */
1532  g_null_cursor = (GR_CURSOR_ID)ui_create_cursor(0, 0, 32, 32, 0, 0);
1533  /* register callbacks, set mask, and run main loop */
1534  GrSelectEvents(g_wnd, -1); /* all events */
1535  GrRegisterInput(g_sck);
1536  GrMainLoop(nanox_event);
1537  /* free null cursor */
1539  /* free graphic context */
1540  GrDestroyGC(g_gc);
1541  GrDestroyGC(g_gc_clean);
1542  /* free window */
1543  GrDestroyWindow(g_wnd);
1544  /* close connection */
1545  GrClose();
1546  return 0;
1547 }
#define realloc
Definition: debug_ros.c:6
DWORD amask
Definition: surface.c:185
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3706
#define RDP_LOGON_NORMAL
Definition: precomp.h:24
void ui_bell(void)
Definition: nanoxwin.c:281
char g_username[64]
Definition: nanoxwin.c:39
GLint GLint GLsizei width
Definition: gl.h:1546
static GR_SCREEN_INFO g_screen_info
Definition: nanoxwin.c:69
#define RDP_KEYPRESS
Definition: constants.h:251
BOOL g_redirect
Definition: nanoxwin.c:87
#define DO_GLYPH(ttext, idx)
Definition: nanoxwin.c:377
#define shift
Definition: input.c:1668
void ui_memblt(uint8 opcode, int x, int y, int cx, int cy, void *src, int srcx, int srcy)
Definition: nanoxwin.c:555
int g_encryption
Definition: nanoxwin.c:43
void generate_random(uint8 *random)
Definition: nanoxwin.c:962
static int get_sc(GR_EVENT_KEYSTROKE *event_keystroke, int *sc, int *ec)
Definition: nanoxwin.c:1251
void ui_set_null_cursor(void)
Definition: nanoxwin.c:767
static int g_bpp
Definition: nanoxwin.c:70
#define TEXT2_IMPLICIT_X
Definition: constants.h:276
char g_redirect_server[64]
Definition: nanoxwin.c:88
void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy)
Definition: nanoxwin.c:626
int g_keyboard_subtype
Definition: nanoxwin.c:55
Definition: mk_font.cpp:20
void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
Definition: nanoxwin.c:608
void * xrealloc(void *in, int size)
Definition: nanoxwin.c:979
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
const WCHAR * text
Definition: package.c:1827
unsigned int uint32
Definition: types.h:32
GLint dy
Definition: linetemp.h:97
void ui_rect(int x, int y, int cx, int cy, int color)
Definition: nanoxwin.c:614
#define free
Definition: debug_ros.c:5
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
Definition: types.h:82
void ui_polygon(uint8 opcode, uint8 fillmode, POINT *point, int npoints, BRUSH *brush, int bgcolor, int fgcolor)
Definition: nanoxwin.c:927
int ui_select(int in)
Definition: nanoxwin.c:245
static int g_ext_disc_reason
Definition: nanoxwin.c:68
void ui_resize_window(void)
Definition: nanoxwin.c:912
GLintptr offset
Definition: glext.h:5920
char g_redirect_password[64]
Definition: nanoxwin.c:90
void * ui_create_cursor(uint32 x, uint32 y, int width, int height, uint8 *andmask, uint8 *xormask)
Definition: nanoxwin.c:846
static int g_Bpp
Definition: nanoxwin.c:71
static void get_username_and_hostname(void)
Definition: nanoxwin.c:1389
#define MIX_OPAQUE
Definition: constants.h:273
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
void ui_line(uint8 opcode, int startx, int starty, int endx, int endy, PEN *pen)
Definition: nanoxwin.c:516
#define MOUSE_FLAG_BUTTON1
Definition: constants.h:255
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static int fd
Definition: io.c:51
void ui_triblt(uint8 opcode, int x, int y, int cx, int cy, void *src, int srcx, int srcy, BRUSH *brush, int bgcolor, int fgcolor)
Definition: nanoxwin.c:547
static GR_GC_ID g_gc
Definition: nanoxwin.c:65
void ui_patblt(uint8 opcode, int x, int y, int cx, int cy, BRUSH *brush, int bgcolor, int fgcolor)
Definition: nanoxwin.c:647
const char * filename
Definition: ioapi.h:135
void ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
Definition: nanoxwin.c:717
static int is1on(uint8 *data, int x, int y)
Definition: nanoxwin.c:796
int ch2
Definition: nanoxwin.c:79
POINTL point
Definition: edittest.c:50
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static int g_sck
Definition: nanoxwin.c:58
static int warp_coords(int *x, int *y, int *cx, int *cy, int *srcx, int *srcy)
Definition: nanoxwin.c:173
static char g_password[64]
Definition: nanoxwin.c:60
int g_width
Definition: nanoxwin.c:40
#define down(mutex)
Definition: glue.h:29
RD_BOOL rdp_loop(RD_BOOL *deactivated, uint32 *ext_disc_reason)
Definition: rdp.c:1695
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MOUSE_FLAG_DOWN
Definition: constants.h:260
RD_BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command, char *directory, RD_BOOL reconnect)
Definition: rdp.c:1742
void ui_set_cursor(void *cursor)
Definition: nanoxwin.c:773
#define va_end(ap)
Definition: acmsvcex.h:90
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint color
Definition: glext.h:6243
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
INT WSAAPI gethostname(OUT char FAR *name, IN INT namelen)
Definition: getxbyxx.c:397
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
int g_tcp_port_rdp
Definition: tcp.c:75
int g_bitmap_cache_persist_enable
Definition: nanoxwin.c:47
static int rop(int rop, int src, int dst)
Definition: nanoxwin.c:124
void ui_set_clip(int x, int y, int cx, int cy)
Definition: nanoxwin.c:255
static PVOID ptr
Definition: dispmode.c:27
static int get_pixel32(uint8 *data, int x, int y, int width, int height)
Definition: nanoxwin.c:149
int g_use_rdp5
Definition: nanoxwin.c:37
void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
Definition: nanoxwin.c:602
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
void cache_put_text(uint8 cache_id, void *data, int length)
Definition: cache.c:335
smooth NULL
Definition: ftsmooth.c:416
int g_bitmap_cache
Definition: nanoxwin.c:46
char * va_list
Definition: acmsvcex.h:78
void * ui_create_colourmap(COLOURMAP *colors)
Definition: nanoxwin.c:330
GLuint index
Definition: glext.h:6031
void ui_end_update(void)
Definition: nanoxwin.c:922
int rd_lock_file(int fd, int start, int len)
Definition: nanoxwin.c:1085
#define b
Definition: ke_i.h:79
static int g_deactivated
Definition: nanoxwin.c:67
void warning(char *format,...)
Definition: nanoxwin.c:1016
char g_redirect_domain[16]
Definition: nanoxwin.c:89
static char g_directory[64]
Definition: nanoxwin.c:63
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
char g_redirect_cookie[128]
Definition: nanoxwin.c:92
void * xmalloc(int size)
Definition: nanoxwin.c:989
static GR_RECT g_clip
Definition: nanoxwin.c:72
#define RDP5_NO_MENUANIMATIONS
Definition: constants.h:271
GLboolean GLboolean g
Definition: glext.h:6204
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
Definition: rdp.c:551
void ui_polyline(uint8 opcode, POINT *points, int npoints, PEN *pen)
Definition: nanoxwin.c:934
#define RDP5_NO_FULLWINDOWDRAG
Definition: constants.h:270
#define COLOR16TO32(color)
Definition: nanoxwin.c:95
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define False
Definition: types.h:25
int ch1
Definition: nanoxwin.c:78
GLsizeiptr size
Definition: glext.h:5919
#define RDP_LOGON_AUTO
Definition: constants.h:261
int rd_pstcache_mkdir(void)
Definition: nanoxwin.c:1049
#define d
Definition: ke_i.h:81
void xfree(void *in)
Definition: nanoxwin.c:995
char g_hostname[16]
Definition: nanoxwin.c:38
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define MOUSE_FLAG_MOVE
Definition: constants.h:254
int rd_lseek_file(int fd, int offset)
Definition: nanoxwin.c:1079
int main(int in_argc, char **in_argv)
Definition: nanoxwin.c:1481
int g_bitmap_compression
Definition: nanoxwin.c:49
Definition: brush.hpp:15
int g_desktop_save
Definition: nanoxwin.c:44
void ui_ellipse(uint8 opcode, uint8 fillmode, int x, int y, int cx, int cy, BRUSH *brush, int bgcolor, int fgcolor)
Definition: nanoxwin.c:954
int g_bitmap_cache_precache
Definition: nanoxwin.c:48
static void out_params(void)
Definition: nanoxwin.c:1413
void ui_reset_clip(void)
Definition: nanoxwin.c:271
unsigned char uint8
Definition: types.h:28
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
static uint32 g_ops[16]
Definition: nanoxwin.c:102
static GR_WINDOW_ID g_wnd
Definition: nanoxwin.c:64
int rd_open_file(char *filename)
Definition: nanoxwin.c:1055
Definition: _map.h:44
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BITMAP bmp
Definition: alphablend.c:62
void * ui_create_glyph(int width, int height, uint8 *data)
Definition: nanoxwin.c:288
GLbitfield flags
Definition: glext.h:7161
void ui_destroy_cursor(void *cursor)
Definition: nanoxwin.c:894
uint32 colour
Definition: types.h:86
void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y, int clipx, int clipy, int clipcx, int clipcy, int boxx, int boxy, int boxcx, int boxcy, BRUSH *brush, int bgcolor, int fgcolor, uint8 *text, uint8 length)
Definition: nanoxwin.c:420
int ch3
Definition: nanoxwin.c:80
GLsizei const GLfloat * points
Definition: glext.h:8112
int g_keyboard_functionkeys
Definition: nanoxwin.c:56
int g_keyboard_type
Definition: nanoxwin.c:54
#define index(s, c)
Definition: various.h:29
void unimpl(char *format,...)
Definition: nanoxwin.c:1027
static GR_CURSOR_ID g_null_cursor
Definition: nanoxwin.c:73
static int state
Definition: maze.c:121
int g_polygon_ellipse_orders
Definition: nanoxwin.c:45
void ui_begin_update(void)
Definition: nanoxwin.c:917
uint32_t entry
Definition: isohybrid.c:63
static void process_keystroke(GR_EVENT_KEYSTROKE *event_keystroke, int down)
Definition: nanoxwin.c:1287
#define RDP5_NO_WALLPAPER
Definition: constants.h:269
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
int chs
Definition: nanoxwin.c:81
GLdouble s
Definition: gl.h:2039
GLenum src
Definition: glext.h:6340
int g_server_bpp
Definition: nanoxwin.c:42
static void set1(uint8 *data, int x, int y)
Definition: nanoxwin.c:811
int g_console_session
Definition: nanoxwin.c:52
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
void save_licence(uint8 *data, int length)
Definition: nanoxwin.c:968
void ui_destroy_bitmap(void *bmp)
Definition: nanoxwin.c:371
uint32 g_redirect_flags
Definition: nanoxwin.c:93
#define random
Definition: rosdhcp.h:81
static int is24on(uint8 *data, int x, int y)
Definition: nanoxwin.c:779
static char g_shell[64]
Definition: nanoxwin.c:62
static void flipover(uint8 *data)
Definition: nanoxwin.c:826
int g_keylayout
Definition: nanoxwin.c:53
const char cursor[]
Definition: icontest.c:13
GLuint in
Definition: glext.h:9616
static int is_pixel_on(uint8 *data, int x, int y, int width, int bpp)
Definition: nanoxwin.c:228
static GR_GC_ID g_gc_clean
Definition: nanoxwin.c:66
void ui_destroy_glyph(void *glyph)
Definition: nanoxwin.c:324
GLuint start
Definition: gl.h:1545
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
unsigned short uint16
Definition: types.h:30
GLenum GLenum dst
Definition: glext.h:6340
void rd_close_file(int fd)
Definition: nanoxwin.c:1061
#define va_start(ap, A)
Definition: acmsvcex.h:91
uid_t getuid()
Definition: uid.c:27
uint16 ui_get_numlock_state(uint32 state)
Definition: nanoxwin.c:900
int g_height
Definition: nanoxwin.c:41
void error(char *format,...)
Definition: nanoxwin.c:1038
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
void * ui_create_bitmap(int width, int height, uint8 *data)
Definition: nanoxwin.c:341
char * strchr(const char *String, int ch)
Definition: utclib.c:501
int rd_write_file(int fd, void *ptr, int len)
Definition: nanoxwin.c:1073
#define MOUSE_FLAG_BUTTON2
Definition: constants.h:256
Definition: mem.c:156
_Out_opt_ int * cx
Definition: commctrl.h:570
char g_redirect_username[64]
Definition: nanoxwin.c:91
static char g_domain[64]
Definition: nanoxwin.c:61
uint32 read_keyboard_state(void)
Definition: nanoxwin.c:906
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
uint32 g_rdp5_performanceflags
Definition: nanoxwin.c:50
void ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 *data)
Definition: nanoxwin.c:750
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static char g_servername[256]
Definition: nanoxwin.c:59
void nanox_event(GR_EVENT *ev)
Definition: nanoxwin.c:1305
static int parse_parameters(int in_argc, char **in_argv)
Definition: nanoxwin.c:1430
#define malloc
Definition: debug_ros.c:4
DWORD bpp
Definition: surface.c:181
UINT op
Definition: effect.c:223
static char * dest
Definition: rtl.c:135
DATABLOB * cache_get_text(uint8 cache_id)
Definition: cache.c:325
#define RDP_KEYRELEASE
Definition: constants.h:252
static int g_flags
Definition: nanoxwin.c:74
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
#define TEXT2_VERTICAL
Definition: constants.h:275
#define memset(x, y, z)
Definition: compat.h:39
int rd_read_file(int fd, void *ptr, int len)
Definition: nanoxwin.c:1067
int load_licence(uint8 **data)
Definition: nanoxwin.c:973
#define VERSION
Definition: rdesktop.h:45
char * xstrdup(const char *s)
Definition: nanoxwin.c:1004
void ui_move_pointer(int x, int y)
Definition: nanoxwin.c:761
Definition: path.c:42
static void init_keys(void)
Definition: nanoxwin.c:1097
static struct key g_keys[256]
Definition: nanoxwin.c:84
static void set_pixel32(uint8 *data, int x, int y, int width, int height, int pixel)
Definition: nanoxwin.c:163
void ui_set_colourmap(void *map)
Definition: nanoxwin.c:336