Package net.cakenet.jsaton.nativedef

Source Code of net.cakenet.jsaton.nativedef.X11$XImage

package net.cakenet.jsaton.nativedef;

import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;

import java.awt.*;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class X11WindowManager extends WindowManager {
    private static final X11 X = X11.INSTANCE;
    private static final X11WindowReference ROOT;

    public WindowReference findWindowByPointImpl(Point loc) {
        X11.WindowByReference root_return = new X11.WindowByReference();
        X11.WindowByReference child_return = new X11.WindowByReference();
        IntByReference dummy = new IntByReference();

        // Find initial...
        X.XQueryPointer(ROOT.display, ROOT.window, root_return, child_return, dummy, dummy, dummy, dummy, dummy);
        X11.Window window = child_return.getValue();

        // Iterate through children until we reach the most deeply nested...
        while (true) {
            X.XQueryPointer(ROOT.display, window, root_return, child_return, dummy, dummy, dummy, dummy, dummy);
            if (child_return.getValue() == null)
                break;
            window = child_return.getValue();
        }
        return new X11WindowReference(ROOT.display, window);
    }

    public WindowReference getDesktopImpl() {
        return ROOT;
    }

    protected List<WindowReference> getTopLevelWindowsImpl() {
        return ROOT.children();
    }

    static class X11WindowReference extends WindowReference {
        private X11.Display display;
        private X11.Window window;

        public X11WindowReference(X11.Display display, X11.Window window) {
            this.display = display;
            this.window = window;
        }

        public int[] capture(int x, int y, int width, int height) {
            X11.XImage cap = X.XGetImage(display, window, x, y, width, height, X11.AllPlanes, X11.ZPixmap);

            if (cap.bytes_per_line != width * 4)
                throw new UnsupportedOperationException("Make sure your bit depth is 24 or 32!");
            if (cap.byte_order != 0)
                throw new UnsupportedOperationException("Wrong byte order! (let me know, I might fix this)");

            int[] pix = cap.data.getIntArray(cap.xoffset, cap.width * cap.height);
            X.XFree(cap.getPointer());
            return pix;
        }

        public String getTitle() {
            X11.XTextProperty name = new X11.XTextProperty();
            X.XGetWMName(display, window, name);
            return name.value;
        }

        public X11WindowReference parent() {
            X11.WindowByReference root_return = new X11.WindowByReference();
            X11.WindowByReference parent_return = new X11.WindowByReference();
            PointerByReference ptr = new PointerByReference();
            X.XQueryTree(display, window, root_return, parent_return, ptr, new IntByReference());
            if(ptr.getValue() != null && ptr.getValue() != Pointer.NULL)
                X.XFree(ptr.getValue());
            return new X11WindowReference(display, parent_return.getValue());
        }

        public List<WindowReference> children() {
            X11.WindowByReference root_return = new X11.WindowByReference();
            X11.WindowByReference parent_return = new X11.WindowByReference();
            PointerByReference ptr = new PointerByReference();
            IntByReference numChildren = new IntByReference();
            X.XQueryTree(display, window, root_return, parent_return, ptr, numChildren);
            if (ptr.getValue() == null || ptr.getValue() == Pointer.NULL)
                return null;

            List<WindowReference> ret = new ArrayList<>();

            Pointer base = ptr.getValue();
            int off = 0;
            for(int i = 0, count = numChildren.getValue(); i < count; i++) {
                X11.WindowByReference wref = new X11.WindowByReference();
                wref.setPointer(base.share(off));
                off += Pointer.SIZE;
                ret.add(new X11WindowReference(display, wref.getValue()));
            }

            X.XFree(ptr.getValue());
            return ret;
        }

        private Rectangle getReportedBounds() {
            X11.WindowByReference root_return = new X11.WindowByReference();
            IntByReference x_return = new IntByReference();
            IntByReference y_return = new IntByReference();
            IntByReference width_return = new IntByReference();
            IntByReference height_return = new IntByReference();
            IntByReference border_width_return = new IntByReference();
            IntByReference depth_return = new IntByReference();
            X.XGetGeometry(display, window, root_return, x_return, y_return, width_return, height_return,
                    border_width_return, depth_return);
            return new Rectangle(x_return.getValue(), y_return.getValue(), width_return.getValue(), height_return.getValue());
        }

        public Rectangle getBounds() {
            Rectangle bounds = getReportedBounds();
            int x = bounds.x;
            int y = bounds.y;
            int width = bounds.width;
            int height = bounds.height;
            if (!parent().equals(ROOT) && !this.equals(ROOT)) {
                x = y = 0;

                X11WindowReference current = this;
                do {
                    Rectangle relative = current.getReportedBounds();
                    x += relative.x;
                    y += relative.y;
                    current = current.parent();
                } while (!current.equals(ROOT));
            }
            return new Rectangle(x, y, width, height);
        }

        public boolean equals(Object o) {
            return o instanceof X11WindowReference && equals((X11WindowReference) o);
        }

        public boolean equals(X11WindowReference other) {
            return other == this || other.window.equals(this.window);
        }

        public String toString() {
            String title = getTitle();
            return window.intValue() + (title != null? String.format(" (%s)", title): "");
        }
    }

    private static final X11.XErrorHandler ERROR_HANDLER = new X11.XErrorHandler() {
        public int apply(X11.Display display, X11.XErrorEvent rep) {
            PrintStream out = System.out;
            out.printf("X Error of failed request: %s\n  ", errorMessage(rep.error_code & 0xff));
            out.printf("Major opcode of failed request: %d\n  ", rep.request_code);
            out.printf("Minor opcode of failed request: %d\n  ", rep.minor_code);
            out.printf("Resource id in failed request: %x\n  ", rep.resourceid.longValue());
            out.printf("Serial number of failed request: %x\n", rep.serial.longValue());
            return 0;
        }
    };

    static {
        X.XInitThreads();
        X11.Display disp = X.XOpenDisplay(null);
        // X.XSynchronize(disp, true); // Uncomment to debug errors synchronously...
        ROOT = new X11WindowReference(disp, X.XDefaultRootWindow(disp));
        //X.XSetErrorHandler(ERROR_HANDLER);
    }

    private static String errorMessage(int code) {
        byte[] mesg = new byte[100];
        X.XGetErrorText(ROOT.display, code, mesg, mesg.length);
        String s = new String(mesg);
        return s.substring(0, s.indexOf(0));
    }
}

interface X11 extends com.sun.jna.platform.unix.X11 {
    //<editor-fold desc="constants">
    public static final NativeLong AllPlanes = new NativeLong(-1);
    //</editor-fold>

    public static X11 INSTANCE = (X11) Native.loadLibrary("X11", X11.class);

    XImage XGetImage(Display display, Drawable d, int x, int y, int width, int height, NativeLong plane_mask, int format);

    int XInitThreads();

    int XSynchronize(Display display, boolean state);

    static class XImage extends Structure {
        public int width;
        public int height;            /* size of image */
        public int xoffset;                  /* number of pixels offset in X direction */
        public int format;                   /* XYBitmap, XYPixmap, ZPixmap */
        public Pointer data;                   /* pointer to image data */
        public int byte_order;               /* data byte order, LSBFirst, MSBFirst */
        public int bitmap_unit;              /* quant. of scanline 8, 16, 32 */
        public int bitmap_bit_order;         /* LSBFirst, MSBFirst */
        public int bitmap_pad;               /* 8, 16, 32 either XY or ZPixmap */
        public int depth;                    /* depth of image */
        public int bytes_per_line;           /* accelerator to next scanline */
        public int bits_per_pixel;           /* bits per pixel (ZPixmap) */
        public NativeLong red_mask;          /* bits in z arrangement */
        public NativeLong green_mask;
        public NativeLong blue_mask;
        public Pointer obdata;              /* hook for the object routines to hang on */
        //public Structure funcs;

        @Override
        protected List getFieldOrder() {
            return Arrays.asList("width", "height", "xoffset", "format", "data", "byte_order", "bitmap_unit",
                    "bitmap_bit_order", "bitmap_pad", "depth", "bytes_per_line", "bits_per_pixel",
                    "red_mask", "green_mask", "blue_mask", "obdata");
        }
//        struct funcs {                /* image manipulation routines */
//            XImage * ( * create_image)();
//            int( * destroy_image)();
//            unsigned long( * get_pixel)();
//            int( * put_pixel)();
//            XImage * ( * sub_image)();
//            int( * add_pixel)();
//        } f;
    }
}
TOP

Related Classes of net.cakenet.jsaton.nativedef.X11$XImage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.