示例#1
0
        private static unsafe void PaintMousePointer(System.IntPtr dpy, XImage *image) //, struct x11grab *s)
        {
            // int x_off = s->x_off;
            // int y_off = s->y_off;
            // int width = s->width;
            // int height = s->height;
            // Display *dpy = s->dpy;

            int x_off  = 0;
            int y_off  = 0;
            int width  = image->width;
            int height = image->height;

            XFixesCursorImage *xcim;
            int x, y;
            int line, column;
            int to_line, to_column;
            int pixstride = image->bits_per_pixel >> 3;
            // Warning: in its insanity, xlib provides unsigned image data through a
            // char* pointer, so we have to make it uint8_t to make things not break.
            // Anyone who performs further investigation of the xlib API likely risks
            // permanent brain damage.

            byte *pix = (byte *)image->data;

            // Cursor c;
            // Window w;
            // XSetWindowAttributes attr;

            // Code doesn't currently support 16-bit or PAL8
            if (image->bits_per_pixel != 24 && image->bits_per_pixel != 32)
            {
                return;
            }

            // c = XCreateFontCursor(dpy, XC_left_ptr);
            // w = DefaultRootWindow(dpy);
            // attr.cursor = c;
            // XChangeWindowAttributes(dpy, w, CWCursor, &attr);

            xcim = LibXfixes.XFixesGetCursorImage(dpy);

            x = xcim->x - xcim->xhot;
            y = xcim->y - xcim->yhot;

            to_line   = FFMIN((y + xcim->height), (height + y_off));
            to_column = FFMIN((x + xcim->width), (width + x_off));

            for (line = FFMAX(y, y_off); line < to_line; line++)
            {
                for (column = FFMAX(x, x_off); column < to_column; column++)
                {
                    int  xcim_addr  = (line - y) * xcim->width + column - x;
                    int  image_addr = ((line - y_off) * width + column - x_off) * pixstride;
                    byte r          = (byte)(xcim->pixels[xcim_addr].ToUInt64() >> 0);
                    byte g          = (byte)(xcim->pixels[xcim_addr].ToUInt64() >> 8);
                    byte b          = (byte)(xcim->pixels[xcim_addr].ToUInt64() >> 16);
                    byte a          = (byte)(xcim->pixels[xcim_addr].ToUInt64() >> 24);

                    if (a == 255)
                    {
                        pix[image_addr + 0] = r;
                        pix[image_addr + 1] = g;
                        pix[image_addr + 2] = b;
                    }
                    else if (a != 0)
                    {
                        byte aaa = pix[image_addr + 2];

                        // pixel values from XFixesGetCursorImage come premultiplied by alpha
                        pix[image_addr + 0] = (byte)(r + (pix[image_addr + 0] * (255 - a) + 255 / 2) / 255);
                        pix[image_addr + 1] = (byte)(g + (pix[image_addr + 1] * (255 - a) + 255 / 2) / 255);
                        pix[image_addr + 2] = (byte)(b + (pix[image_addr + 2] * (255 - a) + 255 / 2) / 255);
                    }
                }
            }

            LibX11Functions.XFree(xcim);
            xcim = null;
        }
示例#2
0
        private static unsafe byte[] SlowScreenshotWithCursor(
            System.IntPtr display
            , System.UIntPtr d
            , int x, int y
            , uint width
            , uint height
            , System.UIntPtr plane_mask
            , int format, bool withCursor)
        {
            byte[] result = null;

            XImage *img = LibX11Functions.XGetImage2(display, d, x, y, width, height, plane_mask, format);

            if (withCursor)
            {
                PaintMousePointer(display, img);
            } // End if (withCursor)


            int bitsPerPixel = img->bits_per_pixel;

            System.UIntPtr ptrImg         = (System.UIntPtr)img;
            System.UIntPtr pixels         = (System.UIntPtr)(&(img->data));
            System.UIntPtr ptr_byte_order = (System.UIntPtr)(&(img->byte_order));

            ulong int64  = pixels.ToUInt64() - ptrImg.ToUInt64();
            ulong int642 = ptr_byte_order.ToUInt64() - ptrImg.ToUInt64();



            System.Console.WriteLine("p1: {0}, p2: {1}", ptrImg.ToUInt64(), pixels.ToUInt64());
            System.Console.WriteLine("Delta: {0}", int64);    // 16
            System.Console.WriteLine("Delta 2: {0}", int642); // 16

            // https://stackoverflow.com/questions/30476131/c-sharp-read-pointer-address-value
            System.IntPtr ptr       = (System.IntPtr)(ptrImg.ToUInt64() + 16);
            long          longValue = System.Runtime.InteropServices.Marshal.ReadInt64(ptr);



            System.Console.WriteLine("pt1: {0}, pt2: {1}", ((System.UIntPtr)(img->data)).ToUInt64(), longValue);


            // BMPImage * foo = CreateBitmapFromScan0(uint16_t bitsPerPixel, int32_t w, int32_t h, uint8_t* scan0);
            // string filename = "/tmp/lol1.bmp";
            // WriteBitmapToFile(filename, bitsPerPixel, width, height, );

            System.Console.WriteLine("Format: {0}, bpp: {1}", format, bitsPerPixel);

            int bytesPerPixel = (bitsPerPixel + 7) / 8;
            int stride        = 4 * (((int)width * bytesPerPixel + 3) / 4);

            // long size = height * stride;
            // byte[] managedArray = new byte[size];
            // System.Runtime.InteropServices.Marshal.Copy((System.IntPtr)(img->data), managedArray, 0, (int)size);

            using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap((int)width, (int)height, stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, (System.IntPtr)img->data))
            {
                // bmp.Save("/tmp/lol1.bmp");

                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                {
                    bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    result = ms.ToArray();
                } // End Using ms
            }     // End Using bmp

            LibX11Functions.XDestroyImage2(img);

            return(result);
        }
示例#3
0
        private static unsafe byte[] UnsafeX11ScreenshotWithCursor(bool withCursor)
        {
            byte[] result = null;


            int AllPlanes = ~0;

            System.UIntPtr AllPlanes2 = new System.UIntPtr((uint)AllPlanes);


            System.IntPtr display = LibX11Functions.XOpenDisplay(System.IntPtr.Zero);

            int defaultScreen = LibX11Functions.XDefaultScreen(display);

            System.UIntPtr    window = LibX11Functions.XRootWindow(display, defaultScreen);
            XWindowAttributes xa     = new XWindowAttributes();

            LibX11Functions.XGetWindowAttributes(display, window, ref xa);
            Screen *screen = xa.screen; // struct screen

            XShmSegmentInfo shminfo = new XShmSegmentInfo();


            XImage *ximg = LibXExt.XShmCreateImage(display, LibXExt.DefaultVisualOfScreen(screen)
                                                   , (uint)LibXExt.DefaultDepthOfScreen(screen), LinScreen.ZPixmap
                                                   , System.IntPtr.Zero, ref shminfo, (uint)xa.width, (uint)xa.height);

            shminfo.shmid   = LibC.shmget(LibC.IPC_PRIVATE, new System.IntPtr(ximg->bytes_per_line * ximg->height), LibC.IPC_CREAT | 0777);
            ximg->data      = (sbyte *)LibC.shmat(shminfo.shmid, System.IntPtr.Zero, 0);
            shminfo.shmaddr = (System.IntPtr)ximg->data;

            shminfo.readOnly = 0;

            if (shminfo.shmid < 0)
            {
                System.Console.WriteLine("Fatal shminfo error!");
            }

            int s1 = LibXExt.XShmAttach(display, ref shminfo);
            // System.Console.WriteLine("XShmAttach() {0}\n", s1 != 0 ? "success!" : "failure!");

            int res = LibXExt.XShmGetImage(display, window, ximg, 0, 0, AllPlanes2);

            // const char *filename = "/tmp/test.bmp";
            // WriteBitmapToFile(filename, (int) ximg->bits_per_pixel, (int)window_attributes.width, (int)window_attributes.height, (const void*) ximg->data);
            int bytesPerPixel = (ximg->bits_per_pixel + 7) / 8;
            int stride        = 4 * ((ximg->width * bytesPerPixel + 3) / 4);

            // long size = ximg->height * stride;
            // byte[] managedArray = new byte[size];
            // Marshal.Copy((IntPtr)(ximg->data), managedArray, 0, (int)size);
            // System.Console.WriteLine(managedArray);

            if (withCursor)
            {
                PaintMousePointer(display, ximg);
            } // End if (withCursor)


            using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ximg->width, ximg->height, stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, (System.IntPtr)ximg->data))
            {
                // bmp.Save("/tmp/shtest.bmp");
#if false
                // ZERO compression at all !

                // using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                // {
                //     bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                //     result = ms.ToArray();
                // } // End Using ms
#else
                result = CompressImage(bmp, 25);
#endif
            } // End Using bmp

            LibX11Functions.XDestroyImage2(ximg);
            LibXExt.XShmDetach(display, ref shminfo);
            LibC.shmdt(shminfo.shmaddr);

            LibX11Functions.XCloseDisplay(display);

            return(result);
        } // End Function UnsafeX11ScreenshotWithCursor