Search in sources :

Example 86 with Pointer

use of com.sun.jna.Pointer in project HearthStats.net-Uploader by HearthStats.

the class ProgramHelperOsx method findWindow.

/**
     * <p>Finds the main Hearthstone window ID for the given process ID.</p>
     * <p>Will only return the window that matches expected characteristics of the main Hearthstone window, namely:</p>
     * <ul>
     *     <li>kCGWindowIsOnscreen = 1</li>
     *     <li>kCGWindowLayer = 0</li>
     *     <li>kCGWindowOwnerPID = [pid]</li>
     * </ul>
     *
     * @param pid The process ID of Hearthstone.
     * @return the window ID if found, or zero if no suitable window was found. It is normal for the window ID to be zero briefly during startup of Hearthstone.
     */
private int findWindow(int pid) {
    final NSAutoreleasePool pool = NSAutoreleasePool.new_();
    try {
        // Obtain a dictionary of all on-screen windows from Quartz Window Services, which will include all running applications.
        // Hearthstone typically has five or six windows, but only one or two are 'on screen' and it is those that we are interested in.
        final CFArrayRef originalArray = CoreGraphicsLibrary.INSTANCE.CGWindowListCopyWindowInfo(CGWindow.kCGWindowListExcludeDesktopElements | CGWindow.kCGWindowListOptionOnScreenOnly, 0);
        long count = CoreFoundationLibrary.INSTANCE.CFArrayGetCount(originalArray);
        for (long i = 0; i < count; i++) {
            // Obtain a CFDictionary containing this window's information dictionary
            Pointer pointer = CoreFoundationLibrary.INSTANCE.CFArrayGetValueAtIndex(originalArray, i);
            CFDictionaryRef dictionaryRef = new CFDictionaryRef(pointer);
            // Determine the process ID of this window
            NSString kCGWindowOwnerPID = CoreGraphicsLibrary.kCGWindowOwnerPID;
            Pointer pidPointer = CoreFoundationLibrary.INSTANCE.CFDictionaryGetValue(dictionaryRef, kCGWindowOwnerPID.id());
            NativeLongByReference longByReference = new NativeLongByReference();
            CoreFoundationLibrary.INSTANCE.CFNumberGetValue(pidPointer, CoreFoundationLibrary.CFNumberType.kCFNumberLongType, longByReference.getPointer());
            long pidLong = longByReference.getValue().longValue();
            if (pidLong == pid) {
                // This window is a Hearthstone window
                // When running in full-screen mode, Hearthstone has two windows: one for the game and one that appears to be a temporary desktop or space for the game to run in.
                // The game window always has a kCGWindowLayer of zero, whereas the desktop has a non-zero kCGWindowLayer.
                NSString kCGWindowLayer = CoreGraphicsLibrary.kCGWindowLayer;
                Pointer windowLayerPointer = CoreFoundationLibrary.INSTANCE.CFDictionaryGetValue(dictionaryRef, kCGWindowLayer.id());
                IntByReference windowLayerRef = new IntByReference();
                CoreFoundationLibrary.INSTANCE.CFNumberGetValue(windowLayerPointer, CoreFoundationLibrary.CFNumberType.kCFNumberFloatType, windowLayerRef.getPointer());
                int windowLayer = windowLayerRef.getValue();
                if (windowLayer == 0) {
                    // This window has a zero kCGWindowLayer so it must be the main Hearthstone window
                    NSString kCGWindowNumber = CoreGraphicsLibrary.kCGWindowNumber;
                    Pointer windowNumberPointer = CoreFoundationLibrary.INSTANCE.CFDictionaryGetValue(dictionaryRef, kCGWindowNumber.id());
                    IntByReference windowIdRef = new IntByReference();
                    CoreFoundationLibrary.INSTANCE.CFNumberGetValue(windowNumberPointer, CoreFoundationLibrary.CFNumberType.kCFNumberIntType, windowIdRef.getPointer());
                    int windowId = windowIdRef.getValue();
                    return windowId;
                }
            }
        }
        // No Hearthstone window was found
        return 0;
    } finally {
        pool.drain();
    }
}
Also used : IntByReference(com.sun.jna.ptr.IntByReference) NSAutoreleasePool(org.rococoa.cocoa.foundation.NSAutoreleasePool) Pointer(com.sun.jna.Pointer) NSString(org.rococoa.cocoa.foundation.NSString) NativeLongByReference(com.sun.jna.ptr.NativeLongByReference)

Example 87 with Pointer

use of com.sun.jna.Pointer in project HearthStats.net-Uploader by HearthStats.

the class ProgramHelperOsx method getWindowImage.

/**
     * <p>Gets a copy of the Hearthstone window with the provided window ID as an in-memory image.</p>
     *
     * @param windowId The window ID of Hearthstone, as reported by a call to Quartz Window Services
     * @return An image of the window, or null if the window doesn't exist or is too small to be an active window.
     */
private BufferedImage getWindowImage(int windowId) {
    // Create a CGRect with zero boundaries so that OS X automatically picks the correct size
    CoreGraphicsLibrary.CGRect bounds = new CoreGraphicsLibrary.CGRect.CGRectByValue();
    bounds.origin = new CoreGraphicsLibrary.CGPoint();
    bounds.origin.x = 0;
    bounds.origin.y = 0;
    bounds.size = new CoreGraphicsLibrary.CGSize();
    bounds.size.width = 0;
    bounds.size.height = 0;
    // Take a screenshot of the program window
    ID imageRef = CoreGraphicsLibrary.INSTANCE.CGWindowListCreateImage(bounds, CoreGraphicsLibrary.kCGWindowListOptionIncludingWindow | CoreGraphicsLibrary.kCGWindowListExcludeDesktopElements, windowId, CoreGraphicsLibrary.kCGWindowImageBoundsIgnoreFraming | CoreGraphicsLibrary.kCGWindowImageNominalResolution);
    // Convert the screenshot into a more useful ImageRep object, and retain the object so that it isn't lost before we extract the image data
    NSBitmapImageRep imageRep = NSBitmapImageRep.CLASS.alloc().initWithCGImage(imageRef).initWithCGImage(imageRef);
    imageRep.retain();
    int width = imageRep.pixelsWide();
    int height = imageRep.pixelsHigh();
    int windowTitleHeight = determineWindowTitleHeight(height, width);
    if (debugLog.isTraceEnabled()) {
        debugLog.trace("    Window height={} width={} titleHeight={}", new Object[] { height, width, windowTitleHeight });
    }
    int heightWithoutTitle = height - windowTitleHeight;
    Pointer bitmapPointer = imageRep.bitmapData();
    if (bitmapPointer == null || bitmapPointer == Pointer.NULL) {
        imageRep.release();
        return null;
    } else {
        int[] data = bitmapPointer.getIntArray(0, width * height);
        if (heightWithoutTitle > 512) {
            BufferedImage image = new BufferedImage(width, heightWithoutTitle, BufferedImage.TYPE_INT_RGB);
            // Start on row windowTitleHeight to exclude the window titlebar
            int idx = windowTitleHeight * width;
            // Manually write each pixel to the raster because OS X generates ARGB screenshots but BufferedImage expects RGB data.
            WritableRaster raster = image.getRaster();
            for (int y = 0; y < heightWithoutTitle; y++) {
                for (int x = 0; x < width; x++) {
                    int pixel = data[idx++];
                    // Red is the second byte
                    raster.setSample(x, y, 0, pixel >> 8 & 0xFF);
                    // Green is the third byte
                    raster.setSample(x, y, 1, pixel >> 16 & 0xFF);
                    // Blue is the fourth byte
                    raster.setSample(x, y, 2, pixel >> 24 & 0xFF);
                }
            }
            // Now that we have a copy of the image in a Java object it's safe to release the native pointers
            Foundation.cfRelease(imageRef);
            imageRep.release();
            return image;
        } else {
            // The window is too small to generate an image
            return null;
        }
    }
}
Also used : WritableRaster(java.awt.image.WritableRaster) Pointer(com.sun.jna.Pointer) ID(org.rococoa.ID) BufferedImage(java.awt.image.BufferedImage)

