summaryrefslogtreecommitdiff
path: root/src/surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/surface.c')
-rw-r--r--src/surface.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/src/surface.c b/src/surface.c
index 7a6fd2e..568aad7 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -1144,13 +1144,102 @@ PyTypeObject PycairoWin32Surface_Type = {
#ifdef CAIRO_HAS_XCB_SURFACE
#include <cairo-xcb.h>
+#ifdef HAVE_XPYB
+/** Convert a Python object from xpyb to a C struct matching libxcb type.
+ * The object must be referenced if you want to keep returned data away from
+ * garbage collection.
+ * @param obj The object to convert.
+ * @param len The size of the object read by Python.
+ * @return A pointer to that data.
+ */
+const void *
+xpyb2struct(PyObject *obj, Py_ssize_t *len)
+{
+ const void *data;
+
+ if (PyObject_AsReadBuffer(obj, &data, len) < 0)
+ return NULL;
+
+ return data;
+}
+
+static int
+have_xpyb(void)
+{
+ static int have_xpyb = -1;
+ if(have_xpyb == -1) {
+ /* Get type from xpyb */
+ xpyb_IMPORT;
+ /* Some types are not defined in the CAPI */
+ PyObject *xpyb_module = PyImport_ImportModule("xcb.xproto");
+ if (xpyb_module) {
+ PyObject *dict = PyModule_GetDict(xpyb_module);
+ xpybVISUALTYPE_type = PyDict_GetItemString(dict, "VISUALTYPE");
+ Py_DECREF(xpyb_module);
+ have_xpyb = 1;
+ }
+ else
+ have_xpyb = 0;
+ }
+ return have_xpyb;
+}
+
+#endif
+
static PyObject *
xcb_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
+#ifdef HAVE_XPYB
+ int width, height;
+ xcb_drawable_t drawable;
+ PyObject *visual;
+ xpybConn *conn;
+
+ if(!have_xpyb())
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "O!IO!ii:XCBSurface.__new__",
+ xpyb_CAPI->xpybConn_type, &conn,
+ &drawable,
+ xpybVISUALTYPE_type, &visual,
+ &width, &height))
+ return NULL;
+
+ /* Convert Python object VISUALTYPE to a xcb_visualtype_t */
+ Py_ssize_t length;
+ xcb_visualtype_t *visualtype = (xcb_visualtype_t *) xpyb2struct(visual, &length);
+
+ if (length < sizeof(xcb_visualtype_t))
+ return NULL;
+
+ return PycairoSurface_FromSurface (
+ cairo_xcb_surface_create (conn->conn, drawable, visualtype,
+ width, height), NULL);
+#else
PyErr_SetString(PyExc_TypeError,
- "The XCBSurface type cannot be directly instantiated");
+ "pycairo was not compiled with xpyb support");
return NULL;
+#endif
}
+#ifdef HAVE_XPYB
+static PyObject *
+xcb_surface_set_size (PycairoXCBSurface *o, PyObject *args) {
+ int width, height;
+
+ if (!PyArg_ParseTuple(args, "ii:XCBSurface.set_size", &width, &height))
+ return NULL;
+ cairo_xcb_surface_set_size (o->surface, width, height);
+ Py_RETURN_NONE;
+}
+#endif
+
+static PyMethodDef xcb_surface_methods[] = {
+#ifdef HAVE_XPYB
+ {"set_size", (PyCFunction)xcb_surface_set_size, METH_VARARGS },
+#endif
+ {NULL, NULL, 0, NULL},
+};
+
PyTypeObject PycairoXCBSurface_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
@@ -1180,7 +1269,7 @@ PyTypeObject PycairoXCBSurface_Type = {
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- 0, /* tp_methods */
+ xcb_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */