📄 svgawin.c
字号:
/* -*- c-basic-offset: 8 -*- rdesktop: A Remote Desktop Protocol client. User interface services - SVGA lib 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.*/#include "../rdesktop.h"#include <vga.h>#include <vgakeyboard.h>#include <vgamouse.h>#include <vgagl.h>#include <unistd.h> // gethostname#include <pwd.h> // getpwuid#include <stdarg.h> // va_list va_start va_end#include <sys/ioctl.h>#include <linux/keyboard.h>#include <linux/kd.h>#include <fcntl.h>extern int g_tcp_port_rdp;int g_use_rdp5 = 0;char g_hostname[16] = "";char g_username[64] = "";int g_height = 600;int g_width = 800;int g_server_bpp = 8;int g_encryption = 1;int g_desktop_save = 1;int g_polygon_ellipse_orders = 0;int g_bitmap_cache = 1;int g_bitmap_cache_persist_enable = False;int g_bitmap_cache_precache = True;int g_bitmap_compression = 1;int g_rdp5_performanceflags = 0;int g_console_session = 0;int g_keylayout = 0x409; /* Defaults to US keyboard layout *//* hack globals */int g_argc = 0;char** g_argv = 0;int UpAndRunning = 0;int g_sock = 0;int deactivated = 0;uint32 ext_disc_reason = 0;char g_servername[128] = "";static uint32* colmap = 0;static uint8* desk_save = 0;static int g_server_Bpp = 1;/* Keyboard LEDS */static int numlock;static int capslock;static int scrolllock;// this is non null if vgalib has non accel functions available// reading from video memory is sooo slowstatic uint8* sdata = 0;static int g_save_mem = 0; // for video memory use eg sdata == 0// video accelerationstatic int use_accel = 1;static int has_fill_box = 0;static int has_screen_copy = 0;static int has_put_image = 0;// clipint clip_startx;int clip_starty;int clip_endx;int clip_endy;// mouseuint8 mouse_under[32 * 32 * 4]; // save area under mouseint mousex = 0;int mousey = 0;int mouseb = 0;// mouse infotypedef struct{ uint8 andmask[32 * 32]; uint8 xormask[32 * 32]; int x; int y; int w; int h;} tcursor;// mouse globalstatic tcursor mcursor;static int g_draw_mouse = 1;// bitmaptypedef struct{ int width; int height; uint8* data; uint8 Bpp;} bitmap;typedef struct{ int x; int y; int cx; int cy; void* prev; void* next;} myrect;myrect* head_rect = 0;//*****************************************************************************// Keyboard stuff - PeterSstatic void setled(int mask, int state){ int fd; long int leds; if (( fd=open("/dev/console", O_NOCTTY)) != -1 ) { if (ioctl (fd, KDGETLED, &leds) != -1) { leds &= 7; if (state) leds |= mask; else leds &= ~mask; ioctl (fd, KDSETLED, leds); } close(fd); }}//*****************************************************************************// do a raster opint 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;}//*****************************************************************************// get a screen pixelint get_pixel(int x, int y){ if (x >= 0 && x < g_width && y >= 0 && y < g_height) { if (sdata != 0) { if (g_server_Bpp == 1) return sdata[y * g_width + x]; else if (g_server_Bpp == 2) return ((uint16*)sdata)[y * g_width + x]; else return 0; } else return vga_getpixel(x, y); } else return 0;}//*****************************************************************************// set a screen pixelvoid set_pixel(int x, int y, int pixel, int op){ if (x >= clip_startx && x < clip_endx && y >= clip_starty && y < clip_endy) { if (x >= 0 && x < g_width && y >= 0 && y < g_height) { if (op == 0x0) pixel = 0; else if (op == 0xf) pixel = -1; else if (op != 0xc) pixel = rop(op, pixel, get_pixel(x, y)); if (sdata != 0) { if (g_server_Bpp == 1) sdata[y * g_width + x] = pixel; else if (g_server_Bpp == 2) ((uint16*)sdata)[y * g_width + x] = pixel; } else { vga_setcolor(pixel); vga_drawpixel(x, y); } } }}//*****************************************************************************// get a pixel from a bitmapint get_pixel2(int x, int y, uint8* data, int width, int bpp){ if (bpp == 8) return data[y * width + x]; else if (bpp == 16) return ((uint16*)data)[y * width + x]; else return 0;}//*****************************************************************************// set a pixel in a bitmapvoid set_pixel2(int x, int y, int pixel, uint8* data, int width, int bpp){ if (bpp == 8) data[y * width + x] = pixel; else if (bpp == 16) ((uint16*)data)[y * width + x] = pixel;}//*****************************************************************************// get a pointer into a bitmapuint8* get_ptr(int x, int y, uint8* data, int width, int bpp){ if (bpp == 8) return data + (y * width + x); else if (bpp == 16) return data + (y * width + x) * 2; else return 0;}//*****************************************************************************// check if a certain pixel is set in a bitmapBOOL 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 if (bpp == 8) { return data[y * width + x] != 0; } else if (bpp == 24) { return data[(y * 3) * width + (x * 3)] != 0 && data[(y * 3) * width + (x * 3) + 1] != 0 && data[(y * 3) * width + (x * 3) + 2] != 0; } else return False;}//*****************************************************************************void set_pixel_on(uint8* data, int x, int y, int width, int bpp, int pixel){ if (bpp == 8) { data[y * width + x] = pixel; }}/*****************************************************************************/int warp_coords(int* x, int* y, int* cx, int* cy, int* srcx, int* srcy){ int dx; int dy;// int lx = *x, ly = *y, lcx = *cx, lcy = *cy; if (clip_startx > *x) dx = clip_startx - *x; else dx = 0; if (clip_starty > *y) dy = clip_starty - *y; else dy = 0; if (*x + *cx > clip_endx) *cx = (*cx - ((*x + *cx) - clip_endx)) /*+ 1*/; if (*y + *cy > clip_endy) *cy = (*cy - ((*y + *cy) - clip_endy)) /*+ 1*/; *cx = *cx - dx; *cy = *cy - dy; if (*cx <= 0) return False; if (*cy <= 0) return False; *x = *x + dx; *y = *y + dy; if (srcx != NULL) *srcx = *srcx + dx; if (srcy != NULL) *srcy = *srcy + dy;// if (*x != lx || *y != ly || *cx != lcx || *cy != lcy)// printf("%d %d %d %d to %d %d %d %d\n", lx, ly, lcx, lcy, *x, *y, *cx, *cy); return True;}//*****************************************************************************void copy_mem(uint8* d, uint8* s, int n){ while (n & (~7)) { *(d++) = *(s++); *(d++) = *(s++); *(d++) = *(s++); *(d++) = *(s++); *(d++) = *(s++); *(d++) = *(s++); *(d++) = *(s++); *(d++) = *(s++); n = n - 8; } while (n > 0) { *(d++) = *(s++); n--; }}//*****************************************************************************void copy_memb(uint8* d, uint8* s, int n){ d = (d + n) - 1; s = (s + n) - 1; while (n & (~7)) { *(d--) = *(s--); *(d--) = *(s--); *(d--) = *(s--); *(d--) = *(s--); *(d--) = *(s--); *(d--) = *(s--); *(d--) = *(s--); *(d--) = *(s--); n = n - 8; } while (n > 0) { *(d--) = *(s--); n--; }}//*****************************************************************************// all in pixel except line_size is in bytesvoid accel_draw_box(int x, int y, int cx, int cy, uint8* data, int line_size){ int i; uint8* s; uint8* d; if (sdata != 0) { s = data; d = get_ptr(x, y, sdata, g_width, g_server_bpp); for (i = 0; i < cy; i++) { copy_mem(d, s, cx * g_server_Bpp); s = s + line_size; d = d + g_width * g_server_Bpp; } } else if (has_put_image && line_size == cx * g_server_Bpp) { vga_accel(ACCEL_PUTIMAGE, x, y, cx, cy, data); } else { s = data; for (i = 0; i < cy; i++) { vga_drawscansegment(s, x, y + i, cx * g_server_Bpp); s = s + line_size; } }}//*****************************************************************************void accel_fill_rect(int x, int y, int cx, int cy, int color){ int i; uint8* temp; uint8* d; if (sdata != 0) { temp = xmalloc(cx * g_server_Bpp); if (g_server_Bpp == 1) for (i = 0; i < cx; i++) temp[i] = color; else if (g_server_Bpp == 2) for (i = 0; i < cx; i++) ((uint16*)temp)[i] = color; d = get_ptr(x, y, sdata, g_width, g_server_bpp); for (i = 0; i < cy; i++) { copy_mem(d, temp, cx * g_server_Bpp); d = d + g_width * g_server_Bpp; } xfree(temp); } else if (has_fill_box) { vga_accel(ACCEL_SETFGCOLOR, color); vga_accel(ACCEL_FILLBOX, x, y, cx, cy); } else { temp = xmalloc(cx * g_server_Bpp); if (g_server_Bpp == 1) for (i = 0; i < cx; i++) temp[i] = color; else if (g_server_Bpp == 2) for (i = 0; i < cx; i++) ((uint16*)temp)[i] = color; for (i = 0; i < cy; i++) vga_drawscansegment(temp, x, y + i, cx * g_server_Bpp); xfree(temp); }}//*****************************************************************************void accel_screen_copy(int x, int y, int cx, int cy, int srcx, int srcy){ uint8* temp; uint8* s; uint8* d; int i; if (sdata != 0) { if (srcy < y) { // bottom to top s = get_ptr(srcx, (srcy + cy) - 1, sdata, g_width, g_server_bpp); d = get_ptr(x, (y + cy) - 1, sdata, g_width, g_server_bpp); for (i = 0; i < cy; i++) // copy down {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -