/// <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();
                }
            }
        }
Exemple #2
0
        /// <summary>
        ///     Worker thread lives here and processes protocol messages infinitely, triggering events or other actions as
        ///     necessary.
        /// </summary>
        private void GetRfbUpdates()
        {
            // Get the initial destkop from the host
            var connLostCount = 0;

            RequestScreenUpdate(true);

            while (true)
            {
                if (CheckIfThreadDone())
                {
                    break;
                }

                try
                {
                    // ReSharper disable once SwitchStatementMissingSomeCases
                    switch (rfb.ReadServerMessageType())
                    {
                    case RfbProtocol.FRAMEBUFFER_UPDATE:
                        var rectangles       = rfb.ReadFramebufferUpdate();
                        var encodedRecangles = new List <Rectangle>();
                        if (CheckIfThreadDone())
                        {
                            break;
                        }

                        // TODO: consider gathering all update rectangles in a batch and *then* posting the event back to the main thread.
                        for (var i = 0; i < rectangles; ++i)
                        {
                            // Get the update rectangle's info
                            rfb.ReadFramebufferUpdateRectHeader(out var rectangle, out var enc);

                            if (enc == RfbProtocol.PSEUDO_LAST_RECT_ENCODING)
                            {
                                break;
                            }

                            // Build a derived EncodedRectangle type and pull-down all the pixel info
                            var er = factory.Build(rectangle, enc);
                            er.Decode();
                            encodedRecangles.Add(er.UpdateRectangle);
                        }

                        // 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)
                        {
                            continue;
                        }
                        var e = new VncEventArgs(encodedRecangles, Framebuffer);

                        // 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 Control control)
                        {
                            control.Invoke(VncUpdate, this, e);
                        }
                        else
                        {
                            // Target is not a WinForms control, so do it on this thread...
                            VncUpdate(this, e);
                        }
                        break;

                    case RfbProtocol.BELL:
                        Beep();
                        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;
                    }

                    // Moved screen update request here to prevent it being called multiple times
                    // This was the case when multiple rectangles were returned by the host
                    RequestScreenUpdate(FullScreenRefresh);
                    connLostCount = 0;
                }
                catch
                {
                    // On the first time of no data being received we force a complete update
                    // This is for times when the server has no update, and caused the timeout.
                    if (connLostCount++ > 1)
                    {
                        OnConnectionLost();
                    }
                    else
                    {
                        RequestScreenUpdate(true);
                    }
                }

                FullScreenRefresh = false;
            }
        }
Exemple #3
0
        /// <summary>
        /// Worker thread lives here and processes protocol messages infinitely, triggering events or other actions as necessary.
        /// </summary>
        private void GetRfbUpdates(CancellationToken token)
        {
            // Get the initial destkop from the host
            int connLostCount = 0;

            RequestScreenUpdate(true);

            while (!token.IsCancellationRequested)
            {
                try
                {
                    // ReSharper disable once SwitchStatementMissingSomeCases
                    var msgType = rfb.ReadServerMessageType();
                    switch (msgType)
                    {
                    case ServerClientMessageType.FramebufferUpdate:
                        var rectangles = rfb.ReadFramebufferUpdate();

                        if (token.IsCancellationRequested)
                        {
                            break;
                        }

                        // TODO: consider gathering all update rectangles in a batch and *then* posting the event back to the main thread.
                        for (var i = 0; i < rectangles; ++i)
                        {
                            // Get the update rectangle's info
                            var(rectangle, enc) = rfb.ReadFramebufferUpdateRectHeader();

                            // Build a derived EncodedRectangle type and pull-down all the pixel info
                            var er = EncodedRectangle.Build(rfb, Framebuffer, 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 (token.IsCancellationRequested || VncUpdate == null)
                            {
                                continue;
                            }
                            var e = new VncEventArgs(er);

                            VncUpdate(this, new VncEventArgs(er));
                        }
                        break;

                    case ServerClientMessageType.Bell:
                        //Beep();
                        break;

                    case ServerClientMessageType.ServerCutText:

                        // TODO: This is invasive, should there be a bool property allowing this message to be ignored?
                        OnServerCutText();
                        break;

                    case ServerClientMessageType.SetColourMapEntries:
                        rfb.ReadColourMapEntry();
                        break;
                    }
                    // Moved screen update request here to prevent it being called multiple times
                    // This was the case when multiple rectangles were returned by the host
                    RequestScreenUpdate(FullScreenRefresh);
                    connLostCount = 0;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    // On the first time of no data being received we force a complete update
                    // This is for times when the server has no update, and caused the timeout.
                    if (connLostCount++ > 1)
                    {
                        OnConnectionLost();
                    }
                    else
                    {
                        RequestScreenUpdate(true);
                    }
                }
                FullScreenRefresh = false;
            }
        }