mirror of
https://github.com/go-vgo/robotgo.git
synced 2025-05-31 06:13:55 +00:00
Merge pull request #457 from go-vgo/bitmap-pr
Refactor some mouse and window C code to Go
This commit is contained in:
commit
fafd2bfcd4
@ -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));
|
||||
|
@ -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__)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
106
mouse/goMouse.h
106
mouse/goMouse.h
@ -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;
|
||||
}
|
@ -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 */
|
@ -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)
|
||||
|
116
robotgo.go
116
robotgo.go
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user