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 + -
显示快捷键?