예제 #1
0
static int
add_templates (gpointer gclass, PyObject * templates)
{
  if (PyTuple_Check (templates)) {
    gint i, len;
    PyGObject *templ;

    len = PyTuple_Size (templates);
    if (len == 0)
      return 0;

    for (i = 0; i < len; i++) {
      templ = (PyGObject *) PyTuple_GetItem (templates, i);

      if (!pygobject_check (templ, &PyGObject_Type)) {
        PyObject *repr = PyObject_Repr ((PyObject *) templ);
#if PY_VERSION_HEX < 0x03000000
        PyErr_Format (PyExc_TypeError, "expected GObject but got %s",
            PyString_AsString (repr));
#else
        PyErr_Format (PyExc_TypeError, "expected GObject but got %s",
            _PyUnicode_AsString (repr));
#endif
        Py_DECREF (repr);

        return -1;
      } else if (!GST_IS_PAD_TEMPLATE (pygobject_get (templ))) {
        gchar *error =
            g_strdup_printf
            ("entries for __gsttemplates__ must be of type GstPadTemplate (%s)",
            G_OBJECT_TYPE_NAME (pygobject_get (templ)));
        PyErr_SetString (PyExc_TypeError, error);
        g_free (error);

        return -1;
      }
    }

    for (i = 0; i < len; i++) {
      templ = (PyGObject *) PyTuple_GetItem (templates, i);
      gst_element_class_add_pad_template (gclass,
          GST_PAD_TEMPLATE (templ->obj));
    }
    return 0;

  } else if (!pygobject_check (templates, &PyGObject_Type) ||
      GST_IS_PAD_TEMPLATE (pygobject_get (templates)) == FALSE) {
    PyErr_SetString (PyExc_TypeError,
        "entry for __gsttemplates__ must be of type GstPadTemplate");

    return -1;
  }

  gst_element_class_add_pad_template (gclass,
      GST_PAD_TEMPLATE (pygobject_get (templates)));

  return 0;
}
예제 #2
0
static PyObject * py_set_strut(PyObject * self, PyObject * args) {
	PyObject * py_gdk_window;
	PyObject * py_list;
	if (!PyArg_ParseTuple(args, "OO", &py_gdk_window, &py_list))
		return NULL;

	if(!pygobject_check(py_gdk_window, pygobject_lookup_class(GDK_TYPE_WINDOW))) {
		return NULL;
	}

	if(!PyList_Check(py_list)) {
		return NULL;
	}

	if (PyList_Size(py_list) == 4) {
		/* if _net_wm_strut */
		long strut[4];
		for (int i = 0; i < 4; ++i) {
			PyObject * v = PyList_GetItem(py_list, i);
			if (PyLong_Check(v)) {
				strut[i] = PyLong_AsLong(v);
			} else {
				return NULL;
			}
		}

		GdkAtom cardinal = gdk_atom_intern("CARDINAL", FALSE);
		GdkAtom _net_wm_strut = gdk_atom_intern("_NET_WM_STRUT", FALSE);

		gdk_property_change(GDK_WINDOW(pygobject_get(py_gdk_window)),
				_net_wm_strut, cardinal, 32, GDK_PROP_MODE_REPLACE,
				(guchar*) strut, 4);
	} else if (PyList_Size(py_list) == 12) {
		/* if _net_wm_strut_partial */

		long strut_partial[12];
		for (int i = 0; i < 12; ++i) {
			PyObject * v = PyList_GetItem(py_list, i);
			if (PyLong_Check(v)) {
				strut_partial[i] = PyLong_AsLong(v);
			} else {
				return NULL;
			}
		}

		GdkAtom cardinal = gdk_atom_intern("CARDINAL", FALSE);
		GdkAtom _net_wm_strut_partial = gdk_atom_intern("_NET_WM_STRUT_PARTIAL", FALSE);

		gdk_property_change(GDK_WINDOW(pygobject_get(py_gdk_window)),
				_net_wm_strut_partial, cardinal, 32, GDK_PROP_MODE_REPLACE,
				(guchar*) strut_partial, 12);
	} else {
		/* else error */
		return NULL;
	}

	Py_RETURN_NONE;
}
예제 #3
0
SignalManager *signal_manager_new(GeanyPlugin *geany_plugin)
{
	SignalManager *man;
	PyObject *module;

	man = g_new0(SignalManager, 1);

	man->geany_plugin = geany_plugin;
	man->py_obj = NULL;
	man->obj = NULL;

	module = PyImport_ImportModule("geany");
	if (!module)
	{
		if (PyErr_Occurred())
			PyErr_Print();
		g_warning("Unable to import 'geany' module");
		return NULL;
	}

	man->py_obj = PyObject_GetAttrString(module, "signals");
	Py_DECREF(module);
	if (!man->py_obj)
	{
		if (PyErr_Occurred())
			PyErr_Print();
		g_warning("Unable to get 'SignalManager' instance from 'geany' module.");
		return NULL;
	}
	man->obj = pygobject_get(man->py_obj);

	signal_manager_connect_signals(man);

	return man;
}
예제 #4
0
static PyObject *
pygst_debug_log (PyObject * pyobject, PyObject * string, GstDebugLevel level,
    gboolean isgstobject)
{
#ifndef GST_DISABLE_GST_DEBUG
  gchar *str;
  gchar *function;
  gchar *filename;
  int lineno;
  PyFrameObject *frame;
  GObject *object = NULL;

  if (!PyArg_ParseTuple (string, "s:gst.debug_log", &str)) {
    PyErr_SetString (PyExc_TypeError, "Need a string!");
    return NULL;
  }

  frame = PyEval_GetFrame ();
  function = PyString_AsString (frame->f_code->co_name);
  filename =
      g_path_get_basename (PyString_AsString (frame->f_code->co_filename));
  lineno = PyCode_Addr2Line (frame->f_code, frame->f_lasti);
  /* gst_debug_log : category, level, file, function, line, object, format, va_list */
  if (isgstobject)
    object = G_OBJECT (pygobject_get (pyobject));
  gst_debug_log (python_debug, level, filename, function, lineno, object,
      "%s", str);
  if (filename)
    g_free (filename);
#endif
  Py_INCREF (Py_None);
  return Py_None;
}
예제 #5
0
static int
add_templates (gpointer gclass, PyObject * templates)
{
  if (PyTuple_Check (templates)) {
    gint i, len;
    PyGObject *templ;

    len = PyTuple_Size (templates);
    if (len == 0)
      return 0;

    for (i = 0; i < len; i++) {
      templ = (PyGObject *) PyTuple_GetItem (templates, i);
      if (GST_IS_PAD_TEMPLATE (pygobject_get (templ)) == FALSE) {
        PyErr_SetString (PyExc_TypeError,
            "entries for __gsttemplates__ must be of type GstPadTemplate");
        return -1;
      }
    }

    for (i = 0; i < len; i++) {
      templ = (PyGObject *) PyTuple_GetItem (templates, i);
      gst_element_class_add_pad_template (gclass,
          GST_PAD_TEMPLATE (templ->obj));
    }
    return 0;

  }

  if (GST_IS_PAD_TEMPLATE (pygobject_get (templates)) == FALSE) {
    PyErr_SetString (PyExc_TypeError,
        "entry for __gsttemplates__ must be of type GstPadTemplate");
    return -1;
  }

  gst_element_class_add_pad_template (gclass,
      GST_PAD_TEMPLATE (pygobject_get (templates)));

  return 0;
}
예제 #6
0
static PyObject * py_print_type(PyObject * self, PyObject * args) {
	PyObject * pyobj;
	if (!PyArg_ParseTuple(args, "O", &pyobj))
		return NULL;

	if(pygobject_check(pyobj, pygobject_lookup_class(CLUTTER_TYPE_STAGE))) {
		GObject * obj = pygobject_get(pyobj);
		GType t = G_OBJECT_TYPE(obj);
		printf("type = %s\n", g_type_name(t));
	} else {
		printf("unknown object\n");
	}

	Py_RETURN_NONE;
}
예제 #7
0
static MooObjectArray *
_moo_pyobject_to_object_array_no_check (PyObject *seq,
                                        int       len)
{
    int i;
    MooObjectArray *ar;

    ar = moo_object_array_new ();

    for (i = 0; i < len; ++i)
    {
        PyObject *item = PySequence_ITEM (seq, i);
        moo_object_array_append (ar, pygobject_get (item));
    }

    return ar;
}
예제 #8
0
static PyObject * py_gdk_add_filter(PyObject * self, PyObject * args) {
	PyObject * pyobj; // the GdkWindow
	PyObject * func; // the function to call

	if (!PyArg_ParseTuple(args, "OO", &pyobj, &func))
		return NULL;

    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError, "parameter must be callable");
        return NULL;
    }

	if(pygobject_check(pyobj, pygobject_lookup_class(GDK_TYPE_WINDOW)) && PyCallable_Check(func)) {
		GdkWindow * window = GDK_WINDOW(pygobject_get(pyobj));
		Py_INCREF(func);
		Py_INCREF(func);
		Py_INCREF(func);
		Py_INCREF(func);
		Py_INCREF(func);
		Py_INCREF(func);
		Py_INCREF(func);

		printf("YYYY %d\n", ((PyObject*)(func))->ob_refcnt);


//		PyObject_Print(func, stdout, 0);
//		printf("\nXXXX %p\n", func);
//		PyObject* result = PyObject_CallFunction(func, "i", 10);
//		printf("return = %p\n", result);
//		if (result != NULL)
//			PyObject_Print(result, stdout, 0);
//		else
//			return NULL;
//
//		Py_DECREF(result);

		g_func = func;
		gdk_window_add_filter(window, &call_python_filter, (gpointer)func);
	} else {
		printf("unknown object\n");
	}

	Py_RETURN_NONE;
}
예제 #9
0
static int
pygtk_style_helper_setitem(PyGtkStyleHelper_Object *self, Py_ssize_t pos,
			   PyObject *value)
{
    extern PyTypeObject PyGdkGC_Type;
    extern PyTypeObject PyGdkPixmap_Type;

    if (pos < 0) pos += NUM_STATES;
    if (pos < 0 || pos >= NUM_STATES) {
	PyErr_SetString(PyExc_IndexError, "index out of range");
	return -1;
    }
    switch (self->type) {
    case STYLE_COLOUR_ARRAY:
	{
	    GdkColor *array = (GdkColor *)self->array;

	    if (!pyg_boxed_check(value, GDK_TYPE_COLOR)) {
		PyErr_SetString(PyExc_TypeError, "can only assign a GdkColor");
		return -1;
	    }
	    array[pos] = *pyg_boxed_get(value, GdkColor);
	    return 0;
	}
    case STYLE_GC_ARRAY:
	{
	    GdkGC **array = (GdkGC **)self->array;

	    if (!pygobject_check(value, &PyGdkGC_Type)) {
		PyErr_SetString(PyExc_TypeError, "can only assign a GdkGC");
		return -1;
	    }
	    if (array[pos]) {
		g_object_unref(array[pos]);
	    }
	    array[pos] = GDK_GC(g_object_ref(pygobject_get(value)));
	    return 0;
	}
    case STYLE_PIXMAP_ARRAY:
	{
	    GdkPixmap **array = (GdkPixmap **)self->array;
	    GdkPixmap *cvalue = NULL;

	    if (pygobject_check(value, &PyGdkPixmap_Type))
		cvalue = GDK_PIXMAP(g_object_ref(pygobject_get(value)));
	    else if (PyLong_Check(value)) {
		if (PyLong_AsLong(value) != GDK_PARENT_RELATIVE) {
		    PyErr_SetString(PyExc_TypeError,
				    "can only assign a GdkPixmap, None or "
				    "GDK_PARENT_RELATIVE");
		    return -1;
		}
		cvalue = (GdkPixmap*)GDK_PARENT_RELATIVE;
	    } else if (value != Py_None) {
		PyErr_SetString(PyExc_TypeError,
				"can only assign a GdkPixmap, None or "
				"GDK_PARENT_RELATIVE");
		return -1;
	    }
	    
	    if (array[pos] && (long)array[pos] != GDK_PARENT_RELATIVE) {
		g_object_unref(array[pos]);
	    }
	    array[pos] = cvalue;
	    return 0;
	}
    }
    g_assert_not_reached();
    return -1;
}
예제 #10
0
GObject* ada_widget_from_pyobject (PyObject* object) {
   return g_object_ref (pygobject_get (object));
}
예제 #11
0
static PyObject *
_wrap_g_field_info_set_value (PyGIBaseInfo *self,
                              PyObject     *args)
{
    PyObject *instance;
    PyObject *py_value;
    GIBaseInfo *container_info;
    GIInfoType container_info_type;
    gpointer pointer;
    GITypeInfo *field_type_info;
    GIArgument value;
    PyObject *retval = NULL;

    if (!PyArg_ParseTuple (args, "OO:FieldInfo.set_value", &instance, &py_value)) {
        return NULL;
    }

    container_info = g_base_info_get_container (self->info);
    g_assert (container_info != NULL);

    /* Check the instance. */
    if (!_pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) container_info, TRUE, instance)) {
        _PyGI_ERROR_PREFIX ("argument 1: ");
        return NULL;
    }

    /* Get the pointer to the container. */
    container_info_type = g_base_info_get_type (container_info);
    switch (container_info_type) {
        case GI_INFO_TYPE_UNION:
        case GI_INFO_TYPE_STRUCT:
            pointer = pyg_boxed_get (instance, void);
            break;
        case GI_INFO_TYPE_OBJECT:
            pointer = pygobject_get (instance);
            break;
        default:
            /* Other types don't have fields. */
            g_assert_not_reached();
    }

    field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info);

    /* Check the value. */
    {
        gboolean retval;

        retval = _pygi_g_type_info_check_object (field_type_info, py_value, TRUE);
        if (retval < 0) {
            goto out;
        }

        if (!retval) {
            _PyGI_ERROR_PREFIX ("argument 2: ");
            goto out;
        }
    }

    /* Set the field's value. */
    /* A few types are not handled by g_field_info_set_field, so do it here. */
    if (!g_type_info_is_pointer (field_type_info)
            && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
        GIBaseInfo *info;
        GIInfoType info_type;

        if (! (g_field_info_get_flags ( (GIFieldInfo *) self->info) & GI_FIELD_IS_WRITABLE)) {
            PyErr_SetString (PyExc_RuntimeError, "field is not writable");
            goto out;
        }

        info = g_type_info_get_interface (field_type_info);

        info_type = g_base_info_get_type (info);

        switch (info_type) {
            case GI_INFO_TYPE_UNION:
                PyErr_SetString (PyExc_NotImplementedError, "setting an union is not supported yet");
                goto out;
            case GI_INFO_TYPE_STRUCT:
            {
                gboolean is_simple;
                gsize offset;
                gssize size;

                is_simple = pygi_g_struct_info_is_simple ( (GIStructInfo *) info);

                if (!is_simple) {
                    PyErr_SetString (PyExc_TypeError,
                                     "cannot set a structure which has no well-defined ownership transfer rules");
                    g_base_info_unref (info);
                    goto out;
                }

                value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);
                if (PyErr_Occurred()) {
                    g_base_info_unref (info);
                    goto out;
                }

                offset = g_field_info_get_offset ( (GIFieldInfo *) self->info);
                size = g_struct_info_get_size ( (GIStructInfo *) info);
                g_assert (size > 0);

                g_memmove ((char*) pointer + offset, value.v_pointer, size);

                g_base_info_unref (info);

                retval = Py_None;
                goto out;
            }
            default:
                /* Fallback. */
                break;
        }

        g_base_info_unref (info);
    } else if (g_type_info_is_pointer (field_type_info)
            && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_VOID) {
        int offset;

        if (py_value != Py_None && !PYGLIB_PyLong_Check(py_value)) {
            if (PyErr_WarnEx(PyExc_RuntimeWarning,
                         "Usage of gpointers to store objects is being deprecated. "
                         "Please use integer values only, see: https://bugzilla.gnome.org/show_bug.cgi?id=683599",
                         1))
                goto out;
        }

        offset = g_field_info_get_offset ((GIFieldInfo *) self->info);
        value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);

        /* Decrement the previous python object stashed on the void pointer.
         * This seems somewhat dangerous as the code is blindly assuming any
         * void pointer field stores a python object pointer and then decrefs it.
         * This is essentially the same as something like:
         *  Py_XDECREF(struct->void_ptr); */
        Py_XDECREF(G_STRUCT_MEMBER (gpointer, pointer, offset));

        /* Assign and increment the newly assigned object. At this point the value
         * arg will hold a pointer the python object "py_value" or NULL.
         * This is essentially:
         *  struct->void_ptr = value.v_pointer;
         *  Py_XINCREF(struct->void_ptr);
         */
        G_STRUCT_MEMBER (gpointer, pointer, offset) = (gpointer)value.v_pointer;
        Py_XINCREF(G_STRUCT_MEMBER (gpointer, pointer, offset));

        retval = Py_None;
        goto out;
    }

    value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_EVERYTHING);
    if (PyErr_Occurred()) {
        goto out;
    }

    if (!g_field_info_set_field ( (GIFieldInfo *) self->info, pointer, &value)) {
        _pygi_argument_release (&value, field_type_info, GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
        PyErr_SetString (PyExc_RuntimeError, "unable to set value for field");
        goto out;
    }

    retval = Py_None;

out:
    g_base_info_unref ( (GIBaseInfo *) field_type_info);

    Py_XINCREF (retval);
    return retval;
}
예제 #12
0
static PyObject *
_wrap_g_field_info_get_value (PyGIBaseInfo *self,
                              PyObject     *args)
{
    PyObject *instance;
    GIBaseInfo *container_info;
    GIInfoType container_info_type;
    gpointer pointer;
    GITypeInfo *field_type_info;
    GIArgument value;
    PyObject *py_value = NULL;
    gboolean free_array = FALSE;

    memset(&value, 0, sizeof(GIArgument));

    if (!PyArg_ParseTuple (args, "O:FieldInfo.get_value", &instance)) {
        return NULL;
    }

    container_info = g_base_info_get_container (self->info);
    g_assert (container_info != NULL);

    /* Check the instance. */
    if (!_pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) container_info, TRUE, instance)) {
        _PyGI_ERROR_PREFIX ("argument 1: ");
        return NULL;
    }

    /* Get the pointer to the container. */
    container_info_type = g_base_info_get_type (container_info);
    switch (container_info_type) {
        case GI_INFO_TYPE_UNION:
        case GI_INFO_TYPE_STRUCT:
            pointer = pyg_boxed_get (instance, void);
            break;
        case GI_INFO_TYPE_OBJECT:
            pointer = pygobject_get (instance);
            break;
        default:
            /* Other types don't have fields. */
            g_assert_not_reached();
    }

    /* Get the field's value. */
    field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info);

    /* A few types are not handled by g_field_info_get_field, so do it here. */
    if (!g_type_info_is_pointer (field_type_info)
            && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
        GIBaseInfo *info;
        GIInfoType info_type;

        if (! (g_field_info_get_flags ( (GIFieldInfo *) self->info) & GI_FIELD_IS_READABLE)) {
            PyErr_SetString (PyExc_RuntimeError, "field is not readable");
            goto out;
        }

        info = g_type_info_get_interface (field_type_info);

        info_type = g_base_info_get_type (info);

        g_base_info_unref (info);

        switch (info_type) {
            case GI_INFO_TYPE_UNION:
                PyErr_SetString (PyExc_NotImplementedError, "getting an union is not supported yet");
                goto out;
            case GI_INFO_TYPE_STRUCT:
            {
                gsize offset;

                offset = g_field_info_get_offset ( (GIFieldInfo *) self->info);

                value.v_pointer = (char*) pointer + offset;

                goto argument_to_object;
            }
            default:
                /* Fallback. */
                break;
        }
    }

    if (!g_field_info_get_field ( (GIFieldInfo *) self->info, pointer, &value)) {
        PyErr_SetString (PyExc_RuntimeError, "unable to get the value");
        goto out;
    }

    if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_ARRAY) {
        value.v_pointer = _pygi_argument_to_array (&value, NULL, NULL,
                                                   field_type_info, &free_array);
    }

argument_to_object:
    py_value = _pygi_argument_to_object (&value, field_type_info, GI_TRANSFER_NOTHING);

    if (free_array) {
        g_array_free (value.v_pointer, FALSE);
    }

out:
    g_base_info_unref ( (GIBaseInfo *) field_type_info);

    return py_value;
}
예제 #13
0
파일: pygtype.c 프로젝트: nzjrs/pygobject
/**
 * pyg_value_from_pyobject:
 * @value: the GValue object to store the converted value in.
 * @obj: the Python object to convert.
 *
 * This function converts a Python object and stores the result in a
 * GValue.  The GValue must be initialised in advance with
 * g_value_init().  If the Python object can't be converted to the
 * type of the GValue, then an error is returned.
 *
 * Returns: 0 on success, -1 on error.
 */
int
pyg_value_from_pyobject(GValue *value, PyObject *obj)
{
    PyObject *tmp;

    switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value))) {
    case G_TYPE_INTERFACE:
	/* we only handle interface types that have a GObject prereq */
	if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_OBJECT)) {
	    if (obj == Py_None)
		g_value_set_object(value, NULL);
	    else {
		if (!PyObject_TypeCheck(obj, &PyGObject_Type)) {
		    return -1;
		}
		if (!G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
						G_VALUE_TYPE(value))) {
		    return -1;
		}
		g_value_set_object(value, pygobject_get(obj));
	    }
	} else {
	    return -1;
	}
	break;
    case G_TYPE_CHAR:
#if PY_VERSION_HEX < 0x03000000
	if (PyString_Check(obj)) {
	    g_value_set_char(value, PyString_AsString(obj)[0]);
	} else
#endif
	if (PyUnicode_Check(obj)) {
	    tmp = PyUnicode_AsUTF8String(obj);
	    g_value_set_char(value, PYGLIB_PyBytes_AsString(tmp)[0]);
	    Py_DECREF(tmp);
	} else {
	    PyErr_Clear();
	    return -1;
	}

	break;
    case G_TYPE_UCHAR:
	if (PYGLIB_PyLong_Check(obj)) {
	    glong val;
	    val = PYGLIB_PyLong_AsLong(obj);
	    if (val >= 0 && val <= 255)
	      g_value_set_uchar(value, (guchar)PYGLIB_PyLong_AsLong (obj));
	    else
	      return -1;
#if PY_VERSION_HEX < 0x03000000
	} else if (PyString_Check(obj)) {
	    g_value_set_uchar(value, PyString_AsString(obj)[0]);
#endif
	} else if (PyUnicode_Check(obj)) {
	    tmp = PyUnicode_AsUTF8String(obj);
	    g_value_set_uchar(value, PYGLIB_PyBytes_AsString(tmp)[0]);
	    Py_DECREF(tmp);
	} else {
	    PyErr_Clear();
	    return -1;
	}
	break;
    case G_TYPE_BOOLEAN:
	g_value_set_boolean(value, PyObject_IsTrue(obj));
	break;
    case G_TYPE_INT:
	g_value_set_int(value, PYGLIB_PyLong_AsLong(obj));
	break;
    case G_TYPE_UINT:
	{
	    if (PYGLIB_PyLong_Check(obj)) {
		glong val;

		val = PYGLIB_PyLong_AsLong(obj);
		if (val >= 0 && val <= G_MAXUINT)
		    g_value_set_uint(value, (guint)val);
		else
		    return -1;
	    } else {
		g_value_set_uint(value, PyLong_AsUnsignedLong(obj));
	    }
	}
	break;
    case G_TYPE_LONG:
	g_value_set_long(value, PYGLIB_PyLong_AsLong(obj));
	break;
    case G_TYPE_ULONG:
