diff --git a/examples/osgvnc/CMakeLists.txt b/examples/osgvnc/CMakeLists.txt index ffd6a1461..a6e8092f6 100644 --- a/examples/osgvnc/CMakeLists.txt +++ b/examples/osgvnc/CMakeLists.txt @@ -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) diff --git a/examples/osgvnc/osgvnc.cpp b/examples/osgvnc/osgvnc.cpp index 085aa8a26..8ae0bd967 100644 --- a/examples/osgvnc/osgvnc.cpp +++ b/examples/osgvnc/osgvnc.cpp @@ -7,27 +7,15 @@ #include #include -#include - #include +#include extern "C" { #include } -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(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(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(&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(&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(&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 image = new osg::Image; // image->setPixelBufferObject(new osg::PixelBufferObject(image.get())); - osg::notify(osg::NOTICE)<<"image = "<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"<