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

add sys scale option displayID support and remove unused files
This commit is contained in:
Evans 2022-01-03 20:01:07 -04:00 committed by GitHub
commit 0b6cc4867e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 68 additions and 419 deletions

View File

@ -33,7 +33,7 @@ typedef MMBitmap *MMBitmapRef;
/* Creates new MMBitmap with the given values.
* Follows the Create Rule (caller is responsible for destroy()'ing object). */
MMBitmapRef createMMBitmap(uint8_t *buffer, size_t width, size_t height,
MMBitmapRef createMMBitmap_c(uint8_t *buffer, size_t width, size_t height,
size_t bytewidth, uint8_t bitsPerPixel,
uint8_t bytesPerPixel);
@ -43,12 +43,12 @@ void destroyMMBitmap(MMBitmapRef bitmap);
/* Releases memory occupied by MMBitmap. Acts via CallBack method*/
void destroyMMBitmapBuffer(char * bitmapBuffer, void * hint);
/* Returns copy of MMBitmap, to be destroy()'d by caller. */
MMBitmapRef copyMMBitmap(MMBitmapRef bitmap);
// /* Returns copy of MMBitmap, to be destroy()'d by caller. */
// MMBitmapRef copyMMBitmap(MMBitmapRef bitmap);
/* Returns copy of one MMBitmap juxtaposed in another (to be destroy()'d
* by the caller.), or NULL on error. */
MMBitmapRef copyMMBitmapFromPortion(MMBitmapRef source, MMRect rect);
// /* Returns copy of one MMBitmap juxtaposed in another (to be destroy()'d
// * by the caller.), or NULL on error. */
// MMBitmapRef copyMMBitmapFromPortion(MMBitmapRef source, MMRect rect);
#define MMBitmapPointInBounds(image, p) ((p).x < (image)->width && \
(p).y < (image)->height)
@ -72,19 +72,19 @@ MMBitmapRef copyMMBitmapFromPortion(MMBitmapRef source, MMRect rect);
#define MMRGBHexAtPoint(image, x, y) \
hexFromMMRGB(MMRGBColorAtPoint(image, x, y))
/* Increment either point.x or point.y depending on the position of point.x.
* That is, if x + 1 is >= width, increment y and start x at the beginning.
* Otherwise, increment x.
*
* This is used as a convenience macro to scan rows when calling functions such
* as findColorInRectAt() and findBitmapInBitmapAt(). */
#define ITER_NEXT_POINT(pixel, width, start_x) \
do { \
if (++(pixel).x >= (width)) { \
(pixel).x = start_x; \
++(point).y; \
} \
} while (0);
// /* Increment either point.x or point.y depending on the position of point.x.
// * That is, if x + 1 is >= width, increment y and start x at the beginning.
// * Otherwise, increment x.
// *
// * This is used as a convenience macro to scan rows when calling functions such
// * as findColorInRectAt() and findBitmapInBitmapAt(). */
// #define ITER_NEXT_POINT(pixel, width, start_x) \
// do { \
// if (++(pixel).x >= (width)) { \
// (pixel).x = start_x; \
// ++(point).y; \
// } \
// } while (0);
#ifdef __cplusplus
}

View File

