Implemented keyboard and mouse dispatch from vnc client to vnc server.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
SET(TARGET_SRC osgvnc.cpp)
|
||||
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${LIBVNCCLIENT_LIBRARY} ${SDL_LIBRARY} ${ZLIB_LIBRARY} ${JPEG_LIBRARY} )
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${LIBVNCCLIENT_LIBRARY} ${ZLIB_LIBRARY} ${JPEG_LIBRARY} )
|
||||
|
||||
INCLUDE_DIRECTORIES(${LIBVNCCLIENT_INCLUDE_DIR} ${SDL_INCLUDE_DIR})
|
||||
INCLUDE_DIRECTORIES(${LIBVNCCLIENT_INCLUDE_DIR})
|
||||
|
||||
#### end var setup ###
|
||||
SETUP_EXAMPLE(osgvnc)
|
||||
|
||||
@@ -7,27 +7,15 @@
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <osg/io_utils>
|
||||
|
||||
extern "C" {
|
||||
#include <rfb/rfbclient.h>
|
||||
}
|
||||
|
||||
struct ButtonMapping { int sdl; int rfb; };
|
||||
|
||||
ButtonMapping buttonMapping[]={
|
||||
{1, rfbButton1Mask},
|
||||
{2, rfbButton2Mask},
|
||||
{3, rfbButton3Mask},
|
||||
{0,0}
|
||||
};
|
||||
|
||||
static rfbBool resize(rfbClient* client) {
|
||||
|
||||
static char first=TRUE;
|
||||
|
||||
static rfbBool resizeImage(rfbClient* client)
|
||||
{
|
||||
osg::Image* image = (osg::Image*)(rfbClientGetClientData(client, 0));
|
||||
|
||||
int width=client->width;
|
||||
@@ -43,38 +31,142 @@ static rfbBool resize(rfbClient* client) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void update(rfbClient* client,int x,int y,int w,int h) {
|
||||
|
||||
static void updateImage(rfbClient* client,int x,int y,int w,int h)
|
||||
{
|
||||
osg::Image* image = (osg::Image*)(rfbClientGetClientData(client, 0));
|
||||
image->dirty();
|
||||
}
|
||||
|
||||
static void kbd_leds(rfbClient* client, int value, int pad) {
|
||||
printf("kbd_leds %d %d\n",value,pad);
|
||||
|
||||
/* note: pad is for future expansion 0=unused */
|
||||
fprintf(stderr,"Led State= 0x%02X\n", value);
|
||||
fflush(stderr);
|
||||
class RfbEventHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
RfbEventHandler(rfbClient* client):
|
||||
_client(client) {}
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv);
|
||||
|
||||
rfbKeySym key2rfbKeySym(int key)
|
||||
{
|
||||
return rfbKeySym(key);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~RfbEventHandler() {}
|
||||
|
||||
bool mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const;
|
||||
|
||||
rfbClient* _client;
|
||||
|
||||
};
|
||||
|
||||
bool RfbEventHandler::mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const
|
||||
{
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
bool foundIntersection = view==0 ? false :
|
||||
(nv==0 ? view->computeIntersections(ea.getX(), ea.getY(), intersections) :
|
||||
view->computeIntersections(ea.getX(), ea.getY(), nv->getNodePath(), intersections));
|
||||
|
||||
if (foundIntersection)
|
||||
{
|
||||
|
||||
osg::Vec2 tc(0.5f,0.5f);
|
||||
|
||||
// use the nearest intersection
|
||||
const osgUtil::LineSegmentIntersector::Intersection& intersection = *(intersections.begin());
|
||||
osg::Drawable* drawable = intersection.drawable.get();
|
||||
osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0;
|
||||
osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0;
|
||||
if (vertices)
|
||||
{
|
||||
// get the vertex indices.
|
||||
const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices = intersection.indexList;
|
||||
const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios = intersection.ratioList;
|
||||
|
||||
if (indices.size()==3 && ratios.size()==3)
|
||||
{
|
||||
unsigned int i1 = indices[0];
|
||||
unsigned int i2 = indices[1];
|
||||
unsigned int i3 = indices[2];
|
||||
|
||||
float r1 = ratios[0];
|
||||
float r2 = ratios[1];
|
||||
float r3 = ratios[2];
|
||||
|
||||
osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0;
|
||||
osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords);
|
||||
if (texcoords_Vec2Array)
|
||||
{
|
||||
// we have tex coord array so now we can compute the final tex coord at the point of intersection.
|
||||
osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1];
|
||||
osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2];
|
||||
osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3];
|
||||
tc = tc1*r1 + tc2*r2 + tc3*r3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
x = int( float(_client->width) * tc.x() );
|
||||
y = int( float(_client->height) * tc.y() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* trivial support for textchat */
|
||||
static void text_chat(rfbClient* client, int value, char *text) {
|
||||
switch(value) {
|
||||
case rfbTextChatOpen:
|
||||
fprintf(stderr,"TextChat: We should open a textchat window!\n");
|
||||
TextChatOpen(client);
|
||||
break;
|
||||
case rfbTextChatClose:
|
||||
fprintf(stderr,"TextChat: We should close our window!\n");
|
||||
break;
|
||||
case rfbTextChatFinished:
|
||||
fprintf(stderr,"TextChat: We should close our window!\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"TextChat: Received \"%s\"\n", text);
|
||||
break;
|
||||
|
||||
bool RfbEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv)
|
||||
{
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
case(osgGA::GUIEventAdapter::DRAG):
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
case(osgGA::GUIEventAdapter::RELEASE):
|
||||
{
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||
int x,y;
|
||||
if (mousePosition(view, nv, ea, x, y))
|
||||
{
|
||||
SendPointerEvent(_client,x,y, ea.getButtonMask());
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(osgGA::GUIEventAdapter::KEYDOWN):
|
||||
case(osgGA::GUIEventAdapter::KEYUP):
|
||||
{
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||
int x,y;
|
||||
bool sendKeyEvent = mousePosition(view, nv, ea, x, y);
|
||||
|
||||
if (sendKeyEvent)
|
||||
{
|
||||
SendKeyEvent(_client,
|
||||
key2rfbKeySym(ea.getKey()),
|
||||
(ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN)?TRUE:FALSE);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Escape)
|
||||
{
|
||||
osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
|
||||
if (viewer) viewer->setDone(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
fflush(stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
class RfbThread : public OpenThreads::Thread
|
||||
@@ -116,24 +208,18 @@ public:
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
int i,buttonMask=0;
|
||||
|
||||
osg::ref_ptr<osg::Image> image = new osg::Image;
|
||||
// image->setPixelBufferObject(new osg::PixelBufferObject(image.get()));
|
||||
|
||||
osg::notify(osg::NOTICE)<<"image = "<<image.get()<<std::endl;
|
||||
|
||||
/* 16-bit: client=rfbGetClient(5,3,2); */
|
||||
rfbClient* client=rfbGetClient(8,3,4);
|
||||
client->MallocFrameBuffer=resize;
|
||||
client->canHandleNewFBSize = TRUE;
|
||||
client->GotFrameBufferUpdate=update;
|
||||
client->HandleKeyboardLedState=kbd_leds;
|
||||
client->HandleTextChat=text_chat;
|
||||
client->MallocFrameBuffer = resizeImage;
|
||||
client->GotFrameBufferUpdate = updateImage;
|
||||
client->HandleKeyboardLedState = 0;
|
||||
client->HandleTextChat = 0;
|
||||
|
||||
rfbClientSetClientData(client, 0, image.get());
|
||||
|
||||
osg::notify(osg::NOTICE)<<"Before rfbInitClient"<<std::endl;
|
||||
|
||||
if(!rfbInitClient(client,&argc,argv))
|
||||
return 1;
|
||||
@@ -168,10 +254,15 @@ int main(int argc,char** argv)
|
||||
viewer.setSceneData(geode);
|
||||
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler);
|
||||
viewer.addEventHandler(new RfbEventHandler(client));
|
||||
|
||||
RfbThread rfbThread(client);
|
||||
rfbThread.startThread();
|
||||
|
||||
viewer.setKeyEventSetsDone(0);
|
||||
|
||||
return viewer.run();
|
||||
|
||||
// rfbClientCleanup(cl);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user