예제 #1
0
/*
 * returns a pointer to a temp stock item you can use until control returns
 * to perl.
 */
static GtkStockItem *
SvGtkStockItem (SV * sv)
{
	HV * hv;
	SV ** svp;
	GtkStockItem * item;

	if (!gperl_sv_is_hash_ref (sv))
		croak ("malformed stock item; use a reference to a hash as a stock item");

	hv = (HV*) SvRV (sv);

	item = gperl_alloc_temp (sizeof (GtkStockItem));

	svp = hv_fetch (hv, "stock_id", 8, FALSE);
	if (svp) item->stock_id = SvGChar (*svp);

	svp = hv_fetch (hv, "label", 5, FALSE);
	if (svp) item->label = SvGChar (*svp);

	svp = hv_fetch (hv, "modifier", 8, FALSE);
	if (svp) item->modifier = SvGdkModifierType (*svp);

	svp = hv_fetch (hv, "keyval", 6, FALSE);
	if (svp) item->keyval = SvUV (*svp);

	svp = hv_fetch (hv, "translation_domain", 18, FALSE);
	if (svp) item->translation_domain = SvGChar (*svp);

	return item;
}
/* transfer and may_be_null can be gotten from arg_info, but sv_to_arg is also
 * called from places which don't have access to a GIArgInfo. */
static void
sv_to_arg (SV * sv,
           GIArgument * arg,
           GIArgInfo * arg_info,
           GITypeInfo * type_info,
           GITransfer transfer,
           gboolean may_be_null,
           GPerlI11nInvocationInfo * invocation_info)
{
	GITypeTag tag = g_type_info_get_tag (type_info);

	if (!gperl_sv_is_defined (sv))
		/* Interfaces and void types need to be able to handle undef
		 * separately. */
		if (!may_be_null && tag != GI_TYPE_TAG_INTERFACE
		                 && tag != GI_TYPE_TAG_VOID) {
			if (arg_info) {
				ccroak ("undefined value for mandatory argument '%s' encountered",
				        g_base_info_get_name ((GIBaseInfo *) arg_info));
			} else {
				ccroak ("undefined value encountered");
			}
		}

	switch (tag) {
	    case GI_TYPE_TAG_VOID:
		/* returns NULL if no match is found */
		arg->v_pointer = sv_to_callback_data (sv, invocation_info);
		break;

	    case GI_TYPE_TAG_BOOLEAN:
		arg->v_boolean = SvTRUE (sv);
		break;

	    case GI_TYPE_TAG_INT8:
		arg->v_int8 = (gint8) SvIV (sv);
		break;

	    case GI_TYPE_TAG_UINT8:
		arg->v_uint8 = (guint8) SvUV (sv);
		break;

	    case GI_TYPE_TAG_INT16:
		arg->v_int16 = (gint16) SvIV (sv);
		break;

	    case GI_TYPE_TAG_UINT16:
		arg->v_uint16 = (guint16) SvUV (sv);
		break;

	    case GI_TYPE_TAG_INT32:
		arg->v_int32 = (gint32) SvIV (sv);
		break;

	    case GI_TYPE_TAG_UINT32:
		arg->v_uint32 = (guint32) SvUV (sv);
		break;

	    case GI_TYPE_TAG_INT64:
		arg->v_int64 = SvGInt64 (sv);
		break;

	    case GI_TYPE_TAG_UINT64:
		arg->v_uint64 = SvGUInt64 (sv);
		break;

	    case GI_TYPE_TAG_FLOAT:
		arg->v_float = (gfloat) SvNV (sv);
		break;

	    case GI_TYPE_TAG_DOUBLE:
		arg->v_double = SvNV (sv);
		break;

	    case GI_TYPE_TAG_UNICHAR:
		arg->v_uint32 = g_utf8_get_char (SvGChar (sv));
		break;

	    case GI_TYPE_TAG_GTYPE:
		/* GType == gsize */
		arg->v_size = gperl_type_from_package (SvPV_nolen (sv));
		if (!arg->v_size)
			arg->v_size = g_type_from_name (SvPV_nolen (sv));
		break;

	    case GI_TYPE_TAG_ARRAY:
                arg->v_pointer = sv_to_array (transfer, type_info, sv, invocation_info);
		break;

	    case GI_TYPE_TAG_INTERFACE:
		dwarn ("    type %p -> interface\n", type_info);
		sv_to_interface (arg_info, type_info, transfer, may_be_null,
		                 sv, arg, invocation_info);
		break;

	    case GI_TYPE_TAG_GLIST:
	    case GI_TYPE_TAG_GSLIST:
		arg->v_pointer = sv_to_glist (transfer, type_info, sv);
		break;

	    case GI_TYPE_TAG_GHASH:
                arg->v_pointer = sv_to_ghash (transfer, type_info, sv);
		break;

	    case GI_TYPE_TAG_ERROR:
		ccroak ("FIXME - A GError as an in/inout arg?  Should never happen!");
		break;

	    case GI_TYPE_TAG_UTF8:
		arg->v_string = gperl_sv_is_defined (sv) ? SvGChar (sv) : NULL;
		if (transfer >= GI_TRANSFER_CONTAINER)
			arg->v_string = g_strdup (arg->v_string);
		break;

	    case GI_TYPE_TAG_FILENAME:
		/* FIXME: Should we use SvPVbyte_nolen here? */
		arg->v_string = gperl_sv_is_defined (sv) ? SvPV_nolen (sv) : NULL;
		if (transfer >= GI_TRANSFER_CONTAINER)
			arg->v_string = g_strdup (arg->v_string);
		break;

	    default:
		ccroak ("Unhandled info tag %d in sv_to_arg", tag);
	}
}
예제 #3
0
static GtkWidget *
gtk2perl_toolbar_insert_internal (GtkToolbar * toolbar,
                                  SV * type,
				  SV * widget,
                                  SV * text,
				  SV * tooltip_text,
				  SV * tooltip_private_text,
				  SV * icon,
				  SV * callback,
				  SV * user_data,
				  SV * position,
				  WhichInsert which,
				  WhichOp op)
{
	GtkWidget * w = NULL;
	const char * real_tooltip_text = NULL;
	const char * real_tooltip_private_text = NULL;

	/* _ornull is not always right for text, but is for the others. */
	real_tooltip_text = SvGChar_ornull (tooltip_text);
	real_tooltip_private_text = SvGChar_ornull (tooltip_private_text);

	switch (which) {
	    case STOCK:
		/* stock with NULL text (the stock id) makes no sense,
		 * so let's make sure perl will issue an uninitialized
		 * value warning for undef passed here for text. */
		w = gtk_toolbar_insert_stock (toolbar, SvGChar (text),
		                              real_tooltip_text,
		                              real_tooltip_private_text,
		                              NULL, NULL, 
		                              SvIV (position));
		break;
	    case ITEM:
		{
		const gchar * real_text = SvGChar_ornull (text);
		GtkWidget * real_icon = SvGtkWidget_ornull (icon);
		switch (op) {
		    case PREPEND:
			w = gtk_toolbar_prepend_item (toolbar, real_text,
			                              real_tooltip_text,
			                              real_tooltip_private_text,
			                              real_icon, NULL, NULL);
			break;
		    case APPEND:
			w = gtk_toolbar_append_item (toolbar, real_text,
			                             real_tooltip_text,
			                             real_tooltip_private_text,
			                             real_icon, NULL, NULL);
			break;
		    case INSERT:
			w = gtk_toolbar_insert_item (toolbar, real_text,
			                             real_tooltip_text,
			                             real_tooltip_private_text,
			                             real_icon, NULL, NULL, 
			                             SvIV (position));
			break;
		    default:
			g_assert_not_reached ();
		}
		}
		break;
	    case ELEMENT:
		{
		GtkToolbarChildType real_type = SvGtkToolbarChildType(type);
		const gchar * real_text = SvGChar_ornull (text);
		GtkWidget * real_widget = SvGtkWidget_ornull (widget);
		GtkWidget * real_icon = SvGtkWidget_ornull (icon);
		switch (op) {
		    case PREPEND:
			w = gtk_toolbar_prepend_element (toolbar, real_type,
			                                 real_widget,
							 real_text,
							 real_tooltip_text,
							 real_tooltip_private_text,
							 real_icon,
							 NULL, NULL);
			break;
		    case APPEND:
			w = gtk_toolbar_append_element (toolbar, real_type,
			                                real_widget,
						        real_text,
						        real_tooltip_text,
						        real_tooltip_private_text,
						        real_icon,
						        NULL, NULL);
			break;
		    case INSERT:
			w = gtk_toolbar_insert_element (toolbar, real_type,
			                                real_widget,
						        real_text,
						        real_tooltip_text,
						        real_tooltip_private_text,
						        real_icon,
						        NULL, NULL,
			                                SvIV (position));
			break;
		    default:
			g_assert_not_reached ();
		}
		}
		break;
	    case WIDGET:
		{
		w = SvGtkWidget (widget);
		switch (op) {
		    case PREPEND:
			gtk_toolbar_prepend_widget (toolbar, w,
			                            real_tooltip_text,
			                            real_tooltip_private_text);
			break;
		    case APPEND:
			gtk_toolbar_append_widget (toolbar, w,
			                           real_tooltip_text,
			                           real_tooltip_private_text);
			break;
		    case INSERT:
			gtk_toolbar_insert_widget (toolbar, w,
			                           real_tooltip_text,
			                           real_tooltip_private_text,
						   SvIV (position));
			break;
		    default:
			g_assert_not_reached ();
		}
		}
		break;
		default:
			g_assert_not_reached ();
	}
	if (gperl_sv_is_defined (callback))
		gperl_signal_connect (newSVGtkWidget (w), "clicked",
		                      callback, user_data, 0);

	return w;
}