Beispiel #1
0
/* Register stylable property of a class */
void xfdashboard_actor_install_stylable_property(XfdashboardActorClass *klass, GParamSpec *inParamSpec)
{
	GParamSpec		*stylableParamSpec;

	g_return_if_fail(XFDASHBOARD_IS_ACTOR_CLASS(klass));
	g_return_if_fail(G_IS_PARAM_SPEC(inParamSpec));
	g_return_if_fail(inParamSpec->flags & G_PARAM_WRITABLE);
	g_return_if_fail(!(inParamSpec->flags & G_PARAM_CONSTRUCT_ONLY));

	/* Check if param-spec is already registered */
	if(g_param_spec_pool_lookup(_xfdashboard_actor_stylable_properties_pool, g_param_spec_get_name(inParamSpec), G_OBJECT_CLASS_TYPE(klass), FALSE))
	{
		g_warning("Class '%s' already contains a stylable property '%s'",
					G_OBJECT_CLASS_NAME(klass),
					g_param_spec_get_name(inParamSpec));
		return;
	}

	/* Add param-spec to pool of themable properties */
	stylableParamSpec=g_param_spec_internal(G_PARAM_SPEC_TYPE(inParamSpec),
												g_param_spec_get_name(inParamSpec),
												NULL,
												NULL,
												0);
	g_param_spec_set_qdata_full(stylableParamSpec,
									XFDASHBOARD_ACTOR_PARAM_SPEC_REF,
									g_param_spec_ref(inParamSpec),
									(GDestroyNotify)g_param_spec_unref);
	g_param_spec_pool_insert(_xfdashboard_actor_stylable_properties_pool, stylableParamSpec, G_OBJECT_CLASS_TYPE(klass));
	XFDASHBOARD_DEBUG(NULL, STYLE,
						"Registered stylable property '%s' for class '%s'",
						g_param_spec_get_name(inParamSpec), G_OBJECT_CLASS_NAME(klass));
}
Beispiel #2
0
void _owr_session_emit_ice_state_changed(OwrSession *session, guint session_id,
    OwrComponentType component_type, OwrIceState state)
{
    OwrIceState old_state, new_state;
    gchar *old_state_name, *new_state_name;
    GParamSpec *pspec;
    gboolean rtcp_mux = FALSE;

    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(session), "rtcp-mux");
    if (pspec && G_PARAM_SPEC_TYPE(pspec) == G_TYPE_BOOLEAN)
        g_object_get(session, "rtcp-mux", &rtcp_mux, NULL);

    if (rtcp_mux) {
        old_state = session->priv->rtp_ice_state;
    } else {
        old_state = owr_session_aggregate_ice_state(session->priv->rtp_ice_state,
            session->priv->rtcp_ice_state);
    }

    if (component_type == OWR_COMPONENT_TYPE_RTP)
        session->priv->rtp_ice_state = state;
    else
        session->priv->rtcp_ice_state = state;

    if (rtcp_mux) {
        new_state = session->priv->rtp_ice_state;
    } else {
        new_state = owr_session_aggregate_ice_state(session->priv->rtp_ice_state,
            session->priv->rtcp_ice_state);
    }

    if (old_state == new_state)
        return;

    old_state_name = owr_ice_state_get_name(old_state);
    new_state_name = owr_ice_state_get_name(new_state);

    if (new_state == OWR_ICE_STATE_FAILED) {
        GST_ERROR_OBJECT(session, "Session %u, ICE failed to establish a connection!\n"
            "ICE state changed from %s to %s",
            session_id, old_state_name, new_state_name);
    } else if (new_state == OWR_ICE_STATE_CONNECTED || new_state == OWR_ICE_STATE_READY) {
        GST_INFO_OBJECT(session, "Session %u, ICE state changed from %s to %s",
            session_id, old_state_name, new_state_name);
    } else {
        GST_DEBUG_OBJECT(session, "Session %u, ICE state changed from %s to %s",
            session_id, old_state_name, new_state_name);
    }
    g_free(old_state_name);
    g_free(new_state_name);

    session->priv->ice_state = new_state;
    g_object_notify_by_pspec(G_OBJECT(session), obj_properties[PROP_ICE_STATE]);
}
Beispiel #3
0
VALUE
rbgobj_get_ruby_object_from_param_spec(GParamSpec* pspec, gboolean alloc)
{
    gpointer data = g_param_spec_get_qdata(pspec, qparamspec);
    if (data)
        return (VALUE)data;
    else if (alloc) {
        VALUE result = pspec_s_allocate(GTYPE2CLASS(G_PARAM_SPEC_TYPE(pspec)));
        rbgobj_param_spec_initialize(result, pspec);
        return result;
    } else
        return Qnil;
}
Beispiel #4
0
void
rbgobj_param_spec_initialize(VALUE self, GParamSpec *pspec)
{
    pspec_holder* holder;
    Data_Get_Struct(self, pspec_holder, holder);

    pspec = g_param_spec_ref(pspec);
    g_param_spec_sink(pspec);

    holder->instance = pspec;
    holder->cinfo    = GTYPE2CINFO(G_PARAM_SPEC_TYPE(pspec));
    g_param_spec_set_qdata(pspec, qparamspec, (gpointer)self);
}
Beispiel #5
0
static gboolean
gst_egueb_demux_install_property (GObjectClass * klass, GObjectClass * from,
    guint id, const gchar *name)
{
  GParamSpec *pspec;
  GParamSpec *npspec;

  pspec = g_object_class_find_property(from, name);
  if (!pspec) return FALSE;

  npspec = g_param_spec_internal (G_PARAM_SPEC_TYPE (pspec), pspec->name,
      g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec), pspec->flags);
  g_object_class_install_property (klass, id, npspec);
  return TRUE;
}
static gboolean
param_param_validate (GParamSpec *pspec,
		      GValue     *value)
{
  /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
  GParamSpec *param = value->data[0].v_pointer;
  guint changed = 0;
  
  if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec)))
    {
      g_param_spec_unref (param);
      value->data[0].v_pointer = NULL;
      changed++;
    }
  
  return changed;
}
Beispiel #7
0
static gboolean
check_write_property (GParamSpec * paramspec, GObject * toCheck)
{
  GType param_type;
  gboolean ret = FALSE;

  param_type = G_PARAM_SPEC_TYPE (paramspec);
  if (param_type == G_TYPE_PARAM_INT) {
    ret = check_write_int_param (paramspec, toCheck);
  } else if (param_type == G_TYPE_PARAM_UINT) {
    ret = check_write_uint_param (paramspec, toCheck);
  } else if (param_type == G_TYPE_PARAM_INT64) {
    ret = check_write_int64_param (paramspec, toCheck);
  } else if (param_type == G_TYPE_PARAM_LONG) {
    ret = check_write_long_param (paramspec, toCheck);
  } else if (param_type == G_TYPE_PARAM_ULONG) {
    ret = check_write_ulong_param (paramspec, toCheck);
  } else {                      // no check performed
    ret = TRUE;
  }
  return ret;
}
Beispiel #8
0
static void
dvb_base_bin_class_init (DvbBaseBinClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstBinClass *bin_class;
  GstElementFactory *dvbsrc_factory;
  GObjectClass *dvbsrc_class;
  typedef struct
  {
    guint prop_id;
    const gchar *prop_name;
  } ProxyedProperty;
  ProxyedProperty *walk;
  ProxyedProperty proxyed_properties[] = {
    {PROP_ADAPTER, "adapter"},
    {PROP_FRONTEND, "frontend"},
    {PROP_DISEQC_SRC, "diseqc-source"},
    {PROP_FREQUENCY, "frequency"},
    {PROP_POLARITY, "polarity"},
    {PROP_SYMBOL_RATE, "symbol-rate"},
    {PROP_BANDWIDTH, "bandwidth"},
    {PROP_CODE_RATE_HP, "code-rate-hp"},
    {PROP_CODE_RATE_LP, "code-rate-lp"},
    {PROP_GUARD, "guard"},
    {PROP_MODULATION, "modulation"},
    {PROP_TRANS_MODE, "trans-mode"},
    {PROP_HIERARCHY, "hierarchy"},
    {PROP_INVERSION, "inversion"},
    {PROP_STATS_REPORTING_INTERVAL, "stats-reporting-interval"},
    {0, NULL}
  };

  bin_class = GST_BIN_CLASS (klass);
  bin_class->handle_message = dvb_base_bin_handle_message;

  element_class = GST_ELEMENT_CLASS (klass);
  element_class->change_state = dvb_base_bin_change_state;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->set_property = dvb_base_bin_set_property;
  gobject_class->get_property = dvb_base_bin_get_property;
  gobject_class->dispose = dvb_base_bin_dispose;
  gobject_class->finalize = dvb_base_bin_finalize;

  /* install dvbsrc properties */
  dvbsrc_factory = gst_element_factory_find ("dvbsrc");
  dvbsrc_class = g_type_class_ref (dvbsrc_factory->type);
  walk = proxyed_properties;
  while (walk->prop_name != NULL) {
    GParamSpec *pspec;
    GParamSpec *our_pspec;

    pspec = g_object_class_find_property (dvbsrc_class, walk->prop_name);
    if (pspec != NULL) {
      GType param_type = G_PARAM_SPEC_TYPE (pspec);

      if (param_type == G_TYPE_PARAM_INT) {
        GParamSpecInt *src_pspec = G_PARAM_SPEC_INT (pspec);

        our_pspec = g_param_spec_int (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
            pspec->flags);
      } else if (param_type == G_TYPE_PARAM_UINT) {
        GParamSpecUInt *src_pspec = G_PARAM_SPEC_UINT (pspec);

        our_pspec = g_param_spec_uint (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
            pspec->flags);
      } else if (param_type == G_TYPE_PARAM_STRING) {
        GParamSpecString *src_pspec = G_PARAM_SPEC_STRING (pspec);

        our_pspec = g_param_spec_string (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->default_value, pspec->flags);
      } else if (param_type == G_TYPE_PARAM_ENUM) {
        GParamSpecEnum *src_pspec = G_PARAM_SPEC_ENUM (pspec);

        our_pspec = g_param_spec_enum (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            pspec->value_type, src_pspec->default_value, pspec->flags);
      } else {
        GST_ERROR ("Unsupported property type %d for property %s",
            param_type, g_param_spec_get_name (pspec));
        ++walk;
        continue;
      }

      g_object_class_install_property (gobject_class, walk->prop_id, our_pspec);
    } else {
      g_warning ("dvbsrc has no property named %s", walk->prop_name);
    }
    ++walk;
  }
  g_type_class_unref (dvbsrc_class);

  g_object_class_install_property (gobject_class, PROP_PROGRAM_NUMBERS,
      g_param_spec_string ("program-numbers",
          "Program Numbers",
          "Colon separated list of programs", "", G_PARAM_READWRITE));
}
Beispiel #9
0
static void
gimp_operation_tool_color_picked (GimpImageMapTool  *im_tool,
                                  gpointer           identifier,
                                  gdouble            x,
                                  gdouble            y,
                                  const Babl        *sample_format,
                                  const GimpRGB     *color)
{
    GimpOperationTool  *tool = GIMP_OPERATION_TOOL (im_tool);
    gchar             **pspecs;

    pspecs = g_strsplit (identifier, ":", 2);

    if (pspecs[1])
    {
        GimpImageMapOptions *options      = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (tool);
        GimpDrawable        *drawable     = GIMP_TOOL (im_tool)->drawable;
        GObjectClass        *object_class = G_OBJECT_GET_CLASS (im_tool->config);
        GParamSpec          *pspec_x;
        GParamSpec          *pspec_y;
        gint                 width        = 1;
        gint                 height       = 1;

        if (drawable)
        {
            gint off_x, off_y;

            gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);

            x -= off_x;
            y -= off_y;

            switch (options->region)
            {
            case GIMP_IMAGE_MAP_REGION_SELECTION:
                if (gimp_item_mask_intersect (GIMP_ITEM (drawable),
                                              &off_x, &off_y, &width, &height))
                {
                    x -= off_x;
                    y -= off_y;
                }
                break;

            case GIMP_IMAGE_MAP_REGION_DRAWABLE:
                width  = gimp_item_get_width  (GIMP_ITEM (drawable));
                height = gimp_item_get_height (GIMP_ITEM (drawable));
                break;
            }
        }

        pspec_x = g_object_class_find_property (object_class, pspecs[0]);
        pspec_y = g_object_class_find_property (object_class, pspecs[1]);

        if (pspec_x && pspec_y &&
                G_PARAM_SPEC_TYPE (pspec_x) == G_PARAM_SPEC_TYPE (pspec_y))
        {
            GValue value_x = G_VALUE_INIT;
            GValue value_y = G_VALUE_INIT;

            g_value_init (&value_x, G_PARAM_SPEC_VALUE_TYPE (pspec_x));
            g_value_init (&value_y, G_PARAM_SPEC_VALUE_TYPE (pspec_y));

#define HAS_KEY(p,k,v) gimp_gegl_param_spec_has_key (p, k, v)

            if (HAS_KEY (pspec_x, "unit", "relative-coordinate") &&
                    HAS_KEY (pspec_y, "unit", "relative-coordinate"))
            {
                x /= (gdouble) width;
                y /= (gdouble) height;
            }

            if (G_IS_PARAM_SPEC_INT (pspec_x))
            {
                g_value_set_int (&value_x, x);
                g_value_set_int (&value_y, y);

                g_param_value_validate (pspec_x, &value_x);
                g_param_value_validate (pspec_y, &value_y);

                g_object_set (im_tool->config,
                              pspecs[0], g_value_get_int (&value_x),
                              pspecs[1], g_value_get_int (&value_y),
                              NULL);
            }
            else if (G_IS_PARAM_SPEC_DOUBLE (pspec_x))
            {
                g_value_set_double (&value_x, x);
                g_value_set_double (&value_y, y);

                g_param_value_validate (pspec_x, &value_x);
                g_param_value_validate (pspec_y, &value_y);

                g_object_set (im_tool->config,
                              pspecs[0], g_value_get_double (&value_x),
                              pspecs[1], g_value_get_double (&value_y),
                              NULL);
            }
            else
            {
                g_warning ("%s: unhandled param spec of type %s",
                           G_STRFUNC, G_PARAM_SPEC_TYPE_NAME (pspec_x));
            }

            g_value_unset (&value_x);
            g_value_unset (&value_y);
        }
    }
    else
    {
        g_object_set (im_tool->config,
                      pspecs[0], color,
                      NULL);
    }

    g_strfreev (pspecs);
}
Beispiel #10
0
/* Pass in the pspec so we can get the generic type. For example, a 
 * value could be held in a GParamSpec allowing OBJECT, but the value 
 * could be of type VipsImage. generics are much faster to compare.
 */
static gboolean 
vips_value_equal( GParamSpec *pspec, GValue *v1, GValue *v2 )
{
	GType generic = G_PARAM_SPEC_TYPE( pspec );
	GType t1 = G_VALUE_TYPE( v1 );
	GType t2 = G_VALUE_TYPE( v2 );

	if( t1 != t2 )
		return( FALSE );

	/* Not compile-time constants, so we have to use a set of if()s. Could
	 * make a table at run time I guess.
	 */

	if( generic == G_TYPE_PARAM_BOOLEAN ) 
		return( g_value_get_boolean( v1 ) == 
			g_value_get_boolean( v2 ) );
	else if( generic == G_TYPE_PARAM_CHAR ) 
		return( VIPS_VALUE_GET_CHAR( v1 ) ==
			VIPS_VALUE_GET_CHAR( v2 ) );
	if( generic == G_TYPE_PARAM_UCHAR ) 
		return( g_value_get_uchar( v1 ) ==
			g_value_get_uchar( v2 ) );
	if( generic == G_TYPE_PARAM_INT ) 
		return( g_value_get_int( v1 ) ==
			g_value_get_int( v2 ) );
	if( generic == G_TYPE_PARAM_UINT ) 
		return( g_value_get_uint( v1 ) ==
			g_value_get_uint( v2 ) );
	if( generic == G_TYPE_PARAM_LONG ) 
		return( g_value_get_long( v1 ) ==
			g_value_get_long( v2 ) );
	if( generic == G_TYPE_PARAM_ULONG ) 
		return( g_value_get_ulong( v1 ) ==
			g_value_get_ulong( v2 ) );
	if( generic == G_TYPE_PARAM_ENUM ) 
		return( g_value_get_enum( v1 ) ==
			g_value_get_enum( v2 ) );
	if( generic == G_TYPE_PARAM_FLAGS ) 
		return( g_value_get_flags( v1 ) ==
			g_value_get_flags( v2 ) );
	if( generic == G_TYPE_PARAM_UINT64 ) 
		return( g_value_get_uint64( v1 ) ==
			g_value_get_uint64( v2 ) );
	if( generic == G_TYPE_PARAM_INT64 ) 
		return( g_value_get_int64( v1 ) ==
			g_value_get_int64( v2 ) );
	if( generic == G_TYPE_PARAM_FLOAT ) 
		return( g_value_get_float( v1 ) ==
			g_value_get_float( v2 ) );
	if( generic == G_TYPE_PARAM_DOUBLE ) 
		return( g_value_get_double( v1 ) ==
			g_value_get_double( v2 ) );
	if( generic == G_TYPE_PARAM_STRING ) {
		const char *s1 = g_value_get_string( v1 );
		const char *s2 = g_value_get_string( v2 );

		if( s1 == s2 )
			return( TRUE );
		else
			return( s1 && s2 && strcmp( s1, s2 ) == 0 );
	}
	if( generic == G_TYPE_PARAM_BOXED ) 
		return( g_value_get_boxed( v1 ) ==
			g_value_get_boxed( v2 ) );
	if( generic == G_TYPE_PARAM_POINTER ) 
		return( g_value_get_pointer( v1 ) ==
			g_value_get_pointer( v2 ) );
	if( generic == G_TYPE_PARAM_OBJECT ) 
		return( g_value_get_object( v1 ) ==
			g_value_get_object( v2 ) );
	else {
		/* Fallback: convert to a string and compare that. 
		 * This is very slow, print a warning if we use it 
		 * so we can add another case.
		 */
		char *s1;
		char *s2;
		gboolean equal;

		s1 = g_strdup_value_contents( v1 ); 
		s2 = g_strdup_value_contents( v2 ); 
		equal = strcmp( s1, s2 ) == 0;

		printf( "vips_value_equal: no case for %s, %s\n", 
			s1, s2 );
		printf( "\tt1 %d, %s\n", (int) t1, g_type_name( t1 ) );
		printf( "\tt2 %d, %s\n", (int) t2, g_type_name( t2 ) );
		printf( "\tgeneric %d, %s\n", 
			(int) G_VALUE_TYPE( generic ),
			g_type_name( generic ) );

		g_free( s1 );
		g_free( s2 );

		return( equal );
	}
}
Beispiel #11
0
/* Pass in the pspec so we can get the generic type. For example, a 
 * held in a GParamSpec allowing OBJECT, but the value could be of type
 * VipsImage. generics are much faster to compare.
 */
static unsigned int
vips_value_hash( GParamSpec *pspec, GValue *value )
{
	GType generic = G_PARAM_SPEC_TYPE( pspec );

	/* Not compile-time constants, so we have to use a set of if()s. Could
	 * make a table at run time I guess.
	 */

	if( generic == G_TYPE_PARAM_BOOLEAN )
		return( (unsigned int) g_value_get_boolean( value ) );
	else if( generic == G_TYPE_PARAM_CHAR )
		return( (unsigned int) VIPS_VALUE_GET_CHAR( value ) );
	else if( generic == G_TYPE_PARAM_UCHAR )
		return( (unsigned int) g_value_get_uchar( value ) );
	else if( generic == G_TYPE_PARAM_INT )
		return( (unsigned int) g_value_get_int( value ) );
	else if( generic == G_TYPE_PARAM_UINT )
		return( (unsigned int) g_value_get_uint( value ) );
	else if( generic == G_TYPE_PARAM_LONG )
		return( (unsigned int) g_value_get_long( value ) );
	else if( generic == G_TYPE_PARAM_ULONG )
		return( (unsigned int) g_value_get_ulong( value ) );
	else if( generic == G_TYPE_PARAM_ENUM )
		return( (unsigned int) g_value_get_enum( value ) );
	else if( generic == G_TYPE_PARAM_FLAGS )
		return( (unsigned int) g_value_get_flags( value ) );
	else if( generic == G_TYPE_PARAM_UINT64 ) {
		guint64 i = g_value_get_uint64( value );

		return( INT64_HASH( (gint64 *) &i ) );
	}
	else if( generic == G_TYPE_PARAM_INT64 ) {
		gint64 i = g_value_get_int64( value );

		return( INT64_HASH( &i ) );
	}
	else if( generic == G_TYPE_PARAM_FLOAT ) {
		float f = g_value_get_float( value );

		return( g_direct_hash( (void *) &f ) );
	}
	else if( generic == G_TYPE_PARAM_DOUBLE ) {
		double d = g_value_get_double( value );

		return( DOUBLE_HASH( &d ) );
	}
	else if( generic == G_TYPE_PARAM_STRING ) {
		const char *s = g_value_get_string( value );

		return( s ? g_str_hash( s ) : 0 );
	}
	else if( generic == G_TYPE_PARAM_BOXED ) {
		void *p = g_value_get_boxed( value );

		return( p ? g_direct_hash( p ) : 0 );
	}
	else if( generic == G_TYPE_PARAM_POINTER ) {
		void *p = g_value_get_pointer( value );

		return( p ? g_direct_hash( p ) : 0 );
	}
	else if( generic == G_TYPE_PARAM_OBJECT ) {
		void *p = g_value_get_object( value );

		return( p ? g_direct_hash( p ) : 0 );
	}
	else {
		/* Fallback: convert to a string and hash that. 
		 * This is very slow, print a warning if we use it 
		 * so we can add another case.
		 */
		char *s;
		unsigned int hash;

		s = g_strdup_value_contents( value ); 
		hash = g_str_hash( s );

		printf( "vips_value_hash: no case for %s\n", s );
		printf( "\ttype %d, %s\n", 
			(int) G_VALUE_TYPE( value ),
			g_type_name( G_VALUE_TYPE( value ) ) );
		printf( "\tgeneric %d, %s\n", 
			(int) G_VALUE_TYPE( generic ),
			g_type_name( generic ) );

		g_free( s );

		return( hash );
	}
}
Beispiel #12
0
static void
dvb_base_bin_class_init (DvbBaseBinClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstBinClass *bin_class;
  DvbBaseBinClass *dvbbasebin_class;
  GstElementFactory *dvbsrc_factory;
  GObjectClass *dvbsrc_class;
  typedef struct
  {
    guint prop_id;
    const gchar *prop_name;
  } ProxyedProperty;
  ProxyedProperty *walk;
  ProxyedProperty proxyed_properties[] = {
    {PROP_ADAPTER, "adapter"},
    {PROP_FRONTEND, "frontend"},
    {PROP_DISEQC_SRC, "diseqc-source"},
    {PROP_FREQUENCY, "frequency"},
    {PROP_POLARITY, "polarity"},
    {PROP_SYMBOL_RATE, "symbol-rate"},
#ifndef GST_REMOVE_DEPRECATED
    {PROP_BANDWIDTH, "bandwidth"},
#endif
    {PROP_CODE_RATE_HP, "code-rate-hp"},
    {PROP_CODE_RATE_LP, "code-rate-lp"},
    {PROP_GUARD, "guard"},
    {PROP_MODULATION, "modulation"},
    {PROP_TRANS_MODE, "trans-mode"},
    {PROP_HIERARCHY, "hierarchy"},
    {PROP_INVERSION, "inversion"},
    {PROP_STATS_REPORTING_INTERVAL, "stats-reporting-interval"},
    {PROP_TUNING_TIMEOUT, "tuning-timeout"},
    {PROP_DELSYS, "delsys"},
    {PROP_PILOT, "pilot"},
    {PROP_ROLLOFF, "rolloff"},
    {PROP_STREAM_ID, "stream-id"},
    {PROP_BANDWIDTH_HZ, "bandwidth-hz"},
    {PROP_ISDBT_LAYER_ENABLED, "isdbt-layer-enabled"},
    {PROP_ISDBT_PARTIAL_RECEPTION, "isdbt-partial-reception"},
    {PROP_ISDBT_SOUND_BROADCASTING, "isdbt-sound-broadcasting"},
    {PROP_ISDBT_SB_SUBCHANNEL_ID, "isdbt-sb-subchannel-id"},
    {PROP_ISDBT_SB_SEGMENT_IDX, "isdbt-sb-segment-idx"},
    {PROP_ISDBT_SB_SEGMENT_COUNT, "isdbt-sb-segment-count"},
    {PROP_ISDBT_LAYERA_FEC, "isdbt-layera-fec"},
    {PROP_ISDBT_LAYERA_MODULATION, "isdbt-layera-modulation"},
    {PROP_ISDBT_LAYERA_SEGMENT_COUNT, "isdbt-layera-segment-count"},
    {PROP_ISDBT_LAYERA_TIME_INTERLEAVING, "isdbt-layera-time-interleaving"},
    {PROP_ISDBT_LAYERB_FEC, "isdbt-layerb-fec"},
    {PROP_ISDBT_LAYERB_MODULATION, "isdbt-layerb-modulation"},
    {PROP_ISDBT_LAYERB_SEGMENT_COUNT, "isdbt-layerb-segment-count"},
    {PROP_ISDBT_LAYERB_TIME_INTERLEAVING, "isdbt-layerb-time-interleaving"},
    {PROP_ISDBT_LAYERC_FEC, "isdbt-layerc-fec"},
    {PROP_ISDBT_LAYERC_MODULATION, "isdbt-layerc-modulation"},
    {PROP_ISDBT_LAYERC_SEGMENT_COUNT, "isdbt-layerc-segment-count"},
    {PROP_ISDBT_LAYERC_TIME_INTERLEAVING, "isdbt-layerc-time-interleaving"},
    {PROP_LNB_SLOF, "lnb-slof"},
    {PROP_LNB_LOF1, "lnb-lof1"},
    {PROP_LNB_LOF2, "lnb-lof2"},
    {PROP_INTERLEAVING, "interleaving"},
    {0, NULL}
  };

  bin_class = GST_BIN_CLASS (klass);
  bin_class->handle_message = dvb_base_bin_handle_message;

  element_class = GST_ELEMENT_CLASS (klass);

  element_class->change_state = dvb_base_bin_change_state;
  element_class->request_new_pad = dvb_base_bin_request_new_pad;
  element_class->release_pad = dvb_base_bin_release_pad;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&program_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_template));

  gst_element_class_set_static_metadata (element_class, "DVB bin",
      "Source/Bin/Video",
      "Access descramble and split DVB streams",
      "Alessandro Decina <*****@*****.**>\n"
      "Reynaldo H. Verdejo Pinochet <*****@*****.**>");

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->set_property = dvb_base_bin_set_property;
  gobject_class->get_property = dvb_base_bin_get_property;
  gobject_class->dispose = dvb_base_bin_dispose;
  gobject_class->finalize = dvb_base_bin_finalize;

  dvbbasebin_class = (DvbBaseBinClass *) klass;
  dvbbasebin_class->do_tune = dvb_base_bin_do_tune;

  /* install dvbsrc properties */
  dvbsrc_factory = gst_element_factory_find ("dvbsrc");
  dvbsrc_class =
      g_type_class_ref (gst_element_factory_get_element_type (dvbsrc_factory));
  walk = proxyed_properties;
  while (walk->prop_name != NULL) {
    GParamSpec *pspec;
    GParamSpec *our_pspec;

    pspec = g_object_class_find_property (dvbsrc_class, walk->prop_name);
    if (pspec != NULL) {
      GType param_type = G_PARAM_SPEC_TYPE (pspec);

      if (param_type == G_TYPE_PARAM_INT) {
        GParamSpecInt *src_pspec = G_PARAM_SPEC_INT (pspec);

        our_pspec = g_param_spec_int (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
            pspec->flags);
      } else if (param_type == G_TYPE_PARAM_UINT) {
        GParamSpecUInt *src_pspec = G_PARAM_SPEC_UINT (pspec);

        our_pspec = g_param_spec_uint (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
            pspec->flags);
      } else if (param_type == G_TYPE_PARAM_UINT64) {
        GParamSpecUInt64 *src_pspec = G_PARAM_SPEC_UINT64 (pspec);

        our_pspec = g_param_spec_uint64 (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
            pspec->flags);
      } else if (param_type == G_TYPE_PARAM_STRING) {
        GParamSpecString *src_pspec = G_PARAM_SPEC_STRING (pspec);

        our_pspec = g_param_spec_string (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->default_value, pspec->flags);
      } else if (param_type == G_TYPE_PARAM_ENUM) {
        GParamSpecEnum *src_pspec = G_PARAM_SPEC_ENUM (pspec);

        our_pspec = g_param_spec_enum (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            pspec->value_type, src_pspec->default_value, pspec->flags);
      } else {
        GST_ERROR ("Unsupported property type %s for property %s",
            g_type_name (param_type), g_param_spec_get_name (pspec));
        ++walk;
        continue;
      }

      g_object_class_install_property (gobject_class, walk->prop_id, our_pspec);
    } else {
      g_warning ("dvbsrc has no property named %s", walk->prop_name);
    }
    ++walk;
  }
  g_type_class_unref (dvbsrc_class);

  g_object_class_install_property (gobject_class, PROP_PROGRAM_NUMBERS,
      g_param_spec_string ("program-numbers",
          "Program Numbers",
          "Colon separated list of programs", "", G_PARAM_READWRITE));
  /**
   * DvbBaseBin::tuning-start:
   * @dvbbasebin: the element on which the signal is emitted
   *
   * Signal emited when the element first attempts to tune the
   * frontend tunner to a given frequency.
   */
  dvb_base_bin_signals[SIGNAL_TUNING_START] =
      g_signal_new ("tuning-start", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
  /**
   * DvbBaseBin::tuning-done:
   * @dvbbasebin: the element on which the signal is emitted
   *
   * Signal emited when the tunner has successfully got a lock on a signal.
   */
  dvb_base_bin_signals[SIGNAL_TUNING_DONE] =
      g_signal_new ("tuning-done", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
  /**
   * DvbBaseBin::tuning-fail:
   * @dvbbasebin: the element on which the signal is emitted
   *
   * Signal emited when the tunner failed to get a lock on the
   * signal.
   */
  dvb_base_bin_signals[SIGNAL_TUNING_FAIL] =
      g_signal_new ("tuning-fail", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);

  /**
   * DvbBaseBin::tune:
   * @dvbbasesink: the element on which the signal is emitted
   *
   * Signal emited from the application to the element, instructing it
   * to tune.
   */
  dvb_base_bin_signals[SIGNAL_TUNE] =
      g_signal_new ("tune", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (DvbBaseBinClass, do_tune),
      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
Beispiel #13
0
static GtkWidget *
property_editor (GObject                *object,
                 GParamSpec             *spec,
                 GtkInspectorPropEditor *editor)
{
  GtkWidget *prop_edit;
  GtkAdjustment *adj;
  gchar *msg;
  GType type = G_PARAM_SPEC_TYPE (spec);

  if (type == G_TYPE_PARAM_INT)
    {
      adj = gtk_adjustment_new (G_PARAM_SPEC_INT (spec)->default_value,
                                G_PARAM_SPEC_INT (spec)->minimum,
                                G_PARAM_SPEC_INT (spec)->maximum,
                                1,
                                MAX ((G_PARAM_SPEC_INT (spec)->maximum - G_PARAM_SPEC_INT (spec)->minimum) / 10, 1),
                                0.0);

      prop_edit = gtk_spin_button_new (adj, 1.0, 0);

      g_object_connect_property (object, spec, G_CALLBACK (int_changed), adj, G_OBJECT (adj)); 

      connect_controller (G_OBJECT (adj), "value_changed",
                          object, spec, G_CALLBACK (int_modified));
    }
  else if (type == G_TYPE_PARAM_UINT)
    {
      adj = gtk_adjustment_new (G_PARAM_SPEC_UINT (spec)->default_value,
                                G_PARAM_SPEC_UINT (spec)->minimum,
                                G_PARAM_SPEC_UINT (spec)->maximum,
                                1,
                                MAX ((G_PARAM_SPEC_UINT (spec)->maximum - G_PARAM_SPEC_UINT (spec)->minimum) / 10, 1),
                                0.0);

      prop_edit = gtk_spin_button_new (adj, 1.0, 0);

      g_object_connect_property (object, spec,
                                 G_CALLBACK (uint_changed),
                                 adj, G_OBJECT (adj));

      connect_controller (G_OBJECT (adj), "value_changed",
                          object, spec, G_CALLBACK (uint_modified));
    }
  else if (type == G_TYPE_PARAM_FLOAT)
    {
      adj = gtk_adjustment_new (G_PARAM_SPEC_FLOAT (spec)->default_value,
                                G_PARAM_SPEC_FLOAT (spec)->minimum,
                                G_PARAM_SPEC_FLOAT (spec)->maximum,
                                0.1,
                                MAX ((G_PARAM_SPEC_FLOAT (spec)->maximum - G_PARAM_SPEC_FLOAT (spec)->minimum) / 10, 0.1),
                                0.0);

      prop_edit = gtk_spin_button_new (adj, 0.1, 2);

      g_object_connect_property (object, spec,
                                 G_CALLBACK (float_changed),
                                 adj, G_OBJECT (adj));

      connect_controller (G_OBJECT (adj), "value_changed",
                          object, spec, G_CALLBACK (float_modified));
    }
  else if (type == G_TYPE_PARAM_DOUBLE)
    {
      adj = gtk_adjustment_new (G_PARAM_SPEC_DOUBLE (spec)->default_value,
                                G_PARAM_SPEC_DOUBLE (spec)->minimum,
                                G_PARAM_SPEC_DOUBLE (spec)->maximum,
                                0.1,
                                MAX ((G_PARAM_SPEC_DOUBLE (spec)->maximum - G_PARAM_SPEC_DOUBLE (spec)->minimum) / 10, 0.1),
                                0.0);

      prop_edit = gtk_spin_button_new (adj, 0.1, 2);

      g_object_connect_property (object, spec,
                                 G_CALLBACK (double_changed),
                                 adj, G_OBJECT (adj));

      connect_controller (G_OBJECT (adj), "value_changed",
                          object, spec, G_CALLBACK (double_modified));
    }
  else if (type == G_TYPE_PARAM_STRING)
    {
      prop_edit = gtk_entry_new ();

      g_object_connect_property (object, spec,
                                 G_CALLBACK (string_changed),
                                 prop_edit, G_OBJECT (prop_edit));

      connect_controller (G_OBJECT (prop_edit), "changed",
                          object, spec, G_CALLBACK (string_modified));
    }
  else if (type == G_TYPE_PARAM_BOOLEAN)
    {
      prop_edit = gtk_toggle_button_new_with_label ("");

      g_object_connect_property (object, spec,
                                 G_CALLBACK (bool_changed),
                                 prop_edit, G_OBJECT (prop_edit));

      connect_controller (G_OBJECT (prop_edit), "toggled",
                          object, spec, G_CALLBACK (bool_modified));
    }
  else if (type == G_TYPE_PARAM_ENUM)
    {
      {
        GtkWidget *box;
        GEnumClass *eclass;
        GtkWidget *first;
        gint j;

        prop_edit = gtk_scrolled_window_new (NULL, NULL);
        g_object_set (prop_edit,
                      "expand", TRUE,
                      "hscrollbar-policy", GTK_POLICY_NEVER,
                      "vscrollbar-policy", GTK_POLICY_NEVER,
                      NULL);
        box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
        gtk_widget_show (box);
        gtk_container_add (GTK_CONTAINER (prop_edit), box);

        eclass = G_ENUM_CLASS (g_type_class_ref (spec->value_type));

        j = 0;
        first = NULL;
        while (j < eclass->n_values)
          {
            GtkWidget *b;

            b = gtk_radio_button_new_with_label_from_widget ((GtkRadioButton*)first, eclass->values[j].value_name);
            if (first == NULL)
              first = b;
            g_object_set_data (G_OBJECT (b), "index", GINT_TO_POINTER (j));
            gtk_widget_show (b);
            gtk_box_pack_start (GTK_BOX (box), b, FALSE, FALSE, 0);
            connect_controller (G_OBJECT (b), "toggled",
                                object, spec, G_CALLBACK (enum_modified));
            ++j;
          }

        if (j >= 10)
          g_object_set (prop_edit, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL);

        g_type_class_unref (eclass);

        g_object_connect_property (object, spec,
                                   G_CALLBACK (enum_changed),
                                   prop_edit, G_OBJECT (prop_edit));
      }
    }
  else if (type == G_TYPE_PARAM_FLAGS)
    {
      {
        GtkWidget *box;
        GFlagsClass *fclass;
        gint j;

        prop_edit = gtk_scrolled_window_new (NULL, NULL);
        g_object_set (prop_edit,
                      "expand", TRUE,
                      "hscrollbar-policy", GTK_POLICY_NEVER,
                      "vscrollbar-policy", GTK_POLICY_NEVER,
                      NULL);
        box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
        gtk_widget_show (box);
        gtk_container_add (GTK_CONTAINER (prop_edit), box);

        fclass = G_FLAGS_CLASS (g_type_class_ref (spec->value_type));

        for (j = 0; j < fclass->n_values; j++)
          {
            GtkWidget *b;

            b = gtk_check_button_new_with_label (fclass->values[j].value_name);
            g_object_set_data (G_OBJECT (b), "index", GINT_TO_POINTER (j));
            gtk_widget_show (b);
            gtk_box_pack_start (GTK_BOX (box), b, FALSE, FALSE, 0);
            connect_controller (G_OBJECT (b), "toggled",
                                object, spec, G_CALLBACK (flags_modified));
          }

        if (j >= 10)
          g_object_set (prop_edit, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL);

        g_type_class_unref (fclass);

        g_object_connect_property (object, spec,
                                   G_CALLBACK (flags_changed),
                                   prop_edit, G_OBJECT (prop_edit));
      }
    }
  else if (type == G_TYPE_PARAM_UNICHAR)
    {
      prop_edit = gtk_entry_new ();
      gtk_entry_set_max_length (GTK_ENTRY (prop_edit), 1);

      g_object_connect_property (object, spec,
                                 G_CALLBACK (unichar_changed),
                                 prop_edit, G_OBJECT (prop_edit));

      connect_controller (G_OBJECT (prop_edit), "changed",
                          object, spec, G_CALLBACK (unichar_modified));
    }
  else if (type == G_TYPE_PARAM_POINTER)
    {
      prop_edit = gtk_label_new ("");

      g_object_connect_property (object, spec,
                                 G_CALLBACK (pointer_changed),
                                 prop_edit, G_OBJECT (prop_edit));
    }
  else if (type == G_TYPE_PARAM_OBJECT)
    {
      GtkWidget *label, *button;

      prop_edit = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);

      label = gtk_label_new ("");
      button = gtk_button_new_with_label (_("Properties"));
      g_signal_connect_swapped (button, "clicked",
                                G_CALLBACK (object_properties),
                                editor);
      gtk_container_add (GTK_CONTAINER (prop_edit), label);
      gtk_container_add (GTK_CONTAINER (prop_edit), button);
      gtk_widget_show (label);
      gtk_widget_show (button);

      g_object_connect_property (object, spec,
                                 G_CALLBACK (object_changed),
                                 prop_edit, G_OBJECT (label));
    }
  else if (type == G_TYPE_PARAM_BOXED &&
           G_PARAM_SPEC_VALUE_TYPE (spec) == GDK_TYPE_RGBA)
    {
      prop_edit = gtk_color_chooser_widget_new ();
      gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop_edit), TRUE);

      g_object_connect_property (object, spec,
                                 G_CALLBACK (rgba_changed),
                                 prop_edit, G_OBJECT (prop_edit));

      connect_controller (G_OBJECT (prop_edit), "notify::rgba",
                          object, spec, G_CALLBACK (rgba_modified));
    }
  else if (type == G_TYPE_PARAM_BOXED &&
           G_PARAM_SPEC_VALUE_TYPE (spec) == g_type_from_name ("GdkColor"))
    {
      prop_edit = gtk_color_chooser_widget_new ();
      gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop_edit), FALSE);

      g_object_connect_property (object, spec,
                                 G_CALLBACK (color_changed),
                                 prop_edit, G_OBJECT (prop_edit));

      connect_controller (G_OBJECT (prop_edit), "notify::rgba",
                          object, spec, G_CALLBACK (color_modified));
    }
  else if (type == G_TYPE_PARAM_BOXED &&
           G_PARAM_SPEC_VALUE_TYPE (spec) == PANGO_TYPE_FONT_DESCRIPTION)
    {
      prop_edit = gtk_font_chooser_widget_new ();

      g_object_connect_property (object, spec,
                                 G_CALLBACK (font_changed),
                                 prop_edit, G_OBJECT (prop_edit));

      connect_controller (G_OBJECT (prop_edit), "notify::font-desc",
                          object, spec, G_CALLBACK (font_modified));
    }
  else
    {
      msg = g_strdup_printf (_("Uneditable property type: %s"),
                             g_type_name (G_PARAM_SPEC_TYPE (spec)));
      prop_edit = gtk_label_new (msg);
      g_free (msg);
      gtk_widget_set_halign (prop_edit, GTK_ALIGN_START);
      gtk_widget_set_valign (prop_edit, GTK_ALIGN_CENTER);
    }

  if (g_param_spec_get_blurb (spec))
    gtk_widget_set_tooltip_text (prop_edit, g_param_spec_get_blurb (spec));

  notify_property (object, spec);

  return prop_edit;
}
Beispiel #14
0
static void
gimp_operation_tool_color_picked (GimpFilterTool  *filter_tool,
                                  gpointer         identifier,
                                  gdouble          x,
                                  gdouble          y,
                                  const Babl      *sample_format,
                                  const GimpRGB   *color)
{
  gchar **pspecs = g_strsplit (identifier, ":", 2);

  if (pspecs[1])
    {
      GObjectClass  *object_class = G_OBJECT_GET_CLASS (filter_tool->config);
      GParamSpec    *pspec_x;
      GParamSpec    *pspec_y;
      gint           off_x, off_y;
      GeglRectangle  area;

      gimp_filter_tool_get_drawable_area (filter_tool, &off_x, &off_y, &area);

      x -= off_x + area.x;
      y -= off_y + area.y;

      pspec_x = g_object_class_find_property (object_class, pspecs[0]);
      pspec_y = g_object_class_find_property (object_class, pspecs[1]);

      if (pspec_x && pspec_y &&
          G_PARAM_SPEC_TYPE (pspec_x) == G_PARAM_SPEC_TYPE (pspec_y))
        {
          GValue value_x = G_VALUE_INIT;
          GValue value_y = G_VALUE_INIT;

          g_value_init (&value_x, G_PARAM_SPEC_VALUE_TYPE (pspec_x));
          g_value_init (&value_y, G_PARAM_SPEC_VALUE_TYPE (pspec_y));

#define HAS_KEY(p,k,v) gimp_gegl_param_spec_has_key (p, k, v)

          if (HAS_KEY (pspec_x, "unit", "relative-coordinate") &&
              HAS_KEY (pspec_y, "unit", "relative-coordinate"))
            {
              x /= (gdouble) area.width;
              y /= (gdouble) area.height;
            }

          if (G_IS_PARAM_SPEC_INT (pspec_x))
            {
              g_value_set_int (&value_x, x);
              g_value_set_int (&value_y, y);

              g_param_value_validate (pspec_x, &value_x);
              g_param_value_validate (pspec_y, &value_y);

              g_object_set (filter_tool->config,
                            pspecs[0], g_value_get_int (&value_x),
                            pspecs[1], g_value_get_int (&value_y),
                            NULL);
            }
          else if (G_IS_PARAM_SPEC_DOUBLE (pspec_x))
            {
              g_value_set_double (&value_x, x);
              g_value_set_double (&value_y, y);

              g_param_value_validate (pspec_x, &value_x);
              g_param_value_validate (pspec_y, &value_y);

              g_object_set (filter_tool->config,
                            pspecs[0], g_value_get_double (&value_x),
                            pspecs[1], g_value_get_double (&value_y),
                            NULL);
            }
          else
            {
              g_warning ("%s: unhandled param spec of type %s",
                         G_STRFUNC, G_PARAM_SPEC_TYPE_NAME (pspec_x));
            }

          g_value_unset (&value_x);
          g_value_unset (&value_y);
        }
    }
  else
    {
      g_object_set (filter_tool->config,
                    pspecs[0], color,
                    NULL);
    }

  g_strfreev (pspecs);
}
Beispiel #15
0
void
fs_utils_set_bitrate (GstElement *element, glong bitrate)
{
  GParamSpec *spec;
  const char *elements_in_kbps[] = { "lamemp3enc", "lame", "x264enc", "twolame",
    "mpeg2enc", NULL
  };
  int i;
  GstElementFactory *factory;
  const gchar *factory_name = NULL;

  g_return_if_fail (GST_IS_ELEMENT (element));

  spec = g_object_class_find_property (G_OBJECT_GET_CLASS (element), "bitrate");
  g_return_if_fail (spec != NULL);

  factory = gst_element_get_factory (element);
  if (factory)
    factory_name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));

  /* divide by 1000 for elements that are known to use kbs */
  for (i = 0; elements_in_kbps[i]; i++)
    if (factory_name && !strcmp (factory_name, elements_in_kbps[i]))
    {
      bitrate /= 1000;
      break;
    }

  if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_LONG)
  {
    g_object_set (element, "bitrate", (glong) CLAMP (bitrate,
            G_PARAM_SPEC_LONG (spec)->minimum,
            G_PARAM_SPEC_LONG (spec)->maximum), NULL);
  }
  else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_ULONG)
  {
    g_object_set (element, "bitrate", (gulong) CLAMP (bitrate,
            G_PARAM_SPEC_ULONG (spec)->minimum,
            G_PARAM_SPEC_ULONG (spec)->maximum), NULL);
  }
  else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_INT)
  {
    gint tmp = MIN (bitrate, G_MAXINT);

    g_object_set (element, "bitrate", (gint)  CLAMP (tmp,
            G_PARAM_SPEC_INT (spec)->minimum,
            G_PARAM_SPEC_INT (spec)->maximum), NULL);
  }
  else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_UINT)
  {
    guint tmp = MIN (bitrate, G_MAXUINT);

    g_object_set (element, "bitrate", (guint) CLAMP (tmp,
            G_PARAM_SPEC_UINT (spec)->minimum,
            G_PARAM_SPEC_UINT (spec)->maximum), NULL);
  }
  else
  {
    g_warning ("bitrate parameter of unknown type");
  }
}
static void
impl_constructed (GObject *object)
{
    RBObjectPropertyEditor *editor;
    GObjectClass *klass;
    int i;
    int row;

    RB_CHAIN_GOBJECT_METHOD (rb_object_property_editor_parent_class, constructed, object);

    editor = RB_OBJECT_PROPERTY_EDITOR (object);
    klass = G_OBJECT_GET_CLASS (editor->priv->object);

    editor->priv->notify_id = g_signal_connect (editor->priv->object, "notify", G_CALLBACK (notify_cb), editor);

    row = 0;
    for (i = 0; editor->priv->properties[i] != NULL; i++) {
        GParamSpec *pspec;
        GtkWidget *label;
        GtkWidget *control;
        GType prop_type;

        pspec = g_object_class_find_property (klass, editor->priv->properties[i]);
        if (pspec == NULL) {
            g_warning ("couldn't find property %s on object %s",
                       editor->priv->properties[i],
                       G_OBJECT_CLASS_NAME (klass));
            continue;
        }

        prop_type = G_PARAM_SPEC_TYPE (pspec);
        if (prop_type == G_TYPE_PARAM_BOOLEAN) {
            control = create_boolean_editor (editor, editor->priv->properties[i], pspec);
        } else if (prop_type == G_TYPE_PARAM_ENUM) {
            control = create_enum_editor (editor, editor->priv->properties[i], pspec);
        } else if (prop_type == G_TYPE_PARAM_INT) {
            control = create_int_editor (editor, editor->priv->properties[i], pspec);
        } else if (prop_type == G_TYPE_PARAM_FLOAT) {
            control = create_float_editor (editor, editor->priv->properties[i], pspec);
        } else if (prop_type == G_TYPE_PARAM_DOUBLE) {
            control = create_double_editor (editor, editor->priv->properties[i], pspec);
        } else {
            /* can't do this */
            g_warning ("don't know how to edit %s", g_type_name (prop_type));
            continue;
        }
        g_signal_connect (control, "focus-out-event", G_CALLBACK (focus_out_cb), editor);
        gtk_widget_set_hexpand (control, TRUE);

        label = gtk_label_new (g_param_spec_get_nick (pspec));
        gtk_widget_set_tooltip_text (label, g_param_spec_get_blurb (pspec));

        gtk_grid_attach (GTK_GRID (editor),
                         label,
                         0, row, 1, 1);
        gtk_grid_attach (GTK_GRID (editor),
                         control,
                         1, row, 1, 1);

        row++;
    }
}