// This event handler deals with Frambebuffer Updates coming from the host. An // EncodedRectangle object is passed via the VncEventArgs (actually an IDesktopUpdater // object so that *only* Draw() can be called here--Decode() is done elsewhere). // The VncClient object handles thread marshalling onto the UI thread. protected void VncUpdate(object sender, VncEventArgs e) { Dispatcher.Invoke(new Action(() => { e.DesktopUpdater.Draw(desktop); })); if (state == RuntimeState.Connected) { vnc.RequestScreenUpdate(fullScreenRefresh); // Make sure the next screen update is incremental fullScreenRefresh = false; } }
/// <summary> /// Worker thread lives here and processes protocol messages infinitely, triggering events or other actions as necessary. /// </summary> private void GetRfbUpdates() { int rectangles; int enc; // Get the initial destkop from the host RequestScreenUpdate(true); while (true) { if (CheckIfThreadDone()) { break; } try { switch (rfb.ReadServerMessageType()) { case RfbProtocol.FRAMEBUFFER_UPDATE: rectangles = rfb.ReadFramebufferUpdate(); if (CheckIfThreadDone()) { break; } // TODO: consider gathering all update rectangles in a batch and *then* posting the event back to the main thread. for (int i = 0; i < rectangles; ++i) { // Get the update rectangle's info Rectangle rectangle; rfb.ReadFramebufferUpdateRectHeader(out rectangle, out enc); // Build a derived EncodedRectangle type and pull-down all the pixel info EncodedRectangle er = factory.Build(rectangle, enc); er.Decode(); // Let the UI know that an updated rectangle is available, but check // to see if the user closed things down first. if (!CheckIfThreadDone() && VncUpdate != null) { VncEventArgs e = new VncEventArgs(er); // In order to play nicely with WinForms controls, we do a check here to // see if it is necessary to synchronize this event with the UI thread. if (VncUpdate.Target is System.Windows.Forms.Control) { Control target = VncUpdate.Target as Control; if (target != null) { target.Invoke(VncUpdate, new object[] { this, e }); } } else { // Target is not a WinForms control, so do it on this thread... VncUpdate(this, new VncEventArgs(er)); } } } break; case RfbProtocol.BELL: Beep(500, 300); // TODO: are there better values than these? break; case RfbProtocol.SERVER_CUT_TEXT: if (CheckIfThreadDone()) { break; } // TODO: This is invasive, should there be a bool property allowing this message to be ignored? Clipboard.SetDataObject(rfb.ReadServerCutText().Replace("\n", Environment.NewLine), true); OnServerCutText(); break; case RfbProtocol.SET_COLOUR_MAP_ENTRIES: rfb.ReadColourMapEntry(); break; } } catch { OnConnectionLost(); } } }
/// <summary> /// Worker thread lives here and processes protocol messages infinitely, triggering events or other actions as necessary. /// </summary> private void GetRfbUpdates() { int rectangles; int enc; // Get the initial destkop from the host RequestScreenUpdate(true); while (true) { if (CheckIfThreadDone()) break; try { switch (rfb.ReadServerMessageType()) { case RfbProtocol.FRAMEBUFFER_UPDATE: rectangles = rfb.ReadFramebufferUpdate(); if (CheckIfThreadDone()) break; // TODO: consider gathering all update rectangles in a batch and *then* posting the event back to the main thread. for (int i = 0; i < rectangles; ++i) { // Get the update rectangle's info Rectangle rectangle; rfb.ReadFramebufferUpdateRectHeader(out rectangle, out enc); // Build a derived EncodedRectangle type and pull-down all the pixel info EncodedRectangle er = factory.Build(rectangle, enc); er.Decode(); // Let the UI know that an updated rectangle is available, but check // to see if the user closed things down first. if (!CheckIfThreadDone() && VncUpdate != null) { VncEventArgs e = new VncEventArgs(er); // In order to play nicely with WinForms controls, we do a check here to // see if it is necessary to synchronize this event with the UI thread. if (VncUpdate.Target is System.Windows.Forms.Control) { Control target = VncUpdate.Target as Control; if (target != null) target.Invoke(VncUpdate, new object[] { this, e }); } else { // Target is not a WinForms control, so do it on this thread... VncUpdate(this, new VncEventArgs(er)); } } } break; case RfbProtocol.BELL: Beep(500, 300); // TODO: are there better values than these? break; case RfbProtocol.SERVER_CUT_TEXT: if (CheckIfThreadDone()) break; // TODO: This is invasive, should there be a bool property allowing this message to be ignored? Clipboard.SetDataObject(rfb.ReadServerCutText().Replace("\n", Environment.NewLine), true); OnServerCutText(); break; case RfbProtocol.SET_COLOUR_MAP_ENTRIES: rfb.ReadColourMapEntry(); break; } } catch { OnConnectionLost(); } } }