?? xserverdesktop.cc
字號:
} } } int rfbMaskBytesPerRow = (w + 7) / 8; rdr::U8* cursorMask = new rdr::U8[rfbMaskBytesPerRow * h]; for (int j = 0; j < h; j++) { for (int i = 0; i < rfbMaskBytesPerRow; i++)#if (BITMAP_BIT_ORDER == MSBFirst) cursorMask[j * rfbMaskBytesPerRow + i] = cursor->bits->mask[j * xMaskBytesPerRow + i];#else cursorMask[j * rfbMaskBytesPerRow + i] = reverseBits[cursor->bits->mask[j * xMaskBytesPerRow + i]];#endif } server->setCursor(cursor->bits->width, cursor->bits->height, Point(cursor->bits->xhot, cursor->bits->yhot), cursorData, cursorMask); server->tryUpdate(); delete [] cursorData; delete [] cursorMask; } catch (rdr::Exception& e) { vlog.error("XserverDesktop::setCursor: %s",e.str()); }}static void printRegion(RegionPtr reg){ int nrects = REGION_NUM_RECTS(reg); fprintf(stderr,"Region num rects %2d extents %3d,%3d %3dx%3d\n",nrects, (REGION_EXTENTS(pScreen,reg))->x1, (REGION_EXTENTS(pScreen,reg))->y1, (REGION_EXTENTS(pScreen,reg))->x2-(REGION_EXTENTS(pScreen,reg))->x1, (REGION_EXTENTS(pScreen,reg))->y2-(REGION_EXTENTS(pScreen,reg))->y1); for (int i = 0; i < nrects; i++) { fprintf(stderr," rect %3d,%3d %3dx%3d\n", REGION_RECTS(reg)[i].x1, REGION_RECTS(reg)[i].y1, REGION_RECTS(reg)[i].x2-REGION_RECTS(reg)[i].x1, REGION_RECTS(reg)[i].y2-REGION_RECTS(reg)[i].y1); }}CARD32 XserverDesktop::deferredUpdateTimerCallback(OsTimerPtr timer, CARD32 now, pointer arg){ XserverDesktop* desktop = (XserverDesktop*)arg; desktop->deferredUpdateTimerSet = false; try { desktop->server->tryUpdate(); } catch (rdr::Exception& e) { vlog.error("XserverDesktop::deferredUpdateTimerCallback: %s",e.str()); } return 0;}void XserverDesktop::deferUpdate(){ if (deferUpdateTime != 0) { if (!deferredUpdateTimerSet || alwaysSetDeferUpdateTimer) { deferredUpdateTimerSet = true; deferredUpdateTimer = TimerSet(deferredUpdateTimer, 0, deferUpdateTime, deferredUpdateTimerCallback, this); } } else { server->tryUpdate(); }}void XserverDesktop::add_changed(RegionPtr reg){ if (ignoreHooks_) return; if (grabbing) return; try { rfb::Region rfbReg; rfbReg.setExtentsAndOrderedRects((ShortRect*)REGION_EXTENTS(pScreen, reg), REGION_NUM_RECTS(reg), (ShortRect*)REGION_RECTS(reg)); server->add_changed(rfbReg); deferUpdate(); } catch (rdr::Exception& e) { vlog.error("XserverDesktop::add_changed: %s",e.str()); }}void XserverDesktop::add_copied(RegionPtr dst, int dx, int dy){ if (ignoreHooks_) return; if (grabbing) return; try { rfb::Region rfbReg; rfbReg.setExtentsAndOrderedRects((ShortRect*)REGION_EXTENTS(pScreen, dst), REGION_NUM_RECTS(dst), (ShortRect*)REGION_RECTS(dst)); server->add_copied(rfbReg, rfb::Point(dx, dy)); deferUpdate(); } catch (rdr::Exception& e) { vlog.error("XserverDesktop::add_copied: %s",e.str()); }}void XserverDesktop::positionCursor(){ if (!cursorPos.equals(oldCursorPos)) { oldCursorPos = cursorPos; (*pScreen->SetCursorPosition) (pScreen, cursorPos.x, cursorPos.y, FALSE); server->setCursorPos(cursorPos); server->tryUpdate(); }}void XserverDesktop::blockHandler(fd_set* fds){ try { ScreenPtr screenWithCursor = GetCurrentRootWindow()->drawable.pScreen; if (screenWithCursor == pScreen) { int x, y; GetSpritePosition(&x, &y); if (x != cursorPos.x || y != cursorPos.y) { cursorPos = oldCursorPos = Point(x, y); server->setCursorPos(cursorPos); server->tryUpdate(); } } if (listener) FD_SET(listener->getFd(), fds); if (httpListener) FD_SET(httpListener->getFd(), fds); std::list<Socket*> sockets; server->getSockets(&sockets); std::list<Socket*>::iterator i; for (i = sockets.begin(); i != sockets.end(); i++) { int fd = (*i)->getFd(); if ((*i)->isShutdown()) { vlog.debug("client gone, sock %d",fd); server->removeSocket(*i); vncClientGone(fd); delete (*i); } else { FD_SET(fd, fds); } } if (httpServer) { httpServer->getSockets(&sockets); for (i = sockets.begin(); i != sockets.end(); i++) { int fd = (*i)->getFd(); if ((*i)->isShutdown()) { vlog.debug("http client gone, sock %d",fd); httpServer->removeSocket(*i); delete (*i); } else { FD_SET(fd, fds); } } } } catch (rdr::Exception& e) { vlog.error("XserverDesktop::blockHandler: %s",e.str()); }}static CARD32 dummyTimerCallback(OsTimerPtr timer, CARD32 now, pointer arg) { return 0;}void XserverDesktop::wakeupHandler(fd_set* fds, int nfds){ try { if (nfds >= 1) { if (listener) { if (FD_ISSET(listener->getFd(), fds)) { FD_CLR(listener->getFd(), fds); Socket* sock = listener->accept(); server->addSocket(sock); vlog.debug("new client, sock %d",sock->getFd()); } } if (httpListener) { if (FD_ISSET(httpListener->getFd(), fds)) { FD_CLR(httpListener->getFd(), fds); Socket* sock = httpListener->accept(); httpServer->addSocket(sock); vlog.debug("new http client, sock %d",sock->getFd()); } } std::list<Socket*> sockets; server->getSockets(&sockets); std::list<Socket*>::iterator i; for (i = sockets.begin(); i != sockets.end(); i++) { int fd = (*i)->getFd(); if (FD_ISSET(fd, fds)) { FD_CLR(fd, fds); server->processSocketEvent(*i); } } if (httpServer) { httpServer->getSockets(&sockets); for (i = sockets.begin(); i != sockets.end(); i++) { int fd = (*i)->getFd(); if (FD_ISSET(fd, fds)) { FD_CLR(fd, fds); httpServer->processSocketEvent(*i); } } } positionCursor(); } int timeout = server->checkTimeouts(); if (timeout > 0) { // set a dummy timer just so we are guaranteed be called again next time. dummyTimer = TimerSet(dummyTimer, 0, timeout, dummyTimerCallback, 0); } } catch (rdr::Exception& e) { vlog.error("XserverDesktop::wakeupHandler: %s",e.str()); }}void XserverDesktop::addClient(Socket* sock, bool reverse){ vlog.debug("new client, sock %d reverse %d",sock->getFd(),reverse); server->addSocket(sock, reverse);}void XserverDesktop::disconnectClients(){ vlog.debug("disconnecting all clients"); return server->closeClients("Disconnection from server end");}int XserverDesktop::getQueryTimeout(void* opaqueId, const char** address, const char** username){ if (opaqueId && queryConnectId == opaqueId) { vlog.info("address=%s, username=%s, timeout=%d", queryConnectAddress.buf, queryConnectUsername.buf, (int)queryConnectTimeout); if (address) *address = queryConnectAddress.buf; if (username) *username = queryConnectUsername.buf; return queryConnectTimeout; } return 0;}void XserverDesktop::approveConnection(void* opaqueId, bool accept, const char* rejectMsg){ if (queryConnectId == opaqueId) { server->approveConnection((network::Socket*)opaqueId, accept, rejectMsg); queryConnectId = 0; }}/////////////////////////////////////////////////////////////////////////////// SDesktop callbacksvoid XserverDesktop::pointerEvent(const Point& pos, int buttonMask){ xEvent ev; DevicePtr dev = LookupPointerDevice(); // SetCursorPosition seems to be very expensive (at least on XFree86 3.3.6 // for S3), so we delay calling it until positionCursor() is called at the // end of processing a load of RFB. //(*pScreen->SetCursorPosition) (pScreen, pos.x, pos.y, FALSE); NewCurrentScreen(pScreen, pos.x, pos.y); ev.u.u.type = MotionNotify; ev.u.u.detail = 0; ev.u.keyButtonPointer.rootX = pos.x; ev.u.keyButtonPointer.rootY = pos.y; ev.u.keyButtonPointer.time = GetTimeInMillis(); if (!pos.equals(cursorPos)) (*dev->processInputProc)(&ev, (DeviceIntPtr)dev, 1); for (int i = 0; i < 5; i++) { if ((buttonMask ^ oldButtonMask) & (1<<i)) {#ifdef XINPUT // God knows why but some idiot decided to conditionally move the pointer // mapping out of DIX, so we guess here that if XINPUT is defined we have // to do it ourselves... ev.u.u.detail = ((DeviceIntPtr)dev)->button->map[i + 1];#else ev.u.u.detail = i + 1;#endif ev.u.u.type = (buttonMask & (1<<i)) ? ButtonPress : ButtonRelease; (*dev->processInputProc)(&ev, (DeviceIntPtr)dev, 1); } } cursorPos = pos; oldButtonMask = buttonMask;}void XserverDesktop::clientCutText(const char* str, int len){ vncClientCutText(str, len);}void XserverDesktop::grabRegion(const rfb::Region& region){ if (directFbptr) return; if (!pScreen->GetImage) { vlog.error("VNC error: pScreen->GetImage == 0"); return; } grabbing = true; int bytesPerPixel = format.bpp/8; int bytesPerRow = pScreen->width * bytesPerPixel; std::vector<rfb::Rect> rects; std::vector<rfb::Rect>::iterator i; region.get_rects(&rects); for (i = rects.begin(); i != rects.end(); i++) { for (int y = i->tl.y; y < i->br.y; y++) { (*pScreen->GetImage) ((DrawablePtr)WindowTable[pScreen->myNum], i->tl.x, y, i->width(), 1, ZPixmap, (unsigned long)~0L, ((char*)data + y * bytesPerRow + i->tl.x * bytesPerPixel)); } } grabbing = false;}void XserverDesktop::lookup(int index, int* r, int* g, int* b){ if ((cmap->c_class | DynamicClass) == DirectColor) { VisualPtr v = cmap->pVisual; *r = cmap->red [(index & v->redMask ) >> v->offsetRed ].co.local.red; *g = cmap->green[(index & v->greenMask) >> v->offsetGreen].co.local.green; *b = cmap->blue [(index & v->blueMask ) >> v->offsetBlue ].co.local.blue; } else { EntryPtr pent; pent = (EntryPtr)&cmap->red[index]; if (pent->fShared) { *r = pent->co.shco.red->color; *g = pent->co.shco.green->color; *b = pent->co.shco.blue->color; } else { *r = pent->co.local.red; *g = pent->co.local.green; *b = pent->co.local.blue; } }}//// Keyboard handling//#define IS_PRESSED(keyc, keycode) \ ((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))// ModifierState is a class which helps simplify generating a "fake" press// or release of shift, ctrl, alt, etc. An instance of the class is created// for every modifier which may need to be pressed or released. Then either// press() or release() may be called to make sure that the corresponding keys// are in the right state. The destructor of the class automatically reverts// to the previous state. Each modifier may have multiple keys associated with// it, so in the case of a fake release, this may involve releasing more than// one key.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -