Implemented keyboard and mouse dispatch from vnc client to vnc server.

This commit is contained in:
Robert Osfield
2008-10-31 13:59:32 +00:00
parent bad9854d71
commit f1cc01c6b8
2 changed files with 142 additions and 51 deletions

View File

@@ -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)

View File

@@ -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);
}