/*
 * This file was generated automatically by ExtUtils::ParseXS version 3.22 from the
 * contents of GnomeProgram.xs. Do not edit this file, edit GnomeProgram.xs instead.
 *
 *    ANY CHANGES MADE HERE WILL BE LOST!
 *
 */

#line 1 "xs/GnomeProgram.xs"
/*
 * Copyright (C) 2003 by the gtk2-perl team (see the file AUTHORS)
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * See the LICENSE file in the top level of this distribution
 * for the complete license terms.
 *
 */

#include "gnome2perl.h"

static const GnomeModuleInfo *
handle_module_info (SV * module_info)
{
	const GnomeModuleInfo * real_module_info = NULL;

	if (!module_info || !SvTRUE (module_info)) {
		/* go ahead and pass NULL.  you get libgnome initialized. */
		/* FIXME FIXME is it right to change default to libgnomeui? */
		real_module_info = LIBGNOMEUI_MODULE;
	} else if (SvPOK (module_info)) {
		/* name of a module.  this is a limited-support hack. */
		char * modname = SvPV_nolen (module_info);
		if (strEQ ("libgnome", modname)) {
			real_module_info = LIBGNOME_MODULE;
		} else if (strEQ ("libgnomeui", modname)) {
			real_module_info = LIBGNOMEUI_MODULE;
		} else {
			croak ("you passed a string for module_info, but it wasn't one of 'libgnome' or 'libgnomeui'");
		}
	} else {
		real_module_info = SvGnomeModuleInfo (module_info);
	}

	return real_module_info;
}

#line 56 "xs/GnomeProgram.c"
#ifndef PERL_UNUSED_VAR
#  define PERL_UNUSED_VAR(var) if (0) var = var
#endif

#ifndef dVAR
#  define dVAR		dNOOP
#endif


/* This stuff is not part of the API! You have been warned. */
#ifndef PERL_VERSION_DECIMAL
#  define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
#endif
#ifndef PERL_DECIMAL_VERSION
#  define PERL_DECIMAL_VERSION \
	  PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
#endif
#ifndef PERL_VERSION_GE
#  define PERL_VERSION_GE(r,v,s) \
	  (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
#endif
#ifndef PERL_VERSION_LE
#  define PERL_VERSION_LE(r,v,s) \
	  (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
#endif

/* XS_INTERNAL is the explicit static-linkage variant of the default
 * XS macro.
 *
 * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
 * "STATIC", ie. it exports XSUB symbols. You probably don't want that
 * for anything but the BOOT XSUB.
 *
 * See XSUB.h in core!
 */


/* TODO: This might be compatible further back than 5.10.0. */
#if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
#  undef XS_EXTERNAL
#  undef XS_INTERNAL
#  if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
#    define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
#    define XS_INTERNAL(name) STATIC XSPROTO(name)
#  endif
#  if defined(__SYMBIAN32__)
#    define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
#    define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name)
#  endif
#  ifndef XS_EXTERNAL
#    if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
#      define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
#      define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__)
#    else
#      ifdef __cplusplus
#        define XS_EXTERNAL(name) extern "C" XSPROTO(name)
#        define XS_INTERNAL(name) static XSPROTO(name)
#      else
#        define XS_EXTERNAL(name) XSPROTO(name)
#        define XS_INTERNAL(name) STATIC XSPROTO(name)
#      endif
#    endif
#  endif
#endif

/* perl >= 5.10.0 && perl <= 5.15.1 */


/* The XS_EXTERNAL macro is used for functions that must not be static
 * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
 * macro defined, the best we can do is assume XS is the same.
 * Dito for XS_INTERNAL.
 */
#ifndef XS_EXTERNAL
#  define XS_EXTERNAL(name) XS(name)
#endif
#ifndef XS_INTERNAL
#  define XS_INTERNAL(name) XS(name)
#endif

/* Now, finally, after all this mess, we want an ExtUtils::ParseXS
 * internal macro that we're free to redefine for varying linkage due
 * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
 * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
 */

#undef XS_EUPXS
#if defined(PERL_EUPXS_ALWAYS_EXPORT)
#  define XS_EUPXS(name) XS_EXTERNAL(name)
#else
   /* default to internal */
#  define XS_EUPXS(name) XS_INTERNAL(name)
#endif

#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)

/* prototype to pass -Wmissing-prototypes */
STATIC void
S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params);

STATIC void
S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params)
{
    const GV *const gv = CvGV(cv);

    PERL_ARGS_ASSERT_CROAK_XS_USAGE;

    if (gv) {
        const char *const gvname = GvNAME(gv);
        const HV *const stash = GvSTASH(gv);
        const char *const hvname = stash ? HvNAME(stash) : NULL;

        if (hvname)
            Perl_croak(aTHX_ "Usage: %s::%s(%s)", hvname, gvname, params);
        else
            Perl_croak(aTHX_ "Usage: %s(%s)", gvname, params);
    } else {
        /* Pants. I don't think that it should be possible to get here. */
        Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
    }
}
#undef  PERL_ARGS_ASSERT_CROAK_XS_USAGE

#ifdef PERL_IMPLICIT_CONTEXT
#define croak_xs_usage(a,b)    S_croak_xs_usage(aTHX_ a,b)
#else
#define croak_xs_usage        S_croak_xs_usage
#endif

#endif

/* NOTE: the prototype of newXSproto() is different in versions of perls,
 * so we define a portable version of newXSproto()
 */
#ifdef newXS_flags
#define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
#else
#define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
#endif /* !defined(newXS_flags) */

#line 198 "xs/GnomeProgram.c"

XS_EUPXS(XS_Gnome2__Program_init); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_init)
{
    dVAR; dXSARGS;
    if (items < 3)
       croak_xs_usage(cv,  "class, app_id, app_version, module_info=NULL, ...");
    {
	const char *	app_id = (const char *)SvPV_nolen(ST(1))
;
	const char *	app_version = (const char *)SvPV_nolen(ST(2))
;
	SV *	module_info;
#line 60 "xs/GnomeProgram.xs"
	int i;
	GPerlArgv *pargv;
	const GnomeModuleInfo * real_module_info = NULL;
#line 216 "xs/GnomeProgram.c"
	GnomeProgram *	RETVAL;

	if (items < 4)
	    module_info = NULL;
	else {
	    module_info = ST(3)
;
	}
#line 64 "xs/GnomeProgram.xs"
#define FIRST_VAR_ARG 4

	/* check validity of stack item count before doing anything else */
	if (items > FIRST_VAR_ARG && 0 != ((items - FIRST_VAR_ARG) % 2)) {
		/* caller didn't specify an even number of parameters... */
		croak ("Usage: Gnome2::Program->init (app_id, app_version, module_info)\n"
		       "   or: Gnome2::Program->init (app_id, app_version, module_info, prop => val, ...)\n"
		       "   there may be any number of prop/val pairs, but there must be a value\n"
		       "   for every prop");
	}

	/* let's see what the user passed for module_info */
	real_module_info = handle_module_info (module_info);

	/* we're good to go.  let's get a hold of @ARGV and $0 so we can
	 * synthesize the argv that gnome_program_init wants. */
	pargv = gperl_argv_new ();
	/* note that we have *not* modifed @ARGV.
	 */
#if LIBGNOME_CHECK_VERSION (2, 8, 0)
{
	GObjectClass *class;
	GParameter *params = NULL;
	guint nparams;
	int j;

	class = g_type_class_ref (GNOME_TYPE_PROGRAM);

	nparams = (items - FIRST_VAR_ARG) / 2;
	params = g_new0 (GParameter, nparams);

	/* get properties off the stack and set them */
	for (i = FIRST_VAR_ARG, j = 0 ; i < items ; i += 2, j++) {
		GType type;

		params[j].name = SvGChar (ST (i));

		/* Map GNOME_CLIENT_PARAM_SM_CONNECT to G_TYPE_BOOLEAN
		 * manually.  It's installed into the GnomeProgram class by
		 * libgnomeui when its module is loaded.  But that happens as
		 * part of gnome_program_init_paramv which we call below.  So
		 * when we try to find out the correct type for sm-connect
		 * *now*, the type system will complain that GnomeProgram has
		 * no such property.
		 */
		if (gperl_str_eq (params[j].name, GNOME_CLIENT_PARAM_SM_CONNECT)) {
			type = G_TYPE_BOOLEAN;
		} else {
			GParamSpec * pspec =
			  g_object_class_find_property (class, params[j].name);
			if (!pspec)
				/* we should do a lot more cleanup here,
				 * in principle, but the GnomeProgram is a
				 * singleton, and most people aren't going to
				 * accept an exception on initializing it. */
				croak ("property %s not found in object class %s",
				       params[j].name,
				       g_type_name (GNOME_TYPE_PROGRAM));
			type = G_PARAM_SPEC_VALUE_TYPE (pspec);
		}

		g_value_init (&params[j].value, type);
		gperl_value_from_sv (&params[j].value, ST (i+1));
	}

	RETVAL = gnome_program_init_paramv (GNOME_TYPE_PROGRAM,
	                                    app_id, app_version,
	                                    real_module_info,
	                                    pargv->argc, pargv->argv,
	                                    nparams, params);

	for (j = 0 ; j < nparams ; j++) {
		g_value_unset (&params[j].value);
	}

	g_free (params);
	g_type_class_unref (class);
}
#else
	RETVAL = gnome_program_init (app_id, app_version, real_module_info,
	                             pargv->argc, pargv->argv,
	                             GNOME_PARAM_NONE);

	/* get properties off the stack and set them */
	for (i = FIRST_VAR_ARG ; i < items ; i += 2) {
		const char * property_name;
		GValue gvalue = {0,};
		GParamSpec * pspec;

		property_name = SvGChar (ST (i));
		pspec = g_object_class_find_property 
		                          (G_OBJECT_GET_CLASS (RETVAL),
		                          property_name);
		if (!pspec)
			/* we should do a lot more cleanup here, 
			 * in principle, but the GnomeProgram is a 
			 * singleton, and most people aren't going to
			 * accept an exception on initializing it. */
			croak ("property %s not found in object class %s",
			       property_name, G_OBJECT_TYPE_NAME (RETVAL));

		g_value_init (&gvalue, G_PARAM_SPEC_VALUE_TYPE (pspec));
		gperl_value_from_sv (&gvalue, ST (i+1));
		g_object_set_property (G_OBJECT (RETVAL), property_name,
		                       &gvalue);
		g_value_unset (&gvalue);
	}
#endif

	gperl_argv_free (pargv);
#line 336 "xs/GnomeProgram.c"
	ST(0) = newSVGnomeProgram (RETVAL);
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Gnome2__Program_get_program); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_get_program)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "class");
    {
	GnomeProgram_ornull *	RETVAL;
#line 182 "xs/GnomeProgram.xs"
	RETVAL = gnome_program_get ();
#line 354 "xs/GnomeProgram.c"
	ST(0) = newSVGnomeProgram_ornull (RETVAL);
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Gnome2__Program_get_human_readable_name); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_get_human_readable_name)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "program");
    {
	const char *	RETVAL;
	dXSTARG;
	GnomeProgram *	program = SvGnomeProgram (ST(0))
;

	RETVAL = gnome_program_get_human_readable_name(program);
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Gnome2__Program_get_app_id); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_get_app_id)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "program");
    {
	const char *	RETVAL;
	dXSTARG;
	GnomeProgram *	program = SvGnomeProgram (ST(0))
;

	RETVAL = gnome_program_get_app_id(program);
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Gnome2__Program_get_app_version); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_get_app_version)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "program");
    {
	const char *	RETVAL;
	dXSTARG;
	GnomeProgram *	program = SvGnomeProgram (ST(0))
;

	RETVAL = gnome_program_get_app_version(program);
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Gnome2__Program_locate_file); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_locate_file)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "program, domain, file_name, only_if_exists");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	GnomeProgram *	program = SvGnomeProgram (ST(0))
;
	GnomeFileDomain	domain = SvGnomeFileDomain (ST(1))
;
	const gchar *	file_name;
	gboolean	only_if_exists = (bool)SvTRUE(ST(3))
;
#line 209 "xs/GnomeProgram.xs"
	gchar *path;
	GSList *i, *ret_locations = NULL;
#line 438 "xs/GnomeProgram.c"

	/* same as SvGChar(), but not in a function */
	sv_utf8_upgrade (ST(2));
	file_name = (const gchar *)SvPV_nolen (ST(2))
;
#line 212 "xs/GnomeProgram.xs"
	path = gnome_program_locate_file (program, domain, file_name,
	                                  only_if_exists, &ret_locations);

	if (path) {
		XPUSHs (sv_2mortal (newSVGChar (path)));
		g_free (path);
	}

	for (i = ret_locations; i != NULL; i = i->next) {
		XPUSHs (sv_2mortal (newSVGChar ((gchar *) i->data)));
		g_free (i->data);
	}

	g_slist_free (ret_locations);
#line 459 "xs/GnomeProgram.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_Gnome2__Program_module_register); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_module_register)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "class, module_info");
    {
	SV *	module_info = ST(1)
;
#line 233 "xs/GnomeProgram.xs"
	const GnomeModuleInfo * real_module_info = NULL;
#line 477 "xs/GnomeProgram.c"
#line 235 "xs/GnomeProgram.xs"
	real_module_info = handle_module_info (module_info);
	gnome_program_module_register(real_module_info);
#line 481 "xs/GnomeProgram.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Gnome2__Program_module_registered); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_module_registered)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "class, module_info");
    {
	SV *	module_info = ST(1)
;
#line 244 "xs/GnomeProgram.xs"
	const GnomeModuleInfo * real_module_info = NULL;
#line 498 "xs/GnomeProgram.c"
	gboolean	RETVAL;
#line 246 "xs/GnomeProgram.xs"
	real_module_info = handle_module_info (module_info);
	RETVAL = gnome_program_module_registered (real_module_info);
#line 503 "xs/GnomeProgram.c"
	ST(0) = boolSV(RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Gnome2__Program_module_load); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Gnome2__Program_module_load)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "class, mod_name");
    {
	const char *	mod_name = (const char *)SvPV_nolen(ST(1))
;
	GnomeModuleInfo *	RETVAL;
#line 257 "xs/GnomeProgram.xs"
	/* just to keep the compiler from complaining about const */
	RETVAL = (GnomeModuleInfo*)gnome_program_module_load(mod_name);
#line 523 "xs/GnomeProgram.c"
	ST(0) = newSVGnomeModuleInfo (RETVAL);
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}

#ifdef __cplusplus
extern "C"
#endif
XS_EXTERNAL(boot_Gnome2__Program); /* prototype to pass -Wmissing-prototypes */
XS_EXTERNAL(boot_Gnome2__Program)
{
    dVAR; dXSARGS;
#if (PERL_REVISION == 5 && PERL_VERSION < 9)
    char* file = __FILE__;
#else
    const char* file = __FILE__;
#endif

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
#ifdef XS_APIVERSION_BOOTCHECK
    XS_APIVERSION_BOOTCHECK;
#endif
    XS_VERSION_BOOTCHECK;

        newXS("Gnome2::Program::init", XS_Gnome2__Program_init, file);
        newXS("Gnome2::Program::get_program", XS_Gnome2__Program_get_program, file);
        newXS("Gnome2::Program::get_human_readable_name", XS_Gnome2__Program_get_human_readable_name, file);
        newXS("Gnome2::Program::get_app_id", XS_Gnome2__Program_get_app_id, file);
        newXS("Gnome2::Program::get_app_version", XS_Gnome2__Program_get_app_version, file);
        newXS("Gnome2::Program::locate_file", XS_Gnome2__Program_locate_file, file);
        newXS("Gnome2::Program::module_register", XS_Gnome2__Program_module_register, file);
        newXS("Gnome2::Program::module_registered", XS_Gnome2__Program_module_registered, file);
        newXS("Gnome2::Program::module_load", XS_Gnome2__Program_module_load, file);
#if (PERL_REVISION == 5 && PERL_VERSION >= 9)
  if (PL_unitcheckav)
       call_list(PL_scopestack_ix, PL_unitcheckav);
#endif
    XSRETURN_YES;
}

