⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 desktopwindow.cxx

📁 linux可以运行程序源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
void DesktopWindow::invertRect(const Rect& r){  int stride;  rdr::U8* p = im->getPixelsRW(r, &stride);  for (int y = 0; y < r.height(); y++) {    for (int x = 0; x < r.width(); x++) {      switch (getPF().bpp) {      case 8:  ((rdr::U8* )p)[x+y*stride] ^= 0xff;       break;      case 16: ((rdr::U16*)p)[x+y*stride] ^= 0xffff;     break;      case 32: ((rdr::U32*)p)[x+y*stride] ^= 0xffffffff; break;      }    }  }  im->put(win(), gc, r);}// resize() - resize the window and the image, taking care to remove the local// cursor first.void DesktopWindow::resize(int w, int h){  hideLocalCursor();  TXWindow::resize(w, h);  im->resize(w, h);}bool DesktopWindow::handleTimeout(rfb::Timer* timer){  if (timer == &setColourMapEntriesTimer) {    im->updateColourMap();    im->put(win(), gc, im->getRect());  } else if (timer == &pointerEventTimer) {    if (!viewOnly) {      cc->writer()->pointerEvent(lastPointerPos, lastButtonMask);    }  }  return false;}void DesktopWindow::handlePointerEvent(const Point& pos, int buttonMask){  if (!viewOnly) {    if (pointerEventInterval == 0 || buttonMask != lastButtonMask) {      cc->writer()->pointerEvent(pos, buttonMask);    } else {      if (!pointerEventTimer.isStarted())        pointerEventTimer.start(pointerEventInterval);    }    lastPointerPos = pos;    lastButtonMask = buttonMask;  }  // - If local cursor rendering is enabled then use it  if (cursorAvailable) {    // - Render the cursor!    if (!pos.equals(cursorPos)) {      hideLocalCursor();      if (im->getRect().contains(pos)) {        cursorPos = pos;        showLocalCursor();      }    }  }}// handleXEvent() handles the various X events on the windowvoid DesktopWindow::handleEvent(TXWindow* w, XEvent* ev){  switch (ev->type) {  case GraphicsExpose:  case Expose:    im->put(win(), gc, Rect(ev->xexpose.x, ev->xexpose.y,                            ev->xexpose.x + ev->xexpose.width,                            ev->xexpose.y + ev->xexpose.height));    break;  case MotionNotify:    while (XCheckTypedWindowEvent(dpy, win(), MotionNotify, ev));    if (viewport && viewport->bumpScrollEvent(&ev->xmotion)) break;    handlePointerEvent(Point(ev->xmotion.x, ev->xmotion.y),                       (ev->xmotion.state & 0x1f00) >> 8);    break;  case ButtonPress:    handlePointerEvent(Point(ev->xbutton.x, ev->xbutton.y),                       (((ev->xbutton.state & 0x1f00) >> 8) |                        (1 << (ev->xbutton.button-1))));    break;  case ButtonRelease:    handlePointerEvent(Point(ev->xbutton.x, ev->xbutton.y),                       (((ev->xbutton.state & 0x1f00) >> 8) &                        ~(1 << (ev->xbutton.button-1))));    break;  case KeyPress:    if (!viewOnly) {      KeySym ks;      char keyname[256];      XLookupString(&ev->xkey, keyname, 256, &ks, NULL);      bool fakeShiftPress = false;      // Turn ISO_Left_Tab into shifted Tab      if (ks == XK_ISO_Left_Tab) {        fakeShiftPress = !(ev->xkey.state & ShiftMask);        ks = XK_Tab;      }      if (fakeShiftPress)        cc->writer()->keyEvent(XK_Shift_L, true);      downKeysym[ev->xkey.keycode] = ks;      cc->writer()->keyEvent(ks, true);      if (fakeShiftPress)        cc->writer()->keyEvent(XK_Shift_L, false);      break;    }  case KeyRelease:    if (!viewOnly) {      if (downKeysym[ev->xkey.keycode]) {        cc->writer()->keyEvent(downKeysym[ev->xkey.keycode], false);        downKeysym[ev->xkey.keycode] = 0;      }    }    break;  case EnterNotify:    newSelection = 0;    if (sendPrimary && !selectionOwner(XA_PRIMARY)) {      XConvertSelection(dpy, XA_PRIMARY, xaTIMESTAMP, xaSELECTION_TIME,                        win(), ev->xcrossing.time);    } else if (!selectionOwner(xaCLIPBOARD)) {      XConvertSelection(dpy, xaCLIPBOARD, xaTIMESTAMP, xaSELECTION_TIME,                        win(), ev->xcrossing.time);    }    break;  case LeaveNotify:    if (serverCutText_ && newServerCutText) {      newServerCutText = false;      vlog.debug("acquiring primary and clipboard selections");      XStoreBytes(dpy, serverCutText_, strlen(serverCutText_));      ownSelection(XA_PRIMARY, ev->xcrossing.time);      ownSelection(xaCLIPBOARD, ev->xcrossing.time);      currentSelectionTime = ev->xcrossing.time;    }    // Release all keys - this should probably done on a FocusOut event, but    // LeaveNotify is near enough...    for (int i = 8; i < 256; i++) {      if (downKeysym[i]) {        cc->writer()->keyEvent(downKeysym[i], false);        downKeysym[i] = 0;      }    }    break;  }}// selectionRequest() is called when we are the selection owner and another X// client has requested the selection.  We simply put the server's cut text// into the requested property.  TXWindow will handle the rest.bool DesktopWindow::selectionRequest(Window requestor,                                     Atom selection, Atom property){  XChangeProperty(dpy, requestor, property, XA_STRING, 8,                  PropModeReplace, (unsigned char*)serverCutText_,                  strlen(serverCutText_));  return true;}// selectionNotify() is called when we have requested any information about a// selection from the selection owner.  Note that there are two selections,// PRIMARY and CLIPBOARD, plus the cut buffer, and we try to use whichever is// the most recent of the three.//// There are two different "targets" for which selectionNotify() is called, the// timestamp and the actual string value of the selection.  We always use the// timestamp to decide which selection to retrieve.//// The first time selectionNotify() is called is when we are trying to find the// timestamp of the selections at initialisation.  This should be called first// for PRIMARY, then we call XConvertSelection() for CLIPBOARD.  The second// time should be the result for CLIPBOARD.  At this stage we've got the// "currentSelectionTime" so we return.//// Subsequently selectionNotify() is called whenever the mouse enters the// viewer window.  Again, the first time it is called should be the timestamp// for PRIMARY, and we then request the timestamp for CLIPBOARD.  When// selectionNotify() is called again with the timestamp for CLIPBOARD, we now// know if either selection is "new" i.e. later than the previous value of// currentSelectionTime.  The last thing to check is the timestamp on the cut// buffer.  If the cut buffer is newest we send that to the server, otherwise// if one of the selections was newer, we request the string value of that// selection.//// Finally, if we get selectionNotify() called for the string value of a// selection, we sent that to the server.//// As a final minor complication, when one of the selections is actually owned// by us, we don't request the details for it.// TIME_LATER treats 0 as meaning a long time ago, so a==0 means a cannot be// later than b.  This is different to the usual meaning of CurrentTime.#define TIME_LATER(a, b) ((a) != 0 && ((b) == 0 || (long)((a) - (b)) > 0))void DesktopWindow::selectionNotify(XSelectionEvent* ev, Atom type, int format,                                    int nitems, void* data){  if (ev->requestor != win())    return;  if (ev->target == xaTIMESTAMP) {    if (ev->property == xaSELECTION_TIME) {      if (data && format == 32 && nitems == 1) {        Time t = *(rdr::U32 *)data;        vlog.debug("selection (%d) time is %d, later %d",                   ev->selection, t, TIME_LATER(t, currentSelectionTime));        if (TIME_LATER(t, currentSelectionTime)) {          currentSelectionTime = t;          newSelection = ev->selection;        }      }    } else {      vlog.debug("no selection (%d)",ev->selection);    }    if (ev->selection == XA_PRIMARY) {      if (!selectionOwner(xaCLIPBOARD)) {        XConvertSelection(dpy, xaCLIPBOARD, xaTIMESTAMP, xaSELECTION_TIME,                          win(), ev->time);        return;      }    } else if (ev->selection != xaCLIPBOARD) {      vlog.error("unknown selection %d",ev->selection);      return;    }    if (gettingInitialSelectionTime) {      gettingInitialSelectionTime = false;      return;    }    if (!sendClipboard) return;    if (sendPrimary) {      vlog.debug("cut buffer time is %d, later %d", cutBufferTime,                 TIME_LATER(cutBufferTime, currentSelectionTime));      if (TIME_LATER(cutBufferTime, currentSelectionTime)) {        currentSelectionTime = cutBufferTime;        int len;        char* str = XFetchBytes(dpy, &len);        if (str) {          if (!viewOnly) {            vlog.debug("sending cut buffer to server");            cc->writer()->clientCutText(str, len);          }          XFree(str);          return;        }      }    }    if (newSelection) {      XConvertSelection(dpy, newSelection, XA_STRING, xaSELECTION_STRING,                        win(), CurrentTime);    }  } else if (ev->target == XA_STRING) {    if (!sendClipboard) return;    if (ev->property == xaSELECTION_STRING) {      if (data && format == 8) {        if (!viewOnly) {          vlog.debug("sending %s selection to server",                     ev->selection == XA_PRIMARY ? "primary" :                     ev->selection == xaCLIPBOARD ? "clipboard" : "unknown" );          cc->writer()->clientCutText((char*)data, nitems);        }      }    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -