Show
Ignore:
Timestamp:
10/31/08 14:59:32 (5 years ago)
Author:
robert
Message:

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

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgvnc/osgvnc.cpp

    r9082 r9083  
    88#include <osgViewer/ViewerEventHandlers> 
    99 
    10 #include <SDL.h> 
    11  
    1210#include <iostream> 
     11#include <osg/io_utils> 
    1312 
    1413extern "C" { 
     
    1615} 
    1716 
    18 struct ButtonMapping { int sdl; int rfb; }; 
    19  
    20 ButtonMapping buttonMapping[]={ 
    21     {1, rfbButton1Mask}, 
    22     {2, rfbButton2Mask}, 
    23     {3, rfbButton3Mask}, 
    24     {0,0} 
    25 }; 
    26  
    27 static rfbBool resize(rfbClient* client) { 
    28  
    29     static char first=TRUE; 
    30      
     17static rfbBool resizeImage(rfbClient* client)  
     18{ 
    3119    osg::Image* image = (osg::Image*)(rfbClientGetClientData(client, 0)); 
    3220     
     
    4432} 
    4533 
    46 static void update(rfbClient* client,int x,int y,int w,int h) { 
    47  
     34static void updateImage(rfbClient* client,int x,int y,int w,int h) 
     35{ 
    4836    osg::Image* image = (osg::Image*)(rfbClientGetClientData(client, 0)); 
    4937    image->dirty(); 
    5038} 
    5139 
    52 static void kbd_leds(rfbClient* client, int value, int pad) { 
    53     printf("kbd_leds %d %d\n",value,pad); 
    54  
    55     /* note: pad is for future expansion 0=unused */ 
    56     fprintf(stderr,"Led State= 0x%02X\n", value); 
    57     fflush(stderr); 
    58 } 
    59  
    60 /* trivial support for textchat */ 
    61 static void text_chat(rfbClient* client, int value, char *text) { 
    62     switch(value) { 
    63     case rfbTextChatOpen: 
    64         fprintf(stderr,"TextChat: We should open a textchat window!\n"); 
    65         TextChatOpen(client); 
    66         break; 
    67     case rfbTextChatClose: 
    68         fprintf(stderr,"TextChat: We should close our window!\n"); 
    69         break; 
    70     case rfbTextChatFinished: 
    71         fprintf(stderr,"TextChat: We should close our window!\n"); 
    72         break; 
    73     default: 
    74         fprintf(stderr,"TextChat: Received \"%s\"\n", text); 
    75         break; 
    76     } 
    77     fflush(stderr); 
     40 
     41class RfbEventHandler : public osgGA::GUIEventHandler 
     42{ 
     43public: 
     44 
     45    RfbEventHandler(rfbClient* client): 
     46        _client(client) {} 
     47     
     48    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv); 
     49     
     50    rfbKeySym key2rfbKeySym(int key) 
     51    { 
     52        return rfbKeySym(key); 
     53    } 
     54 
     55protected: 
     56 
     57    virtual ~RfbEventHandler() {} 
     58     
     59    bool mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const; 
     60 
     61    rfbClient*  _client; 
     62     
     63}; 
     64 
     65bool RfbEventHandler::mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const 
     66{ 
     67    osgUtil::LineSegmentIntersector::Intersections intersections; 
     68    bool foundIntersection = view==0 ? false : 
     69        (nv==0 ? view->computeIntersections(ea.getX(), ea.getY(), intersections) : 
     70                 view->computeIntersections(ea.getX(), ea.getY(), nv->getNodePath(), intersections)); 
     71 
     72    if (foundIntersection) 
     73    { 
     74 
     75        osg::Vec2 tc(0.5f,0.5f); 
     76 
     77        // use the nearest intersection                  
     78        const osgUtil::LineSegmentIntersector::Intersection& intersection = *(intersections.begin()); 
     79        osg::Drawable* drawable = intersection.drawable.get(); 
     80        osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0; 
     81        osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0; 
     82        if (vertices) 
     83        { 
     84            // get the vertex indices. 
     85            const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices = intersection.indexList; 
     86            const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios = intersection.ratioList; 
     87 
     88            if (indices.size()==3 && ratios.size()==3) 
     89            { 
     90                unsigned int i1 = indices[0]; 
     91                unsigned int i2 = indices[1]; 
     92                unsigned int i3 = indices[2]; 
     93 
     94                float r1 = ratios[0]; 
     95                float r2 = ratios[1]; 
     96                float r3 = ratios[2]; 
     97 
     98                osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0; 
     99                osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords); 
     100                if (texcoords_Vec2Array) 
     101                { 
     102                    // we have tex coord array so now we can compute the final tex coord at the point of intersection.                                 
     103                    osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1]; 
     104                    osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2]; 
     105                    osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3]; 
     106                    tc = tc1*r1 + tc2*r2 + tc3*r3; 
     107                } 
     108            } 
     109 
     110        } 
     111 
     112        x = int( float(_client->width) * tc.x() ); 
     113        y = int( float(_client->height) * tc.y() ); 
     114 
     115        return true; 
     116    } 
     117     
     118    return false; 
     119} 
     120 
     121 
     122bool RfbEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv) 
     123{ 
     124    switch(ea.getEventType()) 
     125    { 
     126        case(osgGA::GUIEventAdapter::MOVE): 
     127        case(osgGA::GUIEventAdapter::DRAG): 
     128        case(osgGA::GUIEventAdapter::PUSH): 
     129        case(osgGA::GUIEventAdapter::RELEASE): 
     130        { 
     131            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); 
     132            int x,y; 
     133            if (mousePosition(view, nv, ea, x, y)) 
     134            { 
     135                SendPointerEvent(_client,x,y, ea.getButtonMask()); 
     136                return true; 
     137            } 
     138            break; 
     139        } 
     140        case(osgGA::GUIEventAdapter::KEYDOWN): 
     141        case(osgGA::GUIEventAdapter::KEYUP): 
     142        { 
     143            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); 
     144            int x,y; 
     145            bool sendKeyEvent = mousePosition(view, nv, ea, x, y); 
     146         
     147            if (sendKeyEvent) 
     148            { 
     149                SendKeyEvent(_client, 
     150                    key2rfbKeySym(ea.getKey()), 
     151                    (ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN)?TRUE:FALSE); 
     152 
     153                return true; 
     154            } 
     155            else 
     156            { 
     157                if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Escape) 
     158                { 
     159                    osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa); 
     160                    if (viewer) viewer->setDone(true); 
     161                } 
     162            } 
     163             
     164        } 
     165 
     166        default: 
     167            return false; 
     168    } 
     169    return false; 
    78170} 
    79171 
     
    117209int main(int argc,char** argv) 
    118210{ 
    119     int i,buttonMask=0; 
    120      
    121211    osg::ref_ptr<osg::Image> image = new osg::Image; 
    122212    // image->setPixelBufferObject(new osg::PixelBufferObject(image.get())); 
    123213 
    124     osg::notify(osg::NOTICE)<<"image = "<<image.get()<<std::endl; 
    125  
    126214    /* 16-bit: client=rfbGetClient(5,3,2); */ 
    127215    rfbClient* client=rfbGetClient(8,3,4); 
    128     client->MallocFrameBuffer=resize; 
    129216    client->canHandleNewFBSize = TRUE; 
    130     client->GotFrameBufferUpdate=update; 
    131     client->HandleKeyboardLedState=kbd_leds; 
    132     client->HandleTextChat=text_chat;     
     217    client->MallocFrameBuffer = resizeImage; 
     218    client->GotFrameBufferUpdate = updateImage; 
     219    client->HandleKeyboardLedState = 0; 
     220    client->HandleTextChat = 0; 
    133221 
    134222    rfbClientSetClientData(client, 0, image.get()); 
    135      
    136     osg::notify(osg::NOTICE)<<"Before rfbInitClient"<<std::endl; 
    137223 
    138224    if(!rfbInitClient(client,&argc,argv)) 
     
    169255 
    170256    viewer.addEventHandler(new osgViewer::StatsHandler); 
     257    viewer.addEventHandler(new RfbEventHandler(client)); 
    171258     
    172259    RfbThread rfbThread(client); 
    173260    rfbThread.startThread(); 
     261     
     262    viewer.setKeyEventSetsDone(0); 
    174263 
    175264    return viewer.run(); 
    176 } 
    177  
     265 
     266    // rfbClientCleanup(cl); 
     267} 
     268