/// <summary> /// Fills our copy of framebuffer from actual framebuffer, only called when we suspect that they are out of sync with each other /// </summary> public void fillScreen() { // Get the initial screen for further incremental operations GetChangesBuffer getChangesBuffer = (GetChangesBuffer)Marshal.PtrToStructure(_getChangesBuffer, typeof(GetChangesBuffer)); if (screen == null) { screen = new byte[_bitmapWidth * _bitmapHeight * sizeof(UInt32)]; } try { Marshal.Copy(getChangesBuffer.UserBuffer, screen, 0, screen.Length); } catch (Exception e) { MessageBox.Show("FATAL: Failure to copy framebuffer data " + e.StackTrace); Environment.Exit(1); } /* Make sure that all pixels are opague. Unnecessary * for (int i = 0; i < screen.Length; i += 4) * screen[i + 3] = 0xFF; */ }
/// <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); }