Esempio n. 1
0
/*#
    @method new_from_pixmap GdkCursor
    @brief Creates a new cursor from a given pixmap and mask.
    @param source the pixmap specifying the cursor (GdkPixmap).
    @param mask the pixmap specifying the mask, which must be the same size as source (GdkPixmap).
    @param fg the foreground color, used for the bits in the source which are 1 (GdkColor).
    @param bg the background color, used for the bits in the source which are 0 (GdkColor).
    @param x the horizontal offset of the 'hotspot' of the cursor.
    @param y the vertical offset of the 'hotspot' of the cursor.
    @return a new GdkCursor.

    Both the pixmap and mask must have a depth of 1 (i.e. each pixel has only 2
    values - on or off). The standard cursor size is 16 by 16 pixels. You can
    create a bitmap from inline data as in the below example.

    [...]
 */
FALCON_FUNC Cursor::new_from_pixmap( VMARG )
{
    Item* i_src = vm->param( 0 );
    Item* i_mask = vm->param( 1 );
    Item* i_fg = vm->param( 2 );
    Item* i_bg = vm->param( 3 );
    Item* i_x = vm->param( 4 );
    Item* i_y = vm->param( 5 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_src || !i_src->isObject() || !IS_DERIVED( i_src, GdkPixmap )
        || !i_mask || !i_mask->isObject() || !IS_DERIVED( i_mask, GdkPixmap )
        || !i_fg || !i_fg->isObject() || !IS_DERIVED( i_fg, GdkColor )
        || !i_bg || !i_bg->isObject() || !IS_DERIVED( i_bg, GdkColor )
        || !i_x || !i_x->isInteger()
        || !i_y || !i_y->isInteger() )
        throw_inv_params( "GdkPixmap,GdkPixmap,GdkColor,GdkColor,I,I" );
#endif
    vm->retval( new Gdk::Cursor( vm->findWKI( "GdkCursor" )->asClass(),
        gdk_cursor_new_from_pixmap( GET_PIXMAP( *i_src ),
                                    GET_PIXMAP( *i_mask ),
                                    GET_COLOR( *i_fg ),
                                    GET_COLOR( *i_bg ),
                                    i_x->asInteger(),
                                    i_y->asInteger() ) ) );
}
Esempio n. 2
0
/*#
    @method filter GtkFileFilter
    @brief Tests whether a file should be displayed according to filter.
    @param filter_info a GtkFileFilterInfo structure containing information about a file.
    @return TRUE if the file should be displayed

    The GtkFileFilterInfo structure filter_info should include the fields
    returned from gtk_file_filter_get_needed().

    This function will not typically be used by applications; it is intended
    principally for use in the implementation of GtkFileChooser.
 */
FALCON_FUNC FileFilter::filter( VMARG )
{
    Item* i_info = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_info || !i_info->isObject() || !IS_DERIVED( i_info, GtkFileFilterInfo ) )
        throw_inv_params( "GtkFilefilterInfo" );
#endif
    vm->retval( (bool) gtk_file_filter_filter( GET_FILEFILTER( vm->self() ),
                                               GET_FILEFILTERINFO( *i_info ) ) );
}
Esempio n. 3
0
/*#
    @method new_from_pixbuf GdkCursor
    @brief Creates a new cursor from a pixbuf.
    @param display the GdkDisplay for which the cursor will be created
    @param pixbuf the GdkPixbuf containing the cursor image
    @param x the horizontal offset of the 'hotspot' of the cursor.
    @param y the vertical offset of the 'hotspot' of the cursor.
    @return a new GdkCursor.

    Not all GDK backends support RGBA cursors. If they are not supported, a
    monochrome approximation will be displayed. The functions gdk_display_supports_cursor_alpha()
    and gdk_display_supports_cursor_color() can be used to determine whether
    RGBA cursors are supported; gdk_display_get_default_cursor_size() and
    gdk_display_get_maximal_cursor_size() give information about cursor sizes.

    On the X backend, support for RGBA cursors requires a sufficently new
    version of the X Render extension.
 */
FALCON_FUNC Cursor::new_from_pixbuf( VMARG )
{
    Item* i_display = vm->param( 0 );
    Item* i_pix = vm->param( 1 );
    Item* i_x = vm->param( 2 );
    Item* i_y = vm->param( 3 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_display || !i_display->isObject() || !IS_DERIVED( i_display, GdkDisplay )
        || !i_pix || !i_pix->isObject() || !IS_DERIVED( i_pix, GdkPixbuf )
        || !i_x || !i_x->isInteger()
        || !i_y || !i_y->isInteger() )
        throw_inv_params( "GdkDisplay,GdkPixbuf,I,I" );
#endif
    vm->retval( new Gdk::Cursor( vm->findWKI( "GdkCursor" )->asClass(),
                        gdk_cursor_new_from_pixbuf( GET_DISPLAY( *i_display ),
                                                    GET_PIXBUF( *i_pix ),
                                                    i_x->asInteger(),
                                                    i_y->asInteger() ) ) );
}
Esempio n. 4
0
/*#
    @method is_descendant GtkTreePath
    @brief Returns TRUE if path is a descendant of ancestor.
    @param ancestor another GtkTreePath
    @return TRUE if ancestor contains path somewhere below it
 */
FALCON_FUNC TreePath::is_descendant( VMARG )
{
    Item* i_anc = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_anc || !i_anc->isObject() || !IS_DERIVED( i_anc, GtkTreePath ) )
        throw_inv_params( "GtkTreePath" );
#endif
    GtkTreePath* anc = GET_TREEPATH( *i_anc );
    MYSELF;
    vm->retval( (bool) gtk_tree_path_is_descendant( self->getTreePath(), anc ) );
}
Esempio n. 5
0
/*#
    @method compare GtkTreePath
    @brief Compares two paths.
    @param b A GtkTreePath to compare with.
    @return The relative positions of a and b

    If a appears before b in a tree, then -1 is returned.
    If b appears before a, then 1 is returned.
    If the two nodes are equal, then 0 is returned.
 */
FALCON_FUNC TreePath::compare( VMARG )
{
    Item* i_b = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_b || !i_b->isObject() || !IS_DERIVED( i_b, GtkTreePath ) )
        throw_inv_params( "GtkTreePath" );
#endif
    GtkTreePath* b = GET_TREEPATH( *i_b );
    MYSELF;
    vm->retval( gtk_tree_path_compare( self->getTreePath(), b ) );
}
Esempio n. 6
0
/*#
    @class GtkVScale
    @brief A vertical slider widget for selecting a value from a range
    @param adjustment the GtkAdjustment which sets the range of the scale.

    The GtkVScale widget is used to allow the user to select a value using a
    vertical slider.

    The position to show the current value, and the number of decimal places
    shown can be set using the parent GtkScale class's functions.
 */
FALCON_FUNC VScale::init( VMARG )
{
    Item* i_adj = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_adj || !i_adj->isObject() || !IS_DERIVED( i_adj, GtkAdjustment ) )
        throw_inv_params( "GtkAdjustment" );
#endif
    GtkAdjustment* adj = (GtkAdjustment*) COREGOBJECT( i_adj )->getObject();
    MYSELF;
    self->setObject( (GObject*) gtk_vscale_new( adj ) );
}
Esempio n. 7
0
/*#
    @method set_menu GtkOptionMenu
    @brief Provides the GtkMenu that is popped up to allow the user to choose a new value.
    @param menu the GtkMenu to associate with the GtkOptionMenu.

    You should provide a simple menu avoiding the use of tearoff menu items,
    submenus, and accelerators.
 */
FALCON_FUNC OptionMenu::set_menu( VMARG )
{
    Item* i_menu = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_menu || !i_menu->isObject() || !IS_DERIVED( i_menu, GtkMenu ) )
        throw_inv_params( "GtkMenu" );
#endif
    GtkWidget* menu = (GtkWidget*) COREGOBJECT( i_menu )->getObject();
    MYSELF;
    GET_OBJ( self );
    gtk_option_menu_set_menu( (GtkOptionMenu*)_obj, menu );
}
Esempio n. 8
0
/*#
    @class GtkHScrollbar
    @brief A horizontal scrollbar
    @param adjustment the GtkAdjustment to use, or NULL to create a new adjustment

    The GtkHScrollbar widget is a widget arranged horizontally creating a
    scrollbar. See GtkScrollbar for details on scrollbars. GtkAdjustment
    pointers may be added to handle the adjustment of the scrollbar or it
    may be left NULL in which case one will be created for you.
    See GtkScrollbar for a description of what the fields in an adjustment
    represent for a scrollbar.
 */
FALCON_FUNC HScrollbar::init( VMARG )
{
    Item* i_adj = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_adj || !( i_adj->isNil() || ( i_adj->isObject()
        && IS_DERIVED( i_adj, GtkAdjustment ) ) ) )
        throw_inv_params( "[GtkAdjustment]" );
#endif
    GtkAdjustment* adj = i_adj->isNil() ? NULL : GET_ADJUSTMENT( *i_adj );
    MYSELF;
    self->setObject( (GObject*) gtk_hscrollbar_new( adj ) );
}
Esempio n. 9
0
/*#
    @method union GdkRectangle
    @brief Calculates the union of two rectangles.
    @param src a GdkRectangle.
    @return a GdkRectangle that is the smallest rectangle containing both this rectangle and the GdkRectangle specified by src.
 */
FALCON_FUNC Rectangle::union_( VMARG )
{
    Item* i_src = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_src || !i_src->isObject() || !IS_DERIVED( i_src, GdkRectangle ) )
        throw_inv_params( "GdkRectangle" );
#endif
    GdkRectangle* src1 = GET_RECTANGLE( vm->self() );
    GdkRectangle* src2 = GET_RECTANGLE( *i_src );
    GdkRectangle dest;
    gdk_rectangle_union( src1, src2, &dest );
    vm->retval( new Gdk::Rectangle( vm->findWKI( "GdkRectangle" )->asClass(), &dest ) );
}
Esempio n. 10
0
/*#
    @class GdkColormap
    @brief The GdkColormap structure is used to describe an allocated or unallocated color.
    @param visual a GdkVisual.
    @param allocate if true, the newly created colormap will be a private colormap, and all colors in it will be allocated for the applications use.

    @prop size For pseudo-color colormaps, the number of colors in the colormap.
    @prop colors An array containing the current values in the colormap. This can be used to map from pixel values back to RGB values. This is only meaningful for pseudo-color colormaps.
 */
FALCON_FUNC Colormap::init( VMARG )
{
    Item* i_vis = vm->param( 0 );
    Item* i_allocate = vm->param( 1 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_vis || !i_vis->isObject() || !IS_DERIVED( i_vis, GdkVisual )
        || !i_allocate || !i_allocate->isBoolean() )
        throw_inv_params( "GdkVisual,B" );
#endif
    MYSELF;
    self->setObject( gdk_colormap_new( GET_VISUAL( *i_vis ),
                                       (gboolean) i_allocate->asBoolean() ) );
}
Esempio n. 11
0
/*#
    @method new_with_dialog GtkFileChooserButton
    @brief Creates a GtkFileChooserButton widget which uses dialog as its file-picking window.
    @param dialog the widget to use as dialog
    @return a new button widget.

    Note that dialog must be a GtkDialog (or subclass) which implements the
    GtkFileChooser interface and must not have GTK_DIALOG_DESTROY_WITH_PARENT set.

    Also note that the dialog needs to have its confirmative button added with
    response GTK_RESPONSE_ACCEPT or GTK_RESPONSE_OK in order for the button to
    take over the file selected in the dialog.
 */
FALCON_FUNC FileChooserButton::new_with_dialog( VMARG )
{
    Item* i_dlg = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_dlg || i_dlg->isNil() || !i_dlg->isObject()
        || !IS_DERIVED( i_dlg, GtkWidget ) )
        throw_inv_params( "GtkWidget" );
#endif
    GtkWidget* dlg = (GtkWidget*) COREGOBJECT( i_dlg )->getObject();
    GtkWidget* wdt = gtk_file_chooser_button_new_with_dialog( dlg );
    vm->retval( new Gtk::FileChooserButton(
            vm->findWKI( "GtkFileChooserButton" )->asClass(), (GtkFileChooserButton*) wdt ) );
}
Esempio n. 12
0
/*#
    @method new_for_display GdkCursor
    @brief Creates a new cursor from the set of builtin cursors.
    @param display the GdkDisplay for which the cursor will be created
    @param cursor_type cursor to create (GdkCursorType)
 */
FALCON_FUNC Cursor::new_for_display( VMARG )
{
    Item* i_display = vm->param( 0 );
    Item* i_tp = vm->param( 1 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_display || !i_display->isObject() || !IS_DERIVED( i_display, GdkDisplay )
        || !i_tp || !i_tp->isInteger() )
        throw_inv_params( "GdkDisplay,GdkCursorType" );
#endif
    vm->retval( new Gdk::Cursor( vm->findWKI( "GdkCursor" )->asClass(),
                gdk_cursor_new_for_display( GET_DISPLAY( *i_display ),
                                            (GdkCursorType) i_tp->asInteger() ) ) );
}
Esempio n. 13
0
/*#
    @method remove GtkTextTagTable
    @brief Remove a tag from the table.
    @param tag a GtkTextTag
 */
FALCON_FUNC TextTagTable::remove( VMARG )
{
    Item* i_tag = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_tag || i_tag->isNil() || !i_tag->isObject()
        || !IS_DERIVED( i_tag, GtkTextTag ) )
        throw_inv_params( "GtkTextTag" );
#endif
    GtkTextTag* tag = (GtkTextTag*) COREGOBJECT( i_tag )->getObject();
    MYSELF;
    GET_OBJ( self );
    gtk_text_tag_table_remove( (GtkTextTagTable*)_obj, tag );
}
Esempio n. 14
0
/*#
    @method set_label_widget GtkToolButton
    @brief Sets label_widget as the widget that will be used as the label for button.
    @param label_widget the widget used as label, or NULL.

    If label_widget is NULL the "label" property is used as label. If "label"
    is also NULL, the label in the stock item determined by the "stock_id"
    property is used as label. If "stock_id" is also NULL, button does not have a label.
 */
FALCON_FUNC ToolButton::set_label_widget( VMARG )
{
    Item* i_wdt = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_wdt || !( i_wdt->isNil() || ( i_wdt->isObject()
        && IS_DERIVED( i_wdt, GtkWidget ) ) ) )
        throw_inv_params( "[GtkWidget]" );
#endif
    GtkWidget* wdt = i_wdt->isNil() ? NULL :
                        (GtkWidget*) COREGOBJECT( i_wdt )->getObject();
    MYSELF;
    GET_OBJ( self );
    gtk_tool_button_set_label_widget( (GtkToolButton*)_obj, wdt );
}
Esempio n. 15
0
/*#
    @method set_submenu GtkMenuItem
    @brief Sets or replaces the menu item's submenu, or removes it when a NULL submenu is passed.
    @param submenu the submenu, or NULL.
 */
FALCON_FUNC MenuItem::set_submenu( VMARG )
{
    Item* i_menu = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_menu || !( i_menu->isNil() || ( i_menu->isObject()
        && IS_DERIVED( i_menu, GtkWidget ) ) ) )
        throw_inv_params( "[GtkWidget]" );
#endif
    GtkWidget* menu = i_menu->isNil() ? NULL :
                            (GtkWidget*) COREGOBJECT( i_menu )->getObject();
    MYSELF;
    GET_OBJ( self );
    gtk_menu_item_set_submenu( (GtkMenuItem*)_obj, menu );
}
Esempio n. 16
0
/*#
    @class GtkRadioToolButton
    @brief A toolbar item that contains a radio button
    @param group An existing GtkRadioToolButton, or nil to create a new group of buttons.

    A GtkRadioToolButton is a GtkToolItem that contains a radio button, that is,
    a button that is part of a group of toggle buttons where only one button can
    be active at a time.
 */
