Ejemplo n.º 1
0
static int itemConfigure( Tcl_Interp *interp, int objc, 
      Tcl_Obj * const objv[], CanvasParams *param, GPtrArray *items )
{
   /* canvas itemConfigure tag-or-id ?option val ...? */
   guint k;
   int   ret = TCL_ERROR;

   if( items == NULL )
      return TCL_OK;

   for( k = 0; k < items->len; ++k )
   {
      Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
      if( gnoclParseOptions( interp, objc - 2, objv + 2, info->options ) 
            != TCL_OK )
         goto cleanExit;
   }
   for( k = 0; k < items->len; ++k )
   {
      Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
      if( (*info->setOptions)( interp, info ) != TCL_OK )
         goto cleanExit;
   }

   ret = TCL_OK;

cleanExit:
   for( k = 0; k < items->len; ++k )
   {
      Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
      gnoclClearOptions( info->options );
   }

   return ret;
}
Ejemplo n.º 2
0
// Traverse a threaded chain and pull out the info pointer at the end.
// The info pointer is also tagged with the appropriate pointer tag
// for this closure, which should be attached to the pointer
// subsequently passed to unthread().
STATIC_INLINE StgWord
get_threaded_info( StgPtr p )
{
    StgWord q;
    
    q = (W_)GET_INFO(UNTAG_CLOSURE((StgClosure *)p));

loop:
    switch (GET_CLOSURE_TAG((StgClosure *)q)) 
    {
    case 0:
        ASSERT(LOOKS_LIKE_INFO_PTR(q));
        return q;
    case 1:
    {
        StgWord r = *(StgPtr)(q-1);
        ASSERT(LOOKS_LIKE_INFO_PTR(UNTAG_CLOSURE((StgClosure *)r)));
        return r;
    }
    case 2:
        q = *(StgPtr)(q-2);
        goto loop;
    default:
        barf("get_threaded_info");
    }
}
Ejemplo n.º 3
0
static int itemShow( Tcl_Interp *interp, int objc, Tcl_Obj * const objv[], 
      CanvasParams *param, GPtrArray *items )
{
   guint k;
   int   on = 1;

   if( objc > 4 )
   {
      Tcl_WrongNumArgs( interp, 3, objv, "?on?" );
      return TCL_ERROR;
   }
   if( objc == 4 )
   {
      if( Tcl_GetBooleanFromObj( interp, objv[3], &on ) != TCL_OK )
         return TCL_ERROR;
   }

   if( items != NULL )
   {
      for( k = 0; k < items->len; ++k )
      {
         Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
         if( on )
            gnome_canvas_item_show( info->item );
         else
            gnome_canvas_item_hide( info->item );
      }
   }

   return TCL_OK;
}
Ejemplo n.º 4
0
static int itemCommand( Tcl_Interp *interp, int objc, 
      Tcl_Obj * const objv[], CanvasParams *param, GPtrArray *items )
{
   /* canvas itemCommand tag-or-id command ?option val ...? */
   guint k;
   if( objc < 4 )
   {
      Tcl_WrongNumArgs( interp, 3, objv, "command ?option val ...?" );
      return TCL_ERROR;
   }

   if( items != NULL )
   {
      for( k = 0; k < items->len; ++k )
      {
         Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
         if( info->command == NULL )
         {
            Tcl_SetResult( interp, "Canvas item does not have any command.", 
               TCL_STATIC );
            return TCL_ERROR;
         }
         if( (*info->command)( interp, objc, objv, info ) != TCL_OK )
            return TCL_ERROR;
      }
   }

   return TCL_OK;
}
Ejemplo n.º 5
0
static void destroyFunc( GtkWidget *widget, gpointer data )
{
   CanvasParams *p = (CanvasParams *)data;
   GPtrArray    *items;

   gnoclForgetWidgetFromName( p->name );
   Tcl_DeleteCommand( p->interp, p->name );

   g_free( p->name );
   /*  TODO: the canvas receives the destroy signal before its items. But
             the items use the hash table on destruction.
             Shouldn't children receive the signal before their parents?
             Hmm, GTK widgets do it the same way.  
             gtk_container_foreach( GTK_CONTAINER( widget ), 
                   (GtkCallback)destroyItemFunc, NULL);  
             doesn't help either

   */
   items = gnoclCanvasAllItems( p );
   if( items != NULL )
   {
      int k;
      for( k = items->len - 1; k >= 0; --k )
      {
         Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
         gtk_object_destroy( GTK_OBJECT( info->item ) );
      }
   }
   g_hash_table_destroy( p->tagToItems ); 
}
Ejemplo n.º 6
0
static int itemBounds( Tcl_Interp *interp, int objc, Tcl_Obj * const objv[], 
      CanvasParams *param, GPtrArray *items )
{
   if( objc != 3 )
   {
      Tcl_WrongNumArgs( interp, 2, objv, NULL );
      return TCL_ERROR;
   }

   if( items != NULL && items->len > 0 )
   {
      Tcl_Obj *resList;
      double  xMin, yMin, xMax, yMax;
      guint   k;
      Gnocl_CanvasItemInfo *info = GET_INFO( items, 0 );
      gnome_canvas_item_get_bounds( info->item, &xMin, &yMin, &xMax, &yMax );

      for( k = 1; k < items->len; ++k )
      {
         double x1, y1, x2, y2;
         info = GET_INFO( items, k );
         gnome_canvas_item_get_bounds( info->item, &x1, &y1, &x2, &y2 );
         if( x1 < xMin )
            xMin = x1;
         if( y1 < yMin )
            yMin = y1;
         if( x2 > xMax )
            xMax = x2;
         if( y2 > yMax )
            yMax = y2;
      }

      resList = Tcl_NewListObj( 0, NULL );
      Tcl_ListObjAppendElement( interp, resList, Tcl_NewDoubleObj( xMin ) );
      Tcl_ListObjAppendElement( interp, resList, Tcl_NewDoubleObj( yMin ) );
      Tcl_ListObjAppendElement( interp, resList, Tcl_NewDoubleObj( xMax ) );
      Tcl_ListObjAppendElement( interp, resList, Tcl_NewDoubleObj( yMax ) );
      Tcl_SetObjResult( interp, resList );
   }

   return TCL_OK;
}
Ejemplo n.º 7
0
static int itemRaise( Tcl_Interp *interp, int objc, Tcl_Obj * const objv[], 
      CanvasParams *param, GPtrArray *items, int isRaise )
{
   int k;
   int position = 0;
   if( objc == 4 )
   {
      if( Tcl_GetIntFromObj( interp, objv[3], &position ) != TCL_OK )
         return TCL_ERROR;
      if( position == 0 )
         return TCL_OK;
      if( position < 0 )
      {
         position *= -1;
         isRaise = !isRaise;
      }
   }
   else if( objc > 4 )
   {
      Tcl_WrongNumArgs( interp, 3, objv, "?position?" );
      return TCL_ERROR;
   }

   if( items != NULL )
   {
      for( k = 0; k < items->len; ++k )
      {
         Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
         if( isRaise )
         {
         /* TODO: with libgnomecanvas-2.2.1 raise_to_top works exactly once */
            if( objc == 3 )
               gnome_canvas_item_raise_to_top( info->item ); 
            else
               gnome_canvas_item_raise( info->item, position );
         }
         else
         {
            if( objc == 3 )
               gnome_canvas_item_lower_to_bottom( info->item );
            else
               gnome_canvas_item_lower( info->item, position );
         }
      }
   }

   return TCL_OK;
}
Ejemplo n.º 8
0
static int itemCget( Tcl_Interp *interp, int objc, 
      Tcl_Obj * const objv[], CanvasParams *param, GPtrArray *items )
{
   /* canvas itemCget tag-or-id option */
   Gnocl_CanvasItemInfo *info;
   int idx;

   if( objc != 4 )
   {
      Tcl_WrongNumArgs( interp, 2, objv, "tag-or-id option" );
      return TCL_ERROR;
   }

   if( items == NULL || items->len == 0 )
      return TCL_OK;

   if( items->len > 1 )
   {
      Tcl_SetResult( interp, "tag-or-id must specify a single item", 
            TCL_STATIC );
      return TCL_ERROR;
   }

   info = GET_INFO( items, 0 );

   switch( gnoclCgetOne( interp, objv[3], G_OBJECT( info->item ), 
         info->options, &idx ) )
   {
      case GNOCL_CGET_ERROR:  
               return TCL_ERROR;
      case GNOCL_CGET_HANDLED:
               return TCL_OK;
      case GNOCL_CGET_NOTHANDLED:
               {
                  Tcl_Obj *ret = NULL;
                  if( info->getOption )
                     ret = (*info->getOption)( interp, idx, info );
                  if( ret == NULL )
                     return gnoclCgetNotImplemented( interp, 
                           info->options + idx );
                  Tcl_SetObjResult( interp, ret );
                  return TCL_OK;
               }
   }

   return TCL_ERROR;
}
Ejemplo n.º 9
0
Gnocl_CanvasItemInfo *gnoclInfoFromCanvasItem( CanvasParams *param, 
      GnomeCanvasItem *item )
{
   if( item != NULL )
   {
      GPtrArray *items = gnoclCanvasAllItems( param );
      if( items != NULL )
      {
         guint     n;
         for( n = 0; n < items->len; ++n )
         {
            Gnocl_CanvasItemInfo *info = GET_INFO( items, n );
            if( info->item == item )
               return info;
         }
      }
   }

   return NULL;
}
Ejemplo n.º 10
0
static int itemDelete( Tcl_Interp *interp, int objc, Tcl_Obj * const objv[], 
      CanvasParams *param, GPtrArray *items )
{
   if( objc != 3 )
   {
      Tcl_WrongNumArgs( interp, 3, objv, NULL );
      return TCL_ERROR;
   }

   if( items != NULL )
   {
      int k;
      for( k = 0; k < items->len; ++k )
      {
         Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
         gtk_object_destroy( GTK_OBJECT( info->item ) );
      }
   }

   return TCL_OK;
}
Ejemplo n.º 11
0
static int getIDs( Tcl_Interp *interp, int objc, Tcl_Obj * const objv[], 
      CanvasParams *param, GPtrArray *items )
{
   if( objc != 3 )
   {
      Tcl_WrongNumArgs( interp, 2, objv, NULL );
      return TCL_ERROR;
   }

   if( items != NULL && items->len > 0 )
   {
      int     k;
      Tcl_Obj *resList = Tcl_NewListObj( 0, NULL );
      for( k = 0; k < items->len; ++k )
      {
         Gnocl_CanvasItemInfo *info = GET_INFO( items, k );
         Tcl_ListObjAppendElement( interp, resList, 
               Tcl_NewIntObj( info->id ) );
      }
      Tcl_SetObjResult( interp, resList );
   }
   return TCL_OK;
}
Ejemplo n.º 12
0
void
printClosure( const StgClosure *obj )
{
    const StgInfoTable *info;

    obj = UNTAG_CONST_CLOSURE(obj);
    info = get_itbl(obj);

    switch ( info->type ) {
    case INVALID_OBJECT:
            barf("Invalid object");

    case CONSTR:
    case CONSTR_1_0: case CONSTR_0_1:
    case CONSTR_1_1: case CONSTR_0_2: case CONSTR_2_0:
    case CONSTR_STATIC:
    case CONSTR_NOCAF_STATIC:
        {
            StgWord i, j;
            const StgConInfoTable *con_info = get_con_itbl (obj);

            debugBelch("%s(", GET_CON_DESC(con_info));
            for (i = 0; i < info->layout.payload.ptrs; ++i) {
                if (i != 0) debugBelch(", ");
                printPtr((StgPtr)obj->payload[i]);
            }
            for (j = 0; j < info->layout.payload.nptrs; ++j) {
                if (i != 0 || j != 0) debugBelch(", ");
                debugBelch("%p#", obj->payload[i+j]);
            }
            debugBelch(")\n");
            break;
        }

    case FUN:
    case FUN_1_0: case FUN_0_1:
    case FUN_1_1: case FUN_0_2: case FUN_2_0:
    case FUN_STATIC:
        debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity);
        printPtr((StgPtr)obj->header.info);
#ifdef PROFILING
        debugBelch(", %s", obj->header.prof.ccs->cc->label);
#endif
        printStdObjPayload(obj);
        break;

    case PRIM:
        debugBelch("PRIM(");
        printPtr((StgPtr)obj->header.info);
        printStdObjPayload(obj);
        break;

    case MUT_PRIM:
        debugBelch("MUT_PRIM(");
        printPtr((StgPtr)obj->header.info);
        printStdObjPayload(obj);
        break;

    case THUNK:
    case THUNK_1_0: case THUNK_0_1:
    case THUNK_1_1: case THUNK_0_2: case THUNK_2_0:
    case THUNK_STATIC:
            /* ToDo: will this work for THUNK_STATIC too? */
#ifdef PROFILING
            printThunkObject((StgThunk *)obj,GET_PROF_DESC(info));
#else
            printThunkObject((StgThunk *)obj,"THUNK");
#endif
            break;

    case THUNK_SELECTOR:
        printStdObjHdr(obj, "THUNK_SELECTOR");
        debugBelch(", %p)\n", ((StgSelector *)obj)->selectee);
        break;

    case BCO:
            disassemble( (StgBCO*)obj );
            break;

    case AP:
        {
            StgAP* ap = (StgAP*)obj;
            StgWord i;
            debugBelch("AP("); printPtr((StgPtr)ap->fun);
            for (i = 0; i < ap->n_args; ++i) {
                debugBelch(", ");
                printPtr((P_)ap->payload[i]);
            }
            debugBelch(")\n");
            break;
        }

    case PAP:
        {
            StgPAP* pap = (StgPAP*)obj;
            StgWord i;
            debugBelch("PAP/%d(",(int)pap->arity);
            printPtr((StgPtr)pap->fun);
            for (i = 0; i < pap->n_args; ++i) {
                debugBelch(", ");
                printPtr((StgPtr)pap->payload[i]);
            }
            debugBelch(")\n");
            break;
        }

    case AP_STACK:
        {
            StgAP_STACK* ap = (StgAP_STACK*)obj;
            StgWord i;
            debugBelch("AP_STACK("); printPtr((StgPtr)ap->fun);
            for (i = 0; i < ap->size; ++i) {
                debugBelch(", ");
                printPtr((P_)ap->payload[i]);
            }
            debugBelch(")\n");
            break;
        }

    case IND:
            debugBelch("IND(");
            printPtr((StgPtr)((StgInd*)obj)->indirectee);
            debugBelch(")\n");
            break;

    case IND_STATIC:
            debugBelch("IND_STATIC(");
            printPtr((StgPtr)((StgInd*)obj)->indirectee);
            debugBelch(")\n");
            break;

    case BLACKHOLE:
            debugBelch("BLACKHOLE(");
            printPtr((StgPtr)((StgInd*)obj)->indirectee);
            debugBelch(")\n");
            break;

    /* Cannot happen -- use default case.
    case RET_BCO:
    case RET_SMALL:
    case RET_BIG:
    case RET_FUN:
    */

    case UPDATE_FRAME:
        {
            StgUpdateFrame* u = (StgUpdateFrame*)obj;
            debugBelch("%s(", info_update_frame(obj));
            printPtr((StgPtr)GET_INFO((StgClosure *)u));
            debugBelch(",");
            printPtr((StgPtr)u->updatee);
            debugBelch(")\n");
            break;
        }

    case CATCH_FRAME:
        {
            StgCatchFrame* u = (StgCatchFrame*)obj;
            debugBelch("CATCH_FRAME(");
            printPtr((StgPtr)GET_INFO((StgClosure *)u));
            debugBelch(",");
            printPtr((StgPtr)u->handler);
            debugBelch(")\n");
            break;
        }

    case UNDERFLOW_FRAME:
        {
            StgUnderflowFrame* u = (StgUnderflowFrame*)obj;
            debugBelch("UNDERFLOW_FRAME(");
            printPtr((StgPtr)u->next_chunk);
            debugBelch(")\n");
            break;
        }

    case STOP_FRAME:
        {
            StgStopFrame* u = (StgStopFrame*)obj;
            debugBelch("STOP_FRAME(");
            printPtr((StgPtr)GET_INFO((StgClosure *)u));
            debugBelch(")\n");
            break;
        }

    case ARR_WORDS:
        {
            StgWord i;
            debugBelch("ARR_WORDS(\"");
            for (i=0; i<arr_words_words((StgArrBytes *)obj); i++)
              debugBelch("%" FMT_Word, (W_)((StgArrBytes *)obj)->payload[i]);
            debugBelch("\")\n");
            break;
        }

    case MUT_ARR_PTRS_CLEAN:
        debugBelch("MUT_ARR_PTRS_CLEAN(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs);
        break;

    case MUT_ARR_PTRS_DIRTY:
        debugBelch("MUT_ARR_PTRS_DIRTY(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs);
        break;

    case MUT_ARR_PTRS_FROZEN:
        debugBelch("MUT_ARR_PTRS_FROZEN(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs);
        break;

    case SMALL_MUT_ARR_PTRS_CLEAN:
        debugBelch("SMALL_MUT_ARR_PTRS_CLEAN(size=%" FMT_Word ")\n",
                   (W_)((StgSmallMutArrPtrs *)obj)->ptrs);
        break;

    case SMALL_MUT_ARR_PTRS_DIRTY:
        debugBelch("SMALL_MUT_ARR_PTRS_DIRTY(size=%" FMT_Word ")\n",
                   (W_)((StgSmallMutArrPtrs *)obj)->ptrs);
        break;

    case SMALL_MUT_ARR_PTRS_FROZEN:
        debugBelch("SMALL_MUT_ARR_PTRS_FROZEN(size=%" FMT_Word ")\n",
                   (W_)((StgSmallMutArrPtrs *)obj)->ptrs);
        break;

    case MVAR_CLEAN:
    case MVAR_DIRTY:
        {
          StgMVar* mv = (StgMVar*)obj;
          debugBelch("MVAR(head=%p, tail=%p, value=%p)\n", mv->head, mv->tail, mv->value);
          break;
        }

    case TVAR:
        {
          StgTVar* tv = (StgTVar*)obj;
          debugBelch("TVAR(value=%p, wq=%p, num_updates=%" FMT_Word ")\n", tv->current_value, tv->first_watch_queue_entry, tv->num_updates);
          break;
        }

    case MUT_VAR_CLEAN:
        {
          StgMutVar* mv = (StgMutVar*)obj;
          debugBelch("MUT_VAR_CLEAN(var=%p)\n", mv->var);
          break;
        }

    case MUT_VAR_DIRTY:
        {
          StgMutVar* mv = (StgMutVar*)obj;
          debugBelch("MUT_VAR_DIRTY(var=%p)\n", mv->var);
          break;
        }

    case WEAK:
            debugBelch("WEAK(");
            debugBelch(" key=%p value=%p finalizer=%p",
                    (StgPtr)(((StgWeak*)obj)->key),
                    (StgPtr)(((StgWeak*)obj)->value),
                    (StgPtr)(((StgWeak*)obj)->finalizer));
            debugBelch(")\n");
            /* ToDo: chase 'link' ? */
            break;

    case TSO:
      debugBelch("TSO(");
      debugBelch("%lu (%p)",(unsigned long)(((StgTSO*)obj)->id), (StgTSO*)obj);
      debugBelch(")\n");
      break;

    case STACK:
      debugBelch("STACK");
      break;

#if 0
      /* Symptomatic of a problem elsewhere, have it fall-through & fail */
    case EVACUATED:
      debugBelch("EVACUATED(");
      printClosure((StgEvacuated*)obj->evacuee);
      debugBelch(")\n");
      break;
#endif

    case COMPACT_NFDATA:
        debugBelch("COMPACT_NFDATA(size=%" FMT_Word ")\n",
                   (W_)((StgCompactNFData *)obj)->totalDataW * sizeof(W_));
        break;


    default:
            //barf("printClosure %d",get_itbl(obj)->type);
            debugBelch("*** printClosure: unknown type %d ****\n",
                    (int)get_itbl(obj)->type );
            barf("printClosure %d",get_itbl(obj)->type);
            return;
    }
}
Ejemplo n.º 13
0
BOOL
ShowInstalledAppInfo(INT Index)
{
    WCHAR szText[MAX_PATH], szInfo[MAX_PATH];
    PINSTALLED_INFO Info = (PINSTALLED_INFO) ListViewGetlParam(Index);

    if (!Info || !Info->hSubKey) return FALSE;

    GetApplicationString(Info->hSubKey, L"DisplayName", szText);
    NewRichEditText(szText, CFE_BOLD);

    InsertRichEditText(L"\n", 0);

#define GET_INFO(a, b, c, d) \
    if (GetApplicationString(Info->hSubKey, a, szInfo)) \
    { \
        LoadStringW(hInst, b, szText, sizeof(szText) / sizeof(WCHAR)); \
        InsertRichEditText(szText, c); \
        InsertRichEditText(szInfo, d); \
    } \

    GET_INFO(L"DisplayVersion", IDS_INFO_VERSION, CFE_BOLD, 0);
    GET_INFO(L"Publisher", IDS_INFO_PUBLISHER, CFE_BOLD, 0);
    GET_INFO(L"RegOwner", IDS_INFO_REGOWNER, CFE_BOLD, 0);
    GET_INFO(L"ProductID", IDS_INFO_PRODUCTID, CFE_BOLD, 0);
    GET_INFO(L"HelpLink", IDS_INFO_HELPLINK, CFE_BOLD, CFM_LINK);
    GET_INFO(L"HelpTelephone", IDS_INFO_HELPPHONE, CFE_BOLD, 0);
    GET_INFO(L"Readme", IDS_INFO_README, CFE_BOLD, 0);
    GET_INFO(L"Contact", IDS_INFO_CONTACT, CFE_BOLD, 0);
    GET_INFO(L"URLUpdateInfo", IDS_INFO_UPDATEINFO, CFE_BOLD, CFM_LINK);
    GET_INFO(L"URLInfoAbout", IDS_INFO_INFOABOUT, CFE_BOLD, CFM_LINK);
    GET_INFO(L"Comments", IDS_INFO_COMMENTS, CFE_BOLD, 0);
    GET_INFO(L"InstallDate", IDS_INFO_INSTALLDATE, CFE_BOLD, 0);
    GET_INFO(L"InstallLocation", IDS_INFO_INSTLOCATION, CFE_BOLD, 0);
    GET_INFO(L"InstallSource", IDS_INFO_INSTALLSRC, CFE_BOLD, 0);
    GET_INFO(L"UninstallString", IDS_INFO_UNINSTALLSTR, CFE_BOLD, 0);
    GET_INFO(L"InstallSource", IDS_INFO_INSTALLSRC, CFE_BOLD, 0);
    GET_INFO(L"ModifyPath", IDS_INFO_MODIFYPATH, CFE_BOLD, 0);

    return TRUE;
}
Ejemplo n.º 14
0
static int affine( Tcl_Interp *interp, int objc, Tcl_Obj * const objv[], 
      CanvasParams *param, GPtrArray *items, int type )
{
   GnoclOption options[] = {
      { "-absolute", GNOCL_BOOL, NULL },
      { "-reverseOrder", GNOCL_BOOL, NULL },
      { NULL }
   };
   static const int absoluteIdx     = 0;
   static const int reverseOrderIdx = 1;

   guint m; 
   int   noCoords;
   int   absolute = 0; 
   int   reverse = 0;

   if( objc < 4  )
   {
      /* canvas (affine|move|scale|rotate) tag-or-id  coords ?options ? */
      Tcl_WrongNumArgs( interp, 3, objv, 
            "list-of-coordinates ?option val ...?" );
      return TCL_ERROR;
   }
   if( gnoclParseOptions( interp, objc - 3, objv + 3, options ) != TCL_OK )
      return TCL_ERROR;

   if( options[absoluteIdx].status == GNOCL_STATUS_CHANGED )
      absolute = options[absoluteIdx].val.b;
   if( options[reverseOrderIdx].status == GNOCL_STATUS_CHANGED )
      reverse = options[reverseOrderIdx].val.b;
   gnoclClearOptions( options );

   if( absolute && reverse )
   {
      Tcl_SetResult( interp, "Options \"-reverseOrder\" is only valid "
            "for relative transformations.", TCL_STATIC );
      return TCL_ERROR;
   }

   if( Tcl_ListObjLength( interp, objv[3], &noCoords ) != TCL_OK )
      return TCL_ERROR;

   for( m = 0; m < items->len; ++m )
   {
      Gnocl_CanvasItemInfo *info = GET_INFO( items, m );
      int k;
      double af[6];
      Tcl_Obj *tp;

      for( k = 0; k < 6 && k < noCoords; ++k )
      {
         if( Tcl_ListObjIndex( interp, objv[3], k, &tp ) != TCL_OK )
            return TCL_ERROR;
         if( Tcl_GetDoubleFromObj( interp, tp, &af[k] ) != TCL_OK )
            return TCL_ERROR;
      }

      /*
         x' = af[0] * x + af[2] * y + af[4];
         y' = af[1] * x + af[3] * y + af[5];
      */
      switch( type )
      {
         case Affine:
               if( noCoords != 6 )
               {
                  Tcl_SetResult( interp, 
                        "size of list-of-coordinates must be 6", TCL_STATIC );
                  return TCL_ERROR;
               }
               break;
         case Move:
               if( noCoords != 2 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 2 (delta-x and delta-y)", TCL_STATIC );
                  return TCL_ERROR;
               }
               af[4] = af[0];
               af[5] = af[1];

               af[0] = 1.; af[2] = 0.;
               af[1] = 0.; af[3] = 1.;
               break;
         case Scale:
               if( noCoords != 3 && noCoords != 4 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 3 or 4 (center, x-scale and y-scale)", 
                        TCL_STATIC );
                  return TCL_ERROR;
               }
               else
               {
                  double x = af[0];
                  double y = af[1];
                  double scalex = af[2];
                  double scaley = (noCoords == 4) ? af[3] : scalex;
                  af[0] = scalex; af[2] = .0;     af[4] = x * (1. - scalex);
                  af[1] = .0;     af[3] = scaley; af[5] = y * (1. - scaley);
               }
               break;
         case Rotate:
               /* there seems to be some problems with the 
                  canvas without antialiasing and rotating 
                  (bizarre drawings)
               */
               if( noCoords != 3 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 3 (center and angle)", TCL_STATIC );
                  return TCL_ERROR;
               }
               else
               {
                  double x = af[0];
                  double y = af[1];
                  double w = af[2];
                  const double cw = cos( w );
                  const double sw = sin( w );

                  af[0] = cw; af[2] = -sw; af[4] = x - x * cw + y * sw;
                  af[1] = sw; af[3] =  cw; af[5] = y - x * sw - y * cw;
               }
               break;
      }

      /*
      printf( "\nitem: %p absolute: %d\n", info->item, absolute );
      printf( "before:\n" );
      {
         int k;
         double af[6];
         gnome_canvas_item_i2c_affine( info->item, af );
         for( k = 0; k < 6; k += 2 )
            printf( "%d: %f ", k, af[k] );
         printf( "\n" );
         for( k = 1; k < 6; k += 2 )
            printf( "%d: %f ", k, af[k] );
         printf( "\n" );
      }
      printf( "affine:\n" );
      for( k = 0; k < 6; k += 2 )
         printf( "%d: %f ", k, af[k] );
      printf( "\n" );
      for( k = 1; k < 6; k += 2 )
         printf( "%d: %f ", k, af[k] );
      printf( "\n" );
      */

      if( absolute )
         gnome_canvas_item_affine_absolute( info->item, af );
      else
      {
         /* Well, *I* think this is a bug in gnome: 
            affine_relative should not be the reverse of what one
            would expect. Or do I have wrong expectations? */
         if( reverse )
            gnome_canvas_item_affine_relative( info->item, af );
         else
         {
            double bf[6];
            gnome_canvas_item_i2w_affine( info->item, bf );
            gnome_canvas_item_affine_absolute( info->item, af );
            gnome_canvas_item_affine_relative( info->item, bf );
         }
      }
   }

   return TCL_OK;
}