📄 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 */
int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */
int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */
int g_keyboard_functionkeys = 0xc; /* 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 slow
static uint8* sdata = 0;
static int g_save_mem = 0; // for video memory use eg sdata == 0
// video acceleration
static int use_accel = 1;
static int has_fill_box = 0;
static int has_screen_copy = 0;
static int has_put_image = 0;
// clip
int clip_startx;
int clip_starty;
int clip_endx;
int clip_endy;
// mouse
uint8 mouse_under[32 * 32 * 4]; // save area under mouse
int mousex = 0;
int mousey = 0;
int mouseb = 0;
// mouse info
typedef struct
{
uint8 andmask[32 * 32];
uint8 xormask[32 * 32];
int x;
int y;
int w;
int h;
} tcursor;
// mouse global
static tcursor mcursor;
static int g_draw_mouse = 1;
/* Session Directory redirection */
BOOL g_redirect = False;
char g_redirect_server[64];
char g_redirect_domain[16];
char g_redirect_password[64];
char g_redirect_username[64];
char g_redirect_cookie[128];
uint32 g_redirect_flags = 0;
// bitmap
typedef 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 - PeterS
static 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 op
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;
}
//*****************************************************************************
// get a screen pixel
int 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 pixel
void 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 bitmap
int 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 bitmap
void 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 bitmap
uint8* 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 bitmap
BOOL 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 bytes
void 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)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -