| 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 | |
| | 41 | class RfbEventHandler : public osgGA::GUIEventHandler |
| | 42 | { |
| | 43 | public: |
| | 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 | |
| | 55 | protected: |
| | 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 | |
| | 65 | bool 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 | |
| | 122 | bool 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; |