#include #include #include #include #include #include #include #include extern "C" { #include } class VncImage : public osg::Image { public: VncImage(); bool connect(int* argc, char** argv); void close(); static rfbBool resizeImage(rfbClient* client); static void updateImage(rfbClient* client,int x,int y,int w,int h); protected: virtual ~VncImage(); class RfbThread : public osg::Referenced, public OpenThreads::Thread { public: RfbThread(rfbClient* client): _client(client), _done(false) {} virtual ~RfbThread() { _done = true; cancel(); while(isRunning()) { OpenThreads::Thread::YieldCurrentThread(); } } virtual void run() { do { int i=WaitForMessage(_client,500); if(i<0) return; if(i) if(!HandleRFBServerMessage(_client)) return; } while (!_done && !testCancel()); } rfbClient* _client; bool _done; }; public: rfbClient* _client; osg::ref_ptr _rfbThread; }; VncImage::VncImage() { // setPixelBufferObject(new osg::PixelBufferObject(this); } VncImage::~VncImage() { close(); } bool VncImage::connect(int* argc, char** argv) { if (_client) close(); _client = rfbGetClient(8,3,4); _client->canHandleNewFBSize = TRUE; _client->MallocFrameBuffer = resizeImage; _client->GotFrameBufferUpdate = updateImage; _client->HandleKeyboardLedState = 0; _client->HandleTextChat = 0; rfbClientSetClientData(_client, 0, this); if (rfbInitClient(_client,argc,argv)) { _rfbThread = new RfbThread(_client); _rfbThread->startThread(); } } void VncImage::close() { if (_rfbThread.valid()) { // stop the client thread _rfbThread = 0; } if (_client) { // close the client rfbClientCleanup(_client); _client = 0; } } rfbBool VncImage::resizeImage(rfbClient* client) { osg::Image* image = (osg::Image*)(rfbClientGetClientData(client, 0)); int width=client->width; int height=client->height; int depth=client->format.bitsPerPixel; std::cout<<"resize "<