Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        public void compressSend(Object arg)
        {
            // Now send this update off
            UInt32 hdr;

            byte[]       hdrbuf;
            streamThread parent = (streamThread)arg;

            Debug.Assert(buf != null);

            try {
                if (buf.Length == -1)
                {
                    buf = parent._mirror.GetRect(x, y, w, h);
                }
            } catch {
                Trace.WriteLine("getRect failed");
                return;
            }
            if (buf == null)
            {
                return;
            }

            outbuf = new MemoryStream();

            int checkSum = 1;

            using (DeflateStream compress = new DeflateStream(outbuf, CompressionMode.Compress
#if USE_IONIC_ZLIB
                                                              , CompressionLevel.BestSpeed /* CompressionLevel.BestCompression */)){
                compress.FlushMode = FlushType.Sync;
Beispiel #2
0
 /// <summary>
 /// Send updates. if newStream is not null, send to just this streams, otherwise everyone gets this update
 /// </summary>
 /// <param name="newStream"></param>
 /// <param name="buf"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="w"></param>
 /// <param name="h"></param>
 public sendUpdate(NetworkStream newStream, GCbuf buf, int x, int y, int w, int h)   // , int width, int height, int maskX, int maskY, int maskWidth, int maskHeight) {
 {
     this.newStream = newStream;
     this.buf       = buf;
     this.x         = x;
     this.y         = y;
     this.w         = w;
     this.h         = h;
     // this.width = width;
     // this.height = height;
     // this.maskX = maskX;
     // this.maskY = maskY;
     // this.maskWidth = maskWidth;
     // this.maskHeight = maskHeight;
 }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="newStream"></param>
        private void sendIframe(NetworkStream newStream)
        {
            try {
                GCbuf screenbuf = new GCbuf();

#if USE_BITMAP_COMPRESS
                int ptr = DesktopMirror._bitmapWidth * DesktopMirror._bitmapHeight, num = 0;
                for (int i = 0; i < ptr; i++)
                {
                    screenbuf.buf[num++] = 0xFF;
                }
                for (int i = 0; i < (ptr * 4); i += 4)
                {
                    screenbuf.buf[num++] = _mirror.screen[i];
                    screenbuf.buf[num++] = _mirror.screen[i + 1];
                    screenbuf.buf[num++] = _mirror.screen[i + 2];
                }
#else
                Buffer.BlockCopy(_mirror.screen, 0, screenbuf.buf, 0, _mirror.screen.Length);
#endif
                // screenbuf.buf = _mirror.screen;
                screenbuf.Length = _mirror.screen.Length;

                sendUpdate upd;
                if (Program.maskValid == true)
                {
                    upd = new sendUpdate(newStream, screenbuf, Program.maskX, Program.maskY, Program.maskWidth, Program.maskHeight);
                }
                else
                {
                    upd = new sendUpdate(newStream, screenbuf, 0, 0, DesktopMirror._bitmapWidth, DesktopMirror._bitmapHeight);
                }
                lock (streamer.updates.SyncRoot) {
                    streamer.updates.Enqueue(upd);
                }
            } catch (IOException) {
                Trace.WriteLine("DEBUG: Event creator causes an internal Win32 exception. Just ignore");
            }
        }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="dce"></param>
        static private unsafe void _DesktopChange(object sender, DesktopChangeEventArgs dce)
        {
            if (streamer.clients.Count > 0)     // No one is listening, why bother to process updates
            {
                try {
                    lock (streamer.updates.SyncRoot) {
                        if (streamer.updates.Count == 0)
                        {
                            if (numUpdates++ > 5)
                            {
                                // Send the iFrame

                                GCbuf screenbuf = new GCbuf();
#if USE_BITMAP_COMPRESS
                                int ptr = DesktopMirror._bitmapWidth * DesktopMirror._bitmapHeight, num = 0;
                                for (int i = 0; i < ptr; i++)
                                {
                                    screenbuf.buf[num++] = 0xFF;
                                }
                                for (int i = 0; i < (ptr * 4); i += 4)
                                {
                                    screenbuf.buf[num++] = _mirror.screen[i];
                                    screenbuf.buf[num++] = _mirror.screen[i + 1];
                                    screenbuf.buf[num++] = _mirror.screen[i + 2];
                                }
#else
                                Buffer.BlockCopy(_mirror.screen, 0, screenbuf.buf, 0, _mirror.screen.Length);
                                //    for (int i = 0; i < _mirror.screen.Length; i++)
                                //        screenbuf.buf[i] = _mirror.screen[i];
#endif
                                screenbuf.Length = _mirror.screen.Length;

                                streamer.updates.Enqueue(new sendUpdate(null, screenbuf, maskX, maskY, maskWidth, maskHeight));
                                numUpdates = 0;
                            }
                            else
                            {
                                if (maskValid == true)
                                {
                                    System.Drawing.Rectangle cur  = new System.Drawing.Rectangle(dce.x, dce.y, dce.w, dce.h);
                                    System.Drawing.Rectangle mask = new System.Drawing.Rectangle(Program.maskX, Program.maskY, Program.maskWidth, Program.maskHeight);
                                    cur.Intersect(mask);

                                    if (cur.IsEmpty)
                                    {
                                        return;
                                    }
                                    else
                                    {
                                        streamer.updates.Enqueue(new sendUpdate(null, null, cur.X, cur.Y, cur.Width, cur.Height));
                                    }
                                }
                                else
                                {
                                    streamer.updates.Enqueue(new sendUpdate(null, null, dce.x, dce.y, dce.w, dce.h));
                                }
                            }
                        }
                        else
                        {
                            System.Drawing.Rectangle orig = new System.Drawing.Rectangle(dce.x, dce.y, dce.w, dce.h);

                            if (maskValid == true)
                            {
                                System.Drawing.Rectangle mask = new System.Drawing.Rectangle(Program.maskX, Program.maskY, Program.maskWidth, Program.maskHeight);

                                orig.Intersect(mask);
                                if (orig.IsEmpty)
                                {
                                    return;
                                }
                            }

                            for (int i = streamer.updates.Count; i > 0; i--)
                            {
                                sendUpdate upd = (sendUpdate)streamer.updates.Dequeue();
                                System.Drawing.Rectangle cur = new System.Drawing.Rectangle(upd.x, upd.y, upd.w, upd.h);

                                /* I don't think that I need to do this
                                 * if (maskValid == true) {
                                 *  cur.Intersect(mask);
                                 *  if (cur.IsEmpty)
                                 *      continue;
                                 * }
                                 */

                                cur.Intersect(orig);
                                if (cur.IsEmpty)
                                {
                                    // Move this update to the back of the line? Okay because all pending updates are disjoint
                                    streamer.updates.Enqueue(upd);
                                    // Moved to the front of the for loop
                                    // upd = (sendUpdate)streamer.updates.Dequeue();
                                }
                                else
                                {
                                    cur.X      = upd.x;
                                    cur.Y      = upd.y;
                                    cur.Width  = upd.w;
                                    cur.Height = upd.h;

                                    System.Drawing.Rectangle combined = System.Drawing.Rectangle.Union(orig, cur);
                                    Boolean anymoreCombine            = true;
                                    // int count = 0;
                                    while (anymoreCombine)
                                    {
                                        anymoreCombine = false;

                                        for (int j = streamer.updates.Count; j > 0; j--)
                                        {
                                            sendUpdate u = (sendUpdate)streamer.updates.Dequeue();
                                            System.Drawing.Rectangle nxt = new System.Drawing.Rectangle(u.x, u.y, u.w, u.h);

                                            /* I don't think that I need this either
                                             * if (maskValid == true) {
                                             *  nxt.Intersect(mask);
                                             *  if (nxt.IsEmpty)
                                             *      continue;
                                             * }
                                             */
                                            nxt.Intersect(combined);
                                            if (nxt.IsEmpty)
                                            {
                                                streamer.updates.Enqueue(u);
                                            }
                                            else
                                            {
                                                nxt.X      = u.x;
                                                nxt.Y      = u.y;
                                                nxt.Width  = u.w;
                                                nxt.Height = u.h;

                                                combined       = System.Drawing.Rectangle.Union(combined, nxt);
                                                anymoreCombine = true;

                                                Trace.WriteLine("DEBUG: ----");
                                                break;
                                            }
                                        }
                                    }

                                    streamer.updates.Enqueue(new sendUpdate(null, null, combined.X, combined.Y, combined.Width, combined.Height));
                                    // Trace.WriteLine("DEBUG: need to make sure that this update does not overlap with prior non-overlapping rectangles");
                                    // Actually don't need to because of the way that Queue's work?
                                    return;
                                }
                            }
                            if (maskValid == true)
                            {
                                System.Drawing.Rectangle cur  = new System.Drawing.Rectangle(dce.x, dce.y, dce.w, dce.h);
                                System.Drawing.Rectangle mask = new System.Drawing.Rectangle(Program.maskX, Program.maskY, Program.maskWidth, Program.maskHeight);
                                cur.Intersect(mask);

                                if (cur.IsEmpty)
                                {
                                    return;
                                }
                                streamer.updates.Enqueue(new sendUpdate(null, null, cur.X, cur.Y, cur.Width, cur.Height));
                            }
                            else
                            {
                                streamer.updates.Enqueue(new sendUpdate(null, null, dce.x, dce.y, dce.w, dce.h));
                            }
                        }
                    }
                } catch (System.IO.IOException) {
                    Trace.WriteLine("DEBUG: An internal Win32 exception is caused by update while creating event handler. Ignoring");
                    // Environment.Exit(1);
                } catch (Exception e) {
                    MessageBox.Show("DEBUG: Error while capturing update coordinates " + e.StackTrace);
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="newStream"></param>
        private void sendIframe(NetworkStream newStream)
        {
            try {
                GCbuf screenbuf = new GCbuf();

            #if USE_BITMAP_COMPRESS
                int ptr = DesktopMirror._bitmapWidth * DesktopMirror._bitmapHeight, num = 0;
                for (int i = 0; i < ptr; i++)
                    screenbuf.buf[num++] = 0xFF;
                for (int i = 0; i < (ptr * 4); i += 4) {
                    screenbuf.buf[num++] = _mirror.screen[i];
                    screenbuf.buf[num++] = _mirror.screen[i + 1];
                    screenbuf.buf[num++] = _mirror.screen[i + 2];
                }
            #else
                Buffer.BlockCopy(_mirror.screen, 0, screenbuf.buf, 0, _mirror.screen.Length);
            #endif
                // screenbuf.buf = _mirror.screen;
                screenbuf.Length = _mirror.screen.Length;

                sendUpdate upd;
                if (Program.maskValid == true)
                    upd = new sendUpdate(newStream, screenbuf, Program.maskX, Program.maskY, Program.maskWidth, Program.maskHeight);
                else
                    upd = new sendUpdate(newStream, screenbuf, 0, 0, DesktopMirror._bitmapWidth, DesktopMirror._bitmapHeight);
                lock (streamer.updates.SyncRoot) {
                    streamer.updates.Enqueue(upd);
                }
            } catch (IOException) {
                Trace.WriteLine("DEBUG: Event creator causes an internal Win32 exception. Just ignore");
            }
        }
Beispiel #6
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="dce"></param>
        private static unsafe void _DesktopChange(object sender, DesktopChangeEventArgs dce)
        {
            if (streamer.clients.Count > 0) {   // No one is listening, why bother to process updates
                try {
                     lock (streamer.updates.SyncRoot) {
                        if (streamer.updates.Count == 0) {
                            if (numUpdates++ > 5) {
                                // Send the iFrame

                                GCbuf screenbuf = new GCbuf();
            #if USE_BITMAP_COMPRESS
                                int ptr = DesktopMirror._bitmapWidth * DesktopMirror._bitmapHeight, num = 0;
                                for (int i = 0; i < ptr; i++)
                                    screenbuf.buf[num++] = 0xFF;
                                for (int i = 0; i < (ptr * 4); i += 4) {
                                    screenbuf.buf[num++] = _mirror.screen[i];
                                    screenbuf.buf[num++] = _mirror.screen[i + 1];
                                    screenbuf.buf[num++] = _mirror.screen[i + 2];
                                }
            #else
                            Buffer.BlockCopy(_mirror.screen, 0, screenbuf.buf, 0, _mirror.screen.Length);
                            //    for (int i = 0; i < _mirror.screen.Length; i++)
                            //        screenbuf.buf[i] = _mirror.screen[i];
            #endif
                                screenbuf.Length = _mirror.screen.Length;

                                streamer.updates.Enqueue(new sendUpdate(null, screenbuf, maskX, maskY, maskWidth, maskHeight));
                                numUpdates = 0;
                            } else {
                                if (maskValid == true) {
                                    System.Drawing.Rectangle cur = new System.Drawing.Rectangle(dce.x, dce.y, dce.w, dce.h);
                                    System.Drawing.Rectangle mask = new System.Drawing.Rectangle(Program.maskX, Program.maskY, Program.maskWidth, Program.maskHeight);
                                    cur.Intersect(mask);

                                    if (cur.IsEmpty)
                                        return;
                                    else
                                        streamer.updates.Enqueue(new sendUpdate(null, null, cur.X, cur.Y, cur.Width, cur.Height));
                                } else
                                    streamer.updates.Enqueue(new sendUpdate(null, null, dce.x, dce.y, dce.w, dce.h));
                            }
                        } else {
                            System.Drawing.Rectangle orig = new System.Drawing.Rectangle(dce.x, dce.y, dce.w, dce.h);

                            if (maskValid == true) {
                                System.Drawing.Rectangle mask = new System.Drawing.Rectangle(Program.maskX, Program.maskY, Program.maskWidth, Program.maskHeight);

                                orig.Intersect(mask);
                                if (orig.IsEmpty)
                                    return;
                            }

                            for (int i = streamer.updates.Count; i > 0; i--) {
                                sendUpdate upd = (sendUpdate)streamer.updates.Dequeue();
                                System.Drawing.Rectangle cur = new System.Drawing.Rectangle(upd.x, upd.y, upd.w, upd.h);
                                /* I don't think that I need to do this
                                if (maskValid == true) {
                                    cur.Intersect(mask);
                                    if (cur.IsEmpty)
                                        continue;
                                }
                                 */

                                cur.Intersect(orig);
                                if (cur.IsEmpty) {
                                    // Move this update to the back of the line? Okay because all pending updates are disjoint
                                    streamer.updates.Enqueue(upd);
                                    // Moved to the front of the for loop
                                    // upd = (sendUpdate)streamer.updates.Dequeue();
                                } else {
                                    cur.X = upd.x;
                                    cur.Y = upd.y;
                                    cur.Width = upd.w;
                                    cur.Height = upd.h;

                                    System.Drawing.Rectangle combined = System.Drawing.Rectangle.Union(orig, cur);
                                    Boolean anymoreCombine = true;
                                    // int count = 0;
                                    while (anymoreCombine) {
                                        anymoreCombine = false;

                                        for (int j = streamer.updates.Count; j > 0; j--) {
                                            sendUpdate u = (sendUpdate)streamer.updates.Dequeue();
                                            System.Drawing.Rectangle nxt = new System.Drawing.Rectangle(u.x, u.y, u.w, u.h);
                                            /* I don't think that I need this either
                                            if (maskValid == true) {
                                                nxt.Intersect(mask);
                                                if (nxt.IsEmpty)
                                                    continue;
                                            }
                                             */
                                            nxt.Intersect(combined);
                                            if (nxt.IsEmpty)
                                                streamer.updates.Enqueue(u);
                                            else {
                                                nxt.X = u.x;
                                                nxt.Y = u.y;
                                                nxt.Width = u.w;
                                                nxt.Height = u.h;

                                                combined = System.Drawing.Rectangle.Union(combined, nxt);
                                                anymoreCombine = true;

                                                Trace.WriteLine("DEBUG: ----");
                                                break;
                                            }
                                        }
                                    }

                                    streamer.updates.Enqueue(new sendUpdate(null, null, combined.X, combined.Y, combined.Width, combined.Height));
                                    // Trace.WriteLine("DEBUG: need to make sure that this update does not overlap with prior non-overlapping rectangles");
                                    // Actually don't need to because of the way that Queue's work?
                                    return;
                                }
                            }
                            if (maskValid == true) {
                                System.Drawing.Rectangle cur = new System.Drawing.Rectangle(dce.x, dce.y, dce.w, dce.h);
                                System.Drawing.Rectangle mask = new System.Drawing.Rectangle(Program.maskX, Program.maskY, Program.maskWidth, Program.maskHeight);
                                cur.Intersect(mask);

                                if (cur.IsEmpty)
                                    return;
                                streamer.updates.Enqueue(new sendUpdate(null, null, cur.X, cur.Y, cur.Width, cur.Height));
                            } else
                                streamer.updates.Enqueue(new sendUpdate(null, null, dce.x, dce.y, dce.w, dce.h));
                        }
                    }
                } catch (System.IO.IOException) {
                    Trace.WriteLine("DEBUG: An internal Win32 exception is caused by update while creating event handler. Ignoring");
                    // Environment.Exit(1);
                } catch (Exception e) {
                    MessageBox.Show("DEBUG: Error while capturing update coordinates " + e.StackTrace);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// 
        /// </summary>
		private void pollingThreadProc() {
            // Why bother to poll while there is no one to receive the updates
            while (DesktopChange == null)
                Thread.Sleep(1);

			while (true) {
                if (restartingDriver == false) {
                    var getChangesBuffer = (GetChangesBuffer)Marshal.PtrToStructure(_getChangesBuffer, typeof(GetChangesBuffer));   // Moved it inside the loop in hope of fixing the hibernation bug
                    var buffer = (ChangesBuffer)Marshal.PtrToStructure(getChangesBuffer.Buffer, typeof(ChangesBuffer));

                    // Initialize oldCounter
                    if (oldCounter == long.MaxValue)
                        oldCounter = buffer.counter;

                    if (oldCounter != buffer.counter) {
                        // Trace.WriteLine("Updates: " + (buffer.counter - oldCounter));
                        for (long currentChange = oldCounter; currentChange != buffer.counter; currentChange++) {
                            if (currentChange >= ChangesBuffer.MAXCHANGES_BUF)
                                currentChange = 0;
#if PRODUCTION
                            DesktopChange(this,
                                              new DesktopChangeEventArgs(buffer.pointrect[currentChange].rect.x1,
                                                                         buffer.pointrect[currentChange].rect.y1,
                                                                         buffer.pointrect[currentChange].rect.x2,
                                                                         buffer.pointrect[currentChange].rect.y2,
                                                                         (OperationType)buffer.pointrect[currentChange].type));
#else
                        int x, y, w, h;
                        x = buffer.pointrect[currentChange].rect.x1;
                        y = buffer.pointrect[currentChange].rect.y1;
                        w = (buffer.pointrect[currentChange].rect.x2 - buffer.pointrect[currentChange].rect.x1);
                        h = (buffer.pointrect[currentChange].rect.y2 - buffer.pointrect[currentChange].rect.y1);


#if DEBUG_EXP_1
                        if (log == null) {
                            log = new StreamWriter("c:/mmsys_1.txt");
                            log.AutoFlush = true;
                        }
                        diffT = (DateTime.Now - startTime);
                        log.WriteLine(diffT.TotalMilliseconds + " " + x + " " + y + " " + w + " " + h);
                        continue;
#endif

#if DEBUG_EXP_2
                        if (log == null) {
                            log = new StreamWriter("c:/3.txt");
                            log.AutoFlush = true;
                        }
                       
                        int a0Len, a255Len, rgbLen, vanillaLen, origLen, bitmapLen;

                        origLen = w * h * sizeof(UInt32);
                        diffT = (DateTime.Now - startTime);

                        GCbuf a0 = GetRect(buffer.pointrect[currentChange].rect.x1,
                         buffer.pointrect[currentChange].rect.y1,
                         (buffer.pointrect[currentChange].rect.x2 - buffer.pointrect[currentChange].rect.x1),
                         (buffer.pointrect[currentChange].rect.y2 - buffer.pointrect[currentChange].rect.y1),
                         CompressionType.ALPHA0);
                        int same = 0, diff = 0;
                        for (int i = 0; i < a0.Length; i+=sizeof(UInt32))
                            if (a0.buf[i+3] == 0)
                                same++;
                            else
                                diff++;
                        compressor a0C = new compressor(a0);
                        Thread a0t = new Thread(new ThreadStart(a0C.compressData));
                        a0t.Start();

                        GCbuf bitmap = new GCbuf();
                        Buffer.BlockCopy(a0.buf, 0, bitmap.buf, 0, a0.Length);
                        bitmap.Length = a0.Length;
                        compressor bC = new compressor(bitmap);
                        Thread bT = new Thread(new ThreadStart(bC.bitmapCompressData));
                        bT.Start();

                        GCbuf vanilla = GetRect(buffer.pointrect[currentChange].rect.x1,
                            buffer.pointrect[currentChange].rect.y1,
                            (buffer.pointrect[currentChange].rect.x2 - buffer.pointrect[currentChange].rect.x1),
                            (buffer.pointrect[currentChange].rect.y2 - buffer.pointrect[currentChange].rect.y1),
                            CompressionType.VANILLA);
                        compressor vC = new compressor(vanilla);
                        Thread vt = new Thread(new ThreadStart(vC.compressData));
                        vt.Start();

                        GCbuf rgb = GetRect(buffer.pointrect[currentChange].rect.x1,
                            buffer.pointrect[currentChange].rect.y1,
                            (buffer.pointrect[currentChange].rect.x2 - buffer.pointrect[currentChange].rect.x1),
                            (buffer.pointrect[currentChange].rect.y2 - buffer.pointrect[currentChange].rect.y1),
                            CompressionType.RGB16);
                        compressor rC = new compressor(rgb);
                        Thread rt = new Thread(new ThreadStart(rC.compressData));
                        rt.Start();

                        GCbuf a255 = GetRect(buffer.pointrect[currentChange].rect.x1,
                            buffer.pointrect[currentChange].rect.y1,
                            (buffer.pointrect[currentChange].rect.x2 - buffer.pointrect[currentChange].rect.x1),
                            (buffer.pointrect[currentChange].rect.y2 - buffer.pointrect[currentChange].rect.y1),
                            CompressionType.ALPHA255);
                        compressor a2C = new compressor(a255);
                        Thread a2t = new Thread(new ThreadStart(a2C.compressData));
                        a2t.Start();

                        a0t.Join();
                        a0Len = a0C.retvalue;

                        vt.Join();
                        vanillaLen = vC.retvalue;

                        rt.Join();
                        rgbLen = rC.retvalue;

                        a2t.Join();
                        a255Len = a2C.retvalue;

                        bT.Join();
                        bitmapLen = bC.retvalue;

                        log.WriteLine(diffT.TotalMilliseconds + " S " + same + " D " + diff + " O " + (w * h * sizeof(UInt32)) + " R " + rgbLen + " A0 " + a0Len + " A255 " + a255Len + " V " + vanillaLen + " B " + bitmapLen);
                        
                        a0.Dispose();
                        a255.Dispose();
                        rgb.Dispose();
                        vanilla.Dispose();
                        bitmap.Dispose();

                        continue;                 
#endif

#if DEBUG_EXP_3
                        if (log == null) {
                            log = new StreamWriter("c:/mmsys_3.txt");
                            log.AutoFlush = true;
                        }

                        diffT = (DateTime.Now - startTime);
                        GCbuf bitmap = GetRect(buffer.pointrect[currentChange].rect.x1,
                         buffer.pointrect[currentChange].rect.y1,
                         (buffer.pointrect[currentChange].rect.x2 - buffer.pointrect[currentChange].rect.x1),
                         (buffer.pointrect[currentChange].rect.y2 - buffer.pointrect[currentChange].rect.y1),
                         CompressionType.ALPHA0);

                        compressor bC = new compressor(bitmap);
                        bC.bitmapCompressData();
                        log.WriteLine(diffT.TotalMilliseconds + " " + bC.retvalue);
                        bitmap.Dispose();
#endif
#endif
                        }
                        oldCounter = buffer.counter;
                        idleCount = 0;
                    } else {
#if PRODUCTION
                        if (idleCount++ == (1000 / PollInterval)) {   // One second
                            DesktopChange(this, new DesktopChangeEventArgs(0, 0, _bitmapWidth, _bitmapHeight, OperationType.dmf_dfo_IGNORE));
                            // Trace.WriteLine("DEBUG: Sending iFrame oldCount: " + oldCounter + " buffer " + buffer.counter);
                            idleCount = 0;
                        }
#endif
                    }
                }

				// Just to prevent 100-percent CPU load and to provide thread-safety use manual reset event instead of simple in-memory flag.
                if (_terminatePollingThread.WaitOne(PollInterval, false)) {
					Trace.WriteLine("The thread now exits");
					break;
				}
                
            }

			// We can be sure that _pollingThreadTerminated exists
			_pollingThreadTerminated.Set();
		}
Beispiel #8
0
 public compressor(GCbuf data) {
     this.data = data;
 }
Beispiel #9
0
       /// <summary>
       /// Get the pixels within the update rectangle in CompressionType encoding
       /// </summary>
       /// <param name="x"></param>
       /// <param name="y"></param>
       /// <param name="w"></param>
       /// <param name="h"></param>
       /// <param name="type"></param>
       /// <returns></returns>
        private GCbuf GetRect(int x, int y, int w, int h, CompressionType type) {
            if (loaded == false)
                return null;

            GCbuf retRect = null;
            try {
                retRect = new GCbuf();
            } catch (Exception e) {
                // One reason for failure is when the client stops accepting new updates
                MessageBox.Show("FATAL: Memory allocation failed " + e.Message);
                Environment.Exit(1);
            }

            try {
                GetChangesBuffer getChangesBuffer = (GetChangesBuffer)Marshal.PtrToStructure(_getChangesBuffer, typeof(GetChangesBuffer));
                IntPtr start;
                byte[] membuf = new byte[w * sizeof(UInt32)];
                int bmCount = 0;
                int dtCount = w * h;

                if (type == CompressionType.RGB16)
                    retRect.Length = w * h * sizeof(UInt16);
                else if (type == CompressionType.BITMAP)
                    retRect.Length = w * h * sizeof(byte);      // Just the space for the bitmap
                else
                    retRect.Length = w * h * sizeof(UInt32);    // buffers are always width*height - we waste the remaining to ease in memory management and fragmentation

                unsafe {
                    start = new IntPtr(((Int32*)getChangesBuffer.UserBuffer) + ((y * _bitmapWidth) + x));
                }
                for (int j = 0; j < h; j++) {
                    try {
                        switch (type) {
                            case CompressionType.BITMAP:
                                Marshal.Copy(start, membuf, 0, w * sizeof(UInt32));

                                int indx = ((y + j) * _bitmapWidth + x) * sizeof(UInt32);
                                for (int i = 0; i < (w * sizeof(UInt32)); i += sizeof(UInt32), indx += sizeof(UInt32)) {
                                    if ((membuf[i] == screen[indx]) && (membuf[i + 1] == screen[indx + 1]) && (membuf[i + 2] == screen[indx + 2]))
                                        retRect.buf[bmCount++] = 0x00;
                                    else {
                                        retRect.buf[bmCount++] = 0xFF;
                                        retRect.buf[dtCount++] = screen[indx] = membuf[i];
                                        retRect.buf[dtCount++] = screen[indx + 1] = membuf[i + 1];
                                        retRect.buf[dtCount++] = screen[indx + 2] = membuf[i + 2];

                                        retRect.Length += 3;
                                    }
                                }
                                break;

#if !PRODUCTION
                            case CompressionType.RGB16:
                                Marshal.Copy(start, membuf, 0, w * sizeof(UInt32));
                                for (int i = 0; i < (w * sizeof(UInt32)); i += sizeof(UInt32)) {
                                    UInt16 rgb;

                                    rgb = (ushort)(membuf[i] & 0xF8); // Blue
                                    rgb += (ushort)((membuf[i + 1] & 0xFE) << 5); // Green
                                    rgb += (ushort)((membuf[i + 2] * 0xF8) << 11); // Red
                                    retRect.buf[j * w * sizeof(UInt16) + i] = (byte)((rgb & 0xFF00) >> 8);
                                    retRect.buf[j * w * sizeof(UInt16) + i + 1] = (byte)(rgb & 0x00FF);
                                }
                                break;

                            

                            case CompressionType.ALPHA0:
                            case CompressionType.ALPHA255:
                                Marshal.Copy(start, retRect.buf, j * w * sizeof(UInt32), w * sizeof(UInt32));

                                int indx = ((y + j) * _bitmapWidth + x) * sizeof(UInt32);
                                int ind = (j * w) * sizeof(UInt32);
                                for (int i = 0; i < (w * sizeof(UInt32)); i += sizeof(UInt32)) {
                                    if ((retRect.buf[ind] == screen[indx]) &&
                                        (retRect.buf[ind + 1] == screen[indx + 1]) &&
                                        (retRect.buf[ind + 2] == screen[indx + 2])) {
                                        if (type == CompressionType.ALPHA0) {
                                            retRect.buf[ind] = 0x00;
                                            retRect.buf[ind + 1] = 0x00;
                                            retRect.buf[ind + 2] = 0x00;
                                        }

                                        if (type == CompressionType.ALPHA255) {
                                            retRect.buf[ind] = 0xFF;
                                            retRect.buf[ind + 1] = 0xFF;
                                            retRect.buf[ind + 2] = 0xFF;
                                        }
                                        retRect.buf[ind + 3] = 0;
                                    } else {
                                        if (type == CompressionType.ALPHA255) {
                                            screen[indx] = retRect.buf[ind];
                                            screen[indx + 1] = retRect.buf[ind + 1];
                                            screen[indx + 2] = retRect.buf[ind + 2];
                                        }
                                        retRect.buf[ind + 3] = 0xFF;
                                    }
                                    indx += sizeof(UInt32);
                                    ind += sizeof(UInt32);
                                }
                                break;
#endif
                        }
                    } catch (Exception e) {
                        MessageBox.Show("FATAL: Failure to copy framebuffer data " + e.StackTrace);
                        Environment.Exit(1);
                    }

                    unsafe {
                        start = new IntPtr((Int32*)start + _bitmapWidth);
                    }
                }

                return retRect;
            } catch (Exception e) {
                // Debug.WriteLine("FATAL: Failed to capture pixmap. Please report to Surendar Chandra. Ignoring for now");
                MessageBox.Show("FATAL: Failed to capture pixmap. Please report to [email protected] " + e.Message);
                // myNotifyIcon.ShowBalloonTip(500, "Title", "Tip text", ToolTipIcon.Info);
            }
            return retRect;
        }
Beispiel #10
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="arg"></param>
        public void compressSend(Object arg) {
            // Now send this update off
            UInt32 hdr;
            byte[] hdrbuf;
            streamThread parent = (streamThread)arg;

            Debug.Assert(buf != null);

            try {
                if (buf.Length == -1)
                    buf = parent._mirror.GetRect(x, y, w, h);
            } catch {
                Trace.WriteLine("getRect failed");
                return;
            }
            if (buf == null)
                return;

            outbuf = new MemoryStream();

            int checkSum = 1;
            using (DeflateStream compress = new DeflateStream(outbuf, CompressionMode.Compress
#if USE_IONIC_ZLIB
                , CompressionLevel.BestSpeed /* CompressionLevel.BestCompression */)){
                compress.FlushMode = FlushType.Sync;
#else
                )) { 
#endif           

                hdr = ((UInt32)DesktopMirror._bitmapWidth << 16) + ((UInt32)DesktopMirror._bitmapHeight & 0xFFFF);
                hdrbuf = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int32)hdr));
                compress.Write(hdrbuf, 0, hdrbuf.Length);
                checkSum = Adler32.ComputeChecksum(checkSum, hdrbuf, 0, hdrbuf.Length);

                hdr = ((UInt32)Program.maskX << 16) + ((UInt32)Program.maskY & 0xFFFF);
                hdrbuf = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int32)hdr));
                compress.Write(hdrbuf, 0, hdrbuf.Length);
                checkSum = Adler32.ComputeChecksum(checkSum, hdrbuf, 0, hdrbuf.Length);

                hdr = ((UInt32)Program.maskWidth << 16) + ((UInt32)Program.maskHeight & 0xFFFF);
                hdrbuf = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int32)hdr));
                compress.Write(hdrbuf, 0, hdrbuf.Length);
                checkSum = Adler32.ComputeChecksum(checkSum, hdrbuf, 0, hdrbuf.Length);

                hdr = ((UInt32)x << 16) + ((UInt32)y & 0xFFFF);
                hdrbuf = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int32)hdr));
                compress.Write(hdrbuf, 0, hdrbuf.Length);
                checkSum = Adler32.ComputeChecksum(checkSum, hdrbuf, 0, hdrbuf.Length);

                hdr = ((UInt32)w << 16) + ((UInt32)h & 0xFFFF);
                hdrbuf = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int32)hdr));
                compress.Write(hdrbuf, 0, hdrbuf.Length);
                checkSum = Adler32.ComputeChecksum(checkSum, hdrbuf, 0, hdrbuf.Length);

                /*
    #if USE_BITMAP_COMPRESS
                byte[] bm = new byte[buf.Length / 4];
                byte[] dt = new byte[buf.Length];
                int bi = 0, di = 0;

                for (int i = 0; i < buf.Length; i += sizeof(UInt32))
                    if (buf.buf[i + 3] == 0)
                        bm[bi++] = 0x00;
                    else {
                        bm[bi++] = 0xFF;
                        dt[di++] = buf.buf[i];
                        dt[di++] = buf.buf[i + 1];
                        dt[di++] = buf.buf[i + 2];
                    }

                compress.Write(bm, 0, bi);
                compress.Write(dt, 0, di);
    #else
                compress.Write(buf.buf, 0, buf.Length);
    #endif
                 */
                compress.Write(buf.buf, 0, buf.Length);
            }

            byte[] compHdr = new byte[] { 0x58, 0x85 };
            
            byte[] compData = outbuf.ToArray();
            
            checkSum = Adler32.ComputeChecksum(checkSum, buf.buf, 0, buf.Length);
            int ncheckSum = IPAddress.HostToNetworkOrder(checkSum);
            // byte[] compCheckSum = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(ncheckSum));
            byte[] compCheckSum = BitConverter.GetBytes(ncheckSum);

            hdr = (UInt32)(compHdr.Length + compData.Length + compCheckSum.Length);
            hdrbuf = BitConverter.GetBytes(hdr);
            // Trace.WriteLine("Size: " + (compData.Length));

            // buf.Dispose();
            // Trying to reduce the memory footprint
            // GC.Collect(0, GCCollectionMode.Optimized);
            // GC.Collect(0, GCCollectionMode.Forced);