#if PY_VERSION_HEX < 0x03000000
	if (PyInt_Check(obj)) {
            long val;

            val = PYGLIB_PyLong_AsLong(obj);
            if (val < 0) {
                PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property");
                return -1;
            }
            g_value_set_ulong(value, (gulong)val);
        } else
#endif
        if (PyLong_Check(obj))
	    g_value_set_ulong(value, PyLong_AsUnsignedLong(obj));
        else
            return -1;
        break;
    case G_TYPE_INT64:
	g_value_set_int64(value, PyLong_AsLongLong(obj));
	break;
    case G_TYPE_UINT64:
#if PY_VERSION_HEX < 0x03000000
        if (PyInt_Check(obj)) {
            long v = PyInt_AsLong(obj);
            if (v < 0) {
                PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property");
                return -1;
            }
            g_value_set_uint64(value, v);
        } else
#endif
        if (PyLong_Check(obj))
            g_value_set_uint64(value, PyLong_AsUnsignedLongLong(obj));
        else
            return -1;
	break;
    case G_TYPE_ENUM:
	{
	    gint val = 0;
	    if (pyg_enum_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
		PyErr_Clear();
		return -1;
	    }
	    g_value_set_enum(value, val);
	}
	break;
    case G_TYPE_FLAGS:
	{
	    gint val = 0;
	    if (pyg_flags_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
		PyErr_Clear();
		return -1;
	    }
	    g_value_set_flags(value, val);
	}
	break;
    case G_TYPE_FLOAT:
	g_value_set_float(value, PyFloat_AsDouble(obj));
	break;
    case G_TYPE_DOUBLE:
	g_value_set_double(value, PyFloat_AsDouble(obj));
	break;
    case G_TYPE_STRING:
	if (obj == Py_None) {
	    g_value_set_string(value, NULL);
#if PY_VERSION_HEX < 0x03000000
	} else if (PyString_Check(obj)) {
	    g_value_set_string(value, PyString_AsString(obj));
#endif
	} else if (PyUnicode_Check(obj)) {
	    tmp = PyUnicode_AsUTF8String(obj);
	    g_value_set_string(value, PYGLIB_PyBytes_AsString(tmp));
	    Py_DECREF(tmp);
	} else {
	    PyErr_Clear();
	    return -1;
	}
	break;
    case G_TYPE_POINTER:
	if (obj == Py_None)
	    g_value_set_pointer(value, NULL);
	else if (PyObject_TypeCheck(obj, &PyGPointer_Type) &&
		   G_VALUE_HOLDS(value, ((PyGPointer *)obj)->gtype))
	    g_value_set_pointer(value, pyg_pointer_get(obj, gpointer));
	else if (PYGLIB_CPointer_Check(obj))
	    g_value_set_pointer(value, PYGLIB_CPointer_GetPointer(obj, NULL));
	else
	    return -1;
	break;
    case G_TYPE_BOXED: {
	PyGTypeMarshal *bm;

	if (obj == Py_None)
	    g_value_set_boxed(value, NULL);
	else if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT))
	    g_value_set_boxed(value, obj);
	else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) &&
		   G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype))
	    g_value_set_boxed(value, pyg_boxed_get(obj, gpointer));
        else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) {
            GType type;
            GValue *n_value;

            type = pyg_type_from_object((PyObject*)Py_TYPE(obj));
            if (G_UNLIKELY (! type)) {
                PyErr_Clear();
                return -1;
            }
            n_value = g_new0 (GValue, 1);
            g_value_init (n_value, type);
            g_value_take_boxed (value, n_value);
            return pyg_value_from_pyobject (n_value, obj);
        }
        else if (PySequence_Check(obj) &&
		   G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY))
	    return pyg_value_array_from_pyobject(value, obj, NULL);
	else if (PYGLIB_PyUnicode_Check(obj) &&
                 G_VALUE_HOLDS(value, G_TYPE_GSTRING)) {
            GString *string;
            char *buffer;
            Py_ssize_t len;
            if (PYGLIB_PyUnicode_AsStringAndSize(obj, &buffer, &len))
                return -1;
            string = g_string_new_len(buffer, len);
	    g_value_set_boxed(value, string);
	    g_string_free (string, TRUE);
            break;
        }
	else if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
	    return bm->tovalue(value, obj);
	else if (PYGLIB_CPointer_Check(obj))
	    g_value_set_boxed(value, PYGLIB_CPointer_GetPointer(obj, NULL));
	else
	    return -1;
	break;
    }
    case G_TYPE_PARAM:
	if (PyGParamSpec_Check(obj))
	    g_value_set_param(value, PYGLIB_CPointer_GetPointer(obj, NULL));
	else
	    return -1;
	break;
    case G_TYPE_OBJECT:
	if (obj == Py_None) {
	    g_value_set_object(value, NULL);
	} else if (PyObject_TypeCheck(obj, &PyGObject_Type) &&
		   G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
					      G_VALUE_TYPE(value))) {
	    g_value_set_object(value, pygobject_get(obj));
	} else
	    return -1;
	break;
    default:
	{
	    PyGTypeMarshal *bm;
	    if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
		return bm->tovalue(value, obj);
	    break;
	}
    }
    if (PyErr_Occurred()) {
        g_value_unset(value);
        PyErr_Clear();
        return -1;
    }
    return 0;
}
예제 #14
0
static PyObject *
_wrap_g_field_info_set_value (PyGIBaseInfo *self,
                              PyObject     *args)
{
    PyObject *instance;
    PyObject *py_value;
    GIBaseInfo *container_info;
    GIInfoType container_info_type;
    gpointer pointer;
    GITypeInfo *field_type_info;
    GIArgument value;
    PyObject *retval = NULL;

    if (!PyArg_ParseTuple (args, "OO:FieldInfo.set_value", &instance, &py_value)) {
        return NULL;
    }

    container_info = g_base_info_get_container (self->info);
    g_assert (container_info != NULL);

    /* Check the instance. */
    if (!_pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) container_info, TRUE, instance)) {
        _PyGI_ERROR_PREFIX ("argument 1: ");
        return NULL;
    }

    /* Get the pointer to the container. */
    container_info_type = g_base_info_get_type (container_info);
    switch (container_info_type) {
        case GI_INFO_TYPE_UNION:
        case GI_INFO_TYPE_STRUCT:
            pointer = pyg_boxed_get (instance, void);
            break;
        case GI_INFO_TYPE_OBJECT:
            pointer = pygobject_get (instance);
            break;
        default:
            /* Other types don't have fields. */
            g_assert_not_reached();
    }

    field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info);

    /* Check the value. */
    {
        gboolean retval;

        retval = _pygi_g_type_info_check_object (field_type_info, py_value, TRUE);
        if (retval < 0) {
            goto out;
        }

        if (!retval) {
            _PyGI_ERROR_PREFIX ("argument 2: ");
            goto out;
        }
    }

    /* Set the field's value. */
    /* A few types are not handled by g_field_info_set_field, so do it here. */
    if (!g_type_info_is_pointer (field_type_info)
            && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
        GIBaseInfo *info;
        GIInfoType info_type;

        if (! (g_field_info_get_flags ( (GIFieldInfo *) self->info) & GI_FIELD_IS_WRITABLE)) {
            PyErr_SetString (PyExc_RuntimeError, "field is not writable");
            goto out;
        }

        info = g_type_info_get_interface (field_type_info);

        info_type = g_base_info_get_type (info);

        switch (info_type) {
            case GI_INFO_TYPE_UNION:
                PyErr_SetString (PyExc_NotImplementedError, "setting an union is not supported yet");
                goto out;
            case GI_INFO_TYPE_STRUCT:
            {
                gboolean is_simple;
                gsize offset;
                gssize size;

                is_simple = pygi_g_struct_info_is_simple ( (GIStructInfo *) info);

                if (!is_simple) {
                    PyErr_SetString (PyExc_TypeError,
                                     "cannot set a structure which has no well-defined ownership transfer rules");
                    g_base_info_unref (info);
                    goto out;
                }

                value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);
                if (PyErr_Occurred()) {
                    g_base_info_unref (info);
                    goto out;
                }

                offset = g_field_info_get_offset ( (GIFieldInfo *) self->info);
                size = g_struct_info_get_size ( (GIStructInfo *) info);
                g_assert (size > 0);

                g_memmove (pointer + offset, value.v_pointer, size);

                g_base_info_unref (info);

                retval = Py_None;
                goto out;
            }
            default:
                /* Fallback. */
                break;
        }

        g_base_info_unref (info);
    }

    value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_EVERYTHING);
    if (PyErr_Occurred()) {
        goto out;
    }

    if (!g_field_info_set_field ( (GIFieldInfo *) self->info, pointer, &value)) {
        _pygi_argument_release (&value, field_type_info, GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
        PyErr_SetString (PyExc_RuntimeError, "unable to set value for field");
        goto out;
    }

    retval = Py_None;

out:
    g_base_info_unref ( (GIBaseInfo *) field_type_info);

    Py_XINCREF (retval);
    return retval;
}