Example 88 with Pointer

use of com.sun.jna.Pointer in project HearthStats.net-Uploader by HearthStats.

the class ProgramHelperWindows method getWindowHandle.

private HWND getWindowHandle() {
    // Cache the window handle for five seconds to reduce CPU load and (possibly) minimise memory leaks
    long currentTime = System.currentTimeMillis();
    if (currentTime < lastWindowsHandleCheck + 5000) {
        // It has been less than five seconds since the last check, so use the cached value
        return windowHandle;
    } else {
        debugLog.debug("Updating window handle ({}ms since last update)", currentTime - lastWindowsHandleCheck);
        lastWindowsHandleCheck = currentTime;
        windowHandle = null;
    }
    User32.INSTANCE.EnumWindows(new WNDENUMPROC() {

        @Override
        public boolean callback(HWND hWnd, Pointer arg1) {
            int titleLength = User32.INSTANCE.GetWindowTextLength(hWnd) + 1;
            char[] title = new char[titleLength];
            User32.INSTANCE.GetWindowText(hWnd, title, titleLength);
            String wText = Native.toString(title);
            if (wText.isEmpty()) {
                return true;
            }
            PointerByReference pointer = new PointerByReference();
            User32DLL.GetWindowThreadProcessId(hWnd, pointer);
            Pointer process = Kernel32.OpenProcess(Kernel32.PROCESS_QUERY_INFORMATION | Kernel32.PROCESS_VM_READ, false, pointer.getValue());
            Psapi.GetModuleBaseNameW(process, null, baseNameBuffer, STRING_BUFFER_LENGTH);
            String baseNameString = Native.toString(baseNameBuffer);
            // see https://github.com/JeromeDane/HearthStats.net-Uploader/issues/66#issuecomment-33829132
            User32.INSTANCE.GetClassName(hWnd, classNameBuffer, STRING_BUFFER_LENGTH);
            String classNameString = Native.toString(classNameBuffer);
            if (baseNameString.equals(processName) && classNameString.equals("UnityWndClass")) {
                windowHandle = hWnd;
                if (windowHandleId == null) {
                    windowHandleId = windowHandle.toString();
                    if (lastKnownWindowHandleId == null || lastKnownWindowHandleId != windowHandleId) {
                        // The window handle has changed, so try to find the location the HearthStats executable. This is used to
                        // find the HS log file. Only compatible with Windows Vista and later, so we skip for Windows XP.
                        lastKnownWindowHandleId = windowHandleId;
                        if (Environment.isOsVersionAtLeast(6, 0)) {
                            debugLog.debug("Windows version is Vista or later so the location of the Hearthstone is being determined from the process");
                            Kernel32.QueryFullProcessImageNameW(process, 0, processFileNameBuffer, lpdwSize);
                            String processFileNameString = Native.toString(processFileNameBuffer);
                            if (processFileNameString != null) {
                                int lastSlash = processFileNameString.lastIndexOf('\\');
                                hearthstoneProcessFolder = processFileNameString.substring(0, lastSlash);
                            }
                        }
                    }
                    _notifyObserversOfChangeTo("Hearthstone window found with process name " + processName);
                }
            }
            return true;
        }
    }, null);
    // notify of window lost
    if (windowHandle == null && windowHandleId != null) {
        _notifyObserversOfChangeTo("Hearthstone window with process name " + processName + " closed");
        windowHandleId = null;
    }
    return windowHandle;
}
Also used : HWND(com.sun.jna.platform.win32.WinDef.HWND) PointerByReference(com.sun.jna.ptr.PointerByReference) WNDENUMPROC(com.sun.jna.platform.win32.WinUser.WNDENUMPROC) Pointer(com.sun.jna.Pointer)