@ -4,23 +4,20 @@
static uint32_t deadbeef_seed;
static uint32_t deadbeef_beef = 0xdeadbeef;
uint32_t deadbeef_rand(void)
{
uint32_t deadbeef_rand(void) {
deadbeef_seed = (deadbeef_seed << 7) ^ ((deadbeef_seed >> 25) + deadbeef_beef);
deadbeef_beef = (deadbeef_beef << 7) ^ ((deadbeef_beef >> 25) + 0xdeadbeef);
return deadbeef_seed;
}
void deadbeef_srand(uint32_t x)
{
void deadbeef_srand(uint32_t x) {
deadbeef_seed = x;
deadbeef_beef = 0xdeadbeef;
}
/* Taken directly from the documentation:
* http://inglorion.net/software/cstuff/deadbeef_rand/ */
uint32_t deadbeef_generate_seed(void)
{
uint32_t deadbeef_generate_seed(void) {
uint32_t t = (uint32_t)time(NULL);
uint32_t c = (uint32_t)clock();
return (t << 24) ^ (c << 11) ^ t ^ (size_t) &c;

View File

@ -1,252 +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.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "pub.h"
void dispatch_proc(iohook_event * const event) {
char buffer[256] = { 0 };
size_t length = snprintf(buffer, sizeof(buffer),
"id=%i,when=%" PRIu64 ",mask=0x%X",
event->type, event->time, event->mask);
switch (event->type) {
case EVENT_KEY_PRESSED:
// If the escape key is pressed, naturally terminate the program.
if (event->data.keyboard.keycode == VC_ESCAPE) {
// int status = hook_stop();
// switch (status) {
// // System level errors.
// case IOHOOK_ERROR_OUT_OF_MEMORY:
// loggerProc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status);
// break;
// case IOHOOK_ERROR_X_RECORD_GET_CONTEXT:
// // NOTE This is the only platform specific error that occurs on hook_stop().
// loggerProc(LOG_LEVEL_ERROR, "Failed to get XRecord context. (%#X)", status);
// break;
// // Default error.
// case IOHOOK_FAILURE:
// default:
// loggerProc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status);
// break;
// }
}
case EVENT_KEY_RELEASED:
snprintf(buffer + length, sizeof(buffer) - length,
",keycode=%u,rawcode=0x%X",
event->data.keyboard.keycode, event->data.keyboard.rawcode);
int akeyCode = (uint16_t) event->data.keyboard.keycode;
if (event->data.keyboard.keycode == VC_ESCAPE
&& atoi(cevent) == 11) {
int stopEvent = stop_event();
// printf("stop_event%d\n", stopEvent);
cstatus = 0;
}
// printf("atoi(str)---%d\n", atoi(cevent));
if (akeyCode == atoi(cevent)) {
int stopEvent = stop_event();
// printf("%d\n", stopEvent);
cstatus = 0;
}
break;
case EVENT_KEY_TYPED:
snprintf(buffer + length, sizeof(buffer) - length,
",keychar=%lc,rawcode=%u",
(uint16_t) event->data.keyboard.keychar,
event->data.keyboard.rawcode);
#ifdef WE_REALLY_WANT_A_POINTER
char *buf = malloc (6);
#else
char buf[6];
#endif
sprintf(buf, "%lc", (uint16_t) event->data.keyboard.keychar);
#ifdef WE_REALLY_WANT_A_POINTER
free (buf);
#endif
if (strcmp(buf, cevent) == 0) {
int stopEvent = stop_event();
// printf("%d\n", stopEvent);
cstatus = 0;
}
// return (char*) event->data.keyboard.keychar;
break;
case EVENT_MOUSE_PRESSED:
case EVENT_MOUSE_RELEASED:
case EVENT_MOUSE_CLICKED:
case EVENT_MOUSE_MOVED:
case EVENT_MOUSE_DRAGGED:
snprintf(buffer + length, sizeof(buffer) - length,
",x=%i,y=%i,button=%i,clicks=%i",
event->data.mouse.x, event->data.mouse.y,
event->data.mouse.button, event->data.mouse.clicks);
int abutton = event->data.mouse.button;
int aclicks = event->data.mouse.clicks;
int amouse = -1;
if (strcmp(cevent, "mleft") == 0) {
amouse = 1;
}
if (strcmp(cevent, "mright") == 0) {
amouse = 2;
}
if (strcmp(cevent, "wheelDown") == 0) {
amouse = 4;
}
if (strcmp(cevent, "wheelUp") == 0) {
amouse = 5;
}
if (strcmp(cevent, "wheelLeft") == 0) {
amouse = 6;
}
if (strcmp(cevent, "wheelRight") == 0) {
amouse = 7;
}
if (abutton == amouse && aclicks == 1) {
int stopEvent = stop_event();
cstatus = 0;
}
break;
case EVENT_MOUSE_WHEEL:
snprintf(buffer + length, sizeof(buffer) - length,
",type=%i,amount=%i,rotation=%i",
event->data.wheel.type, event->data.wheel.amount,
event->data.wheel.rotation);
break;
default:
break;
}
// fprintf(stdout, "----%s\n", buffer);
}
int add_event(char *key_event) {
// (uint16_t *)
cevent = key_event;
// Set the logger callback for library output.
hookSetlogger(&loggerProc);
// Set the event callback for IOhook events.
hook_set_dispatch_proc(&dispatch_proc);
// Start the hook and block.
// NOTE If EVENT_HOOK_ENABLED was delivered, the status will always succeed.
int status = hook_run();
switch (status) {
case IOHOOK_SUCCESS:
// Everything is ok.
break;
// System level errors.
case IOHOOK_ERROR_OUT_OF_MEMORY:
loggerProc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status);
break;
// X11 specific errors.
case IOHOOK_ERROR_X_OPEN_DISPLAY:
loggerProc(LOG_LEVEL_ERROR, "Failed to open X11 display. (%#X)", status);
break;
case IOHOOK_ERROR_X_RECORD_NOT_FOUND:
loggerProc(LOG_LEVEL_ERROR, "Unable to locate XRecord extension. (%#X)", status);
break;
case IOHOOK_ERROR_X_RECORD_ALLOC_RANGE:
loggerProc(LOG_LEVEL_ERROR, "Unable to allocate XRecord range. (%#X)", status);
break;
case IOHOOK_ERROR_X_RECORD_CREATE_CONTEXT:
loggerProc(LOG_LEVEL_ERROR, "Unable to allocate XRecord context. (%#X)", status);
break;
case IOHOOK_ERROR_X_RECORD_ENABLE_CONTEXT:
loggerProc(LOG_LEVEL_ERROR, "Failed to enable XRecord context. (%#X)", status);
break;
// Windows specific errors.
case IOHOOK_ERROR_SET_WINDOWS_HOOK_EX:
loggerProc(LOG_LEVEL_ERROR, "Failed to register low level windows hook. (%#X)", status);
break;
// Darwin specific errors.
case IOHOOK_ERROR_AXAPI_DISABLED:
loggerProc(LOG_LEVEL_ERROR, "Failed to enable access for assistive devices. (%#X)", status);
break;
case IOHOOK_ERROR_CREATE_EVENT_PORT:
loggerProc(LOG_LEVEL_ERROR, "Failed to create apple event port. (%#X)", status);
break;
case IOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE:
loggerProc(LOG_LEVEL_ERROR, "Failed to create apple run loop source. (%#X)", status);
break;
case IOHOOK_ERROR_GET_RUNLOOP:
loggerProc(LOG_LEVEL_ERROR, "Failed to acquire apple run loop. (%#X)", status);
break;
case IOHOOK_ERROR_CREATE_OBSERVER:
loggerProc(LOG_LEVEL_ERROR, "Failed to create apple run loop observer. (%#X)", status);
break;
// Default error.
case IOHOOK_FAILURE:
default:
loggerProc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status);
break;
}
// return status;
// printf("%d\n", status);
return cstatus;
}
int stop_event(){
int status = hook_stop();
switch (status) {
// System level errors.
case IOHOOK_ERROR_OUT_OF_MEMORY:
loggerProc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status);
break;
case IOHOOK_ERROR_X_RECORD_GET_CONTEXT:
// NOTE This is the only platform specific error that occurs on hook_stop().
loggerProc(LOG_LEVEL_ERROR, "Failed to get XRecord context. (%#X)", status);
break;
// Default error.
case IOHOOK_FAILURE:
default:
// loggerProc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status);
break;
}
return status;
}

View File

@ -1,95 +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/os.h"
#if defined(IS_MACOSX)
#include "../cdeps/hook/darwin/input_c.h"
#include "../cdeps/hook/darwin/hook_c.h"
#include "../cdeps/hook/darwin/event_c.h"
#include "../cdeps/hook/darwin/properties_c.h"
#elif defined(USE_X11)
//#define USE_XKBCOMMON 0
#include "../cdeps/hook/x11/input_c.h"
#include "../cdeps/hook/x11/hook_c.h"
#include "../cdeps/hook/x11/event_c.h"
#include "../cdeps/hook/x11/properties_c.h"
#elif defined(IS_WINDOWS)
#include "../cdeps/hook/windows/input_c.h"
#include "../cdeps/hook/windows/hook_c.h"
#include "../cdeps/hook/windows/event_c.h"
#include "../cdeps/hook/windows/properties_c.h"
#endif
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "../cdeps/hook/iohook.h"
int vccode[100];
int codesz;
char *cevent;
int rrevent;
// uint16_t *cevent;
int cstatus = 1;
int stop_event();
int add_event(char *key_event);
// int allEvent(char *key_event);
int allEvent(char *key_event, int vcode[], int size);
// NOTE: The following callback executes on the same thread that hook_run() is called
// from.
struct _MEvent {
uint8_t id;
size_t mask;
uint16_t keychar;
// char *keychar;
size_t x;
uint8_t y;
uint8_t bytesPerPixel;
};
typedef struct _MEvent MEvent;
// typedef MMBitmap *MMBitmapRef;
MEvent mEvent;
bool loggerProc(unsigned int level, const char *format, ...) {
bool status = false;
va_list args;
switch (level) {
#ifdef USE_DEBUG
case LOG_LEVEL_DEBUG:
case LOG_LEVEL_INFO:
va_start(args, format);
status = vfprintf(stdout, format, args) >= 0;
va_end(args);
break;
#endif
case LOG_LEVEL_WARN:
case LOG_LEVEL_ERROR:
va_start(args, format);
status = vfprintf(stderr, format, args) >= 0;
va_end(args);
break;
}
return status;
}

View File

@ -236,14 +236,15 @@ func displayIdx(id ...int) int {
}
// SysScale get the sys scale
func SysScale() float64 {
s := C.sys_scale()
func SysScale(displayId ...int) float64 {
display := displayIdx(displayId...)
s := C.sys_scale(C.int32_t(display))
return float64(s)
}
// Scaled get the screen scaled size
func Scaled(x int) int {
f := ScaleF()
func Scaled(x int, displayId ...int) int {
f := ScaleF(displayId...)
return Scaled0(x, f)
}
@ -271,7 +272,7 @@ func GetScreenRect(displayId ...int) Rect {
int(rect.size.w), int(rect.size.h)
if runtime.GOOS == "windows" {
f := ScaleF()
f := ScaleF(displayId...)
x, y, w, h = Scaled0(x, f), Scaled0(y, f), Scaled0(w, f), Scaled0(h, f)
}
return Rect{
@ -281,9 +282,9 @@ func GetScreenRect(displayId ...int) Rect {
}
// GetScaleSize get the screen scale size
func GetScaleSize() (int, int) {
func GetScaleSize(displayId ...int) (int, int) {
x, y := GetScreenSize()
f := ScaleF()
f := ScaleF(displayId...)
return int(float64(x) * f), int(float64(y) * f)
}

View File

@ -14,8 +14,8 @@
package robotgo
// ScaleF get the system scale val
func ScaleF() float64 {
f := SysScale()
func ScaleF(displayId ...int) float64 {
f := SysScale(displayId...)
if f == 0.0 {
f = 1.0
}

View File

@ -53,8 +53,13 @@ func SetFocus(hwnd win.HWND) win.HWND {
}
// ScaleF get the system scale val
func ScaleF() float64 {
f := float64(GetMainDPI()) / 96.0
func ScaleF(displayId ...int) (f float64) {
if len(displayId) > 0 && displayId[0] != -1 {
dpi := GetDPI(win.HWND(displayId[0]))
f = float64(dpi) / 96.0
} else {
f = float64(GetMainDPI()) / 96.0
}
if f == 0.0 {
f = 1.0
}

View File

@ -37,8 +37,8 @@ static int xmessage(char *argv[], int *exit_status);
kCFStringEncodingUTF8))
#endif
int showAlert(const char *title, const char *msg, const char *defaultButton,
const char *cancelButton)
int showAlert(const char *title, const char *msg,
const char *defaultButton, const char *cancelButton)
{
#if defined(IS_MACOSX)
CFStringRef alertHeader = CFStringCreateWithUTF8String(title);
@ -46,17 +46,9 @@ int showAlert(const char *title, const char *msg, const char *defaultButton,
CFStringRef defaultButtonTitle = CFStringCreateWithUTF8String(defaultButton);
CFStringRef cancelButtonTitle = CFStringCreateWithUTF8String(cancelButton);
CFOptionFlags responseFlags;
SInt32 err = CFUserNotificationDisplayAlert(0.0,
kCFUserNotificationNoteAlertLevel,
NULL,
NULL,
NULL,
alertHeader,
alertMessage,
defaultButtonTitle,
cancelButtonTitle,
NULL,
&responseFlags);
SInt32 err = CFUserNotificationDisplayAlert(
0.0, kCFUserNotificationNoteAlertLevel, NULL, NULL, NULL, alertHeader, alertMessage,
defaultButtonTitle, cancelButtonTitle, NULL, &responseFlags);
if (alertHeader != NULL) CFRelease(alertHeader);
if (alertMessage != NULL) CFRelease(alertMessage);

View File

@ -16,26 +16,15 @@
#endif
Bounds get_client(uintptr pid, uintptr isHwnd);
intptr scaleX();
intptr scaleX(){
#if defined(IS_MACOSX)
return 0;
#elif defined(USE_X11)
return 0;
#elif defined(IS_WINDOWS)
// Get desktop dc
HDC desktopDc = GetDC(NULL);
// Get native resolution
intptr horizontalDPI = GetDeviceCaps(desktopDc, LOGPIXELSX);
// intptr verticalDPI = GetDeviceCaps(desktopDc, LOGPIXELSY);
return horizontalDPI;
#endif
}
double sys_scale() {
double sys_scale(int32_t display_id) {
#if defined(IS_MACOSX)
CGDirectDisplayID displayID = CGMainDisplayID();
CGDirectDisplayID displayID = (CGDirectDisplayID) display_id;
if (displayID == -1) {
displayID = CGMainDisplayID();
}
CGDisplayModeRef modeRef = CGDisplayCopyDisplayMode(displayID);
double pixelWidth = CGDisplayModeGetPixelWidth(modeRef);
@ -43,14 +32,11 @@ double sys_scale() {
return pixelWidth / targetWidth;
#elif defined(USE_X11)
double xres;
Display *dpy;
char *displayname = NULL;
Display *dpy = XOpenDisplay(displayname);
int scr = 0; /* Screen number */
dpy = XOpenDisplay(displayname);
xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
double xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
((double) DisplayWidthMM(dpy, scr)));
// https://github.com/glfw/glfw/issues/1019#issuecomment-302772498
@ -79,6 +65,21 @@ double sys_scale() {
#endif
}
intptr scaleX(){
#if defined(IS_MACOSX)
return 0;
#elif defined(USE_X11)
return 0;
#elif defined(IS_WINDOWS)
// Get desktop dc
HDC desktopDc = GetDC(NULL);
// Get native resolution
intptr horizontalDPI = GetDeviceCaps(desktopDc, LOGPIXELSX);
// intptr verticalDPI = GetDeviceCaps(desktopDc, LOGPIXELSY);
return horizontalDPI;
#endif
}
intptr scaleY(){
#if defined(IS_MACOSX)
return 0;