3 #include "vncdisplaythread.h"
4 #include "pipedprocess.h"
8 typedef wxAlphaPixelData PixelData
;
9 //typedef wxPixelFormat<unsigned char, 32, 0, 1, 2> PixelData;
11 DEFINE_EVENT_TYPE(EVT_VNC_UPDATE
)
12 DEFINE_EVENT_TYPE(EVT_VNC_RESIZE
)
14 BEGIN_EVENT_TABLE(VNCPanel
, wxScrolledWindow
)
15 EVT_PAINT(VNCPanel::OnPaint
)
16 EVT_ERASE_BACKGROUND(VNCPanel::OnEraseBackground
)
17 EVT_MOUSE_EVENTS(VNCPanel::OnMouseEvent
)
18 EVT_KEY_DOWN(VNCPanel::OnKeyDown
)
19 EVT_KEY_UP(VNCPanel::OnKeyUp
)
20 EVT_COMMAND(wxID_ANY
,EVT_PROCESS_TERMINATED
,VNCPanel::HandleProcessTermination
)
26 rfbBool
VNCResizeCallback(rfbClient
*client
);
27 void VNCUpdateCallback(rfbClient
* cl
,int x
,int y
,int w
,int h
);
30 VNCPanel::VNCPanel(wxWindow
*parent
,wxString host
,int display
)
31 :wxScrolledWindow(parent
, wxID_ANY
),
33 vncdisplaythread(NULL
),
37 VNCPanel::~VNCPanel(){
41 bool VNCPanel::Connect(int display
){
42 DEBUG_VNC("connecting to display: %d\n",display
);
43 return Connect(wxT(""),display
);
46 bool VNCPanel::Connect(wxString host
,int display
){
47 // 16-bit: vncclient=rfbGetClient(5,3,2);
48 // 24-bit?: vncclient = rfbGetClient(8,3,3);
49 // 32-bit?:vncclient = rfbGetClient(8,3,4);
50 vncclient
= rfbGetClient(8,3,4);
51 // store this instance so we can later use it within the callbacks
52 rfbClientSetClientData(vncclient
, (void *)dummy
, this);
53 vncclient
->serverHost
= strdup("127.0.0.1");
54 vncclient
->serverPort
= display
;
55 vncclient
->MallocFrameBuffer
= VNCResizeCallback
;
56 vncclient
->canHandleNewFBSize
= true;
57 vncclient
->GotFrameBufferUpdate
= VNCUpdateCallback
;
59 vncclient->format.redShift = 16;
60 vncclient->format.greenShift = 8;
61 vncclient->format.blueShift = 0;
64 vncclient
->appData
.useBGR233
= 0;
65 vncclient
->appData
.encodingsString
= "copyrect hextile raw";
66 // vncclient->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw";
67 vncclient
->appData
.compressLevel
= 0;
68 vncclient
->appData
.qualityLevel
= 9;
70 if(vncclient
->serverPort
>=0 && vncclient
->serverPort
<5900)
71 vncclient
->serverPort
+=5900;
73 if(!rfbInitClient(vncclient
,NULL
,NULL
)){
74 DEBUG_VNC("Could not initialize vncclient.\n");
79 vncdisplaythread
= new VNCDisplayThread(this);
80 vncdisplaythread
->Create();
81 vncdisplaythread
->Run();
86 void VNCPanel::Disconnect(){
87 rfbClient
*tmp
= vncclient
;
89 if(vncdisplaythread
!= NULL
){
90 vncdisplaythread
->Stop();
91 vncdisplaythread
->Wait();
92 delete vncdisplaythread
;
93 vncdisplaythread
= NULL
;
97 free(tmp
->frameBuffer
);
98 rfbClientCleanup(tmp
);
102 void VNCPanel::HandleProcessTermination(wxCommandEvent
& WXUNUSED(event
)){
106 rfbClient
* VNCPanel::GetVNCClient(){
107 return this->vncclient
;
110 void VNCPanel::VNCUpdateRect(int x
,int y
,int w
,int h
){
111 wxBitmap
*bmp
= VNCGenerateBitmap(x
,y
,w
,h
);
115 dc
.DrawBitmap(*bmp
,x
,y
,false);
119 wxBitmap
* VNCPanel::VNCGenerateBitmap(int x
,int y
,int w
,int h
){
120 // can't draw if the frame buffer doesn't exists yet
121 if(!vncclient
|| !vncclient
->frameBuffer
)
124 DEBUG_PAINT("generate bitmap: x:%d y:%d w:%d h:%d\n",x
,y
,w
,h
);
125 // create a bitmap from our pixel data
126 // wxBitmap *test = new wxBitmap((const char *)vncclient->frameBuffer,w,h,vncclient->format.bitsPerPixel);
128 wxBitmap
*bmp
= new wxBitmap(w
,h
,vncclient
->format
.bitsPerPixel
);
130 PixelData
data(*bmp
);
132 DEBUG_PAINT("could not access raw pixel data\n");
137 PixelData::Iterator
p(data
);
138 // unsigned char *rawdata=(unsigned char *)&p.Data();
139 // unsigned char *rawdata=(unsigned char *)p.m_ptr;
141 //p.m_ptr = vncclient->frameBuffer;
144 // uint8_t *pp = (uint8_t *)&it.Data();
145 uint8_t *px
= (uint8_t*)vncclient
->frameBuffer
;
146 // move the pointer to the beginning of the requested area
147 px
+=((vncclient
->width
* y
+ x
) * 4);
148 int offsetx
= ((vncclient
->width
- w
)*4);
150 for( int cy
= 0; cy
< h
; ++cy
){
151 PixelData::Iterator rowStart
= p
;
152 for( int cx
= 0; cx
< w
; ++cx
){
158 ++p
; // same as p.OffsetX(1)
168 rfbBool
VNCPanel::VNCResize(){
172 DEBUG_VNC("resize: w: %d h: %d\n",vncclient
->width
,vncclient
->height
);
173 if(vncclient
->frameBuffer
)
174 free(vncclient
->frameBuffer
);
176 vncclient
->frameBuffer
= (uint8_t*)malloc(
177 vncclient
->width
* vncclient
->height
*
178 vncclient
->format
.bitsPerPixel
/8
181 if(vncclient
->frameBuffer
){
182 wxSize
size(vncclient
->width
,vncclient
->height
);
186 GetParent()->GetSizer()->Layout();
187 DEBUG_VNC("resize succeeded\n");
191 DEBUG_VNC("resize failed\n");
195 void VNCPanel::OnPaint(wxPaintEvent
& WXUNUSED(event
)){
201 wxRegionIterator
upd(GetUpdateRegion());
208 // it is important that those values are never bigger than
209 // our framebuffer width/height otherwhise repaint the whole screen
210 if(x
+ w
> vncclient
->width
|| y
+ h
> vncclient
->height
){
214 //printf(" SendingFrameBufferUpdateRequest(%d,%d,%d,%d)\n",x,y,w,h);
215 //SendFramebufferUpdateRequest(vncclient,x,y,w,h,false);
216 wxBitmap
*bmp
= VNCGenerateBitmap(x
,y
,w
,h
);
218 dc
.DrawBitmap(*bmp
,x
,y
,false);
226 void VNCPanel::Paint(){
229 VNCUpdateRect(0,0,vncclient
->width
,vncclient
->height
);
232 void VNCPanel::OnMouseEvent(wxMouseEvent
& event
){
236 //wxPoint point = event.GetLogicalPosition(wxDC(this));
237 wxPoint point
= event
.GetPosition();
238 if(point
.x
< 0 || point
.y
< 0)
240 // mouse just moving no buttons pressed most common case
242 DEBUG_MOUSE("moving: x:%d y:%d\n",point
.x
,point
.y
);
243 SendPointerEvent(vncclient
,point
.x
,point
.y
,0);
247 if(event
.Entering()){
259 if(event
.LeftIsDown())
260 button
|= rfbButton1Mask
;
261 if(event
.MiddleIsDown())
262 button
|= rfbButton2Mask
;
263 if(event
.RightIsDown())
264 button
|= rfbButton3Mask
;
266 DEBUG_MOUSE("event: x:%d y:%d button:%d\n",point
.x
,point
.y
,button
);
267 SendPointerEvent(vncclient
,point
.x
,point
.y
,button
);
270 void VNCPanel::HideCursor(){
273 image
.SetMaskColour(0,0,0);
274 wxCursor
cursor(image
);
278 void VNCPanel::ShowCursor(){
279 SetCursor(wxNullCursor
);
282 void VNCPanel::OnKeyDown(wxKeyEvent
& event
){
284 SendKeyEvent(vncclient
,TranslateKeyCode(event
),true);
287 void VNCPanel::OnKeyUp(wxKeyEvent
& event
){
289 SendKeyEvent(vncclient
,TranslateKeyCode(event
),false);
292 rfbKeySym
VNCPanel::TranslateKeyCode(wxKeyEvent
& event
){
295 switch(event
.GetKeyCode()){
296 case WXK_BACK
: k
= XK_BackSpace
; break;
297 case WXK_TAB
: k
= XK_ISO_Left_Tab
; break;
298 case WXK_CLEAR
: k
= XK_Clear
; break;
299 case WXK_RETURN
: k
= XK_Return
; break;
300 case WXK_PAUSE
: k
= XK_Pause
; break;
301 case WXK_ESCAPE
: k
= XK_Escape
; break;
302 case WXK_SPACE
: k
= XK_space
; break;
303 case WXK_DELETE
: k
= XK_Delete
; break;
304 case WXK_NUMPAD0
: k
= XK_KP_0
; break;
305 case WXK_NUMPAD1
: k
= XK_KP_1
; break;
306 case WXK_NUMPAD2
: k
= XK_KP_2
; break;
307 case WXK_NUMPAD3
: k
= XK_KP_3
; break;
308 case WXK_NUMPAD4
: k
= XK_KP_4
; break;
309 case WXK_NUMPAD5
: k
= XK_KP_5
; break;
310 case WXK_NUMPAD6
: k
= XK_KP_6
; break;
311 case WXK_NUMPAD7
: k
= XK_KP_7
; break;
312 case WXK_NUMPAD8
: k
= XK_KP_8
; break;
313 case WXK_NUMPAD9
: k
= XK_KP_9
; break;
314 case WXK_NUMPAD_DECIMAL
: k
= XK_KP_Decimal
; break;
315 case WXK_NUMPAD_DIVIDE
: k
= XK_KP_Divide
; break;
316 case WXK_NUMPAD_MULTIPLY
: k
= XK_KP_Multiply
; break;
317 case WXK_NUMPAD_SUBTRACT
: k
= XK_KP_Subtract
; break;
318 case WXK_NUMPAD_ADD
: k
= XK_KP_Add
; break;
319 case WXK_NUMPAD_ENTER
: k
= XK_KP_Enter
; break;
320 case WXK_NUMPAD_EQUAL
: k
= XK_KP_Equal
; break;
321 case WXK_UP
: k
= XK_Up
; break;
322 case WXK_DOWN
: k
= XK_Down
; break;
323 case WXK_RIGHT
: k
= XK_Right
; break;
324 case WXK_LEFT
: k
= XK_Left
; break;
325 case WXK_INSERT
: k
= XK_Insert
; break;
326 case WXK_HOME
: k
= XK_Home
; break;
327 case WXK_END
: k
= XK_End
; break;
328 case WXK_PAGEUP
: k
= XK_Page_Up
; break;
329 case WXK_PAGEDOWN
: k
= XK_Page_Down
; break;
330 case WXK_F1
: k
= XK_F1
; break;
331 case WXK_F2
: k
= XK_F2
; break;
332 case WXK_F3
: k
= XK_F3
; break;
333 case WXK_F4
: k
= XK_F4
; break;
334 case WXK_F5
: k
= XK_F5
; break;
335 case WXK_F6
: k
= XK_F6
; break;
336 case WXK_F7
: k
= XK_F7
; break;
337 case WXK_F8
: k
= XK_F8
; break;
338 case WXK_F9
: k
= XK_F9
; break;
339 case WXK_F10
: k
= XK_F10
; break;
340 case WXK_F11
: k
= XK_F11
; break;
341 case WXK_F12
: k
= XK_F12
; break;
342 case WXK_F13
: k
= XK_F13
; break;
343 case WXK_F14
: k
= XK_F14
; break;
344 case WXK_F15
: k
= XK_F15
; break;
345 case WXK_NUMLOCK
: k
= XK_Num_Lock
; break;
346 case WXK_CAPITAL
: k
= XK_Caps_Lock
; break;
347 case WXK_SCROLL
: k
= XK_Scroll_Lock
; break;
348 case WXK_SHIFT
: k
= XK_Shift_L
; break;
349 // case SDLK_RSHIFT: k = XK_Shift_R; break;
350 // case SDLK_LSHIFT: k = XK_Shift_L; break;
351 case WXK_CONTROL
: k
= XK_Control_L
; break;
352 // case SDLK_RCTRL: k = XK_Control_R; break;
353 // case SDLK_LCTRL: k = XK_Control_L; break;
354 case WXK_ALT
: k
= XK_Alt_L
; break;
355 // case SDLK_RALT: k = XK_Alt_R; break;
356 // case SDLK_LALT: k = XK_Alt_L; break;
357 // case SDLK_RMETA: k = XK_Meta_R; break;
358 // case SDLK_LMETA: k = XK_Meta_L; break;
359 case WXK_WINDOWS_LEFT
: k
= XK_Super_L
; break; /* left windows key */
360 case WXK_WINDOWS_RIGHT
: k
= XK_Super_R
; break; /* right windows key */
361 // case SDLK_COMPOSE: k = XK_Compose; break;
362 // case SDLK_MODE: k = XK_Mode_switch; break;
363 case WXK_HELP
: k
= XK_Help
; break;
364 case WXK_PRINT
: k
= XK_Print
; break;
365 // case SDLK_SYSREQ: k = XK_Sys_Req; break;
366 // case WXK_PAUSE: k = XK_Break; break;
368 k
= event
.GetKeyCode();
374 rfbKeySym keycode
= event
.GetRawKeyCode();
375 DEBUG_KEYBOARD("keycode: %d",keycode
);
379 inline void VNCPanel::OnEraseBackground(wxEraseEvent
&){};
381 extern "C" void VNCUpdateCallback(rfbClient
* cl
,int x
,int y
,int w
,int h
) {
382 VNCPanel
*panel
= (VNCPanel
*)rfbClientGetClientData(cl
,(void *)dummy
);
384 DEBUG_VNC("update callback: x:%d y:%d w:%d h:%d\n",x
,y
,w
,h
);
385 panel
->VNCUpdateRect(x
,y
,w
,h
);
389 extern "C" rfbBool
VNCResizeCallback(rfbClient
*client
){
390 DEBUG_VNC("resize callback: w:%d h:%d\n",client
->width
,client
->height
);
391 VNCPanel
*panel
= (VNCPanel
*)rfbClientGetClientData(client
,(void *)dummy
);
393 return panel
->VNCResize();