#if SHOW_STATS
                    if (DateTime.Now.Second != parent.prevSec) {
                        parent.prevSec = DateTime.Now.Second;
                        Trace.WriteLine("DEBUG: Mbps - " + (parent.dataBytes * 8) / 1000000);
                        parent.dataBytes = 0;
                    }
                    parent.dataBytes += (hdrbuf.Length + compHdr.Length + compData.Length + compCheckSum.Length);
#endif
            try {
                this.proceedToSend.WaitOne();   // Wait till I am told to proceed to send
                // this.proceedToSend.Dispose();   // I no longer need this trigger. Dispose now rather than wait for Dispose()
                lock (events.SyncRoot) {    // Reuse
                    events.Add(proceedToSend);
                    proceedToSend = null;
                }
            } catch (Exception e) {
                MessageBox.Show(e.StackTrace);
                Environment.Exit(1);
            }

            if (this.newStream == null) {
#if !SHOW_STATS
                // Deleting inplace causes invalid invocation exception because it is inside the enumerator
                ArrayList failures = new ArrayList();
                foreach (System.Net.Sockets.NetworkStream clnt in parent.clients) {
                    try {
                        clnt.Write(hdrbuf, 0, hdrbuf.Length);
                        clnt.Write(compHdr, 0, compHdr.Length);
                        clnt.Write(compData, 0, compData.Length);
                        clnt.Write(compCheckSum, 0, compCheckSum.Length);
                    } catch (IOException ioe) {
                        Trace.WriteLine("TIMEOUT : " + ioe.Message);
                        // Could've been a timeout of could've been an actual error
                        clnt.Close();
                        failures.Add(clnt);
                    }
                }
                if (failures.Count > 0) {
                    foreach (System.Net.Sockets.NetworkStream clnt in failures) {
                        parent.clients.Remove(clnt);
                    }
                }
#endif
            } else {
                if (parent.clients.Count == 0) // Its been a while
                    parent._mirror.fillScreen();
                parent.clients.Add(this.newStream);

                try {
                    this.newStream.Write(hdrbuf, 0, hdrbuf.Length);
                    this.newStream.Write(compHdr, 0, compHdr.Length);
                    this.newStream.Write(compData, 0, compData.Length);
                    this.newStream.Write(compCheckSum, 0, compCheckSum.Length);
                } catch (IOException) {
                    this.newStream.Close();
                    parent.clients.Remove(this.newStream);
                }
            }
            buf.Dispose();
            buf = null;
            try {
                parent.proceedToNext.Set();
            } catch (Exception e) {
                MessageBox.Show(e.StackTrace);
                Environment.Exit(1);
            }
        }
    }
Beispiel #11
0
 /// <summary>
 /// Send updates. if newStream is not null, send to just this streams, otherwise everyone gets this update
 /// </summary>
 /// <param name="newStream"></param>
 /// <param name="buf"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="w"></param>
 /// <param name="h"></param>
 public sendUpdate(NetworkStream newStream, GCbuf buf, int x, int y, int w, int h) { // , int width, int height, int maskX, int maskY, int maskWidth, int maskHeight) {
     this.newStream = newStream;
     this.buf = buf;
     this.x = x;
     this.y = y;
     this.w = w;
     this.h = h;
     // this.width = width;
     // this.height = height;
     // this.maskX = maskX;
     // this.maskY = maskY;
     // this.maskWidth = maskWidth;
     // this.maskHeight = maskHeight;
 }