FALCON_FUNC RadioToolButton::init( VMARG )
{
    Item* i_grp = vm->param( 0 );
#ifndef NO_PARAMETER_CHECK
    if ( !i_grp || !( i_grp->isNil() || ( i_grp->isObject()
        && IS_DERIVED( i_grp, GtkRadioToolButton ) ) ) )
        throw_inv_params( "[GtkRadioToolButton]" );
#endif
    GtkRadioToolButton* grp = i_grp->isNil() ? NULL
                        : (GtkRadioToolButton*) COREGOBJECT( i_grp )->getObject();
    GtkToolItem* btn = grp ? gtk_radio_tool_button_new_from_widget( grp )
                    : gtk_radio_tool_button_new( NULL );
    MYSELF;
    self->setObject( (GObject*) btn );
}
Esempio n. 17
0
/*
 * Walk the pmidlist[] from pmFetch.
 * For each derived metric found in the list add all the operand metrics,
 * and build a combined pmID list (newlist).
 *
 * Return 0 if no derived metrics in the list, else the number of pmIDs
 * in the combined list.
 *
 * The derived metric pmIDs are left in the combined list (they will
 * return PM_ERR_NOAGENT from the fetch) to simplify the post-processing
 * of the pmResult in __dmpostfetch()
 */
int
__dmprefetch(__pmContext *ctxp, int numpmid, const pmID *pmidlist, pmID **newlist)
{
    int		i;
    int		j;
    int		m;
    int		xtracnt = 0;
    pmID	*xtralist = NULL;
    pmID	*list;
    ctl_t	*cp = (ctl_t *)ctxp->c_dm;

    /* if needed, init() called in __dmopencontext beforehand */

    if (cp == NULL) return 0;

    /*
     * save numpmid to be used in __dmpostfetch() ... works because calls
     * to pmFetch cannot be nested (at all, but certainly for the same
     * context).
     * Ditto for the fast path flag (fetch_has_dm).
     */
    cp->numpmid = numpmid;
    cp->fetch_has_dm = 0;

    for (m = 0; m < numpmid; m++) {
	if (!IS_DERIVED(pmidlist[m]))
	    continue;
	for (i = 0; i < cp->nmetric; i++) {
	    if (pmidlist[m] == cp->mlist[i].pmid) {
		if (cp->mlist[i].expr != NULL) {
		    get_pmids(cp->mlist[i].expr, &xtracnt, &xtralist);
		    cp->fetch_has_dm = 1;
		}
		break;
	    }
	}
    }
    if (xtracnt == 0) {
	if (cp->fetch_has_dm)
	    return numpmid;
	else
	    return 0;
    }

    /*
     * Some of the "extra" ones, may already be in the caller's pmFetch 
     * list, or repeated in xtralist[] (if the same metric operand appears
     * more than once as a leaf node in the expression tree.
     * Remove these duplicates
     */
    j = 0;
    for (i = 0; i < xtracnt; i++) {
	for (m = 0; m < numpmid; m++) {
	    if (xtralist[i] == pmidlist[m])
		/* already in pmFetch list */
		break;
	}
	if (m < numpmid) continue;
	for (m = 0; m < j; m++) {
	    if (xtralist[i] == xtralist[m])
	    	/* already in xtralist[] */
		break;
	}
	if (m == j)
	    xtralist[j++] = xtralist[i];
    }
    xtracnt = j;
    if (xtracnt == 0) {
	free(xtralist);
	return numpmid;
    }

#ifdef PCP_DEBUG
    if ((pmDebug & DBG_TRACE_DERIVE) && (pmDebug & DBG_TRACE_APPL2)) {
	char	strbuf[20];
	fprintf(stderr, "derived metrics prefetch added %d metrics:", xtracnt);
	for (i = 0; i < xtracnt; i++)
	    fprintf(stderr, " %s", pmIDStr_r(xtralist[i], strbuf, sizeof(strbuf)));
	fputc('\n', stderr);
    }
#endif
    if ((list = (pmID *)malloc((numpmid+xtracnt)*sizeof(pmID))) == NULL) {
	__pmNoMem("__dmprefetch: alloc list", (numpmid+xtracnt)*sizeof(pmID), PM_FATAL_ERR);
	/*NOTREACHED*/
    }
    for (m = 0; m < numpmid; m++) {
	list[m] = pmidlist[m];
    }
    for (i = 0; i < xtracnt; i++) {
	list[m++] = xtralist[i];
    }
    free(xtralist);
    *newlist = list;

    return m;
}
Esempio n. 18
0
/*
 * Algorithm here is complicated by trying to re-write the pmResult.
 *
 * On entry the pmResult is likely to be built over a pinned PDU buffer,
 * which means individual pmValueSets cannot be selectively replaced
 * (this would come to tears badly in pmFreeResult() where as soon as
 * one pmValueSet is found to be in a pinned PDU buffer it is assumed
 * they are all so ... leaving a memory leak for any ones we'd modified
 * here).
 *
 * So the only option is to COPY the pmResult, selectively replacing
 * the pmValueSets for the derived metrics, and then calling
 * pmFreeResult() to free the input structure and return the new one.
 *
 * In making the COPY it is critical that we reverse the algorithm
 * used in pmFreeResult() so that a later call to pmFreeResult() will
 * not cause a memory leak.
 * This means ...
 * - malloc() the pmResult (padded out to the right number of vset[]
 *   entries)
 * - if valfmt is not PM_VAL_INSITU use PM_VAL_DPTR (not PM_VAL_SPTR),
 *   so anything we point to is going to be released when our caller
 *   calls pmFreeResult()
 * - use one malloc() for each pmValueSet with vlist[] sized to be 0
 *   if numval < 0 else numval
 * - pmValueBlocks are from malloc()
 *
 * For reference, the same logic appears in __pmLogFetchInterp() to
 * sythesize a pmResult there.
 */
