📄 qtwin.cpp
字号:
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
User interface services - QT Window System
Copyright (C) Jay Sorg 2004-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 "rdesktop.h"
#include <qapplication.h>
#include <qmainwindow.h>
#include <qwidget.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qbrush.h>
#include <qimage.h>
#include <qbitmap.h>
#include <qcursor.h>
#include <qsocketnotifier.h>
#include <qscrollview.h>
#include <qfile.h>
#include "qtwin.h"
#include <unistd.h> // gethostname
#include <pwd.h> // getpwuid
#include <stdarg.h> // va_list va_start va_end
#include <errno.h>
#include <fcntl.h>
/* rdesktop globals */
extern int g_tcp_port_rdp;
int g_use_rdp5 = 1;
char g_hostname[16];
char g_username[64];
int g_height = 600;
int g_width = 800;
int g_server_depth = 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 */
static int g_argc = 0;
static char ** g_argv = 0;
static int g_UpAndRunning = 0;
static int g_sock = 0;
static int g_deactivated = 0;
static uint32 g_ext_disc_reason = 0;
static char g_servername[128];
static char g_title[128] = "";
static int g_flags = RDP_LOGON_NORMAL;
#ifdef WITH_RDPSND
extern int g_dsp_busy;
extern int g_dsp_fd;
static int g_rdpsnd = 0;
static QSocketNotifier * g_SoundNotifier = 0;
#endif
/* qt globals */
static QSocketNotifier * g_SocketNotifier = 0;
static QApplication * g_App = 0;
static QMyMainWindow * g_MW = 0;
static QMyScrollView * g_SV = 0;
static QPixmap * g_BS = 0;
static QPixmap * g_DS = 0;
static QPainter * g_P1 = 0;
static QPainter * g_P2 = 0;
static QColor g_Color1;
static QColor g_Color2;
struct QColorMap
{
uint32 RGBColors[256];
int NumColors;
};
static struct QColorMap * g_CM = 0;
static QRegion * g_ClipRect;
static Qt::RasterOp g_OpCodes[16] = {
Qt::ClearROP, // BLACKNESS 0
Qt::NorROP, // NOTSRCERASE DSon
Qt::NotAndROP, // DSna
Qt::NotCopyROP, // NOTSRCCOPY Sn
Qt::AndNotROP, // SRCERASE SDna
Qt::NotROP, // DSTINVERT Dn
Qt::XorROP, // SRCINVERT DSx
Qt::NandROP, // DSan
Qt::AndROP, // SRCAND DSa
Qt::NotXorROP, // DSxn
Qt::NopROP, // D
Qt::NotOrROP, // MERGEPAINT DSno
Qt::CopyROP, // SRCCOPY S
Qt::OrNotROP, // SDno
Qt::OrROP, // SRCPAINT DSo
Qt::SetROP}; // WHITENESS 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;
//*****************************************************************************
uint32 Color15to32(uint32 InColor)
{
uint32 r, g, b;
r = (InColor & 0x7c00) >> 10;
r = (r * 0xff) / 0x1f;
g = (InColor & 0x03e0) >> 5;
g = (g * 0xff) / 0x1f;
b = (InColor & 0x001f);
b = (b * 0xff) / 0x1f;
return (r << 16) | (g << 8) | b;
}
//*****************************************************************************
uint32 Color16to32(uint32 InColor)
{
uint32 r, g, b;
r = (InColor & 0xf800) >> 11;
r = (r * 0xff) / 0x1f;
g = (InColor & 0x07e0) >> 5;
g = (g * 0xff) / 0x3f;
b = (InColor & 0x001f);
b = (b * 0xff) / 0x1f;
return (r << 16) | (g << 8) | b;
}
//*****************************************************************************
uint32 Color24to32(uint32 InColor)
{
return ((InColor & 0x00ff0000) >> 16) |
((InColor & 0x000000ff) << 16) |
(InColor & 0x0000ff00);
}
//*****************************************************************************
void SetColorx(QColor * Color, uint32 InColor)
{
switch (g_server_depth)
{
case 8:
if (g_CM == NULL || InColor > 255)
{
Color->setRgb(0);
return;
}
Color->setRgb(g_CM->RGBColors[InColor]);
break;
case 15:
Color->setRgb(Color15to32(InColor));
break;
case 16:
Color->setRgb(Color16to32(InColor));
break;
case 24:
Color->setRgb(Color24to32(InColor));
break;
default:
Color->setRgb(0);
}
}
//*****************************************************************************
void SetOpCode(int opcode)
{
if (opcode >= 0 && opcode < 16)
{
Qt::RasterOp op = g_OpCodes[opcode];
if (op != Qt::CopyROP)
{
g_P1->setRasterOp(op);
g_P2->setRasterOp(op);
}
}
}
//*****************************************************************************
void ResetOpCode(int opcode)
{
if (opcode >= 0 && opcode < 16)
{
Qt::RasterOp op = g_OpCodes[opcode];
if (op != Qt::CopyROP)
{
g_P1->setRasterOp(Qt::CopyROP);
g_P2->setRasterOp(Qt::CopyROP);
}
}
}
/*****************************************************************************/
QMyMainWindow::QMyMainWindow(): QWidget()
{
}
/*****************************************************************************/
QMyMainWindow::~QMyMainWindow()
{
}
//*****************************************************************************
void QMyMainWindow::mouseMoveEvent(QMouseEvent * e)
{
if (!g_UpAndRunning)
{
return;
}
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, e->x(), e->y());
}
//*****************************************************************************
void QMyMainWindow::mousePressEvent(QMouseEvent * e)
{
if (!g_UpAndRunning)
{
return;
}
if (e->button() == LeftButton)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
e->x(), e->y());
}
else if (e->button() == RightButton)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
e->x(), e->y());
}
else if (e->button() == MidButton)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON3,
e->x(), e->y());
}
}
//*****************************************************************************
void QMyMainWindow::mouseReleaseEvent(QMouseEvent * e)
{
if (!g_UpAndRunning)
{
return;
}
if (e->button() == LeftButton)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1, e->x(), e->y());
}
else if (e->button() == RightButton)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2, e->x(), e->y());
}
else if (e->button() == MidButton)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3, e->x(), e->y());
}
}
//*****************************************************************************
void QMyMainWindow::wheelEvent(QWheelEvent * e)
{
if (!g_UpAndRunning)
{
return;
}
if (e->delta() > 0)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON4, e->x(), e->y());
}
else if (e->delta() < 0)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON5, e->x(), e->y());
}
}
//*****************************************************************************
int GetScanCode(QKeyEvent* e)
{
int Key = e->key();
int ScanCode = 0;
Qt::ButtonState bs = e->state();
if (!(bs & Qt::ShiftButton)) // shift is not down
{
if (Key == 42) // *
return 0x37;
if (Key == 43) // +
return 0x4e;
}
switch (Key)
{
case 4100: ScanCode = 0x1c; break; // enter
case 4101: ScanCode = 0x1c; break;
case 4117: ScanCode = 0xd0; break; // down arrow
case 4115: ScanCode = 0xc8; break; // up arrow
case 4114: ScanCode = 0xcb; break; // left arrow
case 4116: ScanCode = 0xcd; break; // right arrow
case 4112: ScanCode = 0xc7; break; // home
case 4113: ScanCode = 0xcf; break; // end
case 4102: ScanCode = 0xd2; break; // insert
case 4103: ScanCode = 0xd3; break; // delete
case 4118: ScanCode = 0xc9; break; // page up
case 4119: ScanCode = 0xd1; break; // page down
case 4143: ScanCode = 0x00; break; // num lock
case 47: ScanCode = 0x35; break; // /
case 42: ScanCode = 0x37; break; // *
case 45: ScanCode = 0x0c; break; // -
case 95: ScanCode = 0x0c; break; // _
case 43: ScanCode = 0x0d; break; // +
case 46: ScanCode = 0x34; break; // .
case 48: ScanCode = 0x0b; break; // 0
case 41: ScanCode = 0x0b; break; // )
case 49: ScanCode = 0x02; break; // 1
case 33: ScanCode = 0x02; break; // !
case 50: ScanCode = 0x03; break; // 2
case 64: ScanCode = 0x03; break; // @
case 51: ScanCode = 0x04; break; // 3
case 35: ScanCode = 0x04; break; // #
case 52: ScanCode = 0x05; break; // 4
case 36: ScanCode = 0x05; break; // $
case 53: ScanCode = 0x06; break; // 5
case 37: ScanCode = 0x06; break; // %
case 54: ScanCode = 0x07; break; // 6
case 94: ScanCode = 0x07; break; // ^
case 55: ScanCode = 0x08; break; // 7
case 38: ScanCode = 0x08; break; // &
case 56: ScanCode = 0x09; break; // 8
case 57: ScanCode = 0x0a; break; // 9
case 40: ScanCode = 0x0a; break; // (
case 61: ScanCode = 0x0d; break; // =
case 65: ScanCode = 0x1e; break; // a
case 66: ScanCode = 0x30; break; // b
case 67: ScanCode = 0x2e; break; // c
case 68: ScanCode = 0x20; break; // d
case 69: ScanCode = 0x12; break; // e
case 70: ScanCode = 0x21; break; // f
case 71: ScanCode = 0x22; break; // g
case 72: ScanCode = 0x23; break; // h
case 73: ScanCode = 0x17; break; // i
case 74: ScanCode = 0x24; break; // j
case 75: ScanCode = 0x25; break; // k
case 76: ScanCode = 0x26; break; // l
case 77: ScanCode = 0x32; break; // m
case 78: ScanCode = 0x31; break; // n
case 79: ScanCode = 0x18; break; // o
case 80: ScanCode = 0x19; break; // p
case 81: ScanCode = 0x10; break; // q
case 82: ScanCode = 0x13; break; // r
case 83: ScanCode = 0x1f; break; // s
case 84: ScanCode = 0x14; break; // t
case 85: ScanCode = 0x16; break; // u
case 86: ScanCode = 0x2f; break; // v
case 87: ScanCode = 0x11; break; // w
case 88: ScanCode = 0x2d; break; // x
case 89: ScanCode = 0x15; break; // y
case 90: ScanCode = 0x2c; break; // z
case 32: ScanCode = 0x39; break; // space
case 44: ScanCode = 0x33; break; // ,
case 60: ScanCode = 0x33; break; // <
case 62: ScanCode = 0x34; break; // >
case 63: ScanCode = 0x35; break; // ?
case 92: ScanCode = 0x2b; break; // backslash
case 124: ScanCode = 0x2b; break; // bar
case 4097: ScanCode = 0x0f; break; // tab
case 4132: ScanCode = 0x3a; break; // caps lock
case 4096: ScanCode = 0x01; break; // esc
case 59: ScanCode = 0x27; break; // ;
case 58: ScanCode = 0x27; break; // :
case 39: ScanCode = 0x28; break; // '
case 34: ScanCode = 0x28; break; // "
case 91: ScanCode = 0x1a; break; // [
case 123: ScanCode = 0x1a; break; // {
case 93: ScanCode = 0x1b; break; // ]
case 125: ScanCode = 0x1b; break; // }
case 4144: ScanCode = 0x3b; break; // f1
case 4145: ScanCode = 0x3c; break; // f2
case 4146: ScanCode = 0x3d; break; // f3
case 4147: ScanCode = 0x3e; break; // f4
case 4148: ScanCode = 0x3f; break; // f5
case 4149: ScanCode = 0x40; break; // f6
case 4150: ScanCode = 0x41; break; // f7
case 4151: ScanCode = 0x42; break; // f8
case 4152: ScanCode = 0x43; break; // f9
case 4153: ScanCode = 0x44; break; // f10
case 4154: ScanCode = 0x57; break; // f11
case 4155: ScanCode = 0x58; break; // f12
case 4128: ScanCode = 0x2a; break; // shift
case 4131: ScanCode = 0x38; break; // alt
case 4129: ScanCode = 0x1d; break; // ctrl
case 96: ScanCode = 0x29; break; // `
case 126: ScanCode = 0x29; break; // ~
case 4099: ScanCode = 0x0e; break; // backspace
}
// if (ScanCode == 0)
// printf("key %d scancode %d\n", Key, ScanCode);
return ScanCode;
}
//*****************************************************************************
void QMyMainWindow::keyPressEvent(QKeyEvent* e)
{
if (!g_UpAndRunning)
return;
int ScanCode = GetScanCode(e);
if (ScanCode != 0)
{
rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS, ScanCode, 0);
e->accept();
}
}
//*****************************************************************************
void QMyMainWindow::keyReleaseEvent(QKeyEvent* e)
{
if (!g_UpAndRunning)
{
return;
}
int ScanCode = GetScanCode(e);
if (ScanCode != 0)
{
rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, ScanCode, 0);
e->accept();
}
}
//*****************************************************************************
void QMyMainWindow::paintEvent(QPaintEvent * pe)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -