/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
#include <Python.h>

#include "pygobject.h"
#include "sugar-browser.h"
#include "sugar-key-grabber.h"
#include "sugar-address-entry.h"
#include "sugar-tray-manager.h"
#include "sugar-push-scroller.h"
#include "sugar-download-manager.h"
#include "sugar-download.h"
#include "sugar-audio-manager.h"

#include "pycairo.h"
#include <pygtk/pygtk.h>
#include <glib.h>

extern Pycairo_CAPI_t *Pycairo_CAPI;

%%
modulename gecko
%%
ignore
sugar_tray_manager_new
%%
import gobject.GObject as PyGObject_Type
import gtk.Entry as PyGtkEntry_Type
import gtk.gdk.Screen as PyGdkScreen_Type
import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
import hippo.CanvasImage as HippoCanvasImage_Type
%%
ignore-glob
  *_get_type
  _*
%%
include
  gtkmozembed.override
%%
override sugar_hippo_canvas_image_set_image_from_gdk_pixbuf kwargs
static cairo_surface_t *
_cairo_surface_from_pixbuf (GdkPixbuf *pixbuf)
{
/* Ripped from GooCanvas */
  gint width = gdk_pixbuf_get_width (pixbuf);
  gint height = gdk_pixbuf_get_height (pixbuf);
  guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
  int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
  guchar *cairo_pixels;
  cairo_format_t format;
  cairo_surface_t *surface;
  static const cairo_user_data_key_t key;
  int j;

  if (n_channels == 3)
    format = CAIRO_FORMAT_RGB24;
  else
    format = CAIRO_FORMAT_ARGB32;

  cairo_pixels = g_malloc (4 * width * height);
  surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels,
						 format,
						 width, height, 4 * width);
  cairo_surface_set_user_data (surface, &key,
			       cairo_pixels, (cairo_destroy_func_t)g_free);

  for (j = height; j; j--)
    {
      guchar *p = gdk_pixels;
      guchar *q = cairo_pixels;

      if (n_channels == 3)
	{
	  guchar *end = p + 3 * width;
	  
	  while (p < end)
	    {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
	      q[0] = p[2];
	      q[1] = p[1];
	      q[2] = p[0];
#else	  
	      q[1] = p[0];
	      q[2] = p[1];
	      q[3] = p[2];
#endif
	      p += 3;
	      q += 4;
	    }
	}
      else
	{
	  guchar *end = p + 4 * width;
	  guint t1,t2,t3;
	    
#define MULT(d,c,a,t) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END

	  while (p < end)
	    {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
	      MULT(q[0], p[2], p[3], t1);
	      MULT(q[1], p[1], p[3], t2);
	      MULT(q[2], p[0], p[3], t3);
	      q[3] = p[3];
#else	  
	      q[0] = p[3];
	      MULT(q[1], p[0], p[3], t1);
	      MULT(q[2], p[1], p[3], t2);
	      MULT(q[3], p[2], p[3], t3);
#endif
	      
	      p += 4;
	      q += 4;
	    }
	  
#undef MULT
	}

      gdk_pixels += gdk_rowstride;
      cairo_pixels += 4 * width;
    }

  return surface;
}
static PyObject*
_wrap_sugar_hippo_canvas_image_set_image_from_gdk_pixbuf(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "image", "pixbuf", NULL };
    PyGObject *py_pixbuf;
    PyGObject *py_image;
    cairo_surface_t *surface;
    GObject *image;
    GValue val = {0,};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
            "O!O!:_sugar.hippo_canvas_image_set_image_from_gdk_pixbuf",
            kwlist, &HippoCanvasImage_Type, &py_image, &PyGdkPixbuf_Type, &py_pixbuf)) {
        return NULL;
    }

    surface = _cairo_surface_from_pixbuf(GDK_PIXBUF (py_pixbuf->obj));
	if (surface == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "pixbuf could not be converted");
        return NULL;
    }

    /* FIXME: This has to be a GObject (and not a real HippoCanvasImage object)
     * for now until the HippoCanvas includes situation gets sorted out.
     */
    image = G_OBJECT (py_image->obj);
    if (image == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "invalid HippoCanvasImage object");
        return NULL;
    }

    g_value_init (&val, G_TYPE_POINTER);
    g_value_set_pointer (&val, surface);
    g_object_set_property (image, "image", &val);

    Py_INCREF(Py_None);
    return Py_None;
}
%%
override sugar_cairo_surface_from_gdk_pixbuf kwargs
static PyObject*
_wrap_sugar_cairo_surface_from_gdk_pixbuf(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "pixbuf", NULL };
    PyGObject *child;
    cairo_surface_t *surface;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:sugar.cairo_surface_from_gdk_pixbuf", kwlist, &PyGdkPixbuf_Type, &child))
        return NULL;

    surface = _cairo_surface_from_pixbuf(GDK_PIXBUF (child->obj));
	if (surface == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "pixbuf could not be converted");
        return NULL;
    }

    return PycairoSurface_FromSurface(surface, NULL);
}
%%