Merge pull request #457 from go-vgo/bitmap-pr

Refactor some mouse and window C code to Go
This commit is contained in:
Evans 2022-02-03 03:33:33 -08:00 committed by GitHub
commit fafd2bfcd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 111 additions and 378 deletions

View File

@ -2,7 +2,7 @@
#include <assert.h>
#include <string.h>
MMBitmapRef createMMBitmap_c(uint8_t *buffer, size_t width, size_t height,
MMBitmapRef createMMBitmap_c(uint8_t *buffer, int32_t width, int32_t height,
size_t bytewidth, uint8_t bitsPerPixel, uint8_t bytesPerPixel
) {
MMBitmapRef bitmap = malloc(sizeof(MMBitmap));

View File

@ -5,8 +5,7 @@
/* Python versions under 2.5 don't support this macro, but it's not
* terribly difficult to replicate: */
#ifndef PyModule_AddIntMacro
#define PyModule_AddIntMacro(module, macro) \
PyModule_AddIntConstant(module, #macro, macro)
#define PyModule_AddIntMacro(module, macro) PyModule_AddIntConstant(module, #macro, macro)
#endif /* PyModule_AddIntMacro */
#if !defined(IS_MACOSX) && defined(__APPLE__) && defined(__MACH__)

View File

@ -6,6 +6,7 @@
#include "inline_keywords.h" /* For H_INLINE */
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
/* Some generic, cross-platform types. */
#ifdef RobotGo_64

View File

@ -8,6 +8,13 @@ static int registered = 0;
static char *displayName = NULL;
static int hasDisplayNameChanged = 0;
void XCloseMainDisplay(void) {
if (mainDisplay != NULL) {
XCloseDisplay(mainDisplay);
mainDisplay = NULL;
}
}
Display *XGetMainDisplay(void) {
/* Close the display if displayName has changed */
if (hasDisplayNameChanged) {
@ -40,13 +47,6 @@ Display *XGetMainDisplay(void) {
return mainDisplay;
}
void XCloseMainDisplay(void) {
if (mainDisplay != NULL) {
XCloseDisplay(mainDisplay);
mainDisplay = NULL;
}
}
void setXDisplay(char *name) {
displayName = strdup(name);
hasDisplayNameChanged = 1;

View File

@ -81,23 +81,23 @@ MMKeyCode keyCodeForChar(const char c) {
}
#if defined(IS_MACOSX)
CFStringRef createStringForKey(CGKeyCode keyCode){
TISInputSourceRef currentKeyboard = TISCopyCurrentASCIICapableKeyboardInputSource();
CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(
currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
CFStringRef createStringForKey(CGKeyCode keyCode){
TISInputSourceRef currentKeyboard = TISCopyCurrentASCIICapableKeyboardInputSource();
CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(
currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
if (layoutData == nil) { return 0; }
if (layoutData == nil) { return 0; }
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *) CFDataGetBytePtr(layoutData);
UInt32 keysDown = 0;
UniChar chars[4];
UniCharCount realLength;
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *) CFDataGetBytePtr(layoutData);
UInt32 keysDown = 0;
UniChar chars[4];
UniCharCount realLength;
UCKeyTranslate(keyboardLayout, keyCode, kUCKeyActionDisplay, 0, LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit, &keysDown,
sizeof(chars) / sizeof(chars[0]), &realLength, chars);
CFRelease(currentKeyboard);
UCKeyTranslate(keyboardLayout, keyCode, kUCKeyActionDisplay, 0, LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit, &keysDown,
sizeof(chars) / sizeof(chars[0]), &realLength, chars);
CFRelease(currentKeyboard);
return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
}
return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
}
#endif

View File

@ -19,14 +19,14 @@
Sleep(DEADBEEF_RANDRANGE(0, 1));
}
#elif defined(USE_X11)
void X_KEY_EVENT(Display *display, MMKeyCode key, bool is_press) (
void X_KEY_EVENT(Display *display, MMKeyCode key, bool is_press) {
XTestFakeKeyEvent(display, XKeysymToKeycode(display, key), is_press, CurrentTime);
XSync(display, false);
}
void X_KEY_EVENT_WAIT(Display *display, MMKeyCode key, bool is_press) {
X_KEY_EVENT(display, key, is_press);
microsleep(DEADBEEF_UNIFORM(0.0, 0.5);
microsleep(DEADBEEF_UNIFORM(0.0, 0.5));
}
#endif

View File

@ -1,106 +0,0 @@
// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#include "../base/types.h"
#include "mouse_c.h"
// Global delays.
int mouseDelay = 0;
int move_mouse(int32_t x, int32_t y){
MMPointInt32 point;
point = MMPointInt32Make(x, y);
moveMouse(point);
return 0;
}
int drag_mouse(int32_t x, int32_t y, MMMouseButton button){
MMPointInt32 point;
point = MMPointInt32Make(x, y);
dragMouse(point, button);
microsleep(mouseDelay);
return 0;
}
bool move_mouse_smooth(int32_t x, int32_t y, double lowSpeed,
double highSpeed, int msDelay){
MMPointInt32 point;
point = MMPointInt32Make(x, y);
bool cbool = smoothlyMoveMouse(point, lowSpeed, highSpeed);
microsleep(msDelay);
return cbool;
}
MMPointInt32 get_mouse_pos(){
MMPointInt32 pos = getMousePos();
return pos;
}
int mouse_click(MMMouseButton button, bool doubleC){
if (!doubleC) {
clickMouse(button);
} else {
doubleClick(button);
}
microsleep(mouseDelay);
return 0;
}
int mouse_toggle(char* d, MMMouseButton button){
bool down = false;
if (strcmp(d, "down") == 0) {
down = true;
} else if (strcmp(d, "up") == 0) {
down = false;
} else {
return 1;
}
toggleMouse(down, button);
microsleep(mouseDelay);
return 0;
}
int set_mouse_delay(size_t val){
mouseDelay = val;
return 0;
}
int scroll(int x, int y, int msDelay){
scrollMouseXY(x, y);
microsleep(msDelay);
return 0;
}
int scroll_mouse(size_t scrollMagnitude, char *s){
MMMouseWheelDirection scrollDirection;
if (strcmp(s, "up") == 0) {
scrollDirection = DIRECTION_UP;
} else if (strcmp(s, "down") == 0) {
scrollDirection = DIRECTION_DOWN;
} else {
return 1;
}
scrollMouse(scrollMagnitude, scrollDirection);
microsleep(mouseDelay);
return 0;
}

View File

@ -44,10 +44,4 @@
#error "No mouse button constants set for platform"
#endif
enum __MMMouseWheelDirection {
DIRECTION_DOWN = -1,
DIRECTION_UP = 1
};
typedef int MMMouseWheelDirection;
#endif /* MOUSE_H */

View File

@ -122,7 +122,7 @@ void dragMouse(MMPointInt32 point, const MMMouseButton button){
#if defined(IS_MACOSX)
const CGEventType dragType = MMMouseDragToCGEventType(button);
CGEventRef drag = CGEventCreateMouseEvent(NULL, dragType,
CGPointFromMMPoint(point), (CGMouseButton)button);
CGPointFromMMPointInt32(point), (CGMouseButton)button);
calculateDeltas(&drag, point);
@ -161,7 +161,7 @@ MMPointInt32 getMousePos() {
/* Press down a button, or release it. */
void toggleMouse(bool down, MMMouseButton button) {
#if defined(IS_MACOSX)
const CGPoint currentPos = CGPointFromMMPoint(getMousePos());
const CGPoint currentPos = CGPointFromMMPointInt32(getMousePos());
const CGEventType mouseType = MMMouseToCGEventType(down, button);
CGEventRef event = CGEventCreateMouseEvent(NULL, mouseType, currentPos, (CGMouseButton)button);
@ -196,7 +196,7 @@ void clickMouse(MMMouseButton button){
void doubleClick(MMMouseButton button){
#if defined(IS_MACOSX)
/* Double click for Mac. */
const CGPoint currentPos = CGPointFromMMPoint(getMousePos());
const CGPoint currentPos = CGPointFromMMPointInt32(getMousePos());
const CGEventType mouseTypeDown = MMMouseToCGEventType(true, button);
const CGEventType mouseTypeUP = MMMouseToCGEventType(false, button);
@ -219,56 +219,6 @@ void doubleClick(MMMouseButton button){
}
/* Function used to scroll the screen in the required direction. */
void scrollMouse(int scrollMagnitude, MMMouseWheelDirection scrollDirection){
#if defined(IS_WINDOWS)
// C89 needs variables declared on top of functions (mouseScrollInput)
INPUT mouseScrollInput;
#endif
/* Direction should only be considered based on the scrollDirection. This Should not interfere. */
int cleanScrollMagnitude = abs(scrollMagnitude);
if (!(scrollDirection == DIRECTION_UP || scrollDirection == DIRECTION_DOWN)) {
return;
}
/* Set up the OS specific solution */
#if defined(__APPLE__)
CGWheelCount wheel = 1;
CGEventRef event;
/* Make scroll magnitude negative if we're scrolling down. */
cleanScrollMagnitude = cleanScrollMagnitude * scrollDirection;
event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, wheel, cleanScrollMagnitude, 0);
CGEventPost(kCGHIDEventTap, event);
#elif defined(USE_X11)
int x;
int dir = 4; /* Button 4 is up, 5 is down. */
Display *display = XGetMainDisplay();
if (scrollDirection == DIRECTION_DOWN) {
dir = 5;
}
for (x = 0; x < cleanScrollMagnitude; x++) {
XTestFakeButtonEvent(display, dir, 1, CurrentTime);
XTestFakeButtonEvent(display, dir, 0, CurrentTime);
}
XSync(display, false);
#elif defined(IS_WINDOWS)
mouseScrollInput.type = INPUT_MOUSE;
mouseScrollInput.mi.dx = 0;
mouseScrollInput.mi.dy = 0;
mouseScrollInput.mi.dwFlags = MOUSEEVENTF_WHEEL;
mouseScrollInput.mi.time = 0;
mouseScrollInput.mi.dwExtraInfo = 0;
mouseScrollInput.mi.mouseData = WHEEL_DELTA * scrollDirection * cleanScrollMagnitude;
SendInput(1, &mouseScrollInput, sizeof(mouseScrollInput));
#endif
}
void scrollMouseXY(int x, int y) {
#if defined(IS_WINDOWS)
// Fix for #97, C89 needs variables declared on top of functions (mouseScrollInput)

View File

@ -38,13 +38,12 @@ package robotgo
#cgo windows LDFLAGS: -lgdi32 -luser32
//
#include "screen/goScreen.h"
#include "mouse/goMouse.h"
#include "mouse/mouse_c.h"
#include "window/goWindow.h"
*/
import "C"
import (
"errors"
"image"
"runtime"
"time"
@ -129,7 +128,7 @@ func Sleep(tm int) {
time.Sleep(time.Duration(tm) * time.Second)
}
// MicroSleep time C.microsleep(tm), use the MilliSleep
// MicroSleep time C.microsleep(tm), use the MilliSleep()
func MicroSleep(tm float64) {
C.microsleep(C.double(tm))
}
@ -250,8 +249,7 @@ func Scaled0(x int, f float64) int {
// GetScreenSize get the screen size
func GetScreenSize() (int, int) {
size := C.get_screen_size()
// fmt.Println("...", size, size.width)
size := C.getMainDisplaySize()
return int(size.w), int(size.h)
}
@ -368,8 +366,8 @@ func ToBitmap(bit CBitmap) Bitmap {
func ToCBitmap(bit Bitmap) CBitmap {
cbitmap := C.createMMBitmap_c(
(*C.uint8_t)(bit.ImgBuf),
C.size_t(bit.Width),
C.size_t(bit.Height),
C.int32_t(bit.Width),
C.int32_t(bit.Height),
C.size_t(bit.Bytewidth),
C.uint8_t(bit.BitsPixel),
C.uint8_t(bit.BytesPerPixel),
@ -411,7 +409,7 @@ func GetXDisplayName() string {
//
// ScaleX get the primary display horizontal DPI scale factor, drop
func ScaleX() int {
return int(C.scale_x())
return int(C.scaleX())
}
// Deprecated: use the ScaledF(),
@ -502,7 +500,7 @@ func Move(x, y int) {
cx := C.int32_t(x)
cy := C.int32_t(y)
C.move_mouse(cx, cy)
C.moveMouse(C.MMPointInt32Make(cx, cy))
MilliSleep(MouseSleep)
}
@ -532,7 +530,7 @@ func Drag(x, y int, args ...string) {
button = CheckMouse(args[0])
}
C.drag_mouse(cx, cy, button)
C.dragMouse(C.MMPointInt32Make(cx, cy), button)
MilliSleep(MouseSleep)
}
@ -590,8 +588,8 @@ func MoveSmooth(x, y int, args ...interface{}) bool {
high = 3.0
}
cbool := C.move_mouse_smooth(cx, cy, low, high, C.int(mouseDelay))
MilliSleep(MouseSleep)
cbool := C.smoothlyMoveMouse(C.MMPointInt32Make(cx, cy), low, high)
MilliSleep(MouseSleep + mouseDelay)
return bool(cbool)
}
@ -618,7 +616,7 @@ func MoveSmoothRelative(x, y int, args ...interface{}) {
// GetMousePos get the mouse's portion return x, y
func GetMousePos() (int, int) {
pos := C.get_mouse_pos()
pos := C.getMousePos()
x := int(pos.x)
y := int(pos.y)
@ -645,7 +643,7 @@ func MouseClick(args ...interface{}) {
func Click(args ...interface{}) {
var (
button C.MMMouseButton = C.LEFT_BUTTON
double C.bool
double bool
)
if len(args) > 0 {
@ -653,10 +651,15 @@ func Click(args ...interface{}) {
}
if len(args) > 1 {
double = C.bool(args[1].(bool))
double = args[1].(bool)
}
if !double {
C.clickMouse(button)
} else {
C.doubleClick(button)
}
C.mouse_click(button, double)
MilliSleep(MouseSleep)
}
@ -694,56 +697,28 @@ func Toggle(key ...string) error {
if len(key) > 0 {
button = CheckMouse(key[0])
}
down := C.CString("down")
if len(key) > 1 {
down = C.CString(key[1])
}
i := C.mouse_toggle(down, button)
C.free(unsafe.Pointer(down))
MilliSleep(MouseSleep)
if int(i) == 0 {
return nil
down := true
if len(key) > 1 && key[1] == "up" {
down = false
}
return errors.New("Undefined params.")
C.toggleMouse(C.bool(down), button)
MilliSleep(MouseSleep)
return nil
}
// Deprecated: use the Toggle(),
//
// MouseToggle toggle the mouse
//
// Examples:
// robotgo.MouseToggle("down", "right")
// robotgo.MouseToggle("up", "right")
func MouseToggle(togKey string, args ...interface{}) int {
var button C.MMMouseButton = C.LEFT_BUTTON
if len(args) > 0 {
button = CheckMouse(args[0].(string))
}
down := C.CString(togKey)
i := C.mouse_toggle(down, button)
C.free(unsafe.Pointer(down))
MilliSleep(MouseSleep)
return int(i)
// MouseDown send mouse down event
func MouseDown(key ...string) error {
return Toggle(key...)
}
// Deprecated: use the Scroll(),
//
// ScrollMouse scroll the mouse to (x, "up")
//
// Examples:
// robotgo.ScrollMouse(10, "down")
// robotgo.ScrollMouse(10, "up")
func ScrollMouse(x int, direction string) {
cx := C.size_t(x)
cy := C.CString(direction)
C.scroll_mouse(cx, cy)
C.free(unsafe.Pointer(cy))
MilliSleep(MouseSleep)
// MouseUp send mouse up event
func MouseUp(key ...string) error {
if len(key) <= 0 {
key = append(key, "left")
}
return Toggle(append(key, "up")...)
}
// Scroll scroll the mouse to (x, y)
@ -760,10 +735,9 @@ func Scroll(x, y int, args ...int) {
cx := C.int(x)
cy := C.int(y)
cz := C.int(msDelay)
C.scroll(cx, cy, cz)
MilliSleep(MouseSleep)
C.scrollMouseXY(cx, cy)
MilliSleep(MouseSleep + msDelay)
}
// ScrollSmooth scroll the mouse smooth,
@ -809,12 +783,6 @@ func ScrollRelative(x, y int, args ...int) {
Scroll(mx, my, args...)
}
// SetMouseDelay set mouse delay
func SetMouseDelay(delay int) {
cdelay := C.size_t(delay)
C.set_mouse_delay(cdelay)
}
/*
____ __ ____ __ .__ __. _______ ______ ____ __ ____
\ \ / \ / / | | | \ | | | \ / __ \ \ \ / \ / /
@ -850,7 +818,7 @@ func showAlert(title, msg string, args ...string) bool {
defaultButton := C.CString(defaultBtn)
cancelButton := C.CString(cancelBtn)
cbool := C.show_alert(cTitle, cMsg, defaultButton, cancelButton)
cbool := C.showAlert(cTitle, cMsg, defaultButton, cancelButton)
ibool := int(cbool)
C.free(unsafe.Pointer(cTitle))
@ -929,13 +897,13 @@ func CloseWindow(args ...int32) {
isHwnd = args[1]
}
C.close_window(C.uintptr(hwnd), C.uintptr(isHwnd))
C.close_window_by_PId(C.uintptr(hwnd), C.uintptr(isHwnd))
}
// SetHandle set the window handle
func SetHandle(hwnd int) {
chwnd := C.uintptr(hwnd)
C.set_handle(chwnd)
C.setHandle(chwnd)
}
// SetHandlePid set the window handle by pid
@ -973,14 +941,14 @@ func GetHandle() int {
// This function will be removed in version v1.0.0
func GetBHandle() int {
tt.Drop("GetBHandle", "GetHandle")
hwnd := C.bget_handle()
hwnd := C.b_get_handle()
ghwnd := int(hwnd)
//fmt.Println("gethwnd---", ghwnd)
return ghwnd
}
func cgetTitle(hwnd, isHwnd int32) string {
title := C.get_title(C.uintptr(hwnd), C.uintptr(isHwnd))
title := C.get_title_by_pid(C.uintptr(hwnd), C.uintptr(isHwnd))
gtitle := C.GoString(title)
return gtitle

View File

@ -52,7 +52,6 @@ MMRGBHex get_px_color(int32_t x, int32_t y, int32_t display_id) {
}
bitmap = copyMMBitmapFromDisplayInRect(MMRectInt32Make(x, y, 1, 1), display_id);
// bitmap = MMRectMake(x, y, 1, 1);
color = MMRGBHexAtPoint(bitmap, 0, 0);
destroyMMBitmap(bitmap);
@ -66,12 +65,6 @@ char* get_pixel_color(int32_t x, int32_t y, int32_t display_id) {
return s;
}
MMSizeInt32 get_screen_size() {
// Get display size.
MMSizeInt32 displaySize = getMainDisplaySize();
return displaySize;
}
char* set_XDisplay_name(char* name) {
#if defined(USE_X11)
setXDisplay(name);
@ -111,7 +104,6 @@ uint32_t get_num_displays() {
#endif
}
void bitmap_dealloc(MMBitmapRef bitmap) {
if (bitmap != NULL) {
destroyMMBitmap(bitmap);

View File

@ -95,8 +95,8 @@ MMBitmapRef copyMMBitmapFromDisplayInRect(MMRectInt32 rect, int32_t display_id)
dib = CreateDIBSection(screen, &bi, DIB_RGB_COLORS, &data, NULL, 0);
/* Copy the data into a bitmap struct. */
bool smem = (screenMem = CreateCompatibleDC(screen)) == NULL;
bool bitb = BitBlt(screenMem, (int)0, (int)0, (int)rect.size.w, (int)rect.size.h,
BOOL smem = (screenMem = CreateCompatibleDC(screen)) == NULL;
BOOL bitb = BitBlt(screenMem, (int)0, (int)0, (int)rect.size.w, (int)rect.size.h,
screen, rect.origin.x, rect.origin.y, SRCCOPY);
if (smem || SelectObject(screenMem, dib) == NULL || !bitb) {
/* Error copying data. */

View File

@ -12,27 +12,12 @@
#include "window.h"
#include "win_sys.h"
int show_alert(const char *title, const char *msg,
const char *defaultButton, const char *cancelButton){
return showAlert(title, msg, defaultButton, cancelButton);
}
intptr scale_x(){
return scaleX();
}
bool is_valid(){
return IsValid();
}
void min_window(uintptr pid, bool state, uintptr isHwnd){
#if defined(IS_MACOSX)
// return 0;
AXUIElementRef axID = AXUIElementCreateApplication(pid);
AXUIElementSetAttributeValue(axID, kAXMinimizedAttribute,
state ? kCFBooleanTrue : kCFBooleanFalse);
AXUIElementSetAttributeValue(axID, kAXMinimizedAttribute,
state ? kCFBooleanTrue : kCFBooleanFalse);
#elif defined(USE_X11)
// Ignore X errors
XDismissErrors();
@ -64,16 +49,8 @@ void max_window(uintptr pid, bool state, uintptr isHwnd){
#endif
}
void close_window(uintptr pid, uintptr isHwnd){
close_window_by_PId(pid, isHwnd);
}
bool set_handle(uintptr handle){
return setHandle(handle);
}
uintptr get_handle(){
MData mData = GetActive();
MData mData = get_active();
#if defined(IS_MACOSX)
return (uintptr)mData.CgID;
@ -84,8 +61,7 @@ uintptr get_handle(){
#endif
}
// uint32 uintptr
uintptr getHandle() {
uintptr b_get_handle() {
#if defined(IS_MACOSX)
return (uintptr)mData.CgID;
#elif defined(USE_X11)
@ -95,31 +71,7 @@ uintptr getHandle() {
#endif
}
uintptr bget_handle(){
return getHandle();
}
void set_active(const MData win){
SetActive(win);
}
void active_PID(uintptr pid, uintptr isHwnd){
MData win = set_handle_pid(pid, isHwnd);
SetActive(win);
}
MData get_active(){
MData mdata = GetActive();
return mdata;
}
char* get_title(uintptr pid, uintptr isHwnd){
char* title = get_title_by_pid(pid, isHwnd);
// printf("title::::%s\n", title );
return title;
}
int32_t get_PID(void){
int pid = WGetPID();
return pid;
set_active(win);
}

View File

@ -46,7 +46,6 @@ typedef struct _Bounds Bounds;
static AXUIElementRef GetUIElement(CGWindowID win){
intptr pid = 0;
// double_t pid = 0;
// Create array storing window
CGWindowID window[1] = { win };
CFArrayRef wlist = CFArrayCreate(NULL, (const void**)window, 1, NULL);
@ -59,7 +58,6 @@ typedef struct _Bounds Bounds;
if (info != NULL && CFArrayGetCount(info) > 0) {
// Retrieve description from info array
CFDictionaryRef desc = (CFDictionaryRef)CFArrayGetValueAtIndex(info, 0);
// Get window PID
CFNumberRef data = (CFNumberRef) CFDictionaryGetValue(desc, kCGWindowOwnerPID);
if (data != NULL) {
@ -269,7 +267,6 @@ typedef struct _Bounds Bounds;
#elif defined(IS_WINDOWS)
//
void win_min(HWND hwnd, bool state){
if (state) {
ShowWindow(hwnd, SW_MINIMIZE);

View File

@ -8,10 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// #include "../base/os.h"
#if defined(USE_X11)
// #include <X11/Xlib.h>
// #include <X11/Xatom.h>
#include <X11/Xresource.h>
#endif
@ -79,7 +76,7 @@ intptr scaleX(){
Bounds get_bounds(uintptr pid, uintptr isHwnd){
// Check if the window is valid
Bounds bounds;
if (!IsValid()) { return bounds; }
if (!is_valid()) { return bounds; }
#if defined(IS_MACOSX)
// Bounds bounds;
@ -153,7 +150,7 @@ Bounds get_bounds(uintptr pid, uintptr isHwnd){
Bounds get_client(uintptr pid, uintptr isHwnd) {
// Check if the window is valid
Bounds bounds;
if (!IsValid()) { return bounds; }
if (!is_valid()) { return bounds; }
#if defined(IS_MACOSX)
return get_bounds(pid, isHwnd);
@ -182,9 +179,7 @@ Bounds get_client(uintptr pid, uintptr isHwnd) {
// Coordinates must be translated
if (parent != attr.root) {
XTranslateCoordinates(rDisplay, win.XWin, attr.root, attr.x, attr.y, &x, &y, &parent);
}
// Coordinates can be left alone
else {
} else {
x = attr.x;
y = attr.y;
}
@ -200,7 +195,7 @@ Bounds get_client(uintptr pid, uintptr isHwnd) {
#elif defined(IS_WINDOWS)
HWND hwnd;
if (isHwnd == 0) {
hwnd= GetHwndByPId(pid);
hwnd = GetHwndByPId(pid);
} else {
hwnd = (HWND)pid;
}

View File

@ -8,13 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// #include "../base/os.h"
#include "pub.h"
bool setHandle(uintptr handle);
bool IsValid();
bool is_valid();
bool IsAxEnabled(bool options);
MData GetActive(void);
MData get_active(void);
void initWindow();
char* get_title_by_hand(MData m_data);
void close_window_by_Id(MData m_data);
@ -74,13 +74,13 @@ void set_handle_pid_mData(uintptr pid, uintptr isHwnd){
mData = win;
}
bool IsValid() {
bool is_valid() {
initWindow(initHandle);
if (!IsAxEnabled(true)) {
printf("%s\n", "Window: Accessibility API is disabled!\n"
"Failed to enable access for assistive devices.");
}
MData actdata = GetActive();
MData actdata = get_active();
#if defined(IS_MACOSX)
mData.CgID = actdata.CgID;
@ -131,16 +131,13 @@ bool IsAxEnabled(bool options){
static dispatch_once_t once; dispatch_once (&once,
^{
// Open the framework
void* handle = dlopen("/System/Library/Frameworks/Application"
"Services.framework/ApplicationServices", RTLD_LAZY);
void* handle = dlopen("/System/Library/Frameworks/Application"
"Services.framework/ApplicationServices", RTLD_LAZY);
// Validate the handle
if (handle != NULL) {
*(void**) (&gAXIsProcessTrustedWithOptions) =
dlsym (handle, "AXIsProcessTrustedWithOptions");
gkAXTrustedCheckOptionPrompt =
(CFStringRef*) dlsym (handle, "kAXTrustedCheckOptionPrompt");
*(void**) (&gAXIsProcessTrustedWithOptions) = dlsym (handle, "AXIsProcessTrustedWithOptions");
gkAXTrustedCheckOptionPrompt = (CFStringRef*) dlsym (handle, "kAXTrustedCheckOptionPrompt");
}
});
@ -207,11 +204,11 @@ bool setHandle(uintptr handle){
return false;
#elif defined(USE_X11)
mData.XWin = (Window)handle;
if (handle == 0){
if (handle == 0) {
return true;
}
if (IsValid()){
if (is_valid()) {
return true;
}
@ -223,7 +220,7 @@ bool setHandle(uintptr handle){
return true;
}
if (IsValid()) {
if (is_valid()) {
return true;
}
@ -234,7 +231,7 @@ bool setHandle(uintptr handle){
bool IsTopMost(void){
// Check the window validity
if (!IsValid()) {return false;}
if (!is_valid()) { return false; }
#if defined(IS_MACOSX)
return false; // WARNING: Unavailable
#elif defined(USE_X11)
@ -248,7 +245,7 @@ bool IsTopMost(void){
bool IsMinimized(void){
// Check the window validity
if (!IsValid()) {return false;}
if (!is_valid()) { return false; }
#if defined(IS_MACOSX)
CFBooleanRef data = NULL;
// Determine whether the window is minimized
@ -273,7 +270,7 @@ bool IsMinimized(void){
//////
bool IsMaximized(void){
// Check the window validity
if (!IsValid()) {return false;}
if (!is_valid()) { return false; }
#if defined(IS_MACOSX)
return false; // WARNING: Unavailable
#elif defined(USE_X11)
@ -285,16 +282,15 @@ bool IsMaximized(void){
#endif
}
void SetActive(const MData win) {
void set_active(const MData win) {
// Check if the window is valid
if (!IsValid()) { return; }
if (!is_valid()) { return; }
#if defined(IS_MACOSX)
// Attempt to raise the specified window object
if (AXUIElementPerformAction(win.AxID, kAXRaiseAction) != kAXErrorSuccess) {
pid_t pid = 0;
// Attempt to retrieve the PID of the window
if (AXUIElementGetPid(win.AxID, &pid)
!= kAXErrorSuccess || !pid) {return;}
if (AXUIElementGetPid(win.AxID, &pid) != kAXErrorSuccess || !pid) { return; }
// Ignore deprecated warnings
#pragma clang diagnostic push
@ -309,7 +305,6 @@ void SetActive(const MData win) {
#pragma clang diagnostic pop
}
#elif defined(USE_X11)
// Ignore X errors
XDismissErrors();
@ -355,7 +350,7 @@ void SetActive(const MData win) {
#endif
}
MData GetActive(void) {
MData get_active(void) {
#if defined(IS_MACOSX)
MData result;
// Ignore deprecated warnings
@ -372,7 +367,7 @@ MData GetActive(void) {
// Create accessibility object using focused PID
AXUIElementRef focused = AXUIElementCreateApplication(pid);
if (focused == NULL) {return result; }// Verify
if (focused == NULL) { return result; } // Verify
AXUIElementRef element;
// Retrieve the currently focused window
@ -449,10 +444,9 @@ MData GetActive(void) {
#endif
}
void SetTopMost(bool state){
// Check window validity
if (!IsValid()) {return;}
if (!is_valid()) { return; }
#if defined(IS_MACOSX)
// WARNING: Unavailable
#elif defined(USE_X11)
@ -465,9 +459,9 @@ void SetTopMost(bool state){
#endif
}
void close_main_window (){
void close_main_window () {
// Check if the window is valid
if (!IsValid()) { return; }
if (!is_valid()) { return; }
close_window_by_Id(mData);
}
@ -477,11 +471,10 @@ void close_window_by_PId(uintptr pid, uintptr isHwnd){
close_window_by_Id(win);
}
// CloseWindow
void close_window_by_Id(MData m_data){
// Check window validity
if (!IsValid()) { return; }
if (!is_valid()) { return; }
#if defined(IS_MACOSX)
AXUIElementRef b = NULL;
// Retrieve the close button of this window
@ -506,7 +499,7 @@ void close_window_by_Id(MData m_data){
char* get_main_title(){
// Check if the window is valid
if (!IsValid()) { return "IsValid failed."; }
if (!is_valid()) { return "is_valid failed."; }
return get_title_by_hand(mData);
}
@ -532,7 +525,7 @@ char* named(void *result) {
char* get_title_by_hand(MData m_data){
// Check if the window is valid
if (!IsValid()) { return "IsValid failed."; }
if (!is_valid()) { return "is_valid failed."; }
#if defined(IS_MACOSX)
CFStringRef data = NULL;
// Determine the current title of the window
@ -591,16 +584,15 @@ char* get_title_by_hand(MData m_data){
#endif
}
int32_t WGetPID(void) {
int32_t get_PID(void) {
// Check window validity
if (!IsValid()) { return 0; }
if (!is_valid()) { return 0; }
#if defined(IS_MACOSX)
pid_t pid = 0;
// Attempt to retrieve the window pid
if (AXUIElementGetPid(mData.AxID, &pid)== kAXErrorSuccess) {
return pid;
}
return 0;
#elif defined(USE_X11)
// Ignore X errors
@ -620,4 +612,3 @@ int32_t WGetPID(void) {
return id;
#endif
}