diff --git a/autopy-alert-module.c b/autopy-alert-module.c deleted file mode 100644 index 2b35bd6e..00000000 --- a/autopy-alert-module.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "autopy-alert-module.h" -#include "alert.h" - -/* Syntax: alert(msg, title="AutoPy Alert", default_button="OK", - [cancel_button]) */ -/* Arguments: |msg| => string, - |title| => string, - |default_button| => string, - |cancel_button| => string */ -/* Description: Displays alert with the given attributes. If |cancel_button| is - not given, only the default button is displayed. Returns True - if the default button was pressed, or False if cancelled. Note - that the arguments are keywords, and can be passed as named - parameters (e.g., `alert(msg="bar", title="foo")`). - - Due to limitations in the Win32 API, Windows currently replaces - |default_button| with `"OK"` and |cancel_button| (if given) - with `"Cancel"`. This may be fixed in a later release. */ -static PyObject *alert_alert(PyObject *self, PyObject *args, PyObject *kwds); - -static PyMethodDef AlertMethods[] = { - {"alert", (PyCFunction)alert_alert, METH_VARARGS | METH_KEYWORDS, - "alert(msg, title='AutoPy Alert', default_button='OK', " - "[cancel_button]) => Boolean\n" - "Displays alert with the given attributes.\n" - "Returns True if the default button was pressed, or False if cancelled."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC initalert(void) -{ - Py_InitModule3("alert", AlertMethods, - "autopy module for displaying alerts"); -} - -static PyObject *alert_alert(PyObject *self, PyObject *args, PyObject *kwds) -{ - char *msg = NULL, *title = "AutoPy Alert"; - char *default_button = "OK", *cancel_button = NULL; - - static char *kwdlist[] = {"title", "msg", "default_button", - "cancel_button", NULL}; - int button; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|szz", kwdlist, - &msg, - &title, - &default_button, - &cancel_button)) { - return NULL; - } - - button = showAlert(title, msg, default_button, cancel_button); - if (button == 0) { - Py_RETURN_TRUE; - } else if (button == 1) { - Py_RETURN_FALSE; - } else { - PyErr_SetString(PyExc_OSError, "Could not display alert"); - return NULL; - } -} diff --git a/autopy-alert-module.h b/autopy-alert-module.h deleted file mode 100644 index d9551d0d..00000000 --- a/autopy-alert-module.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#ifndef AUTOPY_ALERT_MODULE_H -#define AUTOPY_ALERT_MODULE_H - -#include - -/* Summary: autopy module for displaying alerts */ -/* Description: This module contains functions for displaying cross-platform - alert dialogs. */ -PyMODINIT_FUNC initalert(void); - -#endif /* AUTOPY_ALERT_MODULE_H */ diff --git a/autopy-bitmap-module.c b/autopy-bitmap-module.c deleted file mode 100644 index d65b6d7e..00000000 --- a/autopy-bitmap-module.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "autopy-bitmap-module.h" -#include "py-bitmap-class.h" -#include "screen.h" -#include "screengrab.h" -#include "py-convenience.h" - -/* Syntax: capture_screen(rect=None) => Bitmap object */ -/* Arguments: |rect| => ((|x|, |y|), (|width|, |height|)) rect of ints */ -/* Description: Returns a screengrab of the given portion of the main display, - or the entire display if |rect| is None. */ -/* Raises: |ValueError| if the rect is out of bounds, - |OSError| if the screengrab was unsuccessful. */ -static PyObject *bitmap_capture_screen(PyObject *self, PyObject *args); - -static PyMethodDef BitmapMethods[] = { - {"capture_screen", bitmap_capture_screen, METH_NOARGS | METH_O, - "capture_screen(rect=None) -> Bitmap object\n" - "Returns a screengrab of the given portion of the main display,\n" - "or the entire display if rect is None."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC initbitmap(void) -{ - PyObject *mod = Py_InitModule3("bitmap", BitmapMethods, - "autopy module for working with bitmaps"); - if (mod == NULL) return; /* Error */ - - /* Instantiate new "Bitmap" class so that it is available in the module. */ - if (Py_AddClassToModule(mod, &Bitmap_Type) < 0) { - return; /* Error */ - } -} - -static PyObject *bitmap_capture_screen(PyObject *self, PyObject *arg) -{ - MMRect rect; - MMBitmapRef bitmap = NULL; - MMSize displaySize = getMainDisplaySize(); - - if (arg == NULL || arg == Py_None) { - rect = MMRectMake(0, 0, displaySize.width, displaySize.height); - } else { - if (!PyArg_ParseTuple(arg, "(kk)(kk)", &rect.origin.x, - &rect.origin.y, - &rect.size.width, - &rect.size.height)) { - PyErr_SetString(PyExc_TypeError, "Argument is not a rect"); - return NULL; - } - - if (rect.origin.x >= displaySize.width || - rect.origin.y >= displaySize.height || - rect.origin.x + rect.size.width > displaySize.width || - rect.origin.y + rect.size.height > displaySize.height) { - PyErr_SetString(PyExc_ValueError, "Rect out of bounds"); - return NULL; - } - } - - bitmap = copyMMBitmapFromDisplayInRect(rect); - if (bitmap == NULL || bitmap->imageBuffer == NULL) { - PyErr_SetString(PyExc_OSError, - "Could not copy RGB data from display"); - return NULL; - } - - return BitmapObject_FromMMBitmap(bitmap); -} diff --git a/autopy-bitmap-module.h b/autopy-bitmap-module.h deleted file mode 100644 index 84557576..00000000 --- a/autopy-bitmap-module.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#ifndef AUTOPY_BITMAP_MODULE_H -#define AUTOPY_BITMAP_MODULE_H - -#include - -/* Summary: autopy module for working with bitmaps */ -/* Description: This module defines the class `Bitmap` for accessing - bitmaps and searching for bitmaps on-screen. - - It also defines functions for taking screenshots of the screen. */ -PyMODINIT_FUNC initbitmap(void); - -#endif /* AUTOPY_BITMAP_MODULE_H */ diff --git a/autopy-color-module.c b/autopy-color-module.c deleted file mode 100644 index a1fd2786..00000000 --- a/autopy-color-module.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "autopy-color-module.h" -#include "MMBitmap.h" - -/* Syntax: hex_to_rgb(hex) => tuple (r, g, b) */ -/* Arguments: |hex| => integer (in range 0x000000 - 0xFFFFFF) */ -/* Description: Returns a tuple `(r, g, b)` of the RGB integer values equivalent - to the given RGB hexadecimal value. |r|, |g|, and |b| are in - the range 0 - 255. */ -static PyObject *color_hex_to_rgb(PyObject *self, PyObject *args); - -/* Syntax: rgb_to_hex(r, g, b) => integer (in the range 0x000000 - 0xFFFFFF) */ -/* Arguments: |r| => integer (0 - 255), - |b| => integer (0 - 255), - |g| => integer (0 - 255) */ -/* Description: Returns hexadecimal value of given RGB tuple. |r|, |g|, and |b| - should be in the range 0 - 255. */ -static PyObject *color_rgb_to_hex(PyObject *self, PyObject *args); - -static PyMethodDef ColorMethods[] = { - {"hex_to_rgb", color_hex_to_rgb, METH_VARARGS, - "hex_to_rgb(hex) -> tuple (r, g, b)\n" - "Returns a tuple (r, g, b) of the RGB integer values equivalent to the\n" - "given RGB hex value."}, - {"rgb_to_hex", color_rgb_to_hex, METH_VARARGS, - "rgb_to_hex(r, g, b) -> integer\n" - "Returns hexadecimal value of given RGB tuple, where |r|, |g|, and\n" - "|b| in the range 0 - 255, and the returned value is in the\n" - "range 0x000000 - 0xFFFFFF."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC initcolor(void) -{ - Py_InitModule3("color", ColorMethods, - "autopy module for converting between color formats"); -} - -static PyObject *color_hex_to_rgb(PyObject *self, PyObject *args) -{ - MMRGBHex hex; - if (!PyArg_ParseTuple(args, "I", &hex)) return NULL; - - return Py_BuildValue("(bbb)", RED_FROM_HEX(hex), - GREEN_FROM_HEX(hex), - BLUE_FROM_HEX(hex)); -} - -static PyObject *color_rgb_to_hex(PyObject *self, PyObject *args) -{ - MMRGBColor color; - if (!PyArg_ParseTuple(args, "bbb", &color.red, - &color.green, - &color.blue)) { - return NULL; - } - - return Py_BuildValue("I", hexFromMMRGB(color)); -} diff --git a/autopy-color-module.h b/autopy-color-module.h deleted file mode 100644 index 44ebaef7..00000000 --- a/autopy-color-module.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#ifndef AUTOPY_COLOR_MODULE_H -#define AUTOPY_COLOR_MODULE_H - -#include - -/* Summary: autopy module for converting color formats */ -/* Description: This module provides routines for converting between the color - format (hexadecimal) used by autopy methods and other, more - readable, formats (e.g., RGB tuples). */ -PyMODINIT_FUNC initcolor(void); - -#endif /* AUTOPY_COLOR_MODULE_H */ diff --git a/autopy-key-module.c b/autopy-key-module.c deleted file mode 100644 index b678a152..00000000 --- a/autopy-key-module.c +++ /dev/null @@ -1,211 +0,0 @@ -#include "autopy-key-module.h" -#include "keypress.h" -#include "py-convenience.h" -#include "deadbeef_rand.h" -#include - -#if defined(_MSC_VER) - #include "ms_stdbool.h" -#else - #include -#endif - -/* Syntax: toggle(key, down_or_up, [modifiers]) */ -/* Arguments: |key| => character or integer describing the key or keycode, - |down_or_up| => Boolean describing whether to hold down or - release the key, - |modifiers| => integer (bitwise-OR of |MOD_*| constants) */ -/* Description: Holds down the given key or keycode if |down_or_up| is True, - or releases it if not. Integer keycodes and modifiers should - be taken from module constants (e.g., |key.K_DELETE| or - |key.MOD_META|). If the given key is a character, it is - automatically converted to a keycode corresponding to the - current keyboard layout. - - To hold down more than one modifier at a time, bitwise-OR them, - e.g.: - {% toggle('a', True, key.MOD_SHIFT | key.MOD_ALT) %} */ -static PyObject *key_toggle(PyObject *self, PyObject *args); - -/* Syntax: tap(key, [modifiers]) */ -/* Arguments: |key| => character or integer, - |modifiers| => integer (bitise-OR of |MOD_*| constants) */ -/* Description: Convenience wrapper around `toggle()` that holds down and then - releases the given key and modifiers. */ -static PyObject *key_tap(PyObject *self, PyObject *args); - -/* Syntax: type_string(string, wpm=0) */ -/* Arguments: |string| => ASCII string, - |wpm| => double (Words per minute to type string, - or unlimited if 0) */ -/* Description: Attempts to simulate typing a string at the given WPM, or as - fast as possible if the WPM is 0. */ -static PyObject *key_type_string(PyObject *self, PyObject *args); - -static PyMethodDef KeyMethods[] = { - {"toggle", key_toggle, METH_VARARGS, - "toggle(key, down_or_up, [modifiers]) -> None\n" - "Holds down given key if down_or_up is True, releases if not."}, - {"tap", key_tap, METH_VARARGS, - "tap(key, [modifiers]) -> None\n" - "Holds down and then releases the given key."}, - {"type_string", key_type_string, METH_VARARGS, - "type_string(string, wpm=0) -> None\n" - "Attempts to type a string at the given WPM, or as fast as possible if\n" - "wpm is 0."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC initkey(void) -{ - PyObject *mod = Py_InitModule3("key", KeyMethods, - "autopy module for working with the " - "keyboard"); - if (mod == NULL) return; /* Error */ - - /* Needed for type_string(). */ - deadbeef_srand_time(); - - /* Add keycode constants for toggle() and tap(). */ - if (PyModule_AddIntMacro(mod, MOD_NONE) < 0 || - PyModule_AddIntMacro(mod, MOD_META) < 0 || - PyModule_AddIntMacro(mod, MOD_ALT) < 0 || - PyModule_AddIntMacro(mod, MOD_CONTROL) < 0 || - PyModule_AddIntMacro(mod, MOD_SHIFT) < 0 || - PyModule_AddIntMacro(mod, K_BACKSPACE) < 0 || - PyModule_AddIntMacro(mod, K_DELETE) < 0 || - PyModule_AddIntMacro(mod, K_RETURN) < 0 || - PyModule_AddIntMacro(mod, K_ESCAPE) < 0 || - PyModule_AddIntMacro(mod, K_UP) < 0 || - PyModule_AddIntMacro(mod, K_DOWN) < 0 || - PyModule_AddIntMacro(mod, K_RIGHT) < 0 || - PyModule_AddIntMacro(mod, K_LEFT) < 0 || - PyModule_AddIntMacro(mod, K_HOME) < 0 || - PyModule_AddIntMacro(mod, K_END) < 0 || - PyModule_AddIntMacro(mod, K_PAGEUP) < 0 || - PyModule_AddIntMacro(mod, K_PAGEDOWN) < 0 || - PyModule_AddIntMacro(mod, K_F1) < 0 || - PyModule_AddIntMacro(mod, K_F2) < 0 || - PyModule_AddIntMacro(mod, K_F3) < 0 || - PyModule_AddIntMacro(mod, K_F4) < 0 || - PyModule_AddIntMacro(mod, K_F5) < 0 || - PyModule_AddIntMacro(mod, K_F6) < 0 || - PyModule_AddIntMacro(mod, K_F7) < 0 || - PyModule_AddIntMacro(mod, K_F8) < 0 || - PyModule_AddIntMacro(mod, K_F9) < 0 || - PyModule_AddIntMacro(mod, K_F10) < 0 || - PyModule_AddIntMacro(mod, K_F11) < 0 || - PyModule_AddIntMacro(mod, K_F12) < 0 || - PyModule_AddIntMacro(mod, K_META) < 0 || - PyModule_AddIntMacro(mod, K_ALT) < 0 || - PyModule_AddIntMacro(mod, K_CONTROL) < 0 || - PyModule_AddIntMacro(mod, K_SHIFT) < 0 || - PyModule_AddIntMacro(mod, K_CAPSLOCK) < 0) { - PyErr_SetString(PyExc_ValueError, "Error adding keycode constants"); - return; - } -} - -/* Attempts to extract MMKeyCode from PyInt. Returns false and sets error if - * MMKeyCode could not be converted, or returns true if it could. */ -static bool MMKeyCodeFromPyInt(PyObject *num, MMKeyCode *val); - -/* Attempts to extract char from PyString. Returns false and sets error if - * MMKeyCode could not be converted, or returns true if it could. */ -static bool charFromPyString(PyObject *str, char *val); - -static PyObject *key_toggle(PyObject *self, PyObject *args) -{ - PyObject *key; - PyObject *downBool; - MMKeyFlags flags = MOD_NONE; - - if (!PyArg_ParseTuple(args, "OO!|K", &key, &PyBool_Type, &downBool, &flags)) { - return NULL; - } - - if (PyNumber_Check(key)) { /* Check for key code */ - MMKeyCode code; - if (!MMKeyCodeFromPyInt(key, &code)) return NULL; - toggleKeyCode(code, downBool == Py_True, flags); - } else if (PyString_Check(key)) { /* Check for single-character string */ - char c; - if (!charFromPyString(key, &c)) return NULL; - toggleKey(c, downBool == Py_True, flags); - } else { - return Py_SetArgConvertErr("integer or char", 1, key); - } - - Py_RETURN_NONE; -} - -static PyObject *key_tap(PyObject *self, PyObject *args) -{ - PyObject *key; - MMKeyFlags flags = MOD_NONE; - - if (!PyArg_ParseTuple(args, "O|I", &key, &flags)) return NULL; - - if (PyNumber_Check(key)) { /* Check for key code */ - MMKeyCode code; - if (!MMKeyCodeFromPyInt(key, &code)) return NULL; - tapKeyCode(code, flags); - } else if (PyString_Check(key)) { /* Check for single-character string */ - char c; - if (!charFromPyString(key, &c)) return NULL; - tapKey(c, flags); - } else { - return Py_SetArgConvertErr("integer or char", 1, key); - } - - Py_RETURN_NONE; -} - -static PyObject *key_type_string(PyObject *self, PyObject *args) -{ - char *str = NULL; - double wpm = 0.0; - if (!PyArg_ParseTuple(args, "s|d", &str, &wpm)) return NULL; - - if (wpm == 0.0) { - typeString(str); - } else { - typeStringDelayed(str, WPM_TO_CPM(wpm)); - } - - Py_RETURN_NONE; -} - -/* -- Helper functions -- */ - -static bool MMKeyCodeFromPyInt(PyObject *num, MMKeyCode *val) -{ - long ival; - assert(val != NULL); - - if (!PyInt_Check(num) || PyFloat_Check(num)) { - Py_SetConvertErr("integer", num); - return false; - } - - ival = PyInt_AsUnsignedLongMask(num); - if (ival == -1 && PyErr_Occurred()) { - Py_SetConvertErr("integer", num); - return false; - } - - *val = (MMKeyCode)ival; - return true; -} - -static bool charFromPyString(PyObject *str, char *val) -{ - assert(val != NULL); - if (PyString_Size(str) != 1) { - Py_SetConvertErr("char", str); - return false; - } else { - *val = PyString_AS_STRING(str)[0]; - return true; - } -} diff --git a/autopy-key-module.h b/autopy-key-module.h deleted file mode 100644 index 060179e1..00000000 --- a/autopy-key-module.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#ifndef AUTOPY_KEY_MODULE_H -#define AUTOPY_KEY_MODULE_H - -#include - -/* Summary: autopy module for working with the keyboard */ -/* Description: This module contains various functions for controlling the - keyboard. */ -PyMODINIT_FUNC initkey(void); - -#endif /* AUTOPY_KEY_MODULE_H */ diff --git a/autopy-mouse-module.c b/autopy-mouse-module.c deleted file mode 100644 index d6c2c20d..00000000 --- a/autopy-mouse-module.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "autopy-mouse-module.h" -#include "mouse.h" -#include "py-convenience.h" -#include "deadbeef_rand.h" -#include "screen.h" - -/* Syntax: move(x, y) */ -/* Arguments: |x| => int, - |y| => int */ -/* Description: Moves the mouse to the given `(x, y)` coordinate. */ -/* Raises: |ValueError| if the point is out of index. */ -static PyObject *mouse_move(PyObject *self, PyObject *args); - -/* Syntax: smooth_move(x, y) */ -/* Arguments: |x| => int, - |y| => int */ -/* Description: Smoothly moves the mouse to the given `(x, y)` coordinate in a - straight line. */ -/* Raises: |ValueError| if the point is out of index. */ -static PyObject *mouse_smooth_move(PyObject *self, PyObject *args); - -/* Syntax: get_pos() => tuple (x, y) */ -/* Description: Returns a tuple `(x, y)` of the current mouse position. */ -static PyObject *mouse_get_pos(PyObject *self, PyObject *args); - -/* Syntax: toggle(down, button=LEFT_BUTTON) */ -/* Arguments: |down| => Boolean - |button| => int */ -/* Description: Holds down or releases the given mouse button in the current - position. |button| can be |LEFT_BUTTON|, |RIGHT_BUTTON|, or - |CENTER_BUTTON|. If no button is given, the left button is - defaulted to. */ -/* Raises: |ValueError| if the mouse button is invalid. */ -static PyObject *mouse_toggle(PyObject *self, PyObject *args); - -/* Syntax: click(button=LEFT_BUTTON) */ -/* Arguments: |button| => int */ -/* Description: Convenience wrapper around `toggle()` that holds down and then - releases the given mouse button. */ -static PyObject *mouse_click(PyObject *self, PyObject *args); - -static PyMethodDef MouseMethods[] = { - {"move", mouse_move, METH_VARARGS, - "move(x, y) -> None\n" - "Moves cursor to given (x, y) coordinate."}, - {"smooth_move", mouse_smooth_move, METH_VARARGS, - "smooth_move(x, y) -> None\n" - "Smoothly moves cursor to given (x, y) coordinate in a straight line."}, - {"get_pos", mouse_get_pos, METH_NOARGS, - "get_pos() -> tuple\n" - "Returns a tuple (x, y) of the current mouse position."}, - {"toggle", mouse_toggle, METH_VARARGS, - "toggle(down, button=LEFT_BUTTON) -> None\n" - "Holds down or releases the mouse with the given button."}, - {"click", mouse_click, METH_VARARGS, - "click(button=LEFT_BUTTON) -> None\n" - "Clicks the mouse with the given button."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC initmouse(void) -{ - PyObject *mod = Py_InitModule3("mouse", MouseMethods, - "autopy module for working with the mouse"); - - if (mod == NULL) return; /* Error */ - - /* Add mouse button constants for click_mouse(). */ - if (PyModule_AddIntMacro(mod, LEFT_BUTTON) < 0 || - PyModule_AddIntMacro(mod, RIGHT_BUTTON) < 0 || - PyModule_AddIntMacro(mod, CENTER_BUTTON) < 0) { - PyErr_SetString(PyExc_ValueError, "Error adding constants to mouse module"); - return; - } - - deadbeef_srand_time(); -} - -static PyObject *mouse_move(PyObject *self, PyObject *args) -{ - MMPoint point; - if (!PyArg_ParseTuple(args, "kk", &point.x, &point.y)) return NULL; - - if (!pointVisibleOnMainDisplay(point)) { - PyErr_SetString(PyExc_ValueError, "Point out of bounds"); - return NULL; - } - - moveMouse(point); - - Py_RETURN_NONE; -} - -static PyObject *mouse_smooth_move(PyObject *self, PyObject *args) -{ - MMPoint point; - if (!PyArg_ParseTuple(args, "kk", &point.x, &point.y)) return NULL; - - if (!pointVisibleOnMainDisplay(point) || !smoothlyMoveMouse(point)) { - PyErr_SetString(PyExc_ValueError, "Point out of bounds"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject *mouse_get_pos(PyObject *self, PyObject *args) -{ - MMPoint pos = getMousePos(); - return Py_BuildValue("kk", pos.x, pos.y); -} - -static PyObject *mouse_toggle(PyObject *self, PyObject *args) -{ - PyObject *downBool; - MMMouseButton button = LEFT_BUTTON; - - if (!PyArg_ParseTuple(args, "O!|I", &PyBool_Type, &downBool, &button)) { - return NULL; - } - - if (!MMMouseButtonIsValid(button)) { - PyErr_SetString(PyExc_ValueError, "Invalid mouse button"); - return NULL; - } - - toggleMouse(downBool == Py_True, button); - - Py_RETURN_NONE; -} - -static PyObject *mouse_click(PyObject *self, PyObject *args) -{ - MMMouseButton button = LEFT_BUTTON; - - if (!PyArg_ParseTuple(args, "|I", &button)) return NULL; - - if (!MMMouseButtonIsValid(button)) { - PyErr_SetString(PyExc_ValueError, "Invalid mouse button"); - return NULL; - } - - clickMouse(button); - - Py_RETURN_NONE; -} diff --git a/autopy-mouse-module.h b/autopy-mouse-module.h deleted file mode 100644 index 825e2727..00000000 --- a/autopy-mouse-module.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#ifndef AUTOPY_MOUSE_MODULE_H -#define AUTOPY_MOUSE_MODULE_H - -#include - -/* Summary: autopy module for working with the mouse */ -/* Description: This module contains functions for getting the current state of - and controlling the mouse cursor. - - Unless otherwise stated, coordinates are those of a screen - coordinate system, where the origin is at the top left. */ -PyMODINIT_FUNC initmouse(void); - -#endif /* AUTOPY_MOUSE_MODULE_H */ diff --git a/autopy-screen-module.c b/autopy-screen-module.c deleted file mode 100644 index 2b2fdd37..00000000 --- a/autopy-screen-module.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "autopy-screen-module.h" -#include "screen.h" -#include "screengrab.h" - -/* Syntax: get_size() => tuple (width, height) */ -/* Description: Returns a tuple `(width, height)` of the size of the - main screen. */ -static PyObject *screen_get_size(PyObject *self, PyObject *args); - -/* Syntax: point_visible(x, y) => Boolean */ -/* Arguments: |x| => integer, - |y| => integer */ -/* Description: Returns True if the given point is inside the main - screen boundaries. */ -static PyObject *screen_point_visible(PyObject *self, PyObject *args); - -/* Syntax: get_color(x, y) => hexadecimal integer */ -/* Arguments: |x| => integer, - |y| => integer */ -/* Description: Returns hexadecimal value describing the RGB color at the - given point. - - Essentially equivalent to: - {% - rect = ((x, y), (1, 1)) - bitmap.capture_screen_portion(rect).get_color(0, 0) - %} - only more efficient/convenient. */ -/* Raises: |ValueError| if the rect is out of bounds, - |OSError| if the system calls were unsuccessful. */ -static PyObject *screen_get_color(PyObject *self, PyObject *args); - -static PyMethodDef ScreenMethods[] = { - {"get_size", screen_get_size, METH_NOARGS, - "get_size() -> tuple (width, height)\n" - "Returns a tuple (width, height) of the size of the main screen."}, - {"point_visible", screen_point_visible, METH_VARARGS, - "point_visible(x, y) -> Boolean\n" - "Returns whether given (x, y) coordinate is inside the main screen."}, - {"get_color", screen_get_color, METH_VARARGS, - "get_color(x, y) -> integer\n" - "Returns hexadecimal value describing the RGB color at the given point."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC initscreen(void) -{ - Py_InitModule3("screen", ScreenMethods, "autopy module for working with " - "the screen"); -} - -static PyObject *screen_get_size(PyObject *self, PyObject *args) -{ - MMSize screenSize = getMainDisplaySize(); - return Py_BuildValue("(kk)", screenSize.width, screenSize.height); -} - -static PyObject *screen_point_visible(PyObject *self, PyObject *args) -{ - MMPoint point; - if (!PyArg_ParseTuple(args, "kk", &point.x, &point.y)) { - return NULL; - } - - if (!pointVisibleOnMainDisplay(point)) { - Py_RETURN_FALSE; - } - - Py_RETURN_TRUE; -} - -static PyObject *screen_get_color(PyObject *self, PyObject *args) -{ - MMPoint point; - - MMBitmapRef bitmap; - MMRGBHex color; - - if (!PyArg_ParseTuple(args, "kk", &point.x, &point.y)) { - return NULL; - } - - if (!pointVisibleOnMainDisplay(point)) { - PyErr_SetString(PyExc_ValueError, "Point out of bounds"); - return NULL; - } - - bitmap = copyMMBitmapFromDisplayInRect(MMRectMake(point.x, point.y, 1, 1)); - if (bitmap == NULL || bitmap->imageBuffer == NULL) { - PyErr_SetString(PyExc_OSError, - "Could not copy RGB data from display."); - return NULL; - } - - color = MMRGBHexAtPoint(bitmap, 0, 0); - destroyMMBitmap(bitmap); - return Py_BuildValue("I", color); -} diff --git a/autopy-screen-module.h b/autopy-screen-module.h deleted file mode 100644 index 2642f279..00000000 --- a/autopy-screen-module.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#ifndef AUTOPY_SCREEN_MODULE_H -#define AUTOPY_SCREEN_MODULE_H - -#include - -/* Summary: autopy module for working with the screen */ -/* Description: This module contains functions for obtaining attributes - about the screen. */ -PyMODINIT_FUNC initscreen(void); - -#endif /* AUTOPY_SCREEN_MODULE_H */ diff --git a/py-bitmap-class.c b/py-bitmap-class.c deleted file mode 100644 index b635f459..00000000 --- a/py-bitmap-class.c +++ /dev/null @@ -1,735 +0,0 @@ -#include "py-bitmap-class.h" -#include "bitmap_find.h" -#include "color_find.h" -#include "screen.h" -#include "io.h" -#include "pasteboard.h" -#include "str_io.h" -#include "py-convenience.h" -#include -#include - -/* -- Bitmap class definition -- */ - -static void Bitmap_dealloc(BitmapObject *self) -{ - if (self->bitmap != NULL) { - destroyMMBitmap(self->bitmap); - self->bitmap = NULL; - } - self->ob_type->tp_free((PyObject *)self); -} - -/* -- Bitmap Class method declarations -- */ - -/* Syntax: Bitmap.open(filepath, format) => Bitmap object */ -/* Arguments: |filepath| => string, - |format| => string ("BMP" or "PNG") */ -/* Description: Opens image at absolute filepath in the given format. - The image type is determined from the filename if possible, - unless |format| is given. */ -/* Raises: |IOError| if the image could not be opened. */ -static PyObject *Bitmap_open(PyObject *self, PyObject *args); - -/* Syntax: Bitmap.from_string(string) => Bitmap object */ -/* Arguments: |string| => string */ -/* Description: Creates bitmap from string created by `bmp.to_string()`. */ -/* Raises: |ValueError| if the given string was invalid. */ -static PyObject *Bitmap_from_string(PyObject *self, PyObject *args); - -/* Syntax: bmp.get_portion(origin, size) => Bitmap object */ -/* Arguments: |origin| => |x|, |y| tuple of ints, - |size| => |width|, |height| tuple of ints */ -/* Description: Returns new bitmap object created from a portion of another. */ -/* Raises: |ValueError| if portion was out of bounds, - |IOError| if portion could not be copied. */ -static PyObject *Bitmap_get_portion(BitmapObject *self, PyObject *args); - -/* -- Bitmap Instance method declarations -- */ - -/* Syntax: bmp.point_in_bounds(x, y) => Boolean */ -/* Arguments: |x| => integer, - |y| => integer */ -/* Description: Returns True if `x < bmp.width` and `y < bmp.height`, or False - if not. */ -static PyObject *Bitmap_point_in_bounds(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.copy_to_pboard() */ -/* Description: Copies image to pasteboard. - Currently only supported on Windows and Mac OS X. */ -/* Raises: |OSError| if the image could not be copied. */ -static PyObject *Bitmap_copy_to_pboard(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.save(filepath, [format]) */ -/* Arguments: |filepath| => string, - |format| => string ("BMP" or "PNG") */ -/* Description: Saves image to absolute filepath in the given format. - The image type is determined from the filename if possible, - unless |format| is given. Note that if the file already exists, - it WILL be overwritten. Check yourself first if you do not - desire this. */ -/* Raises: |IOError| if the image could not be saved. */ -static PyObject *Bitmap_save(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.to_string() => string */ -/* Description: Returns compressed, printable string representing bitmap, to be - used with `Bitmap.from_string()`. */ -/* Raises: |IOError| if the string could not be created. */ -static PyObject *Bitmap_to_string(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.get_color(x, y) => hexadecimal integer */ -/* Arguments: |x| => integer, - |y| => integer */ -/* Description: Returns hexadecimal value describing the RGB color at the - given point. */ -/* Raises: |ValueError| if the point out of bounds. */ -static PyObject *Bitmap_get_color(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.find_color(color, tolerance=0.0, rect=None) => tuple (x, y) - or None */ -/* Arguments: |color| => integer (0x000000 - 0xFFFFFF), - |tolerance| => float, - |rect| => ((|x|, |y|), (|width|, |height|)) rect of ints, - or None */ -/* Description: Attempts to find color inside |rect| in |bmp|; returns - coordinates if found, or None if not. If |rect| is None, - the entire image is searched. */ -static PyObject *Bitmap_find_color(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.find_every_color(color, tolerance=0.0, rect=None) => - list of tuples [(x, y), ...] */ -/* Arguments: |color| => integer (0x000000 - 0xFFFFFF), - |tolerance| => float, - |rect| => ((|x|, |y|), (|width|, |height|)) rect of ints, - or None */ -/* Description: Returns list of all coordinates inside |rect| in |bmp| matching - |color|. If |rect| is None, the entire image is searched. */ -static PyObject *Bitmap_find_every_color(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.count_of_color(color, tolerance=0.0, rect=None) => integer */ -/* Arguments: |color| => integer (0x000000 - 0xFFFFFF), - |tolerance| => float, - |rect| => ((|x|, |y|), (|width|, |height|)) rect of ints, - or None */ -/* Description: Returns count of color in bitmap. - Functionally equivalent to: - {% len(find_every_color(color, tolerance, rect)) %} */ -static PyObject *Bitmap_count_of_color(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.find_bitmap(needle, tolerance=0.0, rect=None) => tuple (x, y) - or None */ -/* Arguments: |needle| => Bitmap object, - |tolerance| => float, - |rect| => ((|x|, |y|), (|width|, |height|)) rect of ints, - or None */ -/* Description: Searches for |needle| in |bmp|. Returns tuple `(x, y)` of - position if found, or None if not. */ -static PyObject *Bitmap_find_bitmap(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.find_every_bitmap(needle, tolerance=0.0, rect=None) => - list of tuples [(x, y), ...] */ -/* Arguments: |needle| => Bitmap object, - |tolerance| => float, - |rect| => ((|x|, |y|), (|width|, |height|)) rect of ints, - or None */ -/* Description: Returns list of all `(x, y)` coordinates where |needle| occurs - in |bmp|. */ -static PyObject *Bitmap_find_every_bitmap(BitmapObject *self, PyObject *args); - -/* Syntax: bmp.count_of_bitmap(needle, tolerance=0.0, rect=None) => - list of tuples [(x, y), ...] */ -/* Arguments: |needle| => Bitmap object, - |tolerance| => float, - |rect| => ((|x|, |y|), (|width|, |height|)) rect of ints, - or None */ -/* Description: Returns count of occurrences of |needle| in |haystack|. - Functionally equivalent to: - {% len(bmp.find_every_bitmap(needle, tolerance)) %} */ -static PyObject *Bitmap_count_of_bitmap(BitmapObject *self, PyObject *args); - -/* Methods to make pixels in bitmap iterable. - * - * E.g., to get, say, the count of all white colors in an image, you could use: - * `len([pixel for pixel in image if image.get_color(*pixel) == 0xFFUUUU])` - * (which is, of course, just a slow version of `bmp.count_of_color(0xFFUUUU)`.) - * - * This should probably not be used in performance-critical code, but is quite - * useful in debugging and general experimenting. */ -static PyObject *Bitmap_iter(BitmapObject *self); -static PyObject *Bitmap_iternext(BitmapObject *self); - -/* Returns a description of the Bitmap object. */ -static PyObject *Bitmap_str(BitmapObject *self); - -/* Getters/setters */ - -static PyObject *Bitmap_get_width(BitmapObject *self, PyObject *args); -static PyObject *Bitmap_get_height(BitmapObject *self, PyObject *args); - -/* Deep copy method */ -static PyObject *Bitmap_deepcopy(BitmapObject *self, PyObject *arg); - -static PyGetSetDef Bitmap_getsetters[] = { - {"width", (getter)Bitmap_get_width, NULL, NULL, NULL}, - {"height", (getter)Bitmap_get_height, NULL, NULL, NULL}, - {NULL} /* Sentinel */ -}; - -static PyMethodDef Bitmap_methods[] = { - {"__deepcopy__", (PyCFunction)Bitmap_deepcopy, METH_O, NULL}, - {"point_in_bounds", (PyCFunction)Bitmap_point_in_bounds, METH_VARARGS, - "Returns true if point is in bounds."}, - {"get_color", (PyCFunction)Bitmap_get_color, METH_VARARGS, - "bmp.get_color(x, y) -> hexadecimal integer\n" - "Returns hexadecimal value describing the RGB color at the given point."}, - {"open", Bitmap_open, METH_CLASS | METH_VARARGS, - "Bitmap.open(filepath) -> Bitmap object\n" - "Attempts to open image at the given absolute filepath."}, - {"from_string", Bitmap_from_string, METH_CLASS | METH_VARARGS, - "Bitmap.from_string(string) -> Bitmap object\n" - "Returns a bitmap object created from the given string."}, - {"get_portion", (PyCFunction)Bitmap_get_portion, METH_VARARGS, - "bmp.get_portion(x, y, width, height) -> Bitmap object\n" - "Returns new bitmap object created from portion of another."}, - {"copy_to_pboard", (PyCFunction)Bitmap_copy_to_pboard, METH_NOARGS, - "bmp.copy_to_pboard() -> None\n" - "Copies image to pasteboard."}, - {"save", (PyCFunction)Bitmap_save, METH_VARARGS, - "bmp.save(filepath, [format]) -> None\n" - "Saves bmp to absolute filepath in the given format.\n" - "If format is omitted, it is determined from the filename, if possible."}, - {"to_string", (PyCFunction)Bitmap_to_string, METH_NOARGS, - "bmp.to_string() -> string\n" - "Returns compressed, printable string representing bitmap."}, - {"find_color", (PyCFunction)Bitmap_find_color, METH_VARARGS, - "bmp.find_color((r, g, b), tolerance=0.0, rect=None) -> tuple (x, y) or " - "None\n" - "Returns tuple (x, y) if color is found in given rect in bmp, or None if " - "not.\n" - "If rect is None, all of bmp is searched."}, - {"find_every_color", (PyCFunction)Bitmap_find_every_color, METH_VARARGS, - "bmp.find_every_color(color, tolerance=0.0, rect=None) -> " - "list of tuples [(x, y), ...]\n" - "Returns list of all coordinates inside the given rect in bmp matching\n" - "the given color.\n" - "If rect is None, entire image is searched."}, - {"count_of_color", (PyCFunction)Bitmap_count_of_color, METH_VARARGS, - "bmp.count_of_color(color, tolerance=0.0, rect=None) -> integer\n" - "Returns count of color inside given rect in of bmp.\n" - "If rect is None, entire image is searched."}, - {"find_bitmap", (PyCFunction)Bitmap_find_bitmap, METH_VARARGS, - "bmp.find_bitmap(needle, tolerance=0.0, rect=None) -> tuple (x, y) " - "or None\n" - "Returns tuple of coordinates if needle is found in given rect in bmp, " - "or None if not."}, - {"find_every_bitmap", (PyCFunction)Bitmap_find_every_bitmap, METH_VARARGS, - "bmp.find_every_bitmap(needle, tolerance=0.0, rect=None) -> " - "list of tuples [(x, y), ...]\n" - "Returns list of all (x, y) coordinates where needle occurs in given " - "rect inside bmp."}, - {"count_of_bitmap", (PyCFunction)Bitmap_count_of_bitmap, METH_VARARGS, - "bmp.count_of_bitmap(needle, tolerance=0.0, rect=None) -> integer\n" - "Returns count of occurrences of needle in given rect inside bmp."}, - {NULL} /* Sentinel */ -}; - -/* Ridiculous monstrosity */ -PyTypeObject Bitmap_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "Bitmap", /* tp_name */ - sizeof(BitmapObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)Bitmap_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)Bitmap_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_ITER, /* tp_flags*/ - "Raw, uncompressed bitmap object", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - (getiterfunc)Bitmap_iter, /* tp_iter */ - (iternextfunc)Bitmap_iternext, /* tp_iternext */ - Bitmap_methods, /* tp_methods */ - 0, /* tp_members */ - Bitmap_getsetters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - -/* -- End of Bitmap class definition -- */ - -/* Helper function for |Bitmap_open()| and |Bitmap_save()|. - * - * Parses the arguments in f(filepath, [format]); that is, it sets |type| to - * the corresponding MMImageType for |format| if |format| is given, or attempts - * to infer the type from the filepath if not. - * - * Returns false and sets error if the image format could not be inferred. */ -static bool parseImageIOArgs(PyObject *args, char **path, MMImageType *type); - -/* -- Bitmap class method definitions -- */ - -static PyObject *Bitmap_open(PyObject *self, PyObject *args) -{ - char *path; - MMImageType type; - - MMBitmapRef bitmap; - MMIOError err; - - if (!parseImageIOArgs(args, &path, &type)) return NULL; - if ((bitmap = newMMBitmapFromFile(path, type, &err)) == NULL) { - PyErr_SetFormatString(PyExc_IOError, BUFSIZ, - "Error opening image: %s", - MMIOErrorString(type, err)); - return NULL; - } - - return BitmapObject_FromMMBitmap(bitmap); -} - -static PyObject *Bitmap_from_string(PyObject *self, PyObject *args) -{ - uint8_t *str; - size_t len; - - MMBitmapRef bitmap; - MMBMPStringError err; - - if (!PyArg_ParseTuple(args, "s#", &str, &len)) return NULL; - if ((bitmap = createMMBitmapFromString(str, len, &err)) == NULL) { - PyErr_SetFormatString(PyExc_ValueError, BUFSIZ, - "Could not create bitmap from string: %s", - MMBitmapStringErrorString(err)); - return NULL; - } - - return BitmapObject_FromMMBitmap(bitmap); -} - -/* -- Bitmap instance method definitions -- */ - -/* Returns false and sets error if |bitmap| is NULL. */ -static bool Bitmap_Ready(BitmapObject *object) -{ - if (object->bitmap == NULL || object->bitmap->imageBuffer == NULL) { - PyErr_SetString(PyExc_ValueError, "No image data set"); - return false; - } - return true; -} - -/* Attempts to extract rect from tuple if |rectTuple| is not NULL, or uses - * bounds of |bitmap| as a fallback. Returns false and sets error if rect could - * not be extracted, or returns true if it could. */ -static bool rectFromTupleOrBitmap(MMBitmapRef bitmap, - PyObject *rectTuple, - MMRect *rect); - -static PyObject *Bitmap_str(BitmapObject *self) -{ - if (!Bitmap_Ready(self)) return NULL; - return PyString_FromFormat("", - self, - (unsigned long)self->bitmap->width, - (unsigned long)self->bitmap->height, - self->bitmap->bitsPerPixel, - self->bitmap->bytesPerPixel); -} - -static PyObject *Bitmap_deepcopy(BitmapObject *self, PyObject *arg) -{ - MMBitmapRef copy = self->bitmap == NULL ? NULL : copyMMBitmap(self->bitmap); - return BitmapObject_FromMMBitmap(copy); -} - -/* Creates new PyList from MMPointArray. */ -static PyObject *PyList_FromPointArray(MMPointArrayRef pointArray); - -/* -- Iterator methods -- */ - -static PyObject *Bitmap_iter(BitmapObject *self) -{ - if (!Bitmap_Ready(self)) return NULL; - - self->point = MMPointZero; - Py_INCREF(self); - return (PyObject *)self; -} - -static PyObject *Bitmap_iternext(BitmapObject *self) -{ - if (!Bitmap_Ready(self)) return NULL; - - if (++(self->point).x < self->bitmap->width) { - return Py_BuildValue("(kk)", self->point.x, self->point.y); - } else if (++(self->point).y < self->bitmap->height){ - self->point.x = 0; - return Py_BuildValue("(kk)", self->point.x, self->point.y); - } else { - /* Raise standard StopIteration exception with empty value. */ - PyErr_SetNone(PyExc_StopIteration); - return NULL; - } -} - -/* -- End of iterator methods -- */ - -/* -- Getters/setters -- */ - -static PyObject *Bitmap_get_width(BitmapObject *self, PyObject *args) -{ - return Py_BuildValue("k", self->bitmap->width); -} - -static PyObject *Bitmap_get_height(BitmapObject *self, PyObject *args) -{ - return Py_BuildValue("k", self->bitmap->height); -} - -/* -- End of getters/setters -- */ - -static PyObject *Bitmap_get_portion(BitmapObject *self, PyObject *args) -{ - MMRect rect; - MMBitmapRef portion = NULL; - if (!PyArg_ParseTuple(args, "(kk)(kk)", &(rect.origin.x), - &(rect.origin.y), - &(rect.size.width), - &(rect.size.height))) { - return NULL; - } - - if (!MMBitmapRectInBounds(self->bitmap, rect)) { - PyErr_SetString(PyExc_ValueError, "Portion out of bounds"); - return NULL; - } - - portion = copyMMBitmapFromPortion(self->bitmap, rect); - - if (portion == NULL) { - PyErr_SetString(PyExc_IOError, "Error grabbing bitmap portion"); - return NULL; - } - return BitmapObject_FromMMBitmap(portion); -} - -static PyObject *Bitmap_point_in_bounds(BitmapObject *self, PyObject *args) -{ - MMPoint point; - - if (!PyArg_ParseTuple(args, "kk", &point.x, &point.y) || - !Bitmap_Ready(self)) { - return NULL; - } - - if (MMBitmapPointInBounds(self->bitmap, point)) { - Py_RETURN_TRUE; - } - - Py_RETURN_FALSE; -} - -static PyObject *Bitmap_copy_to_pboard(BitmapObject *self, PyObject *args) -{ - MMPasteError err; - - if (!Bitmap_Ready(self)) return NULL; - if ((err = copyMMBitmapToPasteboard(self->bitmap)) != kMMPasteNoError) { - PyErr_SetFormatString(PyExc_OSError, BUFSIZ, - "Could not copy image to pasteboard: %s", - MMPasteErrorString(err)); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject *Bitmap_save(BitmapObject *self, PyObject *args) -{ - char *path; - MMImageType type; - - if (!parseImageIOArgs(args, &path, &type) || !Bitmap_Ready(self)) { - return NULL; - } - - if (saveMMBitmapToFile(self->bitmap, path, type) != 0) { - PyErr_SetString(PyExc_IOError, "Could not save image to file"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject *Bitmap_to_string(BitmapObject *self, PyObject *args) -{ - char *buf = NULL; - MMBMPStringError err; - - if (!Bitmap_Ready(self)) return NULL; - - if ((buf = (char *)createStringFromMMBitmap(self->bitmap, &err)) == NULL) { - PyErr_SetFormatString(PyExc_IOError, BUFSIZ, - "Could not create string from bitmap: %s", - MMBitmapStringErrorString(err)); - return NULL; - } - return PyString_FromString(buf); -} - -static PyObject *Bitmap_get_color(BitmapObject *self, PyObject *args) -{ - MMPoint point; - - if (!PyArg_ParseTuple(args, "kk", &point.x, &point.y) || - !Bitmap_Ready(self)) return NULL; - - if (!MMBitmapPointInBounds(self->bitmap, point)) { - PyErr_SetString(PyExc_ValueError, "Point out of bounds"); - return NULL; - } - - return Py_BuildValue("I", MMRGBHexAtPoint(self->bitmap, point.x, point.y)); -} - -static PyObject *Bitmap_find_color(BitmapObject *self, PyObject *args) -{ - MMRGBHex color; - float tolerance = 0.0f; - PyObject *rectTuple = NULL; - - MMRect rect; - MMPoint point; - - if (!PyArg_ParseTuple(args, "k|fO", &color, &tolerance, &rectTuple) || - !Bitmap_Ready(self) || - !rectFromTupleOrBitmap(self->bitmap, rectTuple, &rect)) { - return NULL; - } - - if (findColorInRect(self->bitmap, color, &point, rect, tolerance) == 0) { - return Py_BuildValue("(kk)", point.x, point.y); - } - - Py_RETURN_NONE; -} - -static PyObject *Bitmap_find_every_color(BitmapObject *self, PyObject *args) -{ - MMRGBHex color; - float tolerance = 0.0f; - PyObject *rectTuple = NULL; - - MMRect rect; - MMPointArrayRef pointArray; - PyObject *list; - - if (!PyArg_ParseTuple(args, "k|fO", &color, &tolerance, &rectTuple) || - !Bitmap_Ready(self) || - !rectFromTupleOrBitmap(self->bitmap, rectTuple, &rect)) { - return NULL; - } - - pointArray = findAllColorInRect(self->bitmap, color, rect, tolerance); - if (pointArray == NULL) return NULL; - - list = PyList_FromPointArray(pointArray); - destroyMMPointArray(pointArray); - if (list == NULL) return NULL; - - return list; -} - -static PyObject *Bitmap_count_of_color(BitmapObject *self, PyObject *args) -{ - MMRGBHex color; - float tolerance = 0.0f; - PyObject *rectTuple = NULL; - - MMRect rect; - - if (!PyArg_ParseTuple(args, "k|fO", &color, &tolerance, &rectTuple) || - !Bitmap_Ready(self) || - !rectFromTupleOrBitmap(self->bitmap, rectTuple, &rect)) { - return NULL; - } - - return Py_BuildValue("k", countOfColorsInRect(self->bitmap, color, - rect, tolerance)); -} - -static PyObject *Bitmap_find_bitmap(BitmapObject *self, PyObject *args) -{ - BitmapObject *needle; - float tolerance = 0.0f; - MMPoint point; - PyObject *rectTuple = NULL; - MMRect rect; - - if (!PyArg_ParseTuple(args, "O!|fO", &Bitmap_Type, &needle, - &tolerance, &rectTuple) || - !Bitmap_Ready(self) || !Bitmap_Ready(needle) || - !rectFromTupleOrBitmap(self->bitmap, rectTuple, &rect)) { - return NULL; - } - - if (findBitmapInRect(needle->bitmap, self->bitmap, &point, - rect, tolerance) == 0) { - return Py_BuildValue("(kk)", point.x, point.y); - } - - Py_RETURN_NONE; -} - -static PyObject *Bitmap_find_every_bitmap(BitmapObject *self, PyObject *args) -{ - BitmapObject *needle; - float tolerance = 0.0f; - PyObject *rectTuple = NULL; - MMRect rect; - - MMPointArrayRef pointArray; - PyObject *list; - - if (!PyArg_ParseTuple(args, "O!|fO", &Bitmap_Type, &needle, - &tolerance, &rectTuple) || - !Bitmap_Ready(self) || !Bitmap_Ready(needle) || - !rectFromTupleOrBitmap(self->bitmap, rectTuple, &rect)) { - return NULL; - } - - pointArray = findAllBitmapInRect(needle->bitmap, self->bitmap, - rect, tolerance); - if (pointArray == NULL) return NULL; - - list = PyList_FromPointArray(pointArray); - destroyMMPointArray(pointArray); - if (list == NULL) return NULL; - - return list; -} - -static PyObject *Bitmap_count_of_bitmap(BitmapObject *self, PyObject *args) -{ - BitmapObject *needle; - float tolerance = 0.0f; - PyObject *rectTuple = NULL; - MMRect rect; - - if (!PyArg_ParseTuple(args, "O!|fO", &Bitmap_Type, &needle, - &tolerance, &rectTuple) || - !Bitmap_Ready(self) || !Bitmap_Ready(needle) || - !rectFromTupleOrBitmap(self->bitmap, rectTuple, &rect)) { - return NULL; - } - - return Py_BuildValue("k", countOfBitmapInRect(needle->bitmap, self->bitmap, - rect, tolerance)); -} - -static bool rectFromTupleOrBitmap(MMBitmapRef bitmap, - PyObject *rectTuple, - MMRect *rect) -{ - assert(rect != NULL); - - if (rectTuple == NULL || rectTuple == Py_None) { - *rect = MMBitmapGetBounds(bitmap); - return true; - } - - if (!PyArg_ParseTuple(rectTuple, "(kk)(kk)", &(rect->origin.x), - &(rect->origin.y), - &(rect->size.width), - &(rect->size.height))) { - PyErr_SetString(PyExc_TypeError, "Argument is not a rect"); - return false; - } - - return true; -} - -static PyObject *PyList_FromPointArray(MMPointArrayRef pointArray) -{ - PyObject *list; - size_t i; - assert(pointArray != NULL); - - if ((list = PyList_New(pointArray->count)) == NULL) return NULL; - for (i = 0; i < pointArray->count; ++i) { - MMPoint point = MMPointArrayGetItem(pointArray, i); - PyObject *val = Py_BuildValue("(kk)", point.x, point.y); - if (val == NULL) return NULL; - - PyList_SetItem(list, i, val); /* "Steals" the reference to val. */ - } - - return list; -} - -static bool parseImageIOArgs(PyObject *args, char **path, MMImageType *type) -{ - int pathLen; - char *format = NULL; - - assert(path != NULL); - assert(type != NULL); - - if (!PyArg_ParseTuple(args, "s#|s", path, &pathLen, &format)) return false; - - /* Attempt to derive type from path */ - if (format == NULL) { - const char *ext = getExtension(*path, pathLen); - - if (ext == NULL) { - PyErr_SetString(PyExc_ValueError, "Could not find file extension"); - return false; - } - - *type = imageTypeFromExtension(ext); - } else { - *type = imageTypeFromExtension(format); - } - - if (*type == kInvalidImageType) { - PyErr_SetString(PyExc_TypeError, "Unsupported image format"); - return false; - } - - return true; -} - -/* -- End of Bitmap instance methods -- */ - -PyObject *BitmapObject_FromMMBitmap(MMBitmapRef bitmap) -{ - BitmapObject *newBitmap = (BitmapObject *)_PyObject_New(&Bitmap_Type); - if (newBitmap == NULL) return NULL; - - newBitmap->bitmap = bitmap; - - return (PyObject *)newBitmap; -}