xrdp/uirdesktop/fb.c
2006-08-12 02:17:14 +00:00

1203 lines
26 KiB
C

/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
fb calls
Copyright (C) Jay Sorg 2006
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include "uimain.h"
#include "bsops.h"
extern char g_username[];
extern char g_hostname[];
extern char g_servername[];
extern char g_password[];
extern char g_shell[];
extern char g_directory[];
extern char g_domain[];
extern int g_width;
extern int g_height;
extern int g_tcp_sck;
extern int g_server_depth;
extern int g_tcp_port_rdp; /* in tcp.c */
extern int g_bytes_in;
extern int pal_entries[];
extern int g_bs_bpp;
extern int g_bs_Bpp;
extern char * g_bs;
static int g_bpp = 8;
static int g_Bpp = 1;
/* keys */
struct key
{
int scancode;
int rdpcode;
int ext;
};
static struct key g_keys[256];
static char g_keyfile[64] = "./default.key";
struct cursor
{
unsigned char andmask[32 * 32];
unsigned char xormask[32 * 32];
int x;
int y;
int w;
int h;
};
static struct cursor g_mcursor; /* current mouse */
static int g_mouse_x = 0;
static int g_mouse_y = 0;
static int g_mouse_buttons = 0; /* mouse button states */
static int g_mousefd = 0; /* mouse fd */
static int g_mouse_state = 0; /* used when reading mouse device */
static int g_uts = 0; /* updates to skip */
static int g_alt_down = 0; /* used to disable control alt delete */
static int g_control_down = 0;
static int g_shift_down = 0;
static int g_disable_cad = 0; /* disable control alt delete */
/* and ctrl shift esc */
static int g_wfpx = 0; /* wait for pixel stuff */
static int g_wfpy = 0;
static int g_wfpv = 0;
static int g_show_wfp = 0;
static int g_no_draw = 0; /* this means don't draw the screen but draw on
backingstore */
/* for transparent colour */
static int g_use_trans = 0;
static int g_trans_colour = 0;
/* clip */
static int g_clip_left = 0;
static int g_clip_top = 0;
static int g_clip_right = 0;
static int g_clip_bottom = 0;
static int g_kbfd = 0; /* keyboard fd */
static int g_fbfd = 0; /* framebuffer fd */
static char * g_sdata = 0;
static struct fb_var_screeninfo g_vinfo;
static struct fb_fix_screeninfo g_finfo;
static short g_saved_red[256]; /* original hw palette */
static short g_saved_green[256];
static short g_saved_blue[256];
struct my_rect
{
int x;
int y;
int w;
int h;
};
static struct my_rect g_rect = {0, 0, 0, 0};
/*****************************************************************************/
void
mi_error(char * msg)
{
printf(msg);
}
/*****************************************************************************/
void
mi_warning(char * msg)
{
printf(msg);
}
/*****************************************************************************/
int
mi_read_keyboard_state(void)
{
return 0;
}
/*****************************************************************************/
/* returns non zero if ok */
int
mi_create_window(void)
{
return 1;
}
/*****************************************************************************/
void
mi_update_screen(void)
{
int i;
int j;
int endi;
int endj;
int x;
int y;
int pixel;
int r;
int g;
int b;
if (g_no_draw)
{
return;
}
endi = UI_MIN(g_rect.y + g_rect.h, g_clip_bottom);
endj = UI_MIN(g_rect.x + g_rect.w, g_clip_right);
x = UI_MAX(g_rect.x, g_clip_left);
y = UI_MAX(g_rect.y, g_clip_top);
//printf("hi %d %d %d %d\n", x, y, endi, endj);
if (g_bpp == 16 && g_bs_bpp == 32)
{
for (i = y; i < endi; i++)
{
for (j = x; j < endj; j++)
{
pixel = ((unsigned int *) g_bs)[i * g_width + j];
SPLIT_COLOUR32(pixel, b, g, r);
MAKE_COLOUR16(pixel, r, g, b);
((unsigned short *) g_sdata)[i * g_width + j] = pixel;
}
}
}
g_rect.x = 0;
g_rect.y = 0;
g_rect.w = 0;
g_rect.h = 0;
//printf("bye\n");
}
/*****************************************************************************/
static void
process_keyboard(void)
{
char buf[128];
unsigned char ch;
int count;
int index;
int keyup;
int rdpkey;
int ext;
ext = 0;
index = 0;
count = read(g_kbfd, buf, 128);
while (index < count)
{
ch = (unsigned char)buf[index];
//printf("%2.2x\n", ch);
keyup = ch & 0x80;
rdpkey = ch & 0x7f;
ext = g_keys[rdpkey].ext ? 0x100 : 0;
rdpkey = g_keys[rdpkey].rdpcode;
if (rdpkey == 0x1d) /* control */
{
g_control_down = !keyup;
}
if (rdpkey == 0x38) /* alt */
{
g_alt_down = !keyup;
}
if (rdpkey == 0x2a || rdpkey == 0x36) /* shift */
{
g_shift_down = !keyup;
}
if (g_disable_cad) /* diable control alt delete and control shift escape */
{
if (rdpkey == 0x53 && g_alt_down && g_control_down) /* delete */
{
rdpkey = 0;
}
if (rdpkey == 0x01 && g_shift_down && g_control_down) /* escape */
{
rdpkey = 0;
}
}
if (rdpkey > 0 && g_mouse_buttons == 0)
{
if (!keyup)
{
ui_key_down(rdpkey, ext);
}
else
{
ui_key_up(rdpkey, ext);
}
}
index++;
}
}
/*****************************************************************************/
static int
process_mouse(void)
{
char d[128];
int c;
int i;
int b;
int old_x;
int old_y;
int old_but1;
int old_but2;
int mouse_x; /* hot spot */
int mouse_y; /* hot spot */
mouse_x = g_mouse_x + g_mcursor.x;
mouse_y = g_mouse_y + g_mcursor.y;
old_x = mouse_x;
old_y = mouse_y;
old_but1 = g_mouse_buttons & 1;
old_but2 = g_mouse_buttons & 2;
c = read(g_mousefd, &d, 128);
for (i = 0; i < c; i++)
{
b = (unsigned char)d[i];
switch (g_mouse_state)
{
case 0:
if (b & 0x08) /* PS2_CTRL_BYTE */
{
g_mouse_buttons = b & (1 | 2);
g_mouse_state = 1;
}
break;
case 1: /* x */
if (b > 127)
{
b -= 256;
}
mouse_x += b;
if (mouse_x < 0)
{
mouse_x = 0;
}
else if (mouse_x >= g_width)
{
mouse_x = g_width - 1;
}
g_mouse_state = 2;
break;
case 2: /* y */
if (b > 127)
{
b -= 256;
}
mouse_y += -b;
if (mouse_y < 0)
{
mouse_y = 0;
}
else if (mouse_y >= g_height)
{
mouse_y = g_height - 1;
}
g_mouse_state = 0;
break;
}
}
if (old_x != mouse_x || old_y != mouse_y) /* mouse pos changed */
{
ui_mouse_move(mouse_x, mouse_y);
}
if (old_but1 != (g_mouse_buttons & 1)) /* left button changed */
{
if (g_mouse_buttons & 1)
{
ui_mouse_button(1, mouse_x, mouse_y, 1);
}
else
{
ui_mouse_button(1, mouse_x, mouse_y, 0);
}
}
if (old_but2 != (g_mouse_buttons & 2)) /* right button changed */
{
if (g_mouse_buttons & 2)
{
ui_mouse_button(2, mouse_x, mouse_y, 1);
}
else
{
ui_mouse_button(2, mouse_x, mouse_y, 0);
}
}
//undraw_mouse();
g_mouse_x = mouse_x - g_mcursor.x;
g_mouse_y = mouse_y - g_mcursor.y;
//draw_mouse();
return 0;
}
/*****************************************************************************/
int
mi_main_loop(void)
{
fd_set rfds;
// fd_set wfds;
int rv;
int fd;
struct timeval tv;
fd = UI_MAX(g_tcp_sck, UI_MAX(g_mousefd, g_kbfd));
FD_ZERO(&rfds);
FD_SET(g_tcp_sck, &rfds);
FD_SET(g_mousefd, &rfds);
FD_SET(g_kbfd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
rv = select(fd + 1, &rfds, 0, 0, &tv);
while (rv > -1)
{
if (rv == 0)
{
usleep(0);
}
if (FD_ISSET(g_kbfd, &rfds))
{
process_keyboard();
}
if (FD_ISSET(g_mousefd, &rfds))
{
process_mouse();
}
if (FD_ISSET(g_tcp_sck, &rfds))
{
if (!ui_read_wire())
{
return 0;
}
}
fd = UI_MAX(g_tcp_sck, UI_MAX(g_mousefd, g_kbfd));
FD_ZERO(&rfds);
FD_SET(g_tcp_sck, &rfds);
FD_SET(g_mousefd, &rfds);
FD_SET(g_kbfd, &rfds);
#ifdef WITH_RDPSND
// if (g_rdpsnd && g_dsp_busy)
// {
// fd = MAX(fd, g_dsp_fd);
// FD_ZERO(&wfds);
// FD_SET(g_dsp_fd, &wfds);
// rv = select(fd + 1, &rfds, &wfds, 0, 0);
// if (rv > 0 && FD_ISSET(g_dsp_fd, &wfds))
// {
// wave_out_play();
// }
// }
// else
// {
// rv = select(fd + 1, &rfds, 0, 0, 0);
// }
#else
tv.tv_sec = 0;
tv.tv_usec = 0;
rv = select(fd + 1, &rfds, 0, 0, &tv);
#endif
}
return 0;
}
/*****************************************************************************/
void
mi_add_to(int x, int y, int cx, int cy)
{
int right;
int bottom;
if (g_rect.h == 0 && g_rect.w == 0)
{
g_rect.x = x;
g_rect.y = y;
g_rect.w = cx;
g_rect.h = cy;
}
else
{
right = g_rect.x + g_rect.w;
bottom = g_rect.y + g_rect.h;
if (x + cx > right)
{
right = x + cx;
}
if (y + cy > bottom)
{
bottom = y + cy;
}
if (x < g_rect.x)
{
g_rect.x = x;
}
if (y < g_rect.y)
{
g_rect.y = y;
}
g_rect.w = right - g_rect.x;
g_rect.h = bottom - g_rect.y;
}
}
/*****************************************************************************/
void
mi_invalidate(int x, int y, int cx, int cy)
{
mi_add_to(x, y, cx, cy);
mi_update_screen();
}
/*****************************************************************************/
/* return boolean */
int
mi_create_bs(void)
{
return 1;
}
/*****************************************************************************/
void
mi_begin_update(void)
{
}
/*****************************************************************************/
void
mi_end_update(void)
{
int pixel;
if (g_show_wfp)
{
printf(" %d\r\n", bs_get_pixel(g_wfpx, g_wfpy));
}
if (g_no_draw)
{
pixel = bs_get_pixel(g_wfpx, g_wfpy);
if ((pixel & 0xffffff) == (g_wfpv & 0xffffff))
{
g_no_draw = 0;
mi_invalidate(0, 0, g_width, g_height);
}
}
}
/*****************************************************************************/
void
mi_fill_rect(int x, int y, int cx, int cy, int colour)
{
if (g_no_draw)
{
return;
}
mi_add_to(x, y, cx, cy);
mi_update_screen();
}
/*****************************************************************************/
void
mi_line(int x1, int y1, int x2, int y2, int colour)
{
if (g_no_draw)
{
return;
}
int x;
int y;
int cx;
int cy;
x = UI_MIN(x1, x2);
y = UI_MIN(y1, y2);
cx = (UI_MAX(x1, x2) + 1) - x;
cy = (UI_MAX(y1, y2) + 1) - y;
mi_add_to(x, y, cx, cy);
mi_update_screen();
}
/*****************************************************************************/
void
mi_screen_copy(int x, int y, int cx, int cy, int srcx, int srcy)
{
if (g_no_draw)
{
return;
}
mi_add_to(x, y, cx, cy);
mi_update_screen();
}
/*****************************************************************************/
void
mi_set_clip(int x, int y, int cx, int cy)
{
g_clip_left = x;
g_clip_top = y;
g_clip_right = x + cx;
g_clip_bottom = y + cy;
g_clip_left = UI_MAX(g_clip_left, 0);
g_clip_top = UI_MAX(g_clip_top, 0);
g_clip_right = UI_MIN(g_clip_right, g_width);
g_clip_bottom = UI_MIN(g_clip_bottom, g_height);
}
/*****************************************************************************/
void
mi_reset_clip(void)
{
g_clip_left = 0;
g_clip_top = 0;
g_clip_right = g_width;
g_clip_bottom = g_height;
}
/*****************************************************************************/
void *
mi_create_cursor(unsigned int x, unsigned int y,
int width, int height,
unsigned char * andmask, unsigned char * xormask)
{
struct cursor * c;
int i;
int j;
c = (struct cursor *) malloc(sizeof(struct cursor));
memset(c, 0, sizeof(struct cursor));
c->w = width;
c->h = height;
c->x = x;
c->y = y;
for (i = 0; i < 32; i++)
{
for (j = 0; j < 32; j++)
{
if (bs_is_pixel_on(andmask, j, i, 32, 1))
{
bs_set_pixel_on(c->andmask, j, 31 - i, 32, 8, 255);
}
if (bs_is_pixel_on(xormask, j, i, 32, 1))
{
bs_set_pixel_on(c->xormask, j, 31 - i, 32, 8, 255);
}
}
}
return c;
}
/*****************************************************************************/
void
mi_destroy_cursor(void * cursor)
{
struct cursor * c;
c = (struct cursor *) cursor;
free(c);
}
/*****************************************************************************/
void
mi_set_cursor(void * cursor)
{
}
/*****************************************************************************/
void
mi_set_null_cursor(void)
{
}
/*****************************************************************************/
static void
out_params(void)
{
fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
fprintf(stderr, "Version 1.4.1. Copyright (C) 1999-2006 Matt Chapman.\n");
fprintf(stderr, "direct framebuffer uiport by Jay Sorg\n");
fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
fprintf(stderr, "Usage: dfbrdesktop [options] server\n");
fprintf(stderr, " -u: user name\n");
fprintf(stderr, " -n: client hostname\n");
fprintf(stderr, " -s: shell\n");
fprintf(stderr, " -p: password\n");
fprintf(stderr, " -d: domain\n");
fprintf(stderr, " -c: working directory\n");
fprintf(stderr, " -a: colour depth\n");
fprintf(stderr, " -wfp x y pixel: skip screen updates till x, y pixel is \
this colour\n");
fprintf(stderr, " -trans pixel: transparent colour\n");
fprintf(stderr, "\n");
}
/*****************************************************************************/
static int
parse_parameters(int in_argc, char ** in_argv)
{
int i;
if (in_argc <= 1)
{
out_params();
return 0;
}
for (i = 1; i < in_argc; i++)
{
strcpy(g_servername, in_argv[i]);
if (strcmp(in_argv[i], "-h") == 0)
{
out_params();
return 0;
}
else if (strcmp(in_argv[i], "-u") == 0)
{
strcpy(g_username, in_argv[i + 1]);
}
else if (strcmp(in_argv[i], "-n") == 0)
{
strcpy(g_hostname, in_argv[i + 1]);
}
else if (strcmp(in_argv[i], "-s") == 0)
{
strcpy(g_shell, in_argv[i + 1]);
}
else if (strcmp(in_argv[i], "-p") == 0)
{
strcpy(g_password, in_argv[i + 1]);
}
else if (strcmp(in_argv[i], "-d") == 0)
{
strcpy(g_domain, in_argv[i + 1]);
}
else if (strcmp(in_argv[i], "-c") == 0)
{
strcpy(g_directory, in_argv[i + 1]);
}
else if (strcmp(in_argv[i], "-a") == 0)
{
g_server_depth = atoi(in_argv[i + 1]);
}
else if (strcmp(in_argv[i], "-wfp") == 0)
{
g_wfpx = atoi(in_argv[i + 1]);
g_wfpy = atoi(in_argv[i + 2]);
g_wfpv = atoi(in_argv[i + 3]);
if (g_wfpv == 0)
{
g_show_wfp = 1;
}
else
{
g_no_draw = 1;
}
}
else if (strcmp(in_argv[i], "-trans") == 0)
{
g_use_trans = 1;
g_trans_colour = atoi(in_argv[i + 1]);
}
}
return 1;
}
/*****************************************************************************/
static void
get_username_and_hostname(void)
{
char fullhostname[64];
char * p;
struct passwd * pw;
strncpy(g_username, "unknown", 255);
strncpy(g_hostname, "unknown", 255);
pw = getpwuid(getuid());
if (pw != 0)
{
if (pw->pw_name != 0)
{
strncpy(g_username, pw->pw_name, 255);
}
}
if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
{
p = strchr(fullhostname, '.');
if (p != 0)
{
*p = 0;
}
strncpy(g_hostname, fullhostname, 255);
}
}
/*****************************************************************************/
static void
save_palette(void)
{
struct fb_cmap cmap;
cmap.start = 0;
if (g_bpp == 15)
{
cmap.len = 16;
}
else
{
cmap.len = 256;
}
cmap.red = (unsigned short *) g_saved_red;
cmap.green = (unsigned short *) g_saved_green;
cmap.blue = (unsigned short *) g_saved_blue;
cmap.transp = 0;
ioctl(g_fbfd, FBIOGETCMAP, &cmap);
}
/*****************************************************************************/
static void
restore_palette(void)
{
struct fb_cmap cmap;
cmap.start = 0;
if (g_bpp == 15)
{
cmap.len = 16;
}
else
{
cmap.len = 256;
}
cmap.red = (unsigned short *) g_saved_red;
cmap.green = (unsigned short *) g_saved_green;
cmap.blue = (unsigned short *) g_saved_blue;
cmap.transp = 0;
ioctl(g_fbfd, FBIOPUTCMAP, &cmap);
}
/*****************************************************************************/
static void
set_directcolor_palette(void)
{
short r[256];
int i;
struct fb_cmap cmap;
if (g_bpp == 15)
{
for (i = 0; i < 32; i++)
{
r[i] = i << 11;
}
cmap.len = 32;
}
else
{
for (i = 0; i < 256; i++)
{
r[i] = i << 8;
}
cmap.len = 256;
}
cmap.start = 0;
cmap.red = (unsigned short *) r;
cmap.green = (unsigned short *) r;
cmap.blue = (unsigned short *) r;
cmap.transp = 0;
ioctl(g_fbfd, FBIOPUTCMAP, &cmap);
}
/*****************************************************************************/
static int
htoi(char * val)
{
int rv;
rv = 0;
switch (val[0])
{
case '1': rv = 16; break;
case '2': rv = 16 * 2; break;
case '3': rv = 16 * 3; break;
case '4': rv = 16 * 4; break;
case '5': rv = 16 * 5; break;
case '6': rv = 16 * 6; break;
case '7': rv = 16 * 7; break;
case '8': rv = 16 * 8; break;
case '9': rv = 16 * 9; break;
case 'a': rv = 16 * 10; break;
case 'b': rv = 16 * 11; break;
case 'c': rv = 16 * 12; break;
case 'd': rv = 16 * 13; break;
case 'e': rv = 16 * 14; break;
case 'f': rv = 16 * 15; break;
}
switch (val[1])
{
case '1': rv += 1; break;
case '2': rv += 2; break;
case '3': rv += 3; break;
case '4': rv += 4; break;
case '5': rv += 5; break;
case '6': rv += 6; break;
case '7': rv += 7; break;
case '8': rv += 8; break;
case '9': rv += 9; break;
case 'a': rv += 10; break;
case 'b': rv += 11; break;
case 'c': rv += 12; break;
case 'd': rv += 13; break;
case 'e': rv += 14; break;
case 'f': rv += 15; break;
}
return rv;
}
/*****************************************************************************/
static int
load_keys(void)
{
int fd;
int len;
int index;
int i1;
int comment;
int val1;
int val2;
int val3;
char all_lines[8192];
char line[256];
char val[4];
memset(g_keys, 0, sizeof(g_keys));
fd = open(g_keyfile, O_RDWR);
if (fd > 0)
{
i1 = 0;
line[0] = 0;
comment = 0;
len = read(fd, all_lines, 8192);
for (index = 0; index < len ; index++)
{
if (all_lines[index] == '#')
{
comment = 1;
}
else if (all_lines[index] == 13 || all_lines[index] == 10)
{
if (strlen(line) > 7)
{
val[0] = line[0];
val[1] = line[1];
val[2] = 0;
val1 = htoi(val);
val[0] = line[3];
val[1] = line[4];
val[2] = 0;
val2 = htoi(val);
val[0] = line[6];
val[1] = line[7];
val[2] = 0;
val3 = htoi(val);
g_keys[val1].scancode = val1;
g_keys[val1].rdpcode = val2;
g_keys[val1].ext = val3;
}
line[0] = 0;
i1 = 0;
comment = 0;
}
else if (!comment)
{
line[i1] = all_lines[index];
i1++;
line[i1] = 0;
}
}
close(fd);
}
return 0;
}
/*****************************************************************************/
int
main(int in_argc, char ** in_argv)
{
int rv;
int screensize;
struct termios new_termios;
rv = 0;
g_server_depth = 24;
memset(&g_mcursor, 0, sizeof(struct cursor));
get_username_and_hostname();
/* read command line options */
if (!parse_parameters(in_argc, in_argv))
{
exit(0);
}
/* Open the file for reading and writing */
g_fbfd = open("/dev/fb0", O_RDWR);
if (g_fbfd == -1)
{
printf("Error: cannot open framebuffer device.\n");
exit(101);
}
printf("The framebuffer device was opened successfully.\n");
/* Get fixed screen information */
if (ioctl(g_fbfd, FBIOGET_FSCREENINFO, &g_finfo))
{
printf("Error reading fixed information.\n");
exit(102);
}
/* Get variable screen information */
if (ioctl(g_fbfd, FBIOGET_VSCREENINFO, &g_vinfo))
{
printf("Error reading variable information.\n");
exit(103);
}
g_bpp = g_vinfo.bits_per_pixel;
g_Bpp = (g_bpp + 7) / 8;
g_width = g_vinfo.xres;
g_height = g_vinfo.yres;
g_clip_right = g_width;
g_clip_bottom = g_height;
printf("%dx%d, %dbpp\n", g_vinfo.xres, g_vinfo.yres, g_vinfo.bits_per_pixel);
/* Figure out the size of the screen in bytes */
screensize = g_vinfo.xres * g_vinfo.yres * g_Bpp;
/* Map the device to memory */
g_sdata = (char *) mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
g_fbfd, 0);
g_bs = malloc(screensize);
if ((int) g_sdata == -1)
{
printf("Error: failed to map framebuffer device to memory.\n");
exit(104);
}
printf("The framebuffer device was mapped to memory successfully.\n");
/* open mouse */
g_mousefd = open("/dev/mouse", O_RDWR);
if (g_mousefd == -1)
{
g_mousefd = open("/dev/psaux", O_RDWR);
}
if (g_mousefd == -1)
{
printf("Error: failed to open /dev/mouse or /dev/psaux\n");
exit(105);
}
g_kbfd = open("/dev/tty0", O_RDWR);
if (g_kbfd == -1)
{
printf("Error: failed to open /dev/tty0\n");
exit(106);
}
/* check fb type */
if (g_finfo.visual != FB_VISUAL_DIRECTCOLOR &&
g_finfo.visual != FB_VISUAL_TRUECOLOR)
{
printf("unsupports fb\n");
exit(107);
}
if (g_finfo.visual == FB_VISUAL_DIRECTCOLOR)
{
/* save hardware palette */
save_palette();
/* set palette to match truecolor */
set_directcolor_palette();
}
/* clear the screen */
mi_fill_rect(0, 0, g_width, g_height, 0);
/* connect */
#ifdef WITH_RDPSND
/* init sound */
// if (g_rdpsnd)
// {
// rdpsnd_init();
// }
#endif
#if 0
/* setup keyboard */
ioctl(g_kbfd, KDGKBMODE, &g_org_kbmode); /* save this */
tcgetattr(g_kbfd, &org_termios); /* save this */
new_termios = org_termios;
new_termios.c_lflag &= ~(ICANON | ECHO | ISIG);
new_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
new_termios.c_cc[VMIN] = 0;
new_termios.c_cc[VTIME] = 0;
tcsetattr(g_kbfd, TCSAFLUSH, &new_termios);
ioctl(g_kbfd, KDSKBMODE, K_MEDIUMRAW);
#endif
load_keys();
/* do it all here */
rv = ui_main();
/* clear the screen when done */
mi_fill_rect(0, 0, g_width, g_height, 0);
/* restore some stuff */
if (g_finfo.visual == FB_VISUAL_DIRECTCOLOR)
{
restore_palette();
}
munmap(g_sdata, screensize);
close(g_fbfd);
close(g_mousefd);
#if 0
ioctl(g_kbfd, KDSKBMODE, g_org_kbmode);
tcsetattr(g_kbfd, TCSANOW, &org_termios);
#endif
close(g_kbfd);
free(g_bs);
return rv;
}
/*****************************************************************************/
/* returns non zero ok */
int
librdesktop_init(long obj1, long obj2, long obj3, int in_argc, char ** in_argv)
{
int screensize;
struct termios new_termios;
g_server_depth = 24;
memset(&g_mcursor, 0, sizeof(struct cursor));
get_username_and_hostname();
/* read command line options */
if (!parse_parameters(in_argc, in_argv))
{
return 0;
}
/* Open the file for reading and writing */
//g_fbfd = open("/dev/fb0", O_RDWR);
g_fbfd = obj1;
/* Get fixed screen information */
if (ioctl(g_fbfd, FBIOGET_FSCREENINFO, &g_finfo))
{
printf("Error reading fixed information.\n");
return 1;
}
/* Get variable screen information */
if (ioctl(g_fbfd, FBIOGET_VSCREENINFO, &g_vinfo))
{
printf("Error reading variable information.\n");
return 1;
}
g_bpp = g_vinfo.bits_per_pixel;
g_Bpp = (g_bpp + 7) / 8;
g_width = g_vinfo.xres;
g_height = g_vinfo.yres;
g_clip_right = g_width;
g_clip_bottom = g_height;
printf("%dx%d, %dbpp\n", g_vinfo.xres, g_vinfo.yres, g_vinfo.bits_per_pixel);
/* Figure out the size of the screen in bytes */
screensize = g_vinfo.xres * g_vinfo.yres * 4;
g_sdata = (char*)obj2;
g_bs = malloc(screensize);
return 0;
}
/*****************************************************************************/
/* returns non zero ok */
int
librdesktop_connect(void)
{
return ui_lib_main();
}
/*****************************************************************************/
/* returns non zero ok */
int
librdesktop_check_wire(void)
{
fd_set rfds;
int rv;
int fd;
struct timeval tv;
fd = g_tcp_sck;
FD_ZERO(&rfds);
FD_SET(g_tcp_sck, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
rv = select(fd + 1, &rfds, 0, 0, &tv);
if (rv > -1)
{
if (rv > 0)
{
if (FD_ISSET(g_tcp_sck, &rfds))
{
if (!ui_read_wire())
{
return 0;
}
}
}
}
return 1;
}
/*****************************************************************************/
int
librdesktop_mouse_move(int x, int y)
{
ui_mouse_move(x, y);
return 0;
}
/*****************************************************************************/
int
librdesktop_mouse_button(int button, int x, int y, int down)
{
ui_mouse_button(button, x, y, down);
return 0;
}
/*****************************************************************************/
int
librdesktop_key_down(int key, int ext)
{
ui_key_down(key, ext);
return 0;
}
/*****************************************************************************/
int
librdesktop_key_up(int key, int ext)
{
ui_key_up(key, ext);
return 0;
}
/*****************************************************************************/
int
librdesktop_quit(void)
{
return 1;
}