Example 89 with Pointer

use of com.sun.jna.Pointer in project HearthStats.net-Uploader by HearthStats.

the class JnaUtil method main.

public static void main(String[] args) throws InterruptedException {
    String[] testStrs = { "Untitled-Notepad", "Untitled - Notepad", "Untitled  -  Notepad", "Java-Epic", "Java - Epic", "Fubars rule!", "The First Night", "New Tab", "Citrix X", "EHR PROD - SVC" };
    for (String testStr : testStrs) {
        Pointer hWnd = getWinHwnd(testStr);
        boolean isWindow = windowExists(hWnd);
        System.out.printf("%-22s %5b %16s %b%n", testStr, windowExists(testStr), hWnd, isWindow);
    }
    String ehrProd = "EHR PROD - SVC";
    Pointer hWnd = getWinHwnd(ehrProd);
    System.out.println("is it foreground window? " + isForegroundWindow(hWnd));
    boolean foo = setForegroundWindow(ehrProd);
    System.out.println("foregroundwindow: " + foo);
    Thread.sleep(400);
    System.out.println("is it foreground window? " + isForegroundWindow(hWnd));
    Thread.sleep(400);
    try {
        Rectangle rect = getWindowRect(ehrProd);
        Robot robot = new Robot();
        BufferedImage img = robot.createScreenCapture(rect);
        ImageIcon icon = new ImageIcon(img);
        JLabel label = new JLabel(icon);
        JOptionPane.showMessageDialog(null, label);
    } catch (AWTException e) {
        e.printStackTrace();
    } catch (JnaUtilException e) {
        e.printStackTrace();
    }
}
Also used : ImageIcon(javax.swing.ImageIcon) Rectangle(java.awt.Rectangle) JLabel(javax.swing.JLabel) Pointer(com.sun.jna.Pointer) Robot(java.awt.Robot) BufferedImage(java.awt.image.BufferedImage) AWTException(java.awt.AWTException)

Example 90 with Pointer

use of com.sun.jna.Pointer in project openhab1-addons by openhab.

the class TellstickException method getMessage.

@Override
public String getMessage() {
    Pointer errorP = JNA.CLibrary.INSTANCE.tdGetErrorString(errorcode);
    String error = errorP.getString(0);
    JNA.CLibrary.INSTANCE.tdReleaseString(errorP);
    return dev.getName() + ": " + error;
}
Also used : Pointer(com.sun.jna.Pointer)

Aggregations

Pointer (com.sun.jna.Pointer)93 PointerByReference (com.sun.jna.ptr.PointerByReference)20 Memory (com.sun.jna.Memory)15 IntByReference (com.sun.jna.ptr.IntByReference)15 Test (org.junit.Test)12 HDDEDATA (com.sun.jna.platform.win32.Ddeml.HDDEDATA)8 HSZ (com.sun.jna.platform.win32.Ddeml.HSZ)8 HCONV (com.sun.jna.platform.win32.Ddeml.HCONV)7 ConnectHandler (com.sun.jna.platform.win32.DdemlUtil.ConnectHandler)7 IDdeConnection (com.sun.jna.platform.win32.DdemlUtil.IDdeConnection)7 StandaloneDdeClient (com.sun.jna.platform.win32.DdemlUtil.StandaloneDdeClient)7 HANDLE (com.sun.jna.platform.win32.WinNT.HANDLE)7 File (java.io.File)7 CountDownLatch (java.util.concurrent.CountDownLatch)7 HWND (com.sun.jna.platform.win32.WinDef.HWND)6 ULONG (com.sun.jna.platform.win32.WinDef.ULONG)6 IOException (java.io.IOException)6 BufferedImage (java.awt.image.BufferedImage)5 Function (com.sun.jna.Function)4 ULONG_PTR (com.sun.jna.platform.win32.BaseTSD.ULONG_PTR)4