void
__dmpostfetch(__pmContext *ctxp, pmResult **result)
{
    int		i;
    int		j;
    int		m;
    int		numval;
    int		valfmt;
    size_t	need;
    int		rewrite;
    ctl_t	*cp = (ctl_t *)ctxp->c_dm;
    pmResult	*rp = *result;
    pmResult	*newrp;

    /* if needed, init() called in __dmopencontext beforehand */

    if (cp == NULL || cp->fetch_has_dm == 0) return;

    newrp = (pmResult *)malloc(sizeof(pmResult)+(cp->numpmid-1)*sizeof(pmValueSet *));
    if (newrp == NULL) {
	__pmNoMem("__dmpostfetch: newrp", sizeof(pmResult)+(cp->numpmid-1)*sizeof(pmValueSet *), PM_FATAL_ERR);
	/*NOTREACHED*/
    }
    newrp->timestamp = rp->timestamp;
    newrp->numpmid = cp->numpmid;

    for (j = 0; j < newrp->numpmid; j++) {
	numval = rp->vset[j]->numval;
	valfmt = rp->vset[j]->valfmt;
	rewrite = 0;
	/*
	 * pandering to gcc ... m is not used unless rewrite == 1 in
	 * which case m is well-defined
	 */
	m = 0;
	if (IS_DERIVED(rp->vset[j]->pmid)) {
	    for (m = 0; m < cp->nmetric; m++) {
		if (rp->vset[j]->pmid == cp->mlist[m].pmid) {
		    if (cp->mlist[m].expr == NULL) {
			numval = PM_ERR_PMID;
		    }
		    else {
			rewrite = 1;
			if (cp->mlist[m].expr->desc.type == PM_TYPE_32 ||
			    cp->mlist[m].expr->desc.type == PM_TYPE_U32)
			    valfmt = PM_VAL_INSITU;
			else
			    valfmt = PM_VAL_DPTR;
			numval = eval_expr(cp->mlist[m].expr, rp, 1);
#ifdef PCP_DEBUG
    if ((pmDebug & DBG_TRACE_DERIVE) && (pmDebug & DBG_TRACE_APPL2)) {
	int	k;
	char	strbuf[20];

	fprintf(stderr, "__dmpostfetch: [%d] root node %s: numval=%d", j, pmIDStr_r(rp->vset[j]->pmid, strbuf, sizeof(strbuf)), numval);
	for (k = 0; k < numval; k++) {
	    fprintf(stderr, " vset[%d]: inst=%d", k, cp->mlist[m].expr->info->ivlist[k].inst);
	    if (cp->mlist[m].expr->desc.type == PM_TYPE_32)
		fprintf(stderr, " l=%d", cp->mlist[m].expr->info->ivlist[k].value.l);
	    else if (cp->mlist[m].expr->desc.type == PM_TYPE_U32)
		fprintf(stderr, " u=%u", cp->mlist[m].expr->info->ivlist[k].value.ul);
	    else if (cp->mlist[m].expr->desc.type == PM_TYPE_64)
		fprintf(stderr, " ll=%"PRIi64, cp->mlist[m].expr->info->ivlist[k].value.ll);
	    else if (cp->mlist[m].expr->desc.type == PM_TYPE_U64)
		fprintf(stderr, " ul=%"PRIu64, cp->mlist[m].expr->info->ivlist[k].value.ull);
	    else if (cp->mlist[m].expr->desc.type == PM_TYPE_FLOAT)
		fprintf(stderr, " f=%f", (double)cp->mlist[m].expr->info->ivlist[k].value.f);
	    else if (cp->mlist[m].expr->desc.type == PM_TYPE_DOUBLE)
		fprintf(stderr, " d=%f", cp->mlist[m].expr->info->ivlist[k].value.d);
	    else if (cp->mlist[m].expr->desc.type == PM_TYPE_STRING) {
		fprintf(stderr, " cp=%s (len=%d)", cp->mlist[m].expr->info->ivlist[k].value.cp, cp->mlist[m].expr->info->ivlist[k].vlen);
	    }
	    else {
		fprintf(stderr, " vbp=" PRINTF_P_PFX "%p (len=%d)", cp->mlist[m].expr->info->ivlist[k].value.vbp, cp->mlist[m].expr->info->ivlist[k].vlen);
	    }
	}
	fputc('\n', stderr);
	if (cp->mlist[m].expr->info != NULL)
	    __dmdumpexpr(cp->mlist[m].expr, 1);
    }
#endif
		    }
		    break;
		}
	    }
	}

	if (numval <= 0) {
	    /* only need pmid and numval */
	    need = sizeof(pmValueSet) - sizeof(pmValue);
	}
	else {
	    /* already one pmValue in a pmValueSet */
	    need = sizeof(pmValueSet) + (numval - 1)*sizeof(pmValue);
	}
	if (need > 0) {
	    if ((newrp->vset[j] = (pmValueSet *)malloc(need)) == NULL) {
		__pmNoMem("__dmpostfetch: vset", need, PM_FATAL_ERR);
		/*NOTREACHED*/
	    }
	}
	newrp->vset[j]->pmid = rp->vset[j]->pmid;
	newrp->vset[j]->numval = numval;
	newrp->vset[j]->valfmt = valfmt;
	if (numval < 0)
	    continue;

	for (i = 0; i < numval; i++) {
	    pmValueBlock	*vp;

	    if (!rewrite) {
		newrp->vset[j]->vlist[i].inst = rp->vset[j]->vlist[i].inst;
		if (newrp->vset[j]->valfmt == PM_VAL_INSITU) {
		    newrp->vset[j]->vlist[i].value.lval = rp->vset[j]->vlist[i].value.lval;
		}
		else {
		    need = rp->vset[j]->vlist[i].value.pval->vlen;
		    vp = (pmValueBlock *)malloc(need);
		    if (vp == NULL) {
			__pmNoMem("__dmpostfetch: copy value", need, PM_FATAL_ERR);
			/*NOTREACHED*/
		    }
		    memcpy((void *)vp, (void *)rp->vset[j]->vlist[i].value.pval, need);
		    newrp->vset[j]->vlist[i].value.pval = vp;
		}
		continue;
	    }

	    /*
	     * the rewrite case ...
	     */
	    newrp->vset[j]->vlist[i].inst = cp->mlist[m].expr->info->ivlist[i].inst;
	    switch (cp->mlist[m].expr->desc.type) {
		case PM_TYPE_32:
		case PM_TYPE_U32:
		    newrp->vset[j]->vlist[i].value.lval = cp->mlist[m].expr->info->ivlist[i].value.l;
		    break;

		case PM_TYPE_64:
		case PM_TYPE_U64:
		    need = PM_VAL_HDR_SIZE + sizeof(__int64_t);
		    if ((vp = (pmValueBlock *)malloc(need)) == NULL) {
			__pmNoMem("__dmpostfetch: 64-bit int value", need, PM_FATAL_ERR);
			/*NOTREACHED*/
		    }
		    vp->vlen = need;
		    vp->vtype = cp->mlist[m].expr->desc.type;
		    memcpy((void *)vp->vbuf, (void *)&cp->mlist[m].expr->info->ivlist[i].value.ll, sizeof(__int64_t));
		    newrp->vset[j]->vlist[i].value.pval = vp;
		    break;

		case PM_TYPE_FLOAT:
		    need = PM_VAL_HDR_SIZE + sizeof(float);
		    if ((vp = (pmValueBlock *)malloc(need)) == NULL) {
			__pmNoMem("__dmpostfetch: float value", need, PM_FATAL_ERR);
			/*NOTREACHED*/
		    }
		    vp->vlen = need;
		    vp->vtype = PM_TYPE_FLOAT;
		    memcpy((void *)vp->vbuf, (void *)&cp->mlist[m].expr->info->ivlist[i].value.f, sizeof(float));
		    newrp->vset[j]->vlist[i].value.pval = vp;
		    break;

		case PM_TYPE_DOUBLE:
		    need = PM_VAL_HDR_SIZE + sizeof(double);
		    if ((vp = (pmValueBlock *)malloc(need)) == NULL) {
			__pmNoMem("__dmpostfetch: double value", need, PM_FATAL_ERR);
			/*NOTREACHED*/
		    }
		    vp->vlen = need;
		    vp->vtype = PM_TYPE_DOUBLE;
		    memcpy((void *)vp->vbuf, (void *)&cp->mlist[m].expr->info->ivlist[i].value.f, sizeof(double));
		    newrp->vset[j]->vlist[i].value.pval = vp;
		    break;

		case PM_TYPE_STRING:
		    need = PM_VAL_HDR_SIZE + cp->mlist[m].expr->info->ivlist[i].vlen;
		    vp = (pmValueBlock *)malloc(need);
		    if (vp == NULL) {
			__pmNoMem("__dmpostfetch: string value", need, PM_FATAL_ERR);
			/*NOTREACHED*/
		    }
		    vp->vlen = need;
		    vp->vtype = cp->mlist[m].expr->desc.type;
		    memcpy((void *)vp->vbuf, cp->mlist[m].expr->info->ivlist[i].value.cp, cp->mlist[m].expr->info->ivlist[i].vlen);
		    newrp->vset[j]->vlist[i].value.pval = vp;
		    break;

		case PM_TYPE_AGGREGATE:
		case PM_TYPE_AGGREGATE_STATIC:
		case PM_TYPE_EVENT:
		case PM_TYPE_HIGHRES_EVENT:
		    need = cp->mlist[m].expr->info->ivlist[i].vlen;
		    vp = (pmValueBlock *)malloc(need);
		    if (vp == NULL) {
			__pmNoMem("__dmpostfetch: aggregate or event value", need, PM_FATAL_ERR);
			/*NOTREACHED*/
		    }
		    memcpy((void *)vp, cp->mlist[m].expr->info->ivlist[i].value.vbp, cp->mlist[m].expr->info->ivlist[i].vlen);
		    newrp->vset[j]->vlist[i].value.pval = vp;
		    break;

		default:
		    /*
		     * really nothing should end up here ...
		     * do nothing as numval should have been < 0
		     */
#ifdef PCP_DEBUG
		    if (pmDebug & DBG_TRACE_DERIVE) {
			char	strbuf[20];
			fprintf(stderr, "__dmpostfetch: botch: drived metric[%d]: operand %s has odd type (%d)\n", m, pmIDStr_r(rp->vset[j]->pmid, strbuf, sizeof(strbuf)), cp->mlist[m].expr->desc.type);
		    }
#endif
		    break;
	    }
	}
    }

    /*
     * cull the original pmResult and return the rewritten one
     */
    pmFreeResult(rp);
    *result = newrp;

    return;
}