1a05542005-07-28Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */ #include <version.h> #include <bignum.h> #include <stdarg.h>
ef0ec72005-12-29Martin Nilsson #ifndef INIT_VARIABLES extern struct program *image_color_program; extern struct program *image_program; #endif
ba9e802006-02-27Martin Stjernholm void pgtk2_encode_grey(struct image *i, unsigned char *dest, int bpp, int bpl);
1a05542005-07-28Martin Nilsson 
ba9e802006-02-27Martin Stjernholm void pgtk2_verify_setup() { if (!pgtk2_is_setup)
3d76632005-11-03Lance Dillon  Pike_error("You must call GTK2.setup_gtk( argv ) first\n");
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm void pgtk2_verify_gnome_setup() { extern int pgnome2_is_setup; if (!pgnome2_is_setup)
3d76632005-11-03Lance Dillon  Pike_error("You must call Gnome2.init( app,version,argv ) first\n");
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm void pgtk2_verify_obj_inited() {
1a05542005-07-28Martin Nilsson  if (!THIS->obj) Pike_error("Calling function in unitialized object\n"); }
ba9e802006-02-27Martin Stjernholm void pgtk2_verify_obj_not_inited() {
1a05542005-07-28Martin Nilsson  if (THIS->obj) Pike_error("Tried to initialize object twice\n"); }
ba9e802006-02-27Martin Stjernholm void pgtk2_verify_mixin_inited() {
4ca9822006-01-02Marcus Comstedt  if (!MIXIN_THIS->obj) Pike_error("Calling function in unitialized object\n"); }
ba9e802006-02-27Martin Stjernholm void pgtk2_verify_mixin_not_inited() {
4ca9822006-01-02Marcus Comstedt  if (MIXIN_THIS->obj) Pike_error("Tried to initialize object twice\n"); }
ba9e802006-02-27Martin Stjernholm void pgtk2_pop_n_elems(int n) /* anti-inline */
1a05542005-07-28Martin Nilsson { pop_n_elems(n); }
ba9e802006-02-27Martin Stjernholm void pgtk2_ref_push_object(struct object *o) {
1a05542005-07-28Martin Nilsson  ref_push_object(o); }
ba9e802006-02-27Martin Stjernholm void pgtk2_return_this(int n) {
1a05542005-07-28Martin Nilsson  pop_n_elems(n); ref_push_object(Pike_fp->current_object); }
ba9e802006-02-27Martin Stjernholm void pgtk2_get_image_module() {
1a05542005-07-28Martin Nilsson  push_constant_text("Image"); SAFE_APPLY_MASTER("resolv_or_error",1); }
ba9e802006-02-27Martin Stjernholm void pgtk2_index_stack(char *what) {
1a05542005-07-28Martin Nilsson  push_text(what); f_index(2); #ifdef PIKE_DEBUG
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == PIKE_T_INT)
1a05542005-07-28Martin Nilsson  Pike_error("Internal indexing error.\n"); #endif } int get_color_from_pikecolor(struct object *o, INT_TYPE *r, INT_TYPE *g, INT_TYPE *b) { struct color_struct *col;
13b5ed2014-05-26Per Hedbor  col=get_storage(o,image_color_program);
1a05542005-07-28Martin Nilsson  if (!col) return 0; *r=col->rgbl.r/(COLORLMAX/65535); *g=col->rgbl.g/(COLORLMAX/65535); *b=col->rgbl.b/(COLORLMAX/65535); return 1; }
791e212010-08-01Marcus Comstedt GdkImage *gdkimage_from_pikeimage(struct object *img, int fast, GObject **pi) { GdkImage *i;
1a05542005-07-28Martin Nilsson  GdkColormap *col=gdk_colormap_get_system(); GdkVisual *vis=gdk_visual_get_system();
151a5f2005-11-12Martin Nilsson  struct image *img_data;
1a05542005-07-28Martin Nilsson  INT_TYPE x,y; TIMER_INIT("Getting extents");
151a5f2005-11-12Martin Nilsson 
13b5ed2014-05-26Per Hedbor  img_data=get_storage(img, image_program);
151a5f2005-11-12Martin Nilsson  /* 1a: create the actual image... */ x = img_data->xsize; y = img_data->ysize;
1a05542005-07-28Martin Nilsson  if (x==0 || y==0) Pike_error("Size of image must be > 0x0\n");
791e212010-08-01Marcus Comstedt  if (pi) {
0856802010-08-01Marcus Comstedt  i = GDK_IMAGE(*pi);
791e212010-08-01Marcus Comstedt  if (i != NULL && ((i->width!=x) || (i->height!=y))) { g_object_unref(i);
1a05542005-07-28Martin Nilsson  i=NULL; }
791e212010-08-01Marcus Comstedt  } else i=NULL;
1a05542005-07-28Martin Nilsson  if (!i) { PFTIME("Create"); i=(void *)gdk_image_new(fast,vis,x,y); }
791e212010-08-01Marcus Comstedt  if (pi)
0856802010-08-01Marcus Comstedt  *pi = G_OBJECT(i);
1a05542005-07-28Martin Nilsson  if (!i) Pike_error("Failed to create gdkimage\n"); /* 1b: do the work.. */ if (vis->type==GDK_VISUAL_TRUE_COLOR || vis->type==GDK_VISUAL_STATIC_GRAY) /* no colormap.. */ { int pad=0; int native_byteorder; PFTIME("Convert"); if (vis->type==GDK_VISUAL_STATIC_GRAY)
ba9e802006-02-27Martin Stjernholm  pgtk2_encode_grey(img_data,i->mem,i->bpp,i->bpl);
1a05542005-07-28Martin Nilsson  else { if (i->bpl!=(i->bpp*x)) switch(i->bpl & 3) { case 0: pad = 4; break; case 1: pad = 1; break; case 2: pad = 2; break; case 3: pad = 1; break; } else pad=0;
ba9e802006-02-27Martin Stjernholm  pgtk2_encode_truecolor_masks(img_data,i->bpp*8,pad*8, (i->byte_order!=1),vis->red_mask, vis->green_mask,vis->blue_mask, i->mem, i->bpl*y);
1a05542005-07-28Martin Nilsson  } } else { static int colors_allocated=0; static struct object *pike_cmap; /* I hate this... colormaps, here we come.. */ /* This is rather complicated, but: 1/ build an array of the colors in the colormap 2/ use that array to build a pike X-image colormap. 3/ call Image.X.encode_pseudocolor( img, bpp, lpad, depth, colormp ) 4/ copy the actual data to the image.. */ if (!colors_allocated) { #define COLORMAP_SIZE 256 char allocated[COLORMAP_SIZE]; int j,i,r,g,b; PFTIME("Creating colormap"); colors_allocated=1;
21b12a2014-09-03Martin Nilsson  memset(allocated,0,sizeof(allocated));
1a05542005-07-28Martin Nilsson  for (r=0; r<3; r++) for (g=0; g<4; g++) for (b=0; b<3; b++) { GdkColor color;
5c55b02005-12-30Martin Nilsson  color.red = (guint16)(r * (65535/2.0)); color.green = (guint16)(g * (65535/3.0)); color.blue = (guint16)(b * (65535/2.0));
1a05542005-07-28Martin Nilsson  color.pixel = 0; if (gdk_color_alloc(col,&color)) if (color.pixel<COLORMAP_SIZE) allocated[color.pixel]=1; } for (r=0; r<6; r++) for (g=0; g<7; g++) for (b=0; b<6; b++) { GdkColor color;
5c55b02005-12-30Martin Nilsson  color.red=(guint16)(r*(65535/5.0)); color.green=(guint16)(g*(65535/6.0)); color.blue=(guint16)(b*(65535/5.0));
1a05542005-07-28Martin Nilsson  color.pixel=0; if (gdk_color_alloc(col,&color)) if (color.pixel<COLORMAP_SIZE) allocated[color.pixel]=1; } for (i=0; i<COLORMAP_SIZE; i++) { if (allocated[i]) { push_int(col->colors[i].red>>8); push_int(col->colors[i].green>>8); push_int(col->colors[i].blue>>8); f_aggregate(3); } else push_int(0); } f_aggregate(256); /* now on stack: the array with colors. */
ba9e802006-02-27Martin Stjernholm  pgtk2_get_image_module(); pgtk2_index_stack("colortable");
1a05542005-07-28Martin Nilsson  /* on stack: array function */ Pike_sp[0]=Pike_sp[-1]; Pike_sp[-1]=Pike_sp[-2]; Pike_sp[-2]=Pike_sp[0]; /* on stack: function array */ PFTIME("Creating colormap obj"); apply_svalue(Pike_sp-2,1); /* on stack: function cmap */ get_all_args("internal",1,"%o",&pike_cmap); pike_cmap->refs+=100; /* lets keep this one.. :-) */ push_int(8); push_int(8); push_int(8); apply(pike_cmap,"rigid",3); pop_stack(); apply(pike_cmap,"ordered",0); pop_stack(); pop_stack(); } { /* now we have a colormap available. Happy happy joy joy! */ struct pike_string *s;
ba9e802006-02-27Martin Stjernholm  pgtk2_get_image_module(); pgtk2_index_stack("X"); pgtk2_index_stack("encode_pseudocolor");
1a05542005-07-28Martin Nilsson  /* on stack: function */ add_ref(img); push_object(img); push_int(i->bpp*8); { int pad=0; switch (i->bpl-(i->bpp*x)) { case 0: pad = 0; break; case 1: pad = 16; break; default: pad = 32; break; } push_int(pad); /* extra padding.. */ } push_int(i->depth); add_ref(pike_cmap); push_object(pike_cmap); /* on stack: function img bpp linepad depth cmap*/ /* 6 5 4 3 2 1 */ PFTIME("Dithering image"); apply_svalue(Pike_sp-6,5);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) != PIKE_T_STRING) {
1a05542005-07-28Martin Nilsson  gdk_image_destroy((void *)i); Pike_error("Failed to convert image\n"); } PFTIME("Converting image");
59fc9e2014-09-03Martin Nilsson  memcpy(i->mem,Pike_sp[-1].u.string->str,Pike_sp[-1].u.string->len);
1a05542005-07-28Martin Nilsson  pop_stack(); /* string */ pop_stack(); /* function */ } } TIMER_END(); return i; }
ba9e802006-02-27Martin Stjernholm int pgtk2_is_object_program(struct program *X);
1a05542005-07-28Martin Nilsson  void push_gobjectclass(void *obj, struct program *def) { struct object *o; if (!obj) { push_int(0); return; }
ba9e802006-02-27Martin Stjernholm  if (pgtk2_is_object_program(def))
1a05542005-07-28Martin Nilsson  if ((o=g_object_get_data(((void *)obj),"pike_object"))) { ref_push_object(o); return; } o=low_clone(def); call_c_initializers(o); ((struct object_wrapper *)o->storage)->obj=obj;
ba9e802006-02-27Martin Stjernholm  pgtk2__init_object(o);
e4fbe22008-01-29Per Hedbor  /* Extra ref already added in pgtk2__init_object */
228a2d2016-01-23Chris Angelico  push_object(o);
1a05542005-07-28Martin Nilsson  return; }
2edd4f2008-01-30Per Hedbor void push_pgdk2object(void *obj, struct program *def, int owned) {
1a05542005-07-28Martin Nilsson  struct object *o; if (!obj) { push_int(0); return; } o=low_clone(def); call_c_initializers(o); ((struct object_wrapper *)o->storage)->obj=obj;
2edd4f2008-01-30Per Hedbor  ((struct object_wrapper *)o->storage)->owned = owned;
228a2d2016-01-23Chris Angelico  push_object(o);
1a05542005-07-28Martin Nilsson  return; }
ba9e802006-02-27Martin Stjernholm GObject *get_pg2object(struct object *from, struct program *type) {
1a05542005-07-28Martin Nilsson  struct object_wrapper * o; if (!from) return NULL;
13b5ed2014-05-26Per Hedbor  o=get_storage(from,type);
1a05542005-07-28Martin Nilsson  if (!o) return 0; return o->obj; }
ba9e802006-02-27Martin Stjernholm void *get_pgdk2object(struct object *from, struct program *type) {
1a05542005-07-28Martin Nilsson  void *f;
228a2d2016-01-23Chris Angelico  if (!from)
1a05542005-07-28Martin Nilsson  return NULL;
76f7462014-05-26Martin Nilsson  if (type)
1a05542005-07-28Martin Nilsson  f=get_storage( from, type ); else f=from->storage; /* Add a warning? */ if (!f) return 0; return (void *)((struct object_wrapper *)f)->obj; }
ba9e802006-02-27Martin Stjernholm void pgtk2_destruct(struct object *o) {
76f7462014-05-26Martin Nilsson  struct object_wrapper *ow=get_storage(o,pg2_object_program);
1a05542005-07-28Martin Nilsson  if (ow) /* This should always be true. But let's add a check anyway. */ ow->obj=NULL; if (o->refs>1) destruct(o); free_object(o); /* ref added in __init_object below. */ }
ba9e802006-02-27Martin Stjernholm void pgtk2__init_object(struct object *o) {
1a05542005-07-28Martin Nilsson  GObject *go=get_gobject(o); if (!go) /* Not a real GObject. Refhandling done elsewhere */ return; o->refs++;
ba9e802006-02-27Martin Stjernholm /* gtk_object_set_data_full(go,"pike_object",(void*)o, (void*)pgtk2_destruct); */ g_object_set_data_full(G_OBJECT(go),"pike_object",(void *)o,(void *)pgtk2_destruct);
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm void pgtk2_get_mapping_arg(struct mapping *map,
1a05542005-07-28Martin Nilsson  char *name, int type, int madd, void *dest, long *mask, int len) { struct svalue *s; if ((s=simple_mapping_string_lookup(map,name))) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*s) == type) {
1a05542005-07-28Martin Nilsson  switch(type) { case PIKE_T_STRING: #ifdef PIKE_DEBUG if (len!=sizeof(char *)) Pike_fatal("oddities detected\n"); #endif
c9d3972014-09-03Martin Nilsson  memcpy(dest,&s->u.string->str,sizeof(char *));
1a05542005-07-28Martin Nilsson  break; case PIKE_T_INT: if (len==2) { short i=(short)s->u.integer;
c9d3972014-09-03Martin Nilsson  memcpy(dest,&i,2);
1a05542005-07-28Martin Nilsson  } else if (len==4)
c9d3972014-09-03Martin Nilsson  memcpy(dest,&s->u.integer,len);
1a05542005-07-28Martin Nilsson  break; case PIKE_T_FLOAT: if (len==sizeof(FLOAT_TYPE))
c9d3972014-09-03Martin Nilsson  memcpy(dest,&s->u.float_number,len);
1a05542005-07-28Martin Nilsson  else if (len==sizeof(double)) { double d=s->u.float_number;
c9d3972014-09-03Martin Nilsson  memcpy(dest,&d,len);
1a05542005-07-28Martin Nilsson  } break; } if (mask) *mask|=madd; } } } GdkAtom get_gdkatom(struct object *o) { if (get_gdkobject(o,_atom)) return (GdkAtom)get_gdkobject(o,_atom); apply(o,"get_atom", 0); get_all_args("internal_get_atom",1,"%o",&o); if (get_gdkobject(o,_atom)) { GdkAtom r=(GdkAtom)get_gdkobject(o,_atom); pop_stack(); return r; }
3d76632005-11-03Lance Dillon  Pike_error("Got non GDK2.Atom object to get_gdkatom()\n");
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm struct my_pixel pgtk2_pixel_from_xpixel(unsigned int pix, GdkImage *i) {
1a05542005-07-28Martin Nilsson  static GdkColormap *col; GdkColor * c; struct my_pixel res; int l;
228a2d2016-01-23Chris Angelico  if (!col)
1a05542005-07-28Martin Nilsson  col=gdk_colormap_get_system(); *((int *)&res)=0; switch(i->visual->type) { case GDK_VISUAL_GRAYSCALE: case GDK_VISUAL_PSEUDO_COLOR: for (l=0; l<col->size; l++) if (col->colors[l].pixel==pix) /* 76 */ { res.r=col->colors[l].red/257; res.g=col->colors[l].green/257; res.b=col->colors[l].blue/257; break; } break; case GDK_VISUAL_STATIC_COLOR: case GDK_VISUAL_TRUE_COLOR: case GDK_VISUAL_DIRECT_COLOR: /* Well well well.... */ res.r=((pix&i->visual->red_mask) >>i->visual->red_shift) <<(8-i->visual->red_prec); res.g=((pix&i->visual->green_mask) >>i->visual->green_shift) <<(8-i->visual->green_prec); res.b=((pix&i->visual->blue_mask) >>i->visual->blue_shift) <<(8-i->visual->blue_prec); break; case GDK_VISUAL_STATIC_GRAY: res.r=res.g=res.b=(pix*256)/1<<i->visual->depth; break; } return res; } void push_atom(GdkAtom a) { /* this should really be inserted in the GDK.Atom mapping. */
2edd4f2008-01-30Per Hedbor  push_pgdk2object((void *)a,pgdk2__atom_program,0);
1a05542005-07-28Martin Nilsson } void push_Xpseudo32bitstring(void *f, int nelems) { if (sizeof(long)!=4) { long *q=(long *)f;
dc8d022014-04-27Martin Nilsson  int *res=xalloc(nelems*4),i;
1a05542005-07-28Martin Nilsson  for (i=0; i<nelems; i++) res[i]=q[i]; push_string(make_shared_binary_string2((const p_wchar2 *)res,nelems)); xfree(res); } else { push_string(make_shared_binary_string2(f,nelems)); } } /*
ba9e802006-02-27Martin Stjernholm gint pgtk2_buttonfuncwrapper(GObject *obj, struct signal_data *d, void *foo) {
1a05542005-07-28Martin Nilsson  int res; push_svalue(&d->args); apply_svalue(&d->cb, 1); res=Pike_sp[-1].u.integer; pop_stack(); return res; } */ void push_gdk_event(GdkEvent *e) { if (e) {
228a2d2016-01-23Chris Angelico  GdkEvent *f=g_malloc(sizeof(GdkEvent));
1a05542005-07-28Martin Nilsson  if (f==NULL) { push_int(0); return; } *f=*e;
2edd4f2008-01-30Per Hedbor  push_gdkobject(f,event,1);
1a05542005-07-28Martin Nilsson  } else push_int(0); } enum { PUSHED_NOTHING, PUSHED_VALUE, NEED_RETURN, }; /*
ba9e802006-02-27Martin Stjernholm static int pgtk2_push_selection_data_param( GValue *a )
1a05542005-07-28Martin Nilsson {
ba9e802006-02-27Martin Stjernholm  push_pgdk2object( GTK_VALUE_POINTER(*a), pgtk2_selection_data_program);
1a05542005-07-28Martin Nilsson  return PUSHED_VALUE; } */
68d1052006-08-02Lance Dillon static int pgtk2_push_accel_group_param(const GValue *a) {
1a05542005-07-28Martin Nilsson  g_object_ref(g_value_get_pointer(a));
ba9e802006-02-27Martin Stjernholm  push_gobjectclass(g_value_get_pointer(a),pgtk2_accel_group_program);
1a05542005-07-28Martin Nilsson  return PUSHED_VALUE; } /*
68d1052006-08-02Lance Dillon static int pgtk2_push_ctree_node_param(const GValue *a )
1a05542005-07-28Martin Nilsson {
ba9e802006-02-27Martin Stjernholm  push_pgdk2object( GTK_VALUE_POINTER(*a), pgtk2_ctree_node_program);
1a05542005-07-28Martin Nilsson  return PUSHED_VALUE; } */
68d1052006-08-02Lance Dillon static int pgtk2_push_gdk_drag_context_param(const GValue *a) {
2edd4f2008-01-30Per Hedbor  push_gdkobject(g_value_get_pointer(a),drag_context,0);
1a05542005-07-28Martin Nilsson  return PUSHED_VALUE; }
68d1052006-08-02Lance Dillon static int pgtk2_push_gdk_event_param(const GValue *a) {
1a05542005-07-28Martin Nilsson  push_gdk_event(g_value_get_boxed(a)); return NEED_RETURN; }
68d1052006-08-02Lance Dillon static int pgtk2_push_gdk_rectangle_param(const GValue *a) {
cc4c772006-01-05Marcus Comstedt  GdkRectangle *r = (GdkRectangle *) g_value_get_boxed(a); push_text("x"); push_int(r->x); push_text("y"); push_int(r->y); push_text("width"); push_int(r->width); push_text("height"); push_int(r->height); f_aggregate_mapping(8); return PUSHED_VALUE; }
68d1052006-08-02Lance Dillon static int pgtk2_push_int_param(const GValue *a) {
1a05542005-07-28Martin Nilsson  LONGEST retval; switch (G_VALUE_TYPE(a)) {
48319e2006-08-03Lance Dillon  case G_TYPE_UINT: retval=(LONGEST)g_value_get_uint(a); break; case G_TYPE_INT64: retval=(LONGEST)g_value_get_int64(a); break; case G_TYPE_UINT64: retval=(LONGEST)g_value_get_uint64(a); break;
1a05542005-07-28Martin Nilsson  case G_TYPE_INT:
228a2d2016-01-23Chris Angelico  retval=(LONGEST)g_value_get_int(a);
1a05542005-07-28Martin Nilsson  break; case G_TYPE_FLAGS:
228a2d2016-01-23Chris Angelico  retval=(LONGEST)g_value_get_flags(a);
1a05542005-07-28Martin Nilsson  break; case G_TYPE_BOOLEAN:
228a2d2016-01-23Chris Angelico  retval=(LONGEST)g_value_get_boolean(a);
1a05542005-07-28Martin Nilsson  break; case G_TYPE_LONG:
228a2d2016-01-23Chris Angelico  retval=(LONGEST)g_value_get_long(a);
1a05542005-07-28Martin Nilsson  break; case G_TYPE_CHAR:
8172072014-03-02Marcus Comstedt #ifdef HAVE_G_VALUE_GET_SCHAR
228a2d2016-01-23Chris Angelico  retval=(LONGEST)g_value_get_schar(a);
8172072014-03-02Marcus Comstedt #else
228a2d2016-01-23Chris Angelico  retval=(LONGEST)g_value_get_char(a);
8172072014-03-02Marcus Comstedt #endif
1a05542005-07-28Martin Nilsson  break; default:
228a2d2016-01-23Chris Angelico  retval=(LONGEST)g_value_get_uint(a);
1a05542005-07-28Martin Nilsson  break; } push_int64(retval); return PUSHED_VALUE; }
3a27cd2016-01-23Chris Angelico static int pgtk2_push_enum_param(const GValue *a) { /* This can't be handled by push_int_param as the type of an enumeration is some subclass of G_TYPE_ENUM, rather than actually being G_TYPE_ENUM exactly. */ push_int64((LONGEST)g_value_get_enum(a)); return PUSHED_VALUE; }
68d1052006-08-02Lance Dillon static int pgtk2_push_float_param(const GValue *a) {
1a05542005-07-28Martin Nilsson  FLOAT_TYPE retval; if (G_VALUE_TYPE(a)==G_TYPE_FLOAT) retval=(FLOAT_TYPE)g_value_get_float(a); else retval=(FLOAT_TYPE)g_value_get_double(a); push_float(retval); return PUSHED_VALUE; }
68d1052006-08-02Lance Dillon static int pgtk2_push_string_param(const GValue *a) {
1a05542005-07-28Martin Nilsson  const gchar *t=g_value_get_string(a); if (t) PGTK_PUSH_GCHAR(t); else push_string(empty_pike_string); return PUSHED_VALUE; }
68d1052006-08-02Lance Dillon static int pgtk2_push_object_param(const GValue *a) {
82bd5a2006-09-05Lance Dillon  GObject *obj; gpointer *gp; if (g_type_is_a(G_VALUE_TYPE(a),G_TYPE_BOXED)) { gp=g_value_get_boxed(a); if (G_VALUE_HOLDS(a,g_type_from_name("GdkColor"))) {
2edd4f2008-01-30Per Hedbor  push_gdkobject(gp,color,0);
82bd5a2006-09-05Lance Dillon  } else if (G_VALUE_HOLDS(a,g_type_from_name("GtkTreePath"))) {
2edd4f2008-01-30Per Hedbor  push_pgdk2object(gp,pgtk2_tree_path_program,0);
82bd5a2006-09-05Lance Dillon  } else if (G_VALUE_HOLDS(a,g_type_from_name("GdkRectangle"))) {
2edd4f2008-01-30Per Hedbor  push_gdkobject(gp,rectangle,0);
82bd5a2006-09-05Lance Dillon  } else if (G_VALUE_HOLDS(a,g_type_from_name("GdkRegion"))) {
2edd4f2008-01-30Per Hedbor  push_gdkobject(gp,region,0);
6b2a252014-03-15Chris Angelico  } else { /* Don't know how to push this sort of object, so push its name */ PGTK_PUSH_GCHAR(G_VALUE_TYPE_NAME(a));
82bd5a2006-09-05Lance Dillon  } } else { obj=g_value_get_object(a); if (obj) push_gobject(obj); }
1a05542005-07-28Martin Nilsson  return PUSHED_VALUE; }
68d1052006-08-02Lance Dillon static int pgtk2_push_pike_object_param(const GValue *a) {
9273c02014-03-15Chris Angelico  push_int64((LONGEST)g_value_get_pointer(a));
3d76632005-11-03Lance Dillon  return PUSHED_VALUE; }
68d1052006-08-02Lance Dillon static int pgtk2_push_gparamspec_param(const GValue *a) {
34e7652008-01-23Per Hedbor  push_int(0); return PUSHED_VALUE;
1a05542005-07-28Martin Nilsson } static struct push_callback {
68d1052006-08-02Lance Dillon  int (*callback)(const GValue *);
1a05542005-07-28Martin Nilsson  GType id; struct push_callback *next; } push_callbacks[100], *push_cbtable[63]; static int last_used_callback = 0;
68d1052006-08-02Lance Dillon static void insert_push_callback(GType i, int (*cb)(const GValue *)) {
1a05542005-07-28Martin Nilsson  struct push_callback *new=push_callbacks+last_used_callback++; struct push_callback *old=push_cbtable[i%63]; new->id=i; new->callback=cb; if (old) new->next=old; push_cbtable[i%63]=new; } static void build_push_callbacks() { #define CB(X,Y) insert_push_callback(X,Y);
ba9e802006-02-27Martin Stjernholm  CB(G_TYPE_OBJECT, pgtk2_push_object_param); CB(PANGO_TYPE_TAB_ARRAY, pgtk2_push_object_param); CB(GTK_TYPE_TEXT_ATTRIBUTES, pgtk2_push_object_param); CB(GTK_TYPE_TREE_ITER, pgtk2_push_object_param); CB(GTK_TYPE_TREE_MODEL, pgtk2_push_object_param); CB(PANGO_TYPE_ATTR_LIST, pgtk2_push_object_param);
228a2d2016-01-23Chris Angelico  CB(GTK_TYPE_TREE_PATH, pgtk2_push_object_param);
ba9e802006-02-27Martin Stjernholm  CB(PANGO_TYPE_FONT_DESCRIPTION, pgtk2_push_object_param); CB(PANGO_TYPE_CONTEXT, pgtk2_push_object_param); CB(PANGO_TYPE_LAYOUT, pgtk2_push_object_param); CB( GTK_TYPE_ACCEL_GROUP, pgtk2_push_accel_group_param );
1a05542005-07-28Martin Nilsson  /*#ifndef HAS_GTK_20*/
ba9e802006-02-27Martin Stjernholm  CB( GDK_TYPE_DRAG_CONTEXT, pgtk2_push_gdk_drag_context_param );
1a05542005-07-28Martin Nilsson  /*#endif*/
ba9e802006-02-27Martin Stjernholm  CB( GDK_TYPE_EVENT, pgtk2_push_gdk_event_param ); CB( GDK_TYPE_RECTANGLE, pgtk2_push_gdk_rectangle_param );
1a05542005-07-28Martin Nilsson 
ba9e802006-02-27Martin Stjernholm  CB( GTK_TYPE_ACCEL_FLAGS, pgtk2_push_int_param ); CB( GDK_TYPE_MODIFIER_TYPE,pgtk2_push_int_param );
1a05542005-07-28Martin Nilsson 
ba9e802006-02-27Martin Stjernholm  CB( G_TYPE_FLOAT, pgtk2_push_float_param ); CB( G_TYPE_DOUBLE, pgtk2_push_float_param );
1a05542005-07-28Martin Nilsson 
ba9e802006-02-27Martin Stjernholm  CB( G_TYPE_STRING, pgtk2_push_string_param );
1a05542005-07-28Martin Nilsson 
ba9e802006-02-27Martin Stjernholm  CB( G_TYPE_INT, pgtk2_push_int_param );
48319e2006-08-03Lance Dillon  CB( G_TYPE_INT64, pgtk2_push_int_param ); CB( G_TYPE_UINT64, pgtk2_push_int_param );
3a27cd2016-01-23Chris Angelico  CB( G_TYPE_ENUM, pgtk2_push_enum_param );
ba9e802006-02-27Martin Stjernholm  CB( G_TYPE_FLAGS, pgtk2_push_int_param ); CB( G_TYPE_BOOLEAN, pgtk2_push_int_param ); CB( G_TYPE_UINT, pgtk2_push_int_param ); CB( G_TYPE_LONG, pgtk2_push_int_param ); CB( G_TYPE_ULONG, pgtk2_push_int_param ); CB( G_TYPE_CHAR, pgtk2_push_int_param );
1a05542005-07-28Martin Nilsson 
228a2d2016-01-23Chris Angelico  CB( G_TYPE_NONE, NULL );
ba9e802006-02-27Martin Stjernholm  CB( G_TYPE_POINTER, pgtk2_push_pike_object_param );
1a05542005-07-28Martin Nilsson 
ba9e802006-02-27Martin Stjernholm  CB( G_TYPE_PARAM, pgtk2_push_gparamspec_param );
82bd5a2006-09-05Lance Dillon  CB( G_TYPE_BOXED, pgtk2_push_object_param );
1a05542005-07-28Martin Nilsson /* CB( GTK_TYPE_SIGNAL, NULL ); CB( GTK_TYPE_INVALID, NULL ); * This might not be exactly what we want */ }
68d1052006-08-02Lance Dillon void push_gvalue_r(const GValue *param, GType t) {
1a05542005-07-28Martin Nilsson  int i; struct push_callback *cb=push_cbtable[t%63]; while (cb && (cb->id!=t)) cb=cb->next; if (!cb) /* find parent type */ for (i=0; i<last_used_callback; i++) if (g_type_is_a(t,push_callbacks[i].id)) cb=push_callbacks+i; if (cb) { if (cb->callback) cb->callback(param); return; } else { const char *s=(char *)g_type_name(t);
ab11e72007-11-28Per Hedbor  if( s && (s[0] == 'g') ) // FIXME: How to get these types from GTK? { switch( s[1] ) { case 'c': if( !strcmp( s, "gchararray" ) ) { pgtk2_push_string_param(param); return; } break; case 'f': case 'd': if( !strcmp( s, "gfloat" ) ) { push_float( g_value_get_float( param ) ); return; } if( !strcmp( s, "gdouble" ) ) { push_float( g_value_get_double( param ) ); return; } break; case 'i': case 'u': if( !strcmp( s, "gint" ) ) { push_int(g_value_get_int(param)); return; } else if( !strcmp( s, "guint" ) ) { push_int64(g_value_get_uint(param)); return; } break; } }
34e7652008-01-23Per Hedbor  { char *a=""; if (!s) { a="Unknown child of "; s=g_type_name(g_type_parent(t)); if (!s) s="unknown type"; } Pike_error("No push callback for type %d (%s%s)\n",t,a,s);
1a05542005-07-28Martin Nilsson  } } return; } #include <gobject/gvaluecollector.h> /* This function makes a few assumptions about how signal handlers are * called in GTK. I could not find any good documentation about that, * and the source is somewhat obscure (for good reasons, it's a highly * non-trivial thing to do) * * But, the thing that this code asumes that I am most unsure about is that * params[nparams] should be set to the return value. It does seem to work, * though. */
68d1052006-08-02Lance Dillon /* This function is implement by the functions in the gobject api */ void pgtk2_signal_func_wrapper(struct signal_data *d, gpointer go, guint n_params, const GValue *param_values, GValue *return_value) {
34e7652008-01-23Per Hedbor  unsigned int i;
1a05542005-07-28Martin Nilsson  if (!last_used_callback) build_push_callbacks();
68d1052006-08-02Lance Dillon  push_gobject(G_OBJECT(go)); for (i=0; i<n_params; i++) { pgtk2_push_gvalue_rt(&(param_values[i]));
1a05542005-07-28Martin Nilsson  } push_svalue(&d->args);
418e9c2009-11-13Per Hedbor  apply_svalue(&d->cb,2+n_params);
cd87c12009-11-16Per Hedbor  if (return_value && G_VALUE_TYPE(return_value) != 0 ) pgtk2_set_value(return_value,&Pike_sp[-1]); pop_stack();
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm void pgtk2_free_signal_data(struct signal_data *s, GClosure *gcl) {
1a05542005-07-28Martin Nilsson  free_svalue(&s->cb); free_svalue(&s->args); g_free(s); }
ba9e802006-02-27Martin Stjernholm void pgtk2_push_gchar(const gchar *s) {
fb1f5d2010-09-19Marcus Comstedt  if (s) {
228a2d2016-01-23Chris Angelico  push_text(s);
fb1f5d2010-09-19Marcus Comstedt  push_int(1); f_utf8_to_string(2); } else push_int(0);
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm gchar *pgtk2_get_str(struct svalue *sv) {
1a05542005-07-28Martin Nilsson  gchar *res; push_svalue(sv); push_int(1); f_string_to_utf8(2); res=(gchar *)g_malloc(Pike_sp[-1].u.string->len+1); if (res==NULL) { pop_stack(); return NULL; } memcpy(res,STR0(Pike_sp[-1].u.string),Pike_sp[-1].u.string->len+1); pop_stack(); return res; }
ba9e802006-02-27Martin Stjernholm void pgtk2_free_str(gchar *s) {
1a05542005-07-28Martin Nilsson  g_free(s); }
208e092010-09-19Marcus Comstedt void pgtk2_get_string_arg_with_sprintf( INT32 args ) { if( args < 1 ) Pike_error("Too few arguments, %d required, got %d\n", 1, args);
017b572011-10-28Henrik Grubbström (Grubba)  if( TYPEOF(Pike_sp[-args]) != PIKE_T_STRING )
208e092010-09-19Marcus Comstedt  Pike_error("Illegal argument %d, expected string\n", 0); if( args > 1 ) f_sprintf(args); f_string_to_utf8(1); }
ba9e802006-02-27Martin Stjernholm void pgtk2_default__sprintf(int args, int offset, int len) {
1a05542005-07-28Martin Nilsson  int mode = 0;
017b572011-10-28Henrik Grubbström (Grubba)  if (args>0 && TYPEOF(Pike_sp[-args]) == PIKE_T_INT)
1a05542005-07-28Martin Nilsson  mode=Pike_sp[-args].u.integer;
ba9e802006-02-27Martin Stjernholm  pgtk2_pop_n_elems(args);
1a05542005-07-28Martin Nilsson  if (mode!='O') { push_undefined(); return; }
ba9e802006-02-27Martin Stjernholm  push_string(make_shared_binary_string(__pgtk2_string_data+offset,len));
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm void pgtk2_clear_obj_struct(struct object *o) {
21b12a2014-09-03Martin Nilsson  memset(Pike_fp->current_storage,0,sizeof(struct object_wrapper));
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm void pgtk2_setup_mixin(struct object *o, struct program *p) {
4ca9822006-01-02Marcus Comstedt  ptrdiff_t offset; offset = low_get_storage(o->prog, p); if(offset == -1) Pike_error("This class can not be instantiated on its own.\n"); ((struct mixin_wrapper *)Pike_fp->current_storage)->offset = offset; }
1a05542005-07-28Martin Nilsson 
ba9e802006-02-27Martin Stjernholm LONGEST pgtk2_get_int(struct svalue *s) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*s) == PIKE_T_INT)
1a05542005-07-28Martin Nilsson  return s->u.integer; #ifdef AUTO_BIGNUM if (is_bignum_object_in_svalue(s)) { LONGEST res; int64_from_bignum(&res,s->u.object); return res; } #endif
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*s) == PIKE_T_FLOAT)
1a05542005-07-28Martin Nilsson  return (LONGEST)s->u.float_number; return 0; }
ba9e802006-02-27Martin Stjernholm int pgtk2_is_int(struct svalue *s) {
017b572011-10-28Henrik Grubbström (Grubba)  return ((TYPEOF(*s) == PIKE_T_INT) || (TYPEOF(*s) == PIKE_T_FLOAT)
1a05542005-07-28Martin Nilsson #ifdef AUTO_BIGNUM || is_bignum_object_in_svalue(s) #endif ); } /* double should be enough */
ba9e802006-02-27Martin Stjernholm double pgtk2_get_float(struct svalue *s) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*s) == PIKE_T_FLOAT)
1a05542005-07-28Martin Nilsson  return s->u.float_number;
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*s) == PIKE_T_INT)
1a05542005-07-28Martin Nilsson  return (double)s->u.integer; #ifdef AUTO_BIGNUM if (is_bignum_object_in_svalue(s)) { FLOAT_TYPE f;
8288db2014-08-28Martin Nilsson  ref_push_type_value(float_type_string); stack_swap(); f_cast();
1a05542005-07-28Martin Nilsson  f=Pike_sp[-1].u.float_number; pop_stack(); return (double)f; } #endif return 0.0; }
ba9e802006-02-27Martin Stjernholm void pgtk2_free_object(struct object *o) {
1a05542005-07-28Martin Nilsson  free_object(o); }
ba9e802006-02-27Martin Stjernholm int pgtk2_is_float(struct svalue *s) {
017b572011-10-28Henrik Grubbström (Grubba)  return ((TYPEOF(*s) == PIKE_T_FLOAT) || (TYPEOF(*s) == PIKE_T_INT)
1a05542005-07-28Martin Nilsson #ifdef AUTO_BIGNUM || is_bignum_object_in_svalue(s) #endif ); }
ba9e802006-02-27Martin Stjernholm void pgtk2_set_property(GObject *g, char *prop, struct svalue *sv) {
1a05542005-07-28Martin Nilsson  GParamSpec *gps; GType v; gps=g_object_class_find_property(G_OBJECT_GET_CLASS(g),prop); if (!gps) Pike_error("This object does not have a property called %s.\n",prop); if (!(gps->flags & G_PARAM_WRITABLE)) Pike_error("This property is not writable.\n"); /*
228a2d2016-01-23Chris Angelico  if (gps->value_type==PANGO_TYPE_STYLE ||
1a05542005-07-28Martin Nilsson  gps->value_type==GTK_TYPE_WRAP_MODE || gps->value_type==GTK_TYPE_JUSTIFICATION || gps->value_type==PANGO_TYPE_UNDERLINE || gps->value_type==GTK_TYPE_TEXT_DIRECTION) { g_object_set(g,prop,PGTK_GETINT(sv),NULL); return; } */
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*sv) == PIKE_T_OBJECT) {
6eed032006-02-04Lance Dillon  GObject *go=get_gobject(sv->u.object); if (go && G_IS_OBJECT(go)) { if (gps->value_type==GDK_TYPE_PIXMAP || gps->value_type==GTK_TYPE_WIDGET) g_object_set(g,prop,go,NULL); return; }
1a05542005-07-28Martin Nilsson  } #define do_type(X) do { X i=PGTK_GETINT(sv); g_object_set(g,prop,i,NULL); } while(0) switch (gps->value_type) { case G_TYPE_INT: case G_TYPE_FLAGS: case G_TYPE_ENUM: do_type(gint); break; case G_TYPE_UINT: do_type(guint); break; case G_TYPE_BOOLEAN: do_type(gboolean); break; case G_TYPE_CHAR: do_type(gchar); break; case G_TYPE_UCHAR: do_type(guchar); break; case G_TYPE_LONG: do_type(glong); break; case G_TYPE_ULONG: do_type(gulong); break; case G_TYPE_INT64: do_type(gint64); break; case G_TYPE_UINT64: do_type(guint64); break; case G_TYPE_FLOAT: {
ba9e802006-02-27Martin Stjernholm  gfloat f=pgtk2_get_float(sv);
1a05542005-07-28Martin Nilsson  g_object_set(g,prop,f,NULL); } break; case G_TYPE_DOUBLE: {
ba9e802006-02-27Martin Stjernholm  gdouble f=pgtk2_get_float(sv);
1a05542005-07-28Martin Nilsson  g_object_set(g,prop,f,NULL); } break; case G_TYPE_STRING: { char *s=PGTK_GETSTR(sv); g_object_set(g,prop,s,NULL); PGTK_FREESTR(s); } break; case G_TYPE_OBJECT: g_object_set(g,prop,get_gobject(sv->u.object),NULL); break; case G_TYPE_POINTER: case G_TYPE_BOXED: case G_TYPE_PARAM:
48319e2006-08-03Lance Dillon  { if (gps->value_type==g_type_from_name("GdkColor")) { GdkColor *gc; gc=(GdkColor *)get_gdkobject(sv->u.object,color); g_object_set(g,prop,gc,NULL); } else Pike_error("Unable to handle type %s.\n",g_type_name(gps->value_type)); }
1a05542005-07-28Martin Nilsson  break; default: g_object_set(g,prop,PGTK_GETINT(sv),NULL); break; } }
ba9e802006-02-27Martin Stjernholm void pgtk2_get_property(GObject *g, char *prop) {
1a05542005-07-28Martin Nilsson  GParamSpec *gps=g_object_class_find_property(G_OBJECT_GET_CLASS(g),prop); if (!gps) Pike_error("This object does not have a property called %s.\n",prop); if (!(gps->flags & G_PARAM_READABLE)) Pike_error("This property is not readable.\n");
ba9e802006-02-27Martin Stjernholm  pgtk2__low_get_property(g,prop);
1a05542005-07-28Martin Nilsson }
ba9e802006-02-27Martin Stjernholm void pgtk2__low_get_property(GObject *g, char *prop) {
1a05542005-07-28Martin Nilsson  GParamSpec *gps=g_object_class_find_property(G_OBJECT_GET_CLASS(g),prop); #define get_type(type) do { \ type i; \ g_object_get(g,prop,&i,NULL); \ } while(0) if (G_TYPE_IS_OBJECT(gps->value_type)) { GObject *o; g_object_get(g,prop,&o,NULL); push_gobject(o); return; }
48319e2006-08-03Lance Dillon /* if (gps->value_type==GTK_TYPE_TREE_MODEL) { */ if (G_TYPE_IS_INTERFACE(gps->value_type)) {
1a05542005-07-28Martin Nilsson  GObject *o; g_object_get(g,prop,&o,NULL); push_gobject(o); return; } switch (gps->value_type) { case G_TYPE_INT: case G_TYPE_FLAGS: case G_TYPE_ENUM: { gint i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_UINT: { guint i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_BOOLEAN: { gboolean i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_CHAR: { gchar i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_UCHAR: { guchar i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_LONG: { glong i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_ULONG: { gulong i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_INT64: { gint64 i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_UINT64: { guint64 i; g_object_get(g,prop,&i,NULL); push_int(i); } break; case G_TYPE_FLOAT: { gfloat f; g_object_get(g,prop,&f,NULL); push_float(f); } break; case G_TYPE_DOUBLE: { gdouble f; g_object_get(g,prop,&f,NULL); push_float(f); } break; case G_TYPE_STRING: { gchar *s; g_object_get(g,prop,&s,NULL); if (s) PGTK_PUSH_GCHAR(s); else push_string(empty_pike_string); g_free(s); } break; case G_TYPE_OBJECT: { GObject *o; g_object_get(g,prop,&o,NULL); push_gobject(o); } break; case G_TYPE_BOXED: case G_TYPE_POINTER: case G_TYPE_PARAM: default:
48319e2006-08-03Lance Dillon  { if (gps->value_type==g_type_from_name("GdkColor")) { GdkColor *gc; gc=g_malloc(sizeof(GdkColor)); if (gc==NULL) Pike_error("Out of memory allocating %d bytes\n",sizeof(GdkColor)); g_object_get(g,prop,gc,NULL);
2edd4f2008-01-30Per Hedbor  push_gdkobject(gc,color,1);
48319e2006-08-03Lance Dillon  } else { Pike_error("Unable to handle type %s.\n",g_type_name(gps->value_type)); } }
1a05542005-07-28Martin Nilsson  break; } }
ba9e802006-02-27Martin Stjernholm void pgtk2_destroy_store_data(gpointer data) {
1a05542005-07-28Martin Nilsson  struct store_data *sd=(struct store_data *)data; g_free(sd->types); g_free(sd); }
68d1052006-08-02Lance Dillon 
ba9e802006-02-27Martin Stjernholm void pgtk2_set_gvalue(GValue *gv, GType gt, struct svalue *sv) {
68d1052006-08-02Lance Dillon  if (!G_IS_VALUE(gv)) g_value_init(gv,gt);
3d76632005-11-03Lance Dillon  if (G_TYPE_IS_ENUM(gt)) { g_value_set_enum(gv,(gint)PGTK_GETINT(sv)); return; } /* if (G_TYPE_IS_OBJECT(gt)) { */
0874072005-11-04Henrik Grubbström (Grubba)  if (G_TYPE_IS_OBJECT(gt) || #ifdef HAVE_GTK22 gt==GDK_TYPE_DISPLAY || gt==GDK_TYPE_SCREEN || #endif
3d76632005-11-03Lance Dillon  gt==GDK_TYPE_PIXBUF || gt==GDK_TYPE_PIXMAP || gt==GDK_TYPE_IMAGE ||
0874072005-11-04Henrik Grubbström (Grubba)  gt==GDK_TYPE_WINDOW || gt==GDK_TYPE_VISUAL ||
3d76632005-11-03Lance Dillon  gt==GDK_TYPE_DRAWABLE || gt==GDK_TYPE_GC) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*sv) == PIKE_T_OBJECT) {
6eed032006-02-04Lance Dillon  GObject *go; go=get_gobject(sv->u.object); if (go && G_IS_OBJECT(go)) g_value_set_object(gv,go); return; }
3d76632005-11-03Lance Dillon  } if (gt==GDK_TYPE_COLOR) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*sv) == PIKE_T_OBJECT && get_gdkobject(sv->u.object,color))
3d76632005-11-03Lance Dillon  g_value_set_boxed(gv,get_gdkobject(sv->u.object,color)); return; } if (gt==GDK_TYPE_RECTANGLE) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*sv) == PIKE_T_OBJECT && get_gdkobject(sv->u.object,rectangle))
3d76632005-11-03Lance Dillon  g_value_set_boxed(gv,get_gdkobject(sv->u.object,rectangle)); return; }
1a05542005-07-28Martin Nilsson  switch (gt) { case G_TYPE_INT: g_value_set_int(gv,(gint)PGTK_GETINT(sv)); break; case G_TYPE_UINT: g_value_set_uint(gv,(guint)PGTK_GETINT(sv)); break; case G_TYPE_CHAR:
8172072014-03-02Marcus Comstedt #ifdef HAVE_G_VALUE_SET_SCHAR
fa45bf2014-02-25Per Hedbor  g_value_set_schar(gv,(gchar)PGTK_GETINT(sv));
8172072014-03-02Marcus Comstedt #else g_value_set_char(gv,(gchar)PGTK_GETINT(sv)); #endif
1a05542005-07-28Martin Nilsson  break; case G_TYPE_UCHAR: g_value_set_uchar(gv,(guchar)PGTK_GETINT(sv)); break; case G_TYPE_LONG: g_value_set_long(gv,(glong)PGTK_GETINT(sv)); break; case G_TYPE_ULONG: g_value_set_ulong(gv,(gulong)PGTK_GETINT(sv)); break; case G_TYPE_INT64: g_value_set_int64(gv,(gint64)PGTK_GETINT(sv)); break; case G_TYPE_UINT64: g_value_set_uint64(gv,(guint64)PGTK_GETINT(sv)); break; case G_TYPE_ENUM: g_value_set_enum(gv,(gint)PGTK_GETINT(sv)); break; case G_TYPE_FLAGS: g_value_set_flags(gv,(gint)PGTK_GETINT(sv)); break; case G_TYPE_BOOLEAN: g_value_set_boolean(gv,(gboolean)PGTK_GETINT(sv)); break; case G_TYPE_FLOAT:
ba9e802006-02-27Martin Stjernholm  g_value_set_float(gv,(gfloat)pgtk2_get_float(sv));
1a05542005-07-28Martin Nilsson  break; case G_TYPE_DOUBLE:
ba9e802006-02-27Martin Stjernholm  g_value_set_double(gv,(gdouble)pgtk2_get_float(sv));
1a05542005-07-28Martin Nilsson  break; case G_TYPE_STRING:
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*sv) == PIKE_T_STRING)
34e7652008-01-23Per Hedbor  { push_svalue( sv ); f_string_to_utf8(1); g_value_set_string(gv,CGSTR0(Pike_sp[-1].u.string)); pop_stack();
68d1052006-08-02Lance Dillon  } else
6eed032006-02-04Lance Dillon  g_value_set_string(gv,"");
1a05542005-07-28Martin Nilsson  break; case G_TYPE_OBJECT:
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*sv) == PIKE_T_OBJECT) {
6eed032006-02-04Lance Dillon  GObject *go=get_gobject(sv->u.object); if (go && G_IS_OBJECT(go)) g_value_set_object(gv,go); else g_value_set_object(gv,NULL); } else
1a05542005-07-28Martin Nilsson  g_value_set_object(gv,NULL); break; case G_TYPE_POINTER:
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*sv) == PIKE_T_OBJECT) {
1a05542005-07-28Martin Nilsson  g_value_set_pointer(gv,sv->u.object);
228a2d2016-01-23Chris Angelico  add_ref(sv->u.object);
1a05542005-07-28Martin Nilsson  } else g_value_set_pointer(gv,NULL); break;
cd87c12009-11-16Per Hedbor  case 0: // void break;
1a05542005-07-28Martin Nilsson  default:
cd87c12009-11-16Per Hedbor  Pike_error("Unable to handle type %d - %s.\n",gt,g_type_name(gt) ?g_type_name(gt): "unnamed" );
1a05542005-07-28Martin Nilsson  } }
ba9e802006-02-27Martin Stjernholm int pgtk2_tree_sortable_callback(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, struct signal_data *d) {
1a05542005-07-28Martin Nilsson  int res;
ba9e802006-02-27Martin Stjernholm /* push_gobjectclass(model,pgtk2_tree_model_program); */
6eed032006-02-04Lance Dillon  push_gobject(model);
2edd4f2008-01-30Per Hedbor  push_pgdk2object(a,pgtk2_tree_iter_program,0); push_pgdk2object(b,pgtk2_tree_iter_program,0);
1a05542005-07-28Martin Nilsson  push_svalue(&d->args);
3d76632005-11-03Lance Dillon  apply_svalue(&d->cb,4);
1a05542005-07-28Martin Nilsson  res=Pike_sp[-1].u.integer; pop_stack(); return res; }
3d76632005-11-03Lance Dillon 
ba9e802006-02-27Martin Stjernholm GObject *pgtk2_create_new_obj_with_properties(GType type, struct mapping *m) {
3d76632005-11-03Lance Dillon  GParamSpec *pspec; GObject *obj; GObjectClass *class; GParameter *params; struct keypair *k; int e; int i=0,j; class=g_type_class_ref(type); if (class==NULL) Pike_error("Could not get a reference to type %s.\n",g_type_name(type)); params=g_new0(GParameter,m_sizeof(m)); NEW_MAPPING_LOOP(m->data) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(k->ind) == PIKE_T_STRING) {
3d76632005-11-03Lance Dillon  gchar *s=PGTK_GETSTR(&k->ind); pspec=g_object_class_find_property(class,s); if (!pspec) { PGTK_FREESTR(s); continue; } /* g_value_init(&params[i].value,G_PARAM_SPEC_VALUE_TYPE(pspec)); */
ba9e802006-02-27Martin Stjernholm  pgtk2_set_gvalue(&params[i].value,G_PARAM_SPEC_VALUE_TYPE(pspec),&k->val);
3d76632005-11-03Lance Dillon  params[i++].name=s; } } obj=g_object_newv(type,i,params); for (j=0; j<i; j++) { PGTK_FREESTR((gchar *)params[j].name); g_value_unset(&params[j].value); } g_free(params); g_type_class_unref(class); return obj; }
68d1052006-08-02Lance Dillon  void pgtk2_marshaller(GClosure *closure, GValue *return_value, guint n_params, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*pgtk2_marshal_func)(gpointer data1, gpointer data2,
228a2d2016-01-23Chris Angelico  guint n_params,
68d1052006-08-02Lance Dillon  const GValue *param_values, GValue *return_value); register pgtk2_marshal_func callback; register GCClosure *cc=(GCClosure *)closure; register gpointer data1,data2; if (G_CCLOSURE_SWAP_DATA(closure)) { data1=closure->data; data2=g_value_peek_pointer(param_values+0); } else { data1=g_value_peek_pointer(param_values+0); data2=closure->data; }
9d2be52007-10-09Martin Nilsson 
68d1052006-08-02Lance Dillon  callback=(pgtk2_marshal_func)(marshal_data?marshal_data:cc->callback); callback(data1,data2,n_params-1,param_values+1,return_value); }
48319e2006-08-03Lance Dillon  int pgtk2_tree_view_row_separator_func(GtkTreeModel *model, GtkTreeIter *iter, struct signal_data *d) { int res; push_gobject(model); push_gobjectclass(iter,pgtk2_tree_iter_program); push_svalue(&d->args); apply_svalue(&d->cb,3); res=Pike_sp[-1].u.integer; pop_stack(); return res; }
cd87c12009-11-16Per Hedbor  int pgtk2_entry_completion_match_func( GtkEntryCompletion *x, const gchar *key, GtkTreeIter *iter, struct signal_data *d) { int res; push_gobject(x); pgtk2_push_gchar( key ); push_gobjectclass(iter,pgtk2_tree_iter_program); apply_svalue( &d->cb, 3 ); res = Pike_sp[-1].u.integer; pop_stack(); return res; }
636ceb2010-02-09Lance Dillon  void add_property_docs(GType type, GString *str) { GObjectClass *class; GParamSpec **props; guint n=0,i; gboolean has_prop=FALSE; G_CONST_RETURN gchar *blurb=NULL; class=g_type_class_ref(type); props=g_object_class_list_properties(class,&n); for (i=0; i<n; i++) { if (props[i]->owner_type!=type) continue; /* these are from a parent type */ if (!has_prop) { g_string_append_printf(str,"Properties from %s:\n",g_type_name(type)); has_prop=TRUE; } g_string_append_printf(str," %s - %s: %s\n", g_param_spec_get_name(props[i]), g_type_name(props[i]->value_type), g_param_spec_get_nick(props[i])); blurb=g_param_spec_get_blurb(props[i]); if (blurb) g_string_append_printf(str," %s\n",blurb); } g_free(props); if (has_prop) g_string_append(str,"\n"); g_type_class_unref(class); } void add_signal_docs(GType type, GString *str) { GTypeClass *class=NULL; guint *signal_ids,n=0,i; if (G_TYPE_IS_CLASSED(type)) class=g_type_class_ref(type); signal_ids=g_signal_list_ids(type,&n); if (n>0) { g_string_append_printf(str,"Signals from %s:\n",g_type_name(type)); for (i=0; i<n; i++) { GSignalQuery q; guint j; g_signal_query(signal_ids[i],&q); g_string_append(str," "); g_string_append(str,q.signal_name); g_string_append(str," ("); for (j=0; j<q.n_params; j++) { g_string_append(str,g_type_name(q.param_types[j])); if (j!=q.n_params-1) g_string_append(str,", "); } g_string_append(str,")"); if (q.return_type && q.return_type!=G_TYPE_NONE) { g_string_append(str," -> "); g_string_append(str,g_type_name(q.return_type)); } g_string_append(str,"\n"); } g_free(signal_ids); g_string_append(str,"\n"); } if (class) g_type_class_unref(class); }
a039fb2013-02-08Henrik Grubbström (Grubba) void pgtk2_get_doc(GObject *o, struct svalue *dest) {
636ceb2010-02-09Lance Dillon  GType type=0; GString *str; /* if (o) type=G_OBJECT_TYPE(G_OBJECT(o)->obj); else
a039fb2013-02-08Henrik Grubbström (Grubba)  return;
636ceb2010-02-09Lance Dillon */ type=G_OBJECT_TYPE(o); str=g_string_new_len(NULL,512); if (g_type_is_a(type,G_TYPE_INTERFACE)) g_string_append_printf(str,"Interface %s\n\n",g_type_name(type)); else if (g_type_is_a(type,G_TYPE_OBJECT)) g_string_append_printf(str,"Object %s\n\n",g_type_name(type)); if (g_type_is_a(type,G_TYPE_OBJECT)) { GType parent=G_TYPE_OBJECT; GArray *parents=g_array_new(FALSE,FALSE,sizeof(GType)); int ip; while (parent) { g_array_append_val(parents,parent); parent=g_type_next_base(type,parent); } for (ip=parents->len-1; ip>=0; --ip) { GType *interfaces; guint n,i; parent=g_array_index(parents,GType,ip); add_signal_docs(parent,str); add_property_docs(parent,str); interfaces=g_type_interfaces(parent,&n); for (i=0; i<n; i++) add_signal_docs(interfaces[i],str); g_free(interfaces); } g_array_free(parents,TRUE); } push_string(make_shared_binary_string(str->str,str->len)); g_string_free(str,TRUE);
a039fb2013-02-08Henrik Grubbström (Grubba)  if (dest) { assign_svalue_no_free(dest, Pike_sp - 1);
636ceb2010-02-09Lance Dillon  pop_stack(); } }