/*
* The Python Imaging Library.
*
* display support (and other windows-related stuff)
*
* History:
* 1996-05-13 fl Windows DIB support
* 1996-05-21 fl Added palette stuff
* 1996-05-28 fl Added display_mode stuff
* 1997-09-21 fl Added draw primitive
* 2001-09-17 fl Added ImagingGrabScreen (from _grabscreen.c)
* 2002-05-12 fl Added ImagingListWindows
* 2002-11-19 fl Added clipboard support
* 2002-11-25 fl Added GetDC/ReleaseDC helpers
* 2003-05-21 fl Added create window support (including window callback)
* 2003-09-05 fl Added fromstring/tostring methods
* 2009-03-14 fl Added WMF support (from pilwmf)
*
* Copyright (c) 1997-2003 by Secret Labs AB.
* Copyright (c) 1996-1997 by Fredrik Lundh.
*
* See the README file for information on usage and redistribution.
*/
#include "Python.h"
#include "Imaging.h"
#include "py3.h"
/* -------------------------------------------------------------------- */
/* Windows DIB support */
#ifdef _WIN32
#include "ImDib.h"
#if SIZEOF_VOID_P == 8
#define F_HANDLE "K"
#else
#define F_HANDLE "k"
#endif
typedef struct {
PyObject_HEAD
ImagingDIB dib;
} ImagingDisplayObject;
static PyTypeObject ImagingDisplayType;
static ImagingDisplayObject*
_new(const char* mode, int xsize, int ysize)
{
ImagingDisplayObject *display;
if (PyType_Ready(&ImagingDisplayType) < 0)
return NULL;
display = PyObject_New(ImagingDisplayObject, &ImagingDisplayType);
if (display == NULL)
return NULL;
display->dib = ImagingNewDIB(mode, xsize, ysize);
if (!display->dib) {
Py_DECREF(display);
return NULL;
}
return display;
}
static void
_delete(ImagingDisplayObject* display)
{
if (display->dib)
ImagingDeleteDIB(display->dib);
PyObject_Del(display);
}
static PyObject*
_expose(ImagingDisplayObject* display, PyObject* args)
{
HDC hdc;
if (!PyArg_ParseTuple(args, F_HANDLE, &hdc))
return NULL;
ImagingExposeDIB(display->dib, hdc);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject*
_draw(ImagingDisplayObject* display, PyObject* args)
{
HDC hdc;
int dst[4];
int src[4];
if (!PyArg_ParseTuple(args, F_HANDLE "(iiii)(iiii)", &hdc,
dst+0, dst+1, dst+2, dst+3,
src+0, src+1, src+2, src+3))
return NULL;
ImagingDrawDIB(display->dib, hdc, dst, src);
Py_INCREF(Py_None);
return Py_None;
}
extern Imaging PyImaging_AsImaging(PyObject *op);
static PyObject*
_paste(ImagingDisplayObject* display, PyObject* args)
{
Imaging im;
PyObject* op;
int xy[4];
xy[0] = xy[1] = xy[2] = xy[3] = 0;
if (!PyArg_ParseTuple(args, "O|(iiii)", &op, xy+0, xy+1, xy+2, xy+3))
return NULL;
im = PyImaging_AsImaging(op);
if (!im)
return NULL;
if (xy[2] <= xy[0])
xy[2] = xy[0] + im->xsize;
if (xy[3] <= xy[1])
xy[3] = xy[1] + im->ysize;
ImagingPasteDIB(display->dib, im, xy);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject*
_query_palette(ImagingDisplayObject* display, PyObject* args)
{
HDC hdc;
int status;
if (!PyArg_ParseTuple(args, F_HANDLE, &hdc))
return NULL;
status = ImagingQueryPaletteDIB(display->dib, hdc);
return Py_BuildValue("i", status);
}
static PyObject*
_getdc(ImagingDisplayObject* display, PyObject* args)
{
HWND window;
HDC dc;
if (!PyArg_ParseTuple(args, F_HANDLE, &window))
return NULL;
dc = GetDC(window);
if (!dc) {
PyErr_SetString(PyExc_IOError, "cannot create dc");
return NULL;
}
return Py_BuildValue(F_HANDLE, dc);
}
static PyObject*
_releasedc(ImagingDisplayObject* display, PyObject* args)
{
HWND window;
HDC dc;
if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &window, &dc))
return NULL;
ReleaseDC(window, dc);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject*
_frombytes(ImagingDisplayObject* display, PyObject* args)
{
char* ptr;
int bytes;
#if PY_VERSION_HEX >= 0x03000000
if (!PyArg_ParseTuple(args, "y#:frombytes", &ptr, &bytes))
return NULL;
#else
if (!PyArg_ParseTuple(args, "s#:fromstring", &ptr, &bytes))
return NULL;
#endif
if (display->dib->ysize * display->dib->linesize != bytes) {
PyErr_SetString(PyExc_ValueError, "wrong size");
return NULL;
}
memcpy(display->dib->bits, ptr, bytes);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject*
_tobytes(ImagingDisplayObject* display, PyObject* args)
{
#if PY_VERSION_HEX >= 0x03000000
if (!PyArg_ParseTuple(args, ":tobytes"))
return NULL;
#else
if (!PyArg_ParseTuple(args, ":tostring"))
return NULL;
#endif
return PyBytes_FromStringAndSize(
display->dib->bits, display->dib->ysize * display->dib->linesize
);
}
static struct PyMethodDef methods[] = {
{"draw", (PyCFunction)_draw, 1},
{"expose", (PyCFunction)_expose, 1},
{"paste", (PyCFunction)_paste, 1},
{"query_palette", (PyCFunction)_query_palette, 1},
{"getdc", (PyCFunction)_getdc, 1},
{"releasedc", (PyCFunction)_releasedc, 1},
{"frombytes", (PyCFunction)_frombytes, 1},
{"tobytes", (PyCFunction)_tobytes, 1},
{"fromstring", (PyCFunction)_frombytes, 1},
{"tostring", (PyCFunction)_tobytes, 1},
{NULL, NULL} /* sentinel */
};
static PyObject*
_getattr_mode(ImagingDisplayObject* self, void* closure)
{
return Py_BuildValue("s", self->dib->mode);
}
static PyObject*
_getattr_size(ImagingDisplayObject* self, void* closure)
{
return Py_BuildValue("ii", self->dib->xsize, self->dib->ysize);
}
static struct PyGetSetDef getsetters[] = {
{ "mode", (getter) _getattr_mode },
{ "size", (getter) _getattr_size },
{ NULL }
};
static PyTypeObject ImagingDisplayType = {
PyVarObject_HEAD_INIT(NULL, 0)
"ImagingDisplay", /*tp_name*/
sizeof(ImagingDisplayObject), /*tp_size*/
0, /*tp_itemsize*/
/* methods */
(destructor)_delete, /*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*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
methods, /*tp_methods*/
0, /*tp_members*/
getsetters, /*tp_getset*/
};
PyObject*
PyImaging_DisplayWin32(PyObject* self, PyObject* args)
{
ImagingDisplayObject* display;
char *mode;
int xsize, ysize;
if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize))
return NULL;
display = _new(mode, xsize, ysize);
if (display == NULL)
return NULL;
return (PyObject*) display;
}
PyObject*
PyImaging_DisplayModeWin32(PyObject* self, PyObject* args)
{
char *mode;
int size[2];
mode = ImagingGetModeDIB(size);
return Py_BuildValue("s(ii)", mode, size[0], size[1]);
}
/* -------------------------------------------------------------------- */
/* Windows screen grabber */
PyObject*
PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
{
int width, height;
HBITMAP bitmap;
BITMAPCOREHEADER core;
HDC screen, screen_copy;
PyObject* buffer;
/* step 1: create a memory DC large enough to hold the
entire screen */
screen = CreateDC("DISPLAY", NULL, NULL, NULL);
screen_copy = CreateCompatibleDC(screen);
width = GetDeviceCaps(screen, HORZRES);
height = GetDeviceCaps(screen, VERTRES);
bitmap = CreateCompatibleBitmap(screen, width, height);
if (!bitmap)
goto error;
if (!SelectObject(screen_copy, bitmap))
goto error;
Loading ...