use of org.rococoa.cocoa.foundation.NSString in project HearthStats.net-Uploader by HearthStats.
the class ProgramHelperOsx method getHSWindowBounds.
@Override
public Rectangle getHSWindowBounds() {
final NSAutoreleasePool pool = NSAutoreleasePool.new_();
try {
if (_pid == 0) {
_pid = findProgramPid(_bundleIdentifier);
}
if (_windowId == 0) {
_windowId = findWindow(_pid);
}
// Instead, obtain a dictionary of all on-screen windows from Quartz Window Services, which will include all running applications.
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 ID of this 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 thisWindowId = windowIdRef.getValue();
if (thisWindowId == _windowId) {
// Determine the bounds of this window
NSString kCGWindowBounds = CoreGraphicsLibrary.kCGWindowBounds;
Pointer boundPointer = CoreFoundationLibrary.INSTANCE.CFDictionaryGetValue(dictionaryRef, kCGWindowBounds.id());
CoreGraphicsLibrary.CGRectRef rect = new CoreGraphicsLibrary.CGRectRef();
boolean result = CoreGraphicsLibrary.INSTANCE.CGRectMakeWithDictionaryRepresentation(boundPointer, rect);
int x = (int) rect.origin.x;
int y = (int) rect.origin.y;
int width = (int) rect.size.width;
int height = (int) rect.size.height;
// Determine height of the title bar, if present
int titleHeight = determineWindowTitleHeight(height, width);
debugLog.debug("Found Hearthstone window at x={} y={} width={} height={} title={}", x, y, width, height, titleHeight);
return new Rectangle(x, y, width, height);
}
}
} finally {
pool.drain();
}
// Couldn't find the Hearthstone window so return null... this will break the calling code.
debugLog.warn("Unable to find position of Hearthstone window.");
return null;
}
use of org.rococoa.cocoa.foundation.NSString 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();
}
}
Aggregations