Removed msc, macro and other C code

This commit is contained in:
vcaesar 2022-02-03 01:41:46 -08:00
parent 2d52e2c008
commit f0b614d78e
35 changed files with 182 additions and 897 deletions

View File

@ -5,23 +5,12 @@
#include "types.h"
#include "rgb.h"
#include <assert.h>
// #include <stdint.h>
#if defined(_MSC_VER)
#include "ms_stdint.h"
#else
#include <stdint.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
struct _MMBitmap {
uint8_t *imageBuffer; /* Pixels stored in Quad I format; i.e., origin is in
* top left. Length should be height * bytewidth. */
size_t width; /* Never 0, unless image is NULL. */
size_t height; /* Never 0, unless image is NULL. */
uint8_t *imageBuffer; /* Pixels stored in Quad I format; */
int32_t width; /* Never 0, unless image is NULL. */
int32_t height; /* Never 0, unless image is NULL. */
size_t bytewidth; /* The aligned width (width + padding). */
uint8_t bitsPerPixel; /* Should be either 24 or 32. */
uint8_t bytesPerPixel; /* For convenience; should be bitsPerPixel / 8. */
@ -29,65 +18,18 @@ struct _MMBitmap {
typedef struct _MMBitmap MMBitmap;
typedef MMBitmap *MMBitmapRef;
// MMBitmapRef bitmap;
/* Creates new MMBitmap with the given values.
* Follows the Create Rule (caller is responsible for destroy()'ing object). */
MMBitmapRef createMMBitmap_c(uint8_t *buffer, size_t width, size_t height,
size_t bytewidth, uint8_t bitsPerPixel,
uint8_t bytesPerPixel);
#define MMBitmapPointInBounds(image, p) ((p).x < (image)->width && (p).y < (image)->height)
/* Releases memory occupied by MMBitmap. */
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 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)
#define MMBitmapRectInBounds(image, r) \
(((r).origin.x + (r).size.width <= (image)->width) && \
((r).origin.y + (r).size.height <= (image)->height))
#define MMBitmapGetBounds(image) MMRectMake(0, 0, image->width, image->height)
/* Get pointer to pixel of MMBitmapRef. No bounds checking is performed (check
* yourself before calling this with MMBitmapPointInBounds(). */
#define MMRGBColorRefAtPoint(image, x, y) \
(MMRGBColor *)(assert(MMBitmapPointInBounds(image, MMPointMake(x, y))), \
((image)->imageBuffer) + (((image)->bytewidth * (y)) \
+ ((x) * (image)->bytesPerPixel)))
/* Get pointer to pixel of MMBitmapRef. No bounds checking is performed */
#define MMRGBColorRefAtPoint(image, x, y) ( \
MMRGBColor *)(assert(MMBitmapPointInBounds(image, MMPointInt32Make(x, y))), \
((image)->imageBuffer) + (((image)->bytewidth * (y)) + ((x) * (image)->bytesPerPixel)))
/* Dereference pixel of MMBitmapRef. Again, no bounds checking is performed. */
#define MMRGBColorAtPoint(image, x, y) *MMRGBColorRefAtPoint(image, x, y)
/* Hex/integer value of color at point. */
#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);
#ifdef __cplusplus
}
#endif
#define MMRGBHexAtPoint(image, x, y) hexFromMMRGB(MMRGBColorAtPoint(image, x, y))
#endif /* MMBITMAP_H */

2
base/base.go Normal file
View File

@ -0,0 +1,2 @@
// https://github.com/golang/go/issues/26366
package base

View File

@ -4,11 +4,7 @@
#include <stdint.h>
#define DEADBEEF_MAX UINT32_MAX
/* Dead Beef Random Number Generator
* From: http://inglorion.net/software/deadbeef_rand
* A fast, portable psuedo-random number generator by BJ Amsterdam Zuidoost.
* Stated in license terms: "Feel free to use the code in your own software." */
/* Dead Beef Random Number Generator From: http://inglorion.net/software/deadbeef_rand */
/* Generates a random number between 0 and DEADBEEF_MAX. */
uint32_t deadbeef_rand(void);
@ -22,14 +18,11 @@ uint32_t deadbeef_generate_seed(void);
/* Seeds with the above function. */
#define deadbeef_srand_time() deadbeef_srand(deadbeef_generate_seed())
/* Returns random double in the range [a, b).
* Taken directly from the rand() man page. */
/* Returns random double in the range [a, b).*/
#define DEADBEEF_UNIFORM(a, b) \
((a) + (deadbeef_rand() / (((double)DEADBEEF_MAX / (b - a) + 1))))
/* Returns random integer in the range [a, b).
* Also taken from the rand() man page. */
#define DEADBEEF_RANDRANGE(a, b) \
(uint32_t)DEADBEEF_UNIFORM(a, b)
/* Returns random integer in the range [a, b).*/
#define DEADBEEF_RANDRANGE(a, b) (uint32_t)DEADBEEF_UNIFORM(a, b)
#endif /* DEADBEEF_RAND_H */

View File

@ -15,8 +15,7 @@ void deadbeef_srand(uint32_t x) {
deadbeef_beef = 0xdeadbeef;
}
/* Taken directly from the documentation:
* http://inglorion.net/software/cstuff/deadbeef_rand/ */
/* Taken directly from the documentation: http://inglorion.net/software/cstuff/deadbeef_rand/ */
uint32_t deadbeef_generate_seed(void) {
uint32_t t = (uint32_t)time(NULL);
uint32_t c = (uint32_t)clock();

View File

@ -1,123 +0,0 @@
#pragma once
#ifndef ENDIAN_H
#define ENDIAN_H
#include "os.h"
/*
* (Mostly) cross-platform endian definitions and bit swapping macros.
* Unfortunately, there is no standard C header for this, so we just
* include the most common ones and fallback to our own custom macros.
*/
#if defined(__linux__) /* Linux */
#include <endian.h>
#include <byteswap.h>
#elif (defined(__FreeBSD__) && __FreeBSD_version >= 470000) || \
defined(__OpenBSD__) || defined(__NetBSD__) /* (Free|Open|Net)BSD */
#include <sys/endian.h>
#define __BIG_ENDIAN BIG_ENDIAN
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BYTE_ORDER BYTE_ORDER
#elif defined(IS_MACOSX) || (defined(BSD) && (BSD >= 199103)) /* Other BSD */
#include <machine/endian.h>
#define __BIG_ENDIAN BIG_ENDIAN
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BYTE_ORDER BYTE_ORDER
#elif defined(IS_WINDOWS) /* Windows is assumed to be little endian only. */
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
/* Fallback to custom constants. */
#if !defined(__BIG_ENDIAN)
#define __BIG_ENDIAN 4321
#endif
#if !defined(__LITTLE_ENDIAN)
#define __LITTLE_ENDIAN 1234
#endif
/* Prefer compiler flag settings if given. */
#if defined(MM_BIG_ENDIAN)
#undef __BYTE_ORDER /* Avoid redefined macro compiler warning. */
#define __BYTE_ORDER __BIG_ENDIAN
#elif defined(MM_LITTLE_ENDIAN)
#undef __BYTE_ORDER /* Avoid redefined macro compiler warning. */
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
/* Define default endian-ness. */
#ifndef __LITTLE_ENDIAN
#define __LITTLE_ENDIAN 1234
#endif /* __LITTLE_ENDIAN */
#ifndef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#endif /* __BIG_ENDIAN */
#ifndef __BYTE_ORDER
#warning "Byte order not defined on your system; assuming little endian"
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif /* __BYTE_ORDER */
#if __BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN
#error "__BYTE_ORDER set to unknown byte order"
#endif
#if defined(IS_MACOSX)
#include <libkern/OSByteOrder.h>
/* OS X system functions. */
#define bitswap16(i) OSSwapInt16(i)
#define bitswap32(i) OSSwapInt32(i)
#define swapLittleAndHost32(i) OSSwapLittleToHostInt32(i)
#define swapLittleAndHost16(i) OSSwapLittleToHostInt16(i)
#else
#ifndef bitswap16
#if defined(bswap16)
#define bitswap16(i) bswap16(i) /* FreeBSD system function */
#elif defined(bswap_16)
#define bitswap16(i) bswap_16(i) /* Linux system function */
#else /* Default macro */
#define bitswap16(i) (((uint16_t)(i) & 0xFF00) >> 8) | \
(((uint16_t)(i) & 0x00FF) << 8)
#endif
#endif /* bitswap16 */
#ifndef bitswap32
#if defined(bswap32)
#define bitswap32(i) bswap32(i) /* FreeBSD system function. */
#elif defined(bswap_32)
#define bitswap32(i) bswap_32(i) /* Linux system function. */
#else /* Default macro */
#define bitswap32(i) (((uint32_t)(i) & 0xFF000000) >> 24) | \
((uint32_t)((i) & 0x00FF0000) >> 8) | \
((uint32_t)((i) & 0x0000FF00) << 8) | \
((uint32_t)((i) & 0x000000FF) << 24)
#endif
#endif /* bitswap32 */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
/* Little endian to/from host byte order (big endian). */
#ifndef swapLittleAndHost16
#define swapLittleAndHost16(i) bitswap16(i)
#endif /* swapLittleAndHost16 */
#ifndef swapLittleAndHost32
#define swapLittleAndHost32(i) bitswap32(i)
#endif /* swapLittleAndHost32 */
#elif __BYTE_ORDER == __LITTLE_ENDIAN
/* We are already little endian, so no conversion is needed. */
#ifndef swapLittleAndHost16
#define swapLittleAndHost16(i) i
#endif /* swapLittleAndHost16 */
#ifndef swapLittleAndHost32
#define swapLittleAndHost32(i) i
#endif /* swapLittleAndHost32 */
#endif
#endif /* ENDIAN_H */

View File

@ -5,6 +5,7 @@
#include "os.h"
#include "inline_keywords.h"
// todo: removed
#if !defined(IS_WINDOWS)
/* Make sure nanosleep gets defined even when using C89. */
#if !defined(__USE_POSIX199309) || !__USE_POSIX199309
@ -14,21 +15,12 @@
#include <time.h> /* For nanosleep() */
#endif
/*
* A more widely supported alternative to usleep(), based on Sleep() in Windows
* and nanosleep() everywhere else.
*
* Pauses execution for the given amount of milliseconds.
*/
/* A more widely supported alternative to usleep(), based on Sleep() in Windows and nanosleep() */
H_INLINE void microsleep(double milliseconds) {
#if defined(IS_WINDOWS)
Sleep((DWORD)milliseconds); /* (Unfortunately truncated to a 32-bit integer.) */
#else
/* Technically, nanosleep() is not an ANSI function, but it is the most
* supported precise sleeping function I can find.
*
* If it is really necessary, it may be possible to emulate this with some
* hack using select() in the future if we really have to. */
/* Technically, nanosleep() is not an ANSI function */
struct timespec sleepytime;
sleepytime.tv_sec = milliseconds / 1000;
sleepytime.tv_nsec = (milliseconds - (sleepytime.tv_sec * 1000)) * 1000000;

View File

@ -1,25 +0,0 @@
#pragma once
#if !defined(MS_STDBOOL_H) && \
(!defined(__bool_true_false_are_defined) || __bool_true_false_are_defined)
#define MS_STDBOOL_H
#ifndef _MSC_VER
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif /* _MSC_VER */
#define __bool_true_false_are_defined 1
#ifndef __cplusplus
#if defined(true) || defined(false) || defined(bool)
#error "Boolean type already defined"
#endif
enum {
false = 0,
true = 1
};
typedef unsigned char bool;
#endif /* !__cplusplus */
#endif /* MS_STDBOOL_H */

View File

@ -1,224 +0,0 @@
/* ISO C9x compliant stdint.h for Microsoft Visual Studio
* Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
*
* Copyright (c) 2006-2008 Alexander Chemeris
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MSC_VER
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif /* _MSC_VER */
#ifndef MSC_STDINT_H
#define MSC_STDINT_H
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
/* For Visual Studio 6 in C++ mode and for many Visual Studio versions when
* compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
* or compiler give many errors like this: */
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
#include <wchar.h>
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/* Define _W64 macros to mark types changing their size, like intptr_t. */
#ifndef _W64
#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
#define _W64 __w64
#else
#define _W64
#endif
#endif
/* 7.18.1 Integer types */
/* 7.18.1.1 Exact-width integer types */
/* Visual Studio 6 and Embedded Visual C++ 4 doesn't
* realize that, e.g. char has the same size as __int8
* so we give up on __intX for them. */
#if _MSC_VER < 1300
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
/* 7.18.1.2 Minimum-width integer types */
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
/* 7.18.1.3 Fastest minimum-width integer types */
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
/* 7.18.1.4 Integer types capable of holding object pointers */
#if defined(_WIN64)
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif /* _WIN64 ] */
/* 7.18.1.5 Greatest-width integer types */
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
/* 7.18.2 Limits of specified-width integer types */
/* See footnote 220 at page 257 and footnote 221 at page 259 */
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
/* 7.18.2.1 Limits of exact-width integer types */
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
/* 7.18.2.2 Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
/* 7.18.2.4 Limits of integer types capable of holding object pointers */
#if defined(_WIN64)
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif
/* 7.18.3 Limits of other integer types */
#if defined(_WIN64)
#define PTRDIFF_MIN _I64_MIN
#define PTRDIFF_MAX _I64_MAX
#else
#define PTRDIFF_MIN _I32_MIN
#define PTRDIFF_MAX _I32_MAX
#endif /* _WIN64 */
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX
#if defined(_WIN64)
#define SIZE_MAX _UI64_MAX
#else
#define SIZE_MAX _UI32_MAX
#endif
#endif
/* WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> */
#ifndef WCHAR_MIN
#define WCHAR_MIN 0
#endif /* WCHAR_MIN */
#ifndef WCHAR_MAX
#define WCHAR_MAX _UI16_MAX
#endif /* WCHAR_MAX */
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif /* __STDC_LIMIT_MACROS */
/* 7.18.4 Limits of other integer types */
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) /* See footnote 224 at page 260 */
/* 7.18.4.1 Macros for minimum-width integer constants */
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
/* 7.18.4.2 Macros for greatest-width integer constants */
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif /* __STDC_CONSTANT_MACROS */
#endif /* MSC_STDINT_H */

View File

@ -14,7 +14,7 @@
#endif /* IS_MACOSX */
#if !defined(IS_WINDOWS) && (defined(WIN32) || defined(_WIN32) || \
defined(__WIN32__) || defined(__WINDOWS__) || defined(__CYGWIN__))
defined(__WIN32__) || defined(__WINDOWS__) || defined(__CYGWIN__))
#define IS_WINDOWS
#endif /* IS_WINDOWS */

View File

@ -5,20 +5,7 @@
#include <stdlib.h> /* For abs() */
#include <math.h>
#include "inline_keywords.h" /* For H_INLINE */
// #include <stdint.h>
#if defined(_MSC_VER)
#include "ms_stdint.h"
#else
#include <stdint.h>
#endif
/* RGB colors in MMBitmaps are stored as BGR for convenience in converting
* to/from certain formats (mainly OpenGL).
*
* It is best not to rely on the order (simply use rgb.{blue,green,red} to
* access values), but some situations (e.g., glReadPixels) require one to
* do so. In that case, check to make sure to use MMRGB_IS_BGR for future
* compatibility. */
#include <stdint.h>
/* #define MMRGB_IS_BGR (offsetof(MMRGBColor, red) > offsetof(MMRGBColor, blue)) */
#define MMRGB_IS_BGR 1
@ -28,20 +15,15 @@ struct _MMRGBColor {
uint8_t green;
uint8_t red;
};
typedef struct _MMRGBColor MMRGBColor;
/* MMRGBHex is a hexadecimal color value, akin to HTML's, in the form 0xRRGGBB
* where RR is the red value expressed as hexadecimal, GG is the green value,
* and BB is the blue value. */
/* MMRGBHex is a hexadecimal color value*/
typedef uint32_t MMRGBHex;
#define MMRGBHEX_MIN 0x000000
#define MMRGBHEX_MAX 0xFFFFFF
/* Converts rgb color to hexadecimal value.
* |red|, |green|, and |blue| should each be of the type |uint8_t|, where the
* range is 0 - 255. */
/* Converts rgb color to hexadecimal value. */
#define RGB_TO_HEX(red, green, blue) (((red) << 16) | ((green) << 8) | (blue))
/* Convenience wrapper for MMRGBColors. */
@ -67,9 +49,7 @@ H_INLINE MMRGBColor MMRGBFromHex(MMRGBHex hex) {
(c1).blue == (c2).blue && \
(c1).green == (c2).green)
/* Returns whether two colors are similar within the given range, |tolerance|.
* Tolerance can be in the range 0.0f - 1.0f, where 0 denotes the exact
* color and 1 denotes any color. */
/* Returns whether two colors are similar within the given range, |tolerance|.*/
H_INLINE int MMRGBColorSimilarToColor(MMRGBColor c1, MMRGBColor c2, float tolerance) {
/* Speedy case */
if (tolerance <= 0.0f) {
@ -78,8 +58,7 @@ H_INLINE int MMRGBColorSimilarToColor(MMRGBColor c1, MMRGBColor c2, float tolera
uint8_t d1 = c1.red - c2.red;
uint8_t d2 = c1.green - c2.green;
uint8_t d3 = c1.blue - c2.blue;
return sqrt((double)(d1 * d1) +
(d2 * d2) +
return sqrt((double)(d1 * d1) + (d2 * d2) +
(d3 * d3)) <= (tolerance * 442.0f);
}
}
@ -89,14 +68,10 @@ H_INLINE int MMRGBHexSimilarToColor(MMRGBHex h1, MMRGBHex h2, float tolerance) {
if (tolerance <= 0.0f) {
return h1 == h2;
} else {
// uint8_t d1 = RED_FROM_HEX(h1) - RED_FROM_HEX(h2);
// uint8_t d2 = GREEN_FROM_HEX(h1) - GREEN_FROM_HEX(h2);
// uint8_t d3 = BLUE_FROM_HEX(h1) - BLUE_FROM_HEX(h2);
int d1 = RED_FROM_HEX(h1) - RED_FROM_HEX(h2);
int d2 = GREEN_FROM_HEX(h1) - GREEN_FROM_HEX(h2);
int d3 = BLUE_FROM_HEX(h1) - BLUE_FROM_HEX(h2);
return sqrt((double)(d1 * d1) +
(d2 * d2) +
return sqrt((double)(d1 * d1) + (d2 * d2) +
(d3 * d3)) <= (tolerance * 442.0f);
}
}

View File

@ -16,49 +16,24 @@
typedef uint32_t uintptr; // Unsigned pointer integer
#endif
struct _MMPoint {
size_t x;
size_t y;
};
typedef struct _MMPoint MMPoint;
struct _MMPointInt32 {
int32_t x;
int32_t y;
};
typedef struct _MMPointInt32 MMPointInt32;
struct _MMSize {
size_t width;
size_t height;
};
typedef struct _MMSize MMSize;
struct _MMSizeInt32 {
int32_t w;
int32_t h;
};
typedef struct _MMSizeInt32 MMSizeInt32;
struct _MMRect {
MMPoint origin;
MMSize size;
};
typedef struct _MMRect MMRect;
struct _MMRectInt32 {
MMPointInt32 origin;
MMSizeInt32 size;
};
typedef struct _MMRectInt32 MMRectInt32;
H_INLINE MMPoint MMPointMake(size_t x, size_t y) {
MMPoint point;
point.x = x;
point.y = y;
return point;
}
H_INLINE MMPointInt32 MMPointInt32Make(int32_t x, int32_t y) {
MMPointInt32 point;
point.x = x;
@ -66,13 +41,6 @@ H_INLINE MMPointInt32 MMPointInt32Make(int32_t x, int32_t y) {
return point;
}
H_INLINE MMSize MMSizeMake(size_t width, size_t height) {
MMSize size;
size.width = width;
size.height = height;
return size;
}
H_INLINE MMSizeInt32 MMSizeInt32Make(int32_t w, int32_t h) {
MMSizeInt32 size;
size.w = w;
@ -80,13 +48,6 @@ H_INLINE MMSizeInt32 MMSizeInt32Make(int32_t w, int32_t h) {
return size;
}
H_INLINE MMRect MMRectMake(size_t x, size_t y, size_t width, size_t height) {
MMRect rect;
rect.origin = MMPointMake(x, y);
rect.size = MMSizeMake(width, height);
return rect;
}
H_INLINE MMRectInt32 MMRectInt32Make(int32_t x, int32_t y, int32_t w, int32_t h) {
MMRectInt32 rect;
rect.origin = MMPointInt32Make(x, y);
@ -94,13 +55,9 @@ H_INLINE MMRectInt32 MMRectInt32Make(int32_t x, int32_t y, int32_t w, int32_t h)
return rect;
}
//
#define MMPointZero MMPointMake(0, 0)
#define MMPointZero MMPointInt32Make(0, 0)
#if defined(IS_MACOSX)
#define CGPointFromMMPoint(p) CGPointMake((CGFloat)(p).x, (CGFloat)(p).y)
#define MMPointFromCGPoint(p) MMPointMake((size_t)(p).x, (size_t)(p).y)
#define CGPointFromMMPointInt32(p) CGPointMake((CGFloat)(p).x, (CGFloat)(p).y)
#define MMPointInt32FromCGPoint(p) MMPointInt32Make((int32_t)(p).x, (int32_t)(p).y)
#elif defined(IS_WINDOWS)

View File

@ -1,29 +0,0 @@
#pragma once
#ifndef XDISPLAY_H
#define XDISPLAY_H
#include <X11/Xlib.h>
/* Returns the main display, closed either on exit or when closeMainDisplay()
* is invoked. This removes a bit of the overhead of calling XOpenDisplay() &
* XCloseDisplay() everytime the main display needs to be used.
*
* Note that this is almost certainly not thread safe. */
Display *XGetMainDisplay(void);
/* Closes the main display if it is open, or does nothing if not. */
void XCloseMainDisplay(void);
#ifdef __cplusplus
extern "C"
{
#endif
char *getXDisplay(void);
void setXDisplay(char *name);
#ifdef __cplusplus
}
#endif
#endif /* XDISPLAY_H */

View File

@ -1,6 +1,6 @@
#include "xdisplay.h"
#include <stdio.h> /* For fputs() */
#include <stdlib.h> /* For atexit() */
#include <X11/Xlib.h>
static Display *mainDisplay = NULL;
static int registered = 0;
@ -55,4 +55,3 @@ void setXDisplay(char *name) {
char *getXDisplay(void) {
return displayName;
}

4
key.go
View File

@ -511,7 +511,9 @@ func KeyDown(key string, args ...string) error {
// KeyUp press up a key
func KeyUp(key string, args ...string) error {
return KeyToggle(key, append(args, "up")...)
arr := []string{"up"}
arr = append(arr, args...)
return KeyToggle(key, arr...)
}
// ReadAll read string from clipboard

View File

@ -2,7 +2,5 @@
#include <stdlib.h>
#include "../base/types.h"
// #include "keycode.h"
// #include "keypress.h"
#include "keypress_c.h"
#include "keycode_c.h"

11
key/key.go Normal file
View File

@ -0,0 +1,11 @@
// 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.
package key

4
key/key_windows.go Normal file
View File

@ -0,0 +1,4 @@
//go:build windows
// +build windows
package key

View File

@ -4,11 +4,6 @@
#include "../base/os.h"
#ifdef __cplusplus
extern "C"
{
#endif
#if defined(IS_MACOSX)
#include <Carbon/Carbon.h> /* Really only need <HIToolbox/Events.h> */
@ -406,7 +401,3 @@ typedef int MMKeyCode;
MMKeyCode keyCodeForChar(const char c);
#endif /* KEYCODE_H */
#ifdef __cplusplus
}
#endif

View File

@ -4,16 +4,13 @@
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h> /* For kVK_ constants, and TIS functions. */
/* Returns string representation of key, if it is printable.
* Ownership follows the Create Rule; that is, it is the caller's
* responsibility to release the returned object. */
/* Returns string representation of key, if it is printable. */
CFStringRef createStringForKey(CGKeyCode keyCode);
#endif
MMKeyCode keyCodeForChar(const char c) {
#if defined(IS_MACOSX)
/* OS X does not appear to have a built-in function for this, so instead we
* have to write our own. */
/* OS X does not appear to have a built-in function for this, so instead it. */
static CFMutableDictionaryRef charToCodeDict = NULL;
CGKeyCode code;
UniChar character = c;
@ -58,17 +55,13 @@ MMKeyCode keyCodeForChar(const char c) {
return code;
#elif defined(USE_X11)
MMKeyCode code;
char buf[2];
buf[0] = c;
buf[1] = '\0';
code = XStringToKeysym(buf);
MMKeyCode code = XStringToKeysym(buf);
if (code == NoSymbol) {
/* Some special keys are apparently not handled properly by
* XStringToKeysym() on some systems, so search for them instead in our
* mapping table. */
/* Some special keys are apparently not handled properly */
struct XSpecialCharacterMapping* xs = XSpecialCharacterTable;
while (xs->name) {
if (c == xs->name) {

View File

@ -4,17 +4,7 @@
#include "../base/os.h"
#include "keycode.h"
#if defined(_MSC_VER)
#include "../base/ms_stdbool.h"
#else
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdbool.h>
#if defined(IS_MACOSX)
typedef enum {
@ -32,7 +22,6 @@ extern "C"
MOD_CONTROL = ControlMask,
MOD_SHIFT = ShiftMask
};
typedef unsigned int MMKeyFlags;
#elif defined(IS_WINDOWS)
enum _MMKeyFlags {
@ -43,43 +32,12 @@ extern "C"
MOD_SHIFT = 0, */
MOD_META = MOD_WIN
};
typedef unsigned int MMKeyFlags;
#endif
#if defined(IS_WINDOWS)
/* Send win32 key event for given key. */
void win32KeyEvent(int key, MMKeyFlags flags);
#endif
/* Toggles the given key down or up. */
void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags);
/* Toggles the key down and then up. */
void tapKeyCode(MMKeyCode code, MMKeyFlags flags);
/* Toggles the key corresponding to the given UTF character up or down. */
void toggleKey(char c, const bool down, MMKeyFlags flags);
void tapKey(char c, MMKeyFlags flags);
/* Sends a UTF-8 string without modifiers. */
void typeString(const char *str);
/* Sends a Unicode character without modifiers. */
void unicodeType(const unsigned value);
/* Macro to convert WPM to CPM integers.
* (the average English word length is 5.1 characters.) */
#define WPM_TO_CPM(WPM) (unsigned)(5.1 * WPM)
/* Sends UTF-8 string without modifiers and
* with partially random delays between each letter.
* Note that deadbeef_srand() must be called before this function
* if you actually want randomness.
* */
void typeStringDelayed(const char *str, const unsigned cpm);
#ifdef __cplusplus
}
/* Send win32 key event for given key. */
void win32KeyEvent(int key, MMKeyFlags flags);
#endif
#endif /* KEYPRESS_H */

View File

@ -14,14 +14,20 @@
/* Convenience wrappers around ugly APIs. */
#if defined(IS_WINDOWS)
#define WIN32_KEY_EVENT_WAIT(key, flags) \
(win32KeyEvent(key, flags), Sleep(DEADBEEF_RANDRANGE(0, 1)))
void WIN32_KEY_EVENT_WAIT(MMKeyCode key, DWORD flags) {
win32KeyEvent(key, flags);
Sleep(DEADBEEF_RANDRANGE(0, 1));
}
#elif defined(USE_X11)
#define X_KEY_EVENT(display, key, is_press) ( \
XTestFakeKeyEvent(display, XKeysymToKeycode(display, key), is_press, CurrentTime), \
XSync(display, false))
#define X_KEY_EVENT_WAIT(display, key, is_press) ( \
X_KEY_EVENT(display, key, is_press), microsleep(DEADBEEF_UNIFORM(0.0, 0.5)))
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);
}
#endif
#if defined(IS_MACOSX)
@ -143,10 +149,10 @@ void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags) {
const DWORD dwFlags = down ? 0 : KEYEVENTF_KEYUP;
/* Parse modifier keys. */
if (flags & MOD_META) WIN32_KEY_EVENT_WAIT(K_META, dwFlags);
if (flags & MOD_ALT) WIN32_KEY_EVENT_WAIT(K_ALT, dwFlags);
if (flags & MOD_CONTROL) WIN32_KEY_EVENT_WAIT(K_CONTROL, dwFlags);
if (flags & MOD_SHIFT) WIN32_KEY_EVENT_WAIT(K_SHIFT, dwFlags);
if (flags & MOD_META) { WIN32_KEY_EVENT_WAIT(K_META, dwFlags); }
if (flags & MOD_ALT) { WIN32_KEY_EVENT_WAIT(K_ALT, dwFlags); }
if (flags & MOD_CONTROL) { WIN32_KEY_EVENT_WAIT(K_CONTROL, dwFlags); }
if (flags & MOD_SHIFT) { WIN32_KEY_EVENT_WAIT(K_SHIFT, dwFlags); }
win32KeyEvent(code, dwFlags);
#elif defined(USE_X11)
@ -154,10 +160,10 @@ void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags) {
const Bool is_press = down ? True : False; /* Just to be safe. */
/* Parse modifier keys. */
if (flags & MOD_META) X_KEY_EVENT_WAIT(display, K_META, is_press);
if (flags & MOD_ALT) X_KEY_EVENT_WAIT(display, K_ALT, is_press);
if (flags & MOD_CONTROL) X_KEY_EVENT_WAIT(display, K_CONTROL, is_press);
if (flags & MOD_SHIFT) X_KEY_EVENT_WAIT(display, K_SHIFT, is_press);
if (flags & MOD_META) { X_KEY_EVENT_WAIT(display, K_META, is_press); }
if (flags & MOD_ALT) { X_KEY_EVENT_WAIT(display, K_ALT, is_press); }
if (flags & MOD_CONTROL) { X_KEY_EVENT_WAIT(display, K_CONTROL, is_press); }
if (flags & MOD_SHIFT) { X_KEY_EVENT_WAIT(display, K_SHIFT, is_press); }
X_KEY_EVENT(display, code, is_press);
#endif
@ -206,9 +212,9 @@ void toggleKey(char c, const bool down, MMKeyFlags flags){
#if defined(IS_WINDOWS)
modifiers = keyCode >> 8; // Pull out modifers.
if ((modifiers & 1) != 0) flags |= MOD_SHIFT; // Uptdate flags from keycode modifiers.
if ((modifiers & 2) != 0) flags |= MOD_CONTROL;
if ((modifiers & 4) != 0) flags |= MOD_ALT;
if ((modifiers & 1) != 0) { flags |= MOD_SHIFT; } // Uptdate flags from keycode modifiers.
if ((modifiers & 2) != 0) { flags |= MOD_CONTROL; }
if ((modifiers & 4) != 0) { flags |= MOD_ALT; }
keyCode = keyCode & 0xff; // Mask out modifiers.
#endif
@ -222,12 +228,11 @@ void tapKey(char c, MMKeyFlags flags){
}
#if defined(IS_MACOSX)
void toggleUnicode(UniChar ch, const bool down){
/* This function relies on the convenient
* CGEventKeyboardSetUnicodeString(), which allows us to not have to
* convert characters to a keycode, but does not support adding modifier
* flags. It is therefore only used in typeStringDelayed()
* -- if you need modifier keys, use the above functions instead. */
void toggleUnicode(UniChar ch, const bool down) {
/* This function relies on the convenient CGEventKeyboardSetUnicodeString(),
convert characters to a keycode, but does not support adding modifier flags.
It is only used in typeString().
-- if you need modifier keys, use the above functions instead. */
CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, 0, down);
if (keyEvent == NULL) {
fputs("Could not create keyboard event.\n", stderr);

11
mouse/mouse.go Normal file
View File

@ -0,0 +1,11 @@
// 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.
package mouse

View File

@ -4,24 +4,10 @@
#include "../base/os.h"
#include "../base/types.h"
#if defined(_MSC_VER)
#include "../base/ms_stdbool.h"
#else
#include <stdbool.h>
#endif
#ifdef __cplusplus
// #ifdefined(__cplusplus)||defined(c_plusplus)
extern "C"
{
#endif
#include <stdbool.h>
#if defined(IS_MACOSX)
// #include </System/Library/Frameworks/ApplicationServices.framework/Headers/ApplicationServices.h>
#include <ApplicationServices/ApplicationServices.h>
// #include </System/Library/Frameworks/ApplicationServices.framework/Versions/A/Headers/ApplicationServices.h>
typedef enum {
LEFT_BUTTON = kCGMouseButtonLeft,
@ -32,9 +18,7 @@ extern "C"
WheelLeft = 6,
WheelRight = 7,
} MMMouseButton;
#elif defined(USE_X11)
enum _MMMouseButton {
LEFT_BUTTON = 1,
CENTER_BUTTON = 2,
@ -45,9 +29,7 @@ extern "C"
WheelRight = 7,
};
typedef unsigned int MMMouseButton;
#elif defined(IS_WINDOWS)
enum _MMMouseButton {
LEFT_BUTTON = 1,
CENTER_BUTTON = 2,
@ -58,62 +40,14 @@ extern "C"
WheelRight = 7,
};
typedef unsigned int MMMouseButton;
#else
#error "No mouse button constants set for platform"
#endif
#define MMMouseButtonIsValid(button) \
(button == LEFT_BUTTON || button == RIGHT_BUTTON || \
button == CENTER_BUTTON || button == WheelDown || \
button == WheelUp || button == WheelLeft || \
button == WheelRight)
enum __MMMouseWheelDirection {
DIRECTION_DOWN = -1,
DIRECTION_UP = 1
};
typedef int MMMouseWheelDirection;
/* Immediately moves the mouse to the given point on-screen.
* It is up to the caller to ensure that this point is within the
* screen boundaries. */
void moveMouse(MMPointInt32 point);
/* Like moveMouse, moves the mouse to the given point on-screen, but marks
* the event as the mouse being dragged on platforms where it is supported.
* It is up to the caller to ensure that this point is within the screen
* boundaries. */
void dragMouse(MMPointInt32 point, const MMMouseButton button);
/* Smoothly moves the mouse from the current position to the given point.
* deadbeef_srand() should be called before using this function.
*
* Returns false if unsuccessful (i.e. a point was hit that is outside of the
* screen boundaries), or true if successful. */
bool smoothlyMoveMouse(MMPointInt32 endPoint, double lowSpeed, double highSpeed);
// bool smoothlyMoveMouse(MMPoint point);
/* Returns the coordinates of the mouse on the current screen. */
MMPointInt32 getMousePos(void);
/* Holds down or releases the mouse with the given button in the current
* position. */
void toggleMouse(bool down, MMMouseButton button);
/* Clicks the mouse with the given button in the current position. */
void clickMouse(MMMouseButton button);
/* Double clicks the mouse with the given button. */
void doubleClick(MMMouseButton button);
/* Scrolls the mouse in the stated direction.
* TODO: Add a smoothly scroll mouse next. */
void scrollMouse(int scrollMagnitude, MMMouseWheelDirection scrollDirection);
//#ifdefined(__cplusplus)||defined(c_plusplus)
#ifdef __cplusplus
}
#endif
#endif /* MOUSE_H */

View File

@ -3,7 +3,6 @@
#include "../base/microsleep.h"
#include <math.h> /* For floor() */
#if defined(IS_MACOSX)
// #include </System/Library/Frameworks/ApplicationServices.framework/Headers/ApplicationServices.h>
#include <ApplicationServices/ApplicationServices.h>
@ -12,58 +11,61 @@
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <stdlib.h>
// #include "../base/xdisplay_c.h"
#endif
#if !defined(M_SQRT2)
#define M_SQRT2 1.4142135623730950488016887 /* Fix for MSVC. */
#endif
/* Some convenience macros for converting our enums to the system API types. */
#if defined(IS_MACOSX)
CGEventType MMMouseDownToCGEventType(MMMouseButton button) {
if (button == LEFT_BUTTON) {
return kCGEventLeftMouseDown;
}
if (button == RIGHT_BUTTON) {
return kCGEventRightMouseDown;
}
return kCGEventOtherMouseDown;
}
#define MMMouseToCGEventType(down, button) \
(down ? MMMouseDownToCGEventType(button) : MMMouseUpToCGEventType(button))
CGEventType MMMouseUpToCGEventType(MMMouseButton button) {
if (button == LEFT_BUTTON) { return kCGEventLeftMouseUp; }
if (button == RIGHT_BUTTON) { return kCGEventRightMouseUp; }
return kCGEventOtherMouseUp;
}
#define MMMouseDownToCGEventType(button) \
((button) == (LEFT_BUTTON) ? kCGEventLeftMouseDown \
: ((button) == RIGHT_BUTTON ? kCGEventRightMouseDown : kCGEventOtherMouseDown))
CGEventType MMMouseDragToCGEventType(MMMouseButton button) {
if (button == LEFT_BUTTON) { return kCGEventLeftMouseDragged; }
if (button == RIGHT_BUTTON) { return kCGEventRightMouseDragged; }
return kCGEventOtherMouseDragged;
}
#define MMMouseUpToCGEventType(button) \
((button) == LEFT_BUTTON ? kCGEventLeftMouseUp \
: ((button) == RIGHT_BUTTON ? kCGEventRightMouseUp : kCGEventOtherMouseUp))
#define MMMouseDragToCGEventType(button) \
((button) == LEFT_BUTTON ? kCGEventLeftMouseDragged \
: ((button) == RIGHT_BUTTON ? kCGEventRightMouseDragged : kCGEventOtherMouseDragged))
CGEventType MMMouseToCGEventType(bool down, MMMouseButton button) {
if (down) { return MMMouseDownToCGEventType(button); }
return MMMouseUpToCGEventType(button);
}
#elif defined(IS_WINDOWS)
DWORD MMMouseUpToMEventF(MMMouseButton button) {
if (button == LEFT_BUTTON) { return MOUSEEVENTF_LEFTUP; }
if (button == RIGHT_BUTTON) { return MOUSEEVENTF_RIGHTUP; }
return MOUSEEVENTF_MIDDLEUP;
}
#define MMMouseToMEventF(down, button) \
(down ? MMMouseDownToMEventF(button) : MMMouseUpToMEventF(button))
#define MMMouseUpToMEventF(button) \
((button) == LEFT_BUTTON ? MOUSEEVENTF_LEFTUP \
: ((button) == RIGHT_BUTTON ? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_MIDDLEUP))
#define MMMouseDownToMEventF(button) \
((button) == LEFT_BUTTON ? MOUSEEVENTF_LEFTDOWN \
: ((button) == RIGHT_BUTTON ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_MIDDLEDOWN))
DWORD MMMouseDownToMEventF(MMMouseButton button) {
if (button == LEFT_BUTTON) { return MOUSEEVENTF_LEFTDOWN; }
if (button == RIGHT_BUTTON) { return MOUSEEVENTF_RIGHTDOWN; }
return MOUSEEVENTF_MIDDLEDOWN;
}
DWORD MMMouseToMEventF(bool down, MMMouseButton button) {
if (down) { return MMMouseDownToMEventF(button); }
return MMMouseUpToMEventF(button);
}
#endif
#if defined(IS_MACOSX)
/**
* Calculate the delta for a mouse move and add them to the event.
* @param event The mouse move event (by ref).
* @param point The new mouse x and y.
*/
/* Calculate the delta for a mouse move and add them to the event. */
void calculateDeltas(CGEventRef *event, MMPointInt32 point){
/**
* The next few lines are a workaround for games not detecting mouse moves.
* See this issue for more information:
* https://github.com/go-vgo/robotgo/issues/159
*/
/* The next few lines are a workaround for games not detecting mouse moves. */
CGEventRef get = CGEventCreate(NULL);
CGPoint mouse = CGEventGetLocation(get);
@ -78,11 +80,7 @@ void calculateDeltas(CGEventRef *event, MMPointInt32 point){
}
#endif
/**
* Move the mouse to a specific point.
* @param point The coordinates to move the mouse to (x, y).
*/
/* Move the mouse to a specific point. */
void moveMouse(MMPointInt32 point){
#if defined(IS_MACOSX)
CGEventRef move = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved,
@ -117,7 +115,6 @@ void moveMouse(MMPointInt32 point){
mouseInput.mi.dwExtraInfo = 0;
mouseInput.mi.mouseData = 0;
SendInput(1, &mouseInput, sizeof(mouseInput));
#endif
}
@ -136,7 +133,7 @@ void dragMouse(MMPointInt32 point, const MMMouseButton button){
#endif
}
MMPointInt32 getMousePos(){
MMPointInt32 getMousePos() {
#if defined(IS_MACOSX)
CGEventRef event = CGEventCreate(NULL);
CGPoint point = CGEventGetLocation(event);
@ -144,9 +141,9 @@ MMPointInt32 getMousePos(){
return MMPointInt32FromCGPoint(point);
#elif defined(USE_X11)
int x, y; /* This is all we care about. Seriously. */
Window garb1, garb2; /* Why you can't specify NULL as a parameter */
int garb_x, garb_y; /* is beyond me. */
int x, y; /* This is all we care about. Seriously. */
Window garb1, garb2; /* Why you can't specify NULL as a parameter */
int garb_x, garb_y; /* is beyond me. */
unsigned int more_garbage;
Display *display = XGetMainDisplay();
@ -157,17 +154,12 @@ MMPointInt32 getMousePos(){
#elif defined(IS_WINDOWS)
POINT point;
GetCursorPos(&point);
return MMPointInt32FromPOINT(point);
#endif
}
/**
* Press down a button, or release it.
* @param down True for down, false for up.
* @param button The button to press down or release.
*/
void toggleMouse(bool down, MMMouseButton button){
/* Press down a button, or release it. */
void toggleMouse(bool down, MMMouseButton button) {
#if defined(IS_MACOSX)
const CGPoint currentPos = CGPointFromMMPoint(getMousePos());
const CGEventType mouseType = MMMouseToCGEventType(down, button);
@ -200,10 +192,7 @@ void clickMouse(MMMouseButton button){
toggleMouse(false, button);
}
/**
* Special function for sending double clicks, needed for Mac OS X.
* @param button Button to click.
*/
/* Special function for sending double clicks, needed for Mac OS X. */
void doubleClick(MMMouseButton button){
#if defined(IS_MACOSX)
/* Double click for Mac. */
@ -229,20 +218,14 @@ void doubleClick(MMMouseButton button){
#endif
}
/**
* Function used to scroll the screen in the required direction.
* This uses the magnitude to scroll the required amount in the direction.
* TODO Requires further fine tuning based on the requirements.
*/
/* Function used to scroll the screen in the required direction. */
void scrollMouse(int scrollMagnitude, MMMouseWheelDirection scrollDirection){
#if defined(IS_WINDOWS)
// Fix for #97 https://github.com/go-vgo/robotgo/issues/97,
// 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. */
/* 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;
@ -250,7 +233,6 @@ void scrollMouse(int scrollMagnitude, MMMouseWheelDirection scrollDirection){
/* Set up the OS specific solution */
#if defined(__APPLE__)
CGWheelCount wheel = 1;
CGEventRef event;
@ -289,15 +271,12 @@ void scrollMouse(int scrollMagnitude, MMMouseWheelDirection scrollDirection){
void scrollMouseXY(int x, int y) {
#if defined(IS_WINDOWS)
// Fix for #97,
// C89 needs variables declared on top of functions (mouseScrollInput)
// Fix for #97, C89 needs variables declared on top of functions (mouseScrollInput)
INPUT mouseScrollInputH;
INPUT mouseScrollInputV;
#endif
/* Direction should only be considered based on the scrollDirection. This
* Should not interfere. */
/* Direction should only be considered based on the scrollDirection. This Should not interfere. */
/* Set up the OS specific solution */
#if defined(__APPLE__)
CGEventRef event;
@ -317,8 +296,7 @@ void scrollMouseXY(int x, int y) {
xdir = 7;
}
int xi;
int yi;
int xi; int yi;
for (xi = 0; xi < abs(x); xi++) {
XTestFakeButtonEvent(display, xdir, 1, CurrentTime);
XTestFakeButtonEvent(display, xdir, 0, CurrentTime);
@ -351,16 +329,11 @@ void scrollMouseXY(int x, int y) {
#endif
}
/*
* A crude, fast hypot() approximation to get around the fact that hypot() is
* not a standard ANSI C function.
*
* It is not particularly accurate but that does not matter for our use case.
*
* Taken from this StackOverflow answer:
* http://stackoverflow.com/questions/3506404/fast-hypotenuse-algorithm-for-embedded-processor#3507882
*
*/
/* A crude, fast hypot() approximation to get around the fact that hypot() is not a standard ANSI C function. */
#if !defined(M_SQRT2)
#define M_SQRT2 1.4142135623730950488016887 /* Fix for MSVC. */
#endif
static double crude_hypot(double x, double y){
double big = fabs(x); /* max(|x|, |y|) */
double small = fabs(y); /* min(|x|, |y|) */
@ -381,7 +354,6 @@ bool smoothlyMoveMouse(MMPointInt32 endPoint, double lowSpeed, double highSpeed)
double distance;
while ((distance =crude_hypot((double)pos.x - endPoint.x, (double)pos.y - endPoint.y)) > 1.0) {
double gravity = DEADBEEF_UNIFORM(5.0, 500.0);
// double gravity = DEADBEEF_UNIFORM(lowSpeed, highSpeed);
double veloDistance;
@ -396,12 +368,10 @@ bool smoothlyMoveMouse(MMPointInt32 endPoint, double lowSpeed, double highSpeed)
pos.x += floor(velo_x + 0.5);
pos.y += floor(velo_y + 0.5);
/* Make sure we are in the screen boundaries!
* (Strange things will happen if we are not.) */
/* Make sure we are in the screen boundaries! (Strange things will happen if we are not.) */
if (pos.x >= screenSize.w || pos.y >= screenSize.h) {
return false;
}
moveMouse(pos);
/* Wait 1 - 3 milliseconds. */

4
mouse/mouse_darwin.go Normal file
View File

@ -0,0 +1,4 @@
//go:build darwin
// +build darwin
package mouse

4
mouse/mouse_windows.go Normal file
View File

@ -0,0 +1,4 @@
//go:build windows
// +build windows
package mouse

4
mouse/mouse_x11.go Normal file
View File

@ -0,0 +1,4 @@
//go:build !darwin && !windows
// +build !darwin,!windows
package mouse

View File

@ -14,11 +14,9 @@
#include "screengrab_c.h"
#include "screen_c.h"
#include <stdio.h>
// #include "../MMBitmap_c.h"
void padHex(MMRGBHex color, char* hex) {
// Length needs to be 7 because snprintf includes a terminating null.
// Use %06x to pad hex value with leading 0s.
snprintf(hex, 7, "%06x", color);
}
@ -29,7 +27,6 @@ char* pad_hex(MMRGBHex color) {
char* str = (char*)calloc(100, sizeof(char*));
if (str) { strcpy(str, hex); }
return str;
}
@ -56,7 +53,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);
@ -79,7 +75,7 @@ MMSizeInt32 get_screen_size() {
char* set_XDisplay_name(char* name) {
#if defined(USE_X11)
setXDisplay(name);
return "success";
return "";
#else
return "SetXDisplayName is only supported on Linux";
#endif
@ -88,8 +84,8 @@ char* set_XDisplay_name(char* name) {
char* get_XDisplay_name() {
#if defined(USE_X11)
const char* display = getXDisplay();
char* sd = (char*)calloc(100, sizeof(char*));
if (sd) { strcpy(sd, display); }
return sd;
#else
@ -126,7 +122,6 @@ void bitmap_dealloc(MMBitmapRef bitmap) {
// capture_screen capture screen
MMBitmapRef capture_screen(int32_t x, int32_t y, int32_t w, int32_t h, int32_t display_id) {
MMBitmapRef bitmap = copyMMBitmapFromDisplayInRect(MMRectInt32Make(x, y, w, h), display_id);
// printf("%s\n", bitmap);
return bitmap;
}

1
screen/screen.go Normal file
View File

@ -0,0 +1 @@
package screen

View File

@ -1,29 +0,0 @@
#pragma once
#ifndef SCREEN_H
#define SCREEN_H
#include "../base/types.h"
#if defined(_MSC_VER)
#include "../base/ms_stdbool.h"
#else
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* Returns the size of the main display. */
MMSizeInt32 getMainDisplaySize(void);
/* Convenience function that returns whether the given point is in the bounds
* of the main screen. */
bool pointVisibleOnMainDisplay(MMPointInt32 point);
#ifdef __cplusplus
}
#endif
#endif /* SCREEN_H */

View File

@ -1,4 +1,3 @@
#include "screen.h"
//#include "../base/os.h"
#if defined(IS_MACOSX)
@ -8,7 +7,7 @@
// #include "../base/xdisplay_c.h"
#endif
MMSizeInt32 getMainDisplaySize(void){
MMSizeInt32 getMainDisplaySize(void) {
#if defined(IS_MACOSX)
CGDirectDisplayID displayID = CGMainDisplayID();
CGRect displayRect = CGDisplayBounds(displayID);
@ -53,8 +52,7 @@ MMRectInt32 getScreenRect(int32_t display_id) {
const int screen = DefaultScreen(display);
return MMRectInt32Make(
(int32_t)0,
(int32_t)0,
(int32_t)0, (int32_t)0,
(int32_t)DisplayWidth(display, screen),
(int32_t)DisplayHeight(display, screen));
#elif defined(IS_WINDOWS)

View File

@ -1,22 +0,0 @@
#pragma once
#ifndef SCREENGRAB_H
#define SCREENGRAB_H
#include "../base/types.h"
// #include "../base/MMBitmap_c.h"
#include "../base/bitmap_free_c.h"
#ifdef __cplusplus
extern "C"
{
#endif
/* Returns a raw bitmap of screengrab of the display (to be destroyed()'d by
* caller), or NULL on error. */
MMBitmapRef copyMMBitmapFromDisplayInRect(MMRectInt32 rect, int32_t display_id);
#ifdef __cplusplus
}
#endif
#endif /* SCREENGRAB_H */

View File

@ -1,6 +1,4 @@
#include "screengrab.h"
// #include "../base/bmp_io_c.h"
#include "../base/endian.h"
#include "../base/bitmap_free_c.h"
#include <stdlib.h> /* malloc() */
#if defined(IS_MACOSX)
@ -12,8 +10,6 @@
#include <X11/Xutil.h>
#include "../base/xdisplay_c.h"
#elif defined(IS_WINDOWS)
// #include "windows.h"
// #include <wingdi.h>
#include <string.h>
#endif
@ -99,11 +95,10 @@ 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. */
if ((screenMem = CreateCompatibleDC(screen)) == NULL || SelectObject(screenMem, dib) == NULL ||
!BitBlt(screenMem, (int)0, (int)0, (int)rect.size.w, (int)rect.size.h,
screen, rect.origin.x, rect.origin.y, SRCCOPY)
) {
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. */
ReleaseDC(NULL, screen);
DeleteObject(dib);

View File

@ -1,14 +1,13 @@
// #include "os.h"
#if defined(IS_MACOSX)
#include <CoreFoundation/CoreFoundation.h>
#endif
#if defined(IS_MACOSX)
#define CFStringCreateWithUTF8String(string) \
((string) == NULL ? NULL : CFStringCreateWithCString(NULL, \
string, \
kCFStringEncodingUTF8))
CFStringRef CFStringCreateWithUTF8String(const char *title) {
if (title == NULL) { return NULL; }
return CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
}
#endif
int showAlert(const char *title, const char *msg,
@ -36,7 +35,7 @@ int showAlert(const char *title, const char *msg,
/* TODO: Display custom buttons instead of the pre-defined "OK"
* and "Cancel". */
int response = MessageBox(NULL, msg, title,
(cancelButton == NULL) ? MB_OK : MB_OKCANCEL);
(cancelButton == NULL) ? MB_OK : MB_OKCANCEL );
return (response == IDOK) ? 0 : 1;
#endif
}

1
window/window.go Normal file
View File

@ -0,0 +1 @@
package window