Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions binding.gyp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
'variables': {
'robotjs_enable_png%': '<!(node -p "process.env.ROBOTJS_ENABLE_PNG === \'1\' ? 1 : 0")'
},
'targets': [{
'target_name': 'robotjs',
'cflags!': [ '-fno-exceptions' ],
Expand Down Expand Up @@ -36,8 +39,6 @@
['OS == "linux"', {
'link_settings': {
'libraries': [
'-lpng',
'-lz',
'-lX11',
'-lXtst'
]
Expand All @@ -50,12 +51,51 @@

["OS=='win'", {
'defines': ['IS_WINDOWS']
}],

['robotjs_enable_png==1', {
'defines': ['ROBOTJS_HAS_PNG=1'],
'sources': [
'src/png_io.c'
],
'conditions': [
['OS == "mac"', {
'include_dirs': [
'<!@(sh -c "pkg-config --cflags-only-I libpng | sed s/-I//g")'
],
'link_settings': {
'libraries': [
'<!@(pkg-config --libs libpng)',
'-lz'
]
}
}],
['OS == "linux"', {
'include_dirs': [
'<!@(sh -c "pkg-config --cflags-only-I libpng | sed s/-I//g")'
],
'link_settings': {
'libraries': [
'<!@(pkg-config --libs libpng)',
'-lz'
]
}
}]
]
}, {
'defines': ['ROBOTJS_HAS_PNG=0']
}]
],

'sources': [
'src/robotjs.cc',
'src/io.c',
'src/bmp_io.c',
'src/MMPointArray.c',
'src/deadbeef_rand.c',
'src/UTHashTable.c',
'src/bitmap_find.c',
'src/color_find.c',
'src/mouse.c',
'src/keypress.c',
'src/keycode.c',
Expand All @@ -65,4 +105,4 @@
'src/MMBitmap.c'
]
}]
}
}
73 changes: 70 additions & 3 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,80 @@
export interface Bitmap {
/// <reference types="node" />

export interface Point {
x: number
y: number
}

export interface ScreenPoint {
x: number
y: number
}

export interface Display {
id: number
x: number
y: number
width: number
height: number
image: any
isMain: boolean
}

export interface BitmapSearchOptions {
x?: number
y?: number
width?: number
height?: number
tolerance?: number
}

export type ImageSearchOptions = BitmapSearchOptions

export interface Image {
width: number
height: number
image: Buffer
byteWidth: number
bitsPerPixel: number
bytesPerPixel: number
screenX?: number
screenY?: number
scaleX?: number
scaleY?: number
colorAt(x: number, y: number): string
findColor(color: string, options?: ImageSearchOptions): Point | null
findColors(color: string, options?: ImageSearchOptions): Point[]
countColor(color: string, options?: ImageSearchOptions): number
findImage(needle: Image, options?: ImageSearchOptions): Point | null
findImages(needle: Image, options?: ImageSearchOptions): Point[]
countImage(needle: Image, options?: ImageSearchOptions): number
save(path: string): boolean
toScreenPoint(point: Point, target?: { width: number, height: number }): ScreenPoint
click(point: Point, target?: { width: number, height: number }, button?: string, double?: boolean): ScreenPoint
clickImage(target: Image, options?: ImageSearchOptions, button?: string, double?: boolean): Point | null
}

export declare class Image {
constructor(
width: number,
height: number,
byteWidth: number,
bitsPerPixel: number,
bytesPerPixel: number,
image: Buffer
)
}

export type Bitmap = Image
export declare const Bitmap: typeof Image

export interface Screen {
capture(x?: number, y?: number, width?: number, height?: number): Bitmap
capture(x?: number, y?: number, width?: number, height?: number): Image
}

export interface ImageModule {
load(path: string): Image
save(bitmap: Image, path: string): boolean
supportsPNG: boolean
}

export function setKeyboardDelay(ms: number) : void
Expand All @@ -29,5 +94,7 @@ export function scrollMouse(x: number, y: number) : void
export function getMousePos(): { x: number, y: number }
export function getPixelColor(x: number, y: number): string
export function getScreenSize(): { width: number, height: number }
export function getDisplays(): Display[]

export var screen: Screen
export var image: ImageModule
149 changes: 136 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,159 @@
var robotjs = require('./build/Release/robotjs.node');
const robotjs = require('./build/Release/robotjs.node');

module.exports = robotjs;

module.exports.screen = {};
module.exports.image = {};

function Bitmap(width, height, byteWidth, bitsPerPixel, bytesPerPixel, image)
{
// Convenience constructor for when an object is passed (return of native functions).
if (typeof width === 'object' && width !== null) {
this.screenX = width.screenX;
this.screenY = width.screenY;
this.scaleX = width.scaleX;
this.scaleY = width.scaleY;
image = width.image;
bytesPerPixel = width.bytesPerPixel;
bitsPerPixel = width.bitsPerPixel;
byteWidth = width.byteWidth;
height = width.height;
width = width.width;
}

function bitmap(width, height, byteWidth, bitsPerPixel, bytesPerPixel, image)
{
this.width = width;
this.height = height;
this.byteWidth = byteWidth;
this.bitsPerPixel = bitsPerPixel;
this.bytesPerPixel = bytesPerPixel;
this.image = image;
}

this.colorAt = function(x, y)
{
return robotjs.getColor(this, x, y);
};
function Image(width, height, byteWidth, bitsPerPixel, bytesPerPixel, image)
{
Bitmap.call(this, width, height, byteWidth, bitsPerPixel, bytesPerPixel, image);
}

Image.prototype = Bitmap.prototype;
Image.prototype.constructor = Image;

function getTargetDimensions(target)
{
if (!target || typeof target !== 'object') {
return { width: 0, height: 0 };
}

if (typeof target.width === 'number' && typeof target.height === 'number') {
return { width: target.width, height: target.height };
}

return { width: 0, height: 0 };
}

Image.prototype.colorAt = function(x, y)
{
return robotjs.getColor(this, x, y);
};

Image.prototype.findColor = function(color, options)
{
return robotjs.findColor(this, color, options);
};

Image.prototype.findColors = function(color, options)
{
return robotjs.findColors(this, color, options);
};

Image.prototype.countColor = function(color, options)
{
return robotjs.countColor(this, color, options);
};

Image.prototype.findImage = function(needle, options)
{
return robotjs.findImage(this, needle, options);
};

Image.prototype.findImages = function(needle, options)
{
return robotjs.findImages(this, needle, options);
};

Image.prototype.countImage = function(needle, options)
{
return robotjs.countImage(this, needle, options);
};

Image.prototype.save = function(path)
{
return robotjs.saveImage(this, path);
};

Image.prototype.toScreenPoint = function(point, target)
{
var dimensions = getTargetDimensions(target);
var scaleX = typeof this.scaleX === 'number' && this.scaleX > 0 ? this.scaleX : 1;
var scaleY = typeof this.scaleY === 'number' && this.scaleY > 0 ? this.scaleY : 1;
var screenX = typeof this.screenX === 'number' ? this.screenX : 0;
var screenY = typeof this.screenY === 'number' ? this.screenY : 0;

return {
x: Math.round(screenX + ((point.x + Math.floor(dimensions.width / 2)) / scaleX)),
y: Math.round(screenY + ((point.y + Math.floor(dimensions.height / 2)) / scaleY))
};
};

Image.prototype.click = function(point, target, button, double)
{
var screenPoint = this.toScreenPoint(point, target);

module.exports.moveMouse(screenPoint.x, screenPoint.y);
if (typeof button === 'undefined') {
module.exports.mouseClick();
} else if (typeof double === 'undefined') {
module.exports.mouseClick(button);
} else {
module.exports.mouseClick(button, double);
}

return screenPoint;
};

Image.prototype.clickImage = function(target, options, button, double)
{
var match = this.findImage(target, options);

if (!match) {
return null;
}

this.click(match, target, button, double);
return match;
};

module.exports.Image = Image;
module.exports.Bitmap = Image;

module.exports.screen.capture = function(x, y, width, height)
{
//If coords have been passed, use them.
if (typeof x !== "undefined" && typeof y !== "undefined" && typeof width !== "undefined" && typeof height !== "undefined")
{
b = robotjs.captureScreen(x, y, width, height);
}
else
{
b = robotjs.captureScreen();
return new Image(robotjs.captureScreen(x, y, width, height));
}

return new bitmap(b.width, b.height, b.byteWidth, b.bitsPerPixel, b.bytesPerPixel, b.image);
return new Image(robotjs.captureScreen());
};

module.exports.image.load = function(path)
{
return new Image(robotjs.loadImage(path));
};

module.exports.image.save = function(bitmap, path)
{
return robotjs.saveImage(bitmap, path);
};

module.exports.image.supportsPNG = !!robotjs.hasPNGSupport;
9 changes: 9 additions & 0 deletions src/MMPointArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

#include "types.h"

#ifdef __cplusplus
extern "C"
{
#endif

struct _MMPointArray {
MMPoint *array; /* Pointer to actual data. */
size_t count; /* Number of elements in array. */
Expand All @@ -30,4 +35,8 @@ void MMPointArrayAppendPoint(MMPointArrayRef pointArray, MMPoint point);
/* Set point in array. */
#define MMPointArraySetItem(a, i, item) ((a)->array[i] = item)

#ifdef __cplusplus
}
#endif

#endif /* MMARRAY_H */
Loading