nanoxwin.c

来自「远程桌面登陆软件 用rdesktop 但不基于Xwindows 可基于(nano」· C语言 代码 · 共 1,524 行 · 第 1/3 页

C
1,524
字号
/* -*- c-basic-offset: 8 -*-   rdesktop: A Remote Desktop Protocol client.   User interface services - NanoX(microwindows)   Copyright (C) Jay Sorg 2004-2005   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*//*  problems with nanox lib    opcodes don't work, can only rely on copy    stipple orgins don't work    clip seems to affect source too, it should only affect dest      in copyarea functions*/#include "../rdesktop.h"#include <stdarg.h>  /* va_list va_start va_end */#include <unistd.h> /* gethostname */#include <pwd.h> /* getpwuid */#include <nano-X.h>extern int g_tcp_port_rdp;int g_use_rdp5 = 1;char g_hostname[16];char g_username[64];int g_width = 800;int g_height = 600;int g_server_bpp = 16;int g_encryption = 1;int g_desktop_save = 0; /* todo */int g_polygon_ellipse_orders = 0;int g_bitmap_cache = 1;int g_bitmap_cache_persist_enable = 0;int g_bitmap_cache_precache = 1;int g_bitmap_compression = 1;uint32 g_rdp5_performanceflags =  RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;int g_console_session = 0;int g_keylayout = 0x409; /* Defaults to US keyboard layout */static int g_sck = 0;static char g_servername[256] = "";static char g_password[64] = "";static char g_domain[64] = "";static char g_shell[64] = "";static char g_directory[64] = "";static GR_WINDOW_ID g_wnd = 0;static GR_GC_ID g_gc = 0;static GR_GC_ID g_gc_clean = 0;static int g_deactivated = 0;static int g_ext_disc_reason = 0;static GR_SCREEN_INFO g_screen_info;static int g_bpp = 0;static int g_Bpp = 0;static GR_RECT g_clip; /* set in main */static GR_CURSOR_ID g_null_cursor; /* set in main */static int g_flags = RDP_LOGON_NORMAL;struct key{  int ch1;  int ch2;  int ch3;  int chs; /* shift char */};static struct key g_keys[256];#define COLOR16TO32(color) \( \  ((((color >> 8) & 0xf8) | ((color >> 13) & 0x7)) <<  0) | \  ((((color >> 3) & 0xfc) | ((color >>  9) & 0x3)) <<  8) | \  ((((color << 3) & 0xf8) | ((color >>  2) & 0x7)) << 16) \)static uint32 g_ops[16] ={  GR_MODE_CLEAR,         /* 0 */  GR_MODE_NOR,           /* ~(src | dst) */  GR_MODE_ANDINVERTED,   /* (~src) & dst */  GR_MODE_COPYINVERTED,  /* ~src */  GR_MODE_ANDREVERSE,    /* src & (~dst) */  GR_MODE_INVERT,        /* ~(dst) */  GR_MODE_XOR,           /* src ^ dst */  GR_MODE_NAND,          /* ~(src & dst) */  GR_MODE_AND,           /* src & dst */  GR_MODE_EQUIV,         /* ~(src) ^ dst or is it ~(src ^ dst) */  GR_MODE_NOOP,          /* dst */  GR_MODE_ORINVERTED,    /* (~src) | dst */  GR_MODE_COPY,          /* src */  GR_MODE_ORREVERSE,     /* src | (~dst) */  GR_MODE_OR,            /* src | dst */  GR_MODE_SETTO1         /* ~0 */};/*****************************************************************************//* do a raster op */static int rop(int rop, int src, int dst){  switch (rop)  {    case 0x0: return 0;    case 0x1: return ~(src | dst);    case 0x2: return (~src) & dst;    case 0x3: return ~src;    case 0x4: return src & (~dst);    case 0x5: return ~(dst);    case 0x6: return src ^ dst;    case 0x7: return ~(src & dst);    case 0x8: return src & dst;    case 0x9: return ~(src) ^ dst;    case 0xa: return dst;    case 0xb: return (~src) | dst;    case 0xc: return src;    case 0xd: return src | (~dst);    case 0xe: return src | dst;    case 0xf: return ~0;  }  return dst;}/*****************************************************************************/static int get_pixel32(uint8 * data, int x, int y,                       int width, int height){  if (x >= 0 && y >= 0 && x < width && y < height)  {    return *(((int*)data) + (y * width + x));  }  else  {    return 0;  }}/*****************************************************************************/static void set_pixel32(uint8 * data, int x, int y,                        int width, int height, int pixel){  if (x >= 0 && y >= 0 && x < width && y < height)  {    *(((int*)data) + (y * width + x)) = pixel;  }}/*****************************************************************************/static int warp_coords(int * x, int * y, int * cx, int * cy,                       int * srcx, int * srcy){  int dx;  int dy;  if (g_clip.x > *x)  {    dx = g_clip.x - *x;  }  else  {    dx = 0;  }  if (g_clip.y > *y)  {    dy = g_clip.y - *y;  }  else  {    dy = 0;  }  if (*x + *cx > g_clip.x + g_clip.width)  {    *cx = (*cx - ((*x + *cx) - (g_clip.x + g_clip.width)));  }  if (*y + *cy > g_clip.y + g_clip.height)  {    *cy = (*cy - ((*y + *cy) - (g_clip.y + g_clip.height)));  }  *cx = *cx - dx;  *cy = *cy - dy;  if (*cx <= 0)  {    return 0;  }  if (*cy <= 0)  {    return 0;  }  *x = *x + dx;  *y = *y + dy;  if (srcx != 0)  {    *srcx = *srcx + dx;  }  if (srcy != 0)  {    *srcy = *srcy + dy;  }  return 1;}/******************************************************************************//* check if a certain pixel is set in a bitmap */static int is_pixel_on(uint8 * data, int x, int y, int width, int bpp){  int start;  int shift;  if (bpp == 1)  {    width = (width + 7) / 8;    start = (y * width) + x / 8;    shift = x % 8;    return (data[start] & (0x80 >> shift)) != 0;  }  else    return 0;}/*****************************************************************************/int ui_select(int in){  if (g_sck == 0)  {    g_sck = in;  }  return 1;}/*****************************************************************************/void ui_set_clip(int x, int y, int cx, int cy){  GR_REGION_ID region;  g_clip.x = x;  g_clip.y = y;  g_clip.width = cx;  g_clip.height = cy;  region = GrNewRegion();  GrUnionRectWithRegion(region, &g_clip);  GrSetGCRegion(g_gc, region); /* can't destroy region here, i guess gc */                               /* takes owership, if you destroy it */                               /* clip is reset, hum */}/*****************************************************************************/void ui_reset_clip(void){  GrSetGCRegion(g_gc, 0);  g_clip.x = 0;  g_clip.y = 0;  g_clip.width = g_width;  g_clip.height = g_height;}/*****************************************************************************/void ui_bell(void){  GrBell();}/*****************************************************************************//* gota convert the rdp glyph to nanox glyph */void * ui_create_glyph(int width, int height, uint8 * data){  char * p, * q, * r;  int datasize, i, j;  datasize = GR_BITMAP_SIZE(width, height) * sizeof(GR_BITMAP);  p = xmalloc(datasize);  q = p;  r = data;  memset(p, 0, datasize);  for (i = 0; i < height; i++)  {    j = 0;    while (j + 8 < width)    {      *q = *(r + 1);      q++;      r++;      *q = *(r - 1);      q++;      r++;      j += 16;    }    if ((width % 16) <= 8 && (width % 16) > 0)    {      q++;      *q = *r;      q++;      r++;      j += 8;    }  }  return p;}/*****************************************************************************/void ui_destroy_glyph(void * glyph){  xfree(glyph);}/*****************************************************************************/void * ui_create_colourmap(COLOURMAP * colors){  return 0;}/*****************************************************************************/void ui_set_colourmap(void * map){}/*****************************************************************************/void * ui_create_bitmap(int width, int height, uint8 * data){  GR_WINDOW_ID pixmap;  uint8 * p;  uint32 i, j, pixel;  p = data;  pixmap = GrNewPixmap(width, height, 0);  if (g_server_bpp == 16 && g_bpp == 32)  {    p = xmalloc(width * height * g_Bpp);    for (i = 0; i < height; i++)    {      for (j = 0; j < width; j++)      {        pixel = *(((uint16 *) data) + (i * width + j));        pixel = COLOR16TO32(pixel);        *(((uint32 *) p) + (i * width + j)) = pixel;      }    }  }  GrArea(pixmap, g_gc_clean, 0, 0, width, height, p, MWPF_RGB);  if (p != data)  {    xfree(p);  }  return (void *) pixmap;}/*****************************************************************************/void ui_destroy_bitmap(void * bmp){  GrDestroyWindow((GR_WINDOW_ID)bmp);}/*****************************************************************************/#define DO_GLYPH(ttext,idx) \{ \  glyph = cache_get_font (font, ttext[idx]); \  if (!(flags & TEXT2_IMPLICIT_X)) \  { \    xyoffset = ttext[++idx]; \    if ((xyoffset & 0x80)) \    { \      if (flags & TEXT2_VERTICAL) \      { \        y += ttext[idx+1] | (ttext[idx+2] << 8); \      } \      else \      { \        x += ttext[idx+1] | (ttext[idx+2] << 8); \      } \      idx += 2; \    } \    else \    { \      if (flags & TEXT2_VERTICAL) \      { \        y += xyoffset; \      } \      else \      { \        x += xyoffset; \      } \    } \  } \  if (glyph != NULL) \  { \    x1 = x + glyph->offset; \    y1 = y + glyph->baseline; \    GrBitmap(g_wnd, g_gc, x1, y1, glyph->width, glyph->height, glyph->pixmap); \    if (flags & TEXT2_IMPLICIT_X) \    { \      x += glyph->width; \    } \  } \}/*****************************************************************************/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){  FONTGLYPH * glyph;  int i, j, xyoffset, x1, y1;  DATABLOB * entry;  GrSetGCMode(g_gc, GR_MODE_COPY);  GrSetGCUseBackground(g_gc, 0); /* this can be set when gc is created */  if (g_server_bpp == 16 && g_bpp == 32)  {    fgcolor = COLOR16TO32(fgcolor);    bgcolor = COLOR16TO32(bgcolor);  }  GrSetGCForeground(g_gc, bgcolor);  if (boxx + boxcx > g_width)  {    boxcx = g_width - boxx;  }  if (boxcx > 1)  {    GrFillRect(g_wnd, g_gc, boxx, boxy, boxcx, boxcy);  }  else if (mixmode == MIX_OPAQUE)  {    GrFillRect(g_wnd, g_gc, clipx, clipy, clipcx, clipcy);  }  GrSetGCForeground(g_gc, fgcolor);  /* Paint text, character by character */  for (i = 0; i < length;)  {    switch (text[i])    {      case 0xff:        if (i + 2 < length)        {          cache_put_text(text[i + 1], text, text[i + 2]);        }        else        {          error("this shouldn't be happening\n");          exit(1);        }        /* this will move pointer from start to first character after */        /* FF command */        length -= i + 3;        text = &(text[i + 3]);        i = 0;        break;      case 0xfe:        entry = cache_get_text(text[i + 1]);        if (entry != NULL)        {          if ((((uint8 *) (entry->data))[1] == 0) &&                                (!(flags & TEXT2_IMPLICIT_X)))          {            if (flags & TEXT2_VERTICAL)            {              y += text[i + 2];            }            else            {              x += text[i + 2];            }          }          for (j = 0; j < entry->size; j++)          {            DO_GLYPH(((uint8 *) (entry->data)), j);          }        }        if (i + 2 < length)        {          i += 3;        }        else        {          i += 2;        }        length -= i;        /* this will move pointer from start to first character after */        /* FE command */        text = &(text[i]);        i = 0;        break;      default:        DO_GLYPH(text, i);        i++;        break;    }  }}/*****************************************************************************/void ui_line(uint8 opcode, int startx, int starty, int endx, int endy,             PEN * pen){  uint32 op;  uint32 color;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?