From bf7744fb246839fb2fd727cce749722b1af4ece7 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Wed, 15 May 2002 13:47:27 +0000 Subject: * Correction d'un bug provoquant un core dump en 3.2.5a suite � la modification du code de r�paration de l'image. Un redisplay �tait planifi� lors de la destruction d'un widget. * Adaptations multiples suite au redesign complet de la gestion des images/bitmaps et fontes. * Un tag chaine vide (ou un chemin sans tag final) est �quivalent au tag 'all'. * Meilleure prise en compte de la pr�sence de l'extension GLX. Son absence ne devrait plus g�n�rer de core dump. * La commande clone ne clone plus tous les items d�sign�s par le tagOrId mais seulement le premier dans l'ordre de la display list et elle retourne l'id de ce nouvel item. * Correction d'une erreur dans itemconfigure qui retournait une info incorrecte quand on lui demandait la liste des attributs d'un field. * Les sous commandes de find/addtag ont toutes �t� remani�es d'une mani�re ou d'une autre. * Les tags peuvent d�sormais comporter un chemin permettant de pr�ciser dans quelle partie de l'arborescence les items doivent �tre recherch�s. Beaucoup de modifs. --- generic/tkZinc.c | 846 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 490 insertions(+), 356 deletions(-) (limited to 'generic/tkZinc.c') diff --git a/generic/tkZinc.c b/generic/tkZinc.c index f04d46c..da858a2 100644 --- a/generic/tkZinc.c +++ b/generic/tkZinc.c @@ -51,6 +51,7 @@ static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " #include "Track.h" #include "Transfo.h" #include "Image.h" +#include "Draw.h" #include "Color.h" #include "perfos.h" #ifdef GPC @@ -84,7 +85,7 @@ typedef struct _TagSearchExpr { #define SYMBOL_WIDTH 8 #define SYMBOL_HEIGHT 8 -static char SYMBOLS_bits[][SYMBOL_WIDTH*SYMBOL_HEIGHT/8] = { +static char SYMBOLS_BITS[][SYMBOL_WIDTH*SYMBOL_HEIGHT/8] = { { 0x18, 0x18, 0x24, 0x24, 0x5a, 0x5a, 0x81, 0xff }, { 0xff, 0x81, 0x99, 0xbd, 0xbd, 0x99, 0x81, 0xff }, { 0x18, 0x24, 0x42, 0x99, 0x99, 0x42, 0x24, 0x18 }, @@ -127,6 +128,8 @@ static Tk_Uid end_paren_uid; static Tk_Uid neg_paren_uid; static Tk_Uid tag_val_uid; static Tk_Uid neg_tag_val_uid; +static Tk_Uid dot_uid; +static Tk_Uid star_uid; static int ZnReliefParse _ANSI_ARGS_((ClientData client_data, Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *ovalue, @@ -140,6 +143,15 @@ static int ZnGradientParse _ANSI_ARGS_((ClientData client_data, Tcl_Interp *inte static Tcl_Obj *ZnGradientPrint _ANSI_ARGS_((ClientData client_data, Tk_Window tkwin, char *widget_rec, int offset, Tcl_FreeProc **free_proc)); +static int ZnImageParse _ANSI_ARGS_((ClientData client_data, Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj *ovalue, + char *widget_rec, int offset)); +static int ZnBitmapParse _ANSI_ARGS_((ClientData client_data, Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj *ovalue, + char *widget_rec, int offset)); +static Tcl_Obj *ZnImagePrint _ANSI_ARGS_((ClientData client_data, Tk_Window tkwin, + char *widget_rec, int offset, + Tcl_FreeProc **free_proc)); static Tk_CustomOption reliefOption = { ZnReliefParse, ZnReliefPrint, @@ -150,6 +162,16 @@ static Tk_CustomOption gradientOption = { ZnGradientPrint, NULL }; +static Tk_CustomOption imageOption = { + ZnImageParse, + ZnImagePrint, + NULL +}; +static Tk_CustomOption bitmapOption = { + ZnBitmapParse, + ZnImagePrint, + NULL +}; /* * Information used for argv parsing. @@ -184,8 +206,9 @@ static Tk_ConfigSpec config_specs[] = { "600", Tk_Offset(WidgetInfo, insert_on_time), 0}, {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", "2", Tk_Offset(WidgetInfo, text_info.insert_width), 0}, - {TK_CONFIG_BITMAP, "-mapdistancesymbol", "mapDistanceSymbol", "MapDistanceSymbol", - "AtcSymbol19", Tk_Offset(WidgetInfo, map_distance_symbol), TK_CONFIG_NULL_OK}, + {TK_CONFIG_CUSTOM, "-mapdistancesymbol", "mapDistanceSymbol", "MapDistanceSymbol", + "AtcSymbol19", Tk_Offset(WidgetInfo, map_distance_symbol), + TK_CONFIG_NULL_OK, &bitmapOption}, {TK_CONFIG_FONT, "-maptextfont", "mapTextFont", "MapTextFont", "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*", Tk_Offset(WidgetInfo, map_text_font), 0}, @@ -207,8 +230,8 @@ static Tk_ConfigSpec config_specs[] = { "SpeedVectorLength", "3", Tk_Offset(WidgetInfo, speed_vector_length), 0}, {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", NULL, Tk_Offset(WidgetInfo, take_focus), TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-tile", "tile", "Tile", - "", Tk_Offset(WidgetInfo, tile_name), 0}, + {TK_CONFIG_CUSTOM, "-tile", "tile", "Tile", + "", Tk_Offset(WidgetInfo, tile), 0, &imageOption}, {TK_CONFIG_BOOLEAN, "-trackmanagehistory", "trackManageHistory", "TrackManageHistory", "1", Tk_Offset(WidgetInfo, track_manage_history), 0}, {TK_CONFIG_INT, "-trackmanagedhistorysize", "trackManagedHistorySize", @@ -305,7 +328,7 @@ Tcl_GetString(Tcl_Obj *obj) * * ZnReliefParse * ZnReliefPrint -- - * Converters for the -relief option. + * Converter for the -relief option. * *---------------------------------------------------------------------- */ @@ -348,7 +371,7 @@ ZnReliefPrint(ClientData client_data, * * ZnGradientParse * ZnGradientPrint -- - * Converters for the -*color* options. + * Converter for the -*color* options. * *---------------------------------------------------------------------- */ @@ -361,17 +384,17 @@ ZnGradientParse(ClientData client_data, int offset) { ZnGradient **grad_ptr = (ZnGradient **) (widget_rec + offset); - ZnGradient *grad, *last_grad; + ZnGradient *grad, *prev_grad; char *value = Tcl_GetString(ovalue); - last_grad = *grad_ptr; + prev_grad = *grad_ptr; if ((value != NULL) && (*value != '\0')) { grad = ZnGetGradient(interp, tkwin, value); if (grad == NULL) { return ZN_ERROR; } - if (last_grad != NULL) { - ZnFreeGradient(last_grad); + if (prev_grad != NULL) { + ZnFreeGradient(prev_grad); } *grad_ptr = grad; } @@ -393,6 +416,82 @@ ZnGradientPrint(ClientData client_data, /* *---------------------------------------------------------------------- * + * ZnBitmapParse + * ZnImageParse + * ZnImagePrint -- + * Converter for the -*color* options. + * + *---------------------------------------------------------------------- + */ +static int +ZnBitmapParse(ClientData client_data, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj *ovalue, + char *widget_rec, + int offset) +{ + ZnImage *image_ptr = (ZnImage *) (widget_rec + offset); + ZnImage image, prev_image; + char *value = Tcl_GetString(ovalue); + WidgetInfo *wi = (WidgetInfo*) widget_rec; + + prev_image = *image_ptr; + if ((value != NULL) && (*value != '\0')) { + image = ZnGetBitmap(wi, value); + if (image == NULL) { + return ZN_ERROR; + } + if (prev_image != NULL) { + ZnFreeImage(prev_image); + } + *image_ptr = image; + } + return ZN_OK; +} + +static int +ZnImageParse(ClientData client_data, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj *ovalue, + char *widget_rec, + int offset) +{ + ZnImage *image_ptr = (ZnImage *) (widget_rec + offset); + ZnImage image, prev_image; + char *value = Tcl_GetString(ovalue); + WidgetInfo *wi = (WidgetInfo*) widget_rec; + + prev_image = *image_ptr; + if ((value != NULL) && (*value != '\0')) { + image = ZnGetImage(wi, value); + if (image == NULL) { + return ZN_ERROR; + } + if (prev_image != NULL) { + ZnFreeImage(prev_image); + } + *image_ptr = image; + } + return ZN_OK; +} + +static Tcl_Obj * +ZnImagePrint(ClientData client_data, + Tk_Window tkwin, + char *widget_rec, + int offset, + Tcl_FreeProc **free_proc) +{ + ZnImage image = *(ZnImage *) (widget_rec + offset); + return NewStringObj(ZnNameOfImage(image)); +} + + +/* + *---------------------------------------------------------------------- + * * ZnGetAlphaStipple -- * Need to be handled per screen/dpy toolkit wide, not on a * widget basis. @@ -490,16 +589,19 @@ ZincObjCmd(ClientData client_data, /* Main window associated with wi->dpy = Tk_Display(tkwin); wi->screen = Tk_Screen(tkwin); #ifdef GLX - if (glXQueryExtension(wi->dpy, &first_err, &first_evt)) { - int minor_op; - if (glXQueryVersion(wi->dpy, &major_op, &minor_op)) { - if ((major_op == 1) && (minor_op >= 1)) { + wi->has_glx = False; + if (XQueryExtension(wi->dpy, "GLX", &major_op, &first_evt, &first_err)) { + if (glXQueryExtension(wi->dpy, &first_err, &first_evt)) { + int minor_op; + if (glXQueryVersion(wi->dpy, &major_op, &minor_op)) { + if ((major_op == 1) && (minor_op >= 1)) { #if GLX_PRINT_CONFIG - if (wi->render) { - printf("GLX version %d.%d\n", major_op, minor_op); - } + if (wi->render) { + printf("GLX version %d.%d\n", major_op, minor_op); + } #endif - wi->has_glx = True; + wi->has_glx = True; + } } } } @@ -548,7 +650,6 @@ ZincObjCmd(ClientData client_data, /* Main window associated with wi->track_managed_history_size = 0; wi->speed_vector_length = 0; wi->tile = ZnUnspecifiedImage; - wi->tile_name = NULL; wi->id_table = (Tcl_HashTable *) ZnMalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(wi->id_table, TCL_ONE_WORD_KEYS); @@ -586,6 +687,7 @@ ZincObjCmd(ClientData client_data, /* Main window associated with wi->work_doubles = ZnListNew(8, sizeof(double)); #endif wi->work_xpts = ZnListNew(8, sizeof(XPoint)); + wi->work_strs = ZnListNew(8, sizeof(char *)); /* * Text management init. @@ -646,15 +748,17 @@ ZincObjCmd(ClientData client_data, /* Main window associated with #ifdef GLX if (wi->has_glx) { #ifdef GLX_PRINT_CONFIG - int val; + int val; #endif - int attribs[] = { GLX_RGBA, - GLX_DOUBLEBUFFER, - GLX_BUFFER_SIZE, 24, - /*GLX_BUFFER_SIZE, 32,*/ - GLX_STENCIL_SIZE, 8, - /*GLX_ALPHA_SIZE, 8,*/ - None }; + int attribs[] = { + GLX_RGBA, + GLX_DOUBLEBUFFER, + GLX_BUFFER_SIZE, 24, + /*GLX_BUFFER_SIZE, 32,*/ + GLX_STENCIL_SIZE, 8, + /*GLX_ALPHA_SIZE, 8,*/ + None + }; wi->gl_visual = glXChooseVisual(wi->dpy, XScreenNumberOfScreen(wi->screen), @@ -698,6 +802,10 @@ ZincObjCmd(ClientData client_data, /* Main window associated with } } } + else { + printf("glx not available\n"); + wi->render = 0; + } #endif } if (!wi->render) { @@ -731,7 +839,7 @@ EncodeItemPart(Item item, { if (part >= 0) { FieldSet fs; - if (!item->class->has_fields) { + if (!item->class->GetFieldSet) { return item; } fs = item->class->GetFieldSet(item); @@ -1165,6 +1273,56 @@ TagSearchEvalExpr(TagSearchExpr *expr, /* Search expression */ } +static Item +LookupGroupFromPath(Item start, + Tk_Uid *names, + int num_names) +{ + Tk_Uid name, *tags; + int count; + ZnBool recursive; + Item result, current = ZnGroupHead(start); + + if (num_names == 0) { + return start; + } + + name = names[1]; + recursive = (names[0] == star_uid); + /* printf("LookupGroupFromPath; group: %d, nom: %s, recursive: %s\n", + start->id, name, names[0]);*/ + while (current != ZN_NO_ITEM) { + if ((current->class == ZnGroup) && (current->tags)) { + tags = ZnListArray(current->tags); + count = ZnListSize(current->tags); + for (; count > 0; tags++, count--) { + if (name == *tags) { + if (num_names > 2) { + result = LookupGroupFromPath(current, names+2, num_names-2); + return result; + } + else { + return current; + } + } + } + /* + * This group doesn't match try to search depth first. + */ + if (recursive) { + result = LookupGroupFromPath(current, names, num_names); + if (result != ZN_NO_ITEM) { + return result; + } + } + } + current = current->next; + } + + return ZN_NO_ITEM; +} + + /* *-------------------------------------------------------------- * @@ -1192,16 +1350,15 @@ static int ZnTagSearchScan(WidgetInfo *wi, Tcl_Obj *tag_obj, /* Object giving tag value, NULL * is the same as 'all'. */ - TagSearch **search_var, /* Record describing tag search; + TagSearch **search_var) /* Record describing tag search; * will be initialized here. */ - Item group, /* Start group */ - ZnBool recursive) /* Does the search walk down the - * tree ? */ { char *tag; int i; TagSearch *search; - + Item group = wi->top_group; + ZnBool recursive = True; + if (tag_obj) { tag = Tcl_GetString(tag_obj); } @@ -1244,6 +1401,90 @@ ZnTagSearchScan(WidgetInfo *wi, } /* + * If a path specification exists in the tag, strip it from the + * tag and search for a matching group. + */ + if (strpbrk(tag, ".*")) { + char *path, *next; + char c; + unsigned long id; + Tcl_HashEntry *entry; + + ZnListEmpty(wi->work_strs); + recursive = False; + if ((*tag == '.') || (*tag == '*')) { + recursive = (*tag == '*'); + tag++; + } + path = tag; + while ((next = strpbrk(path, ".*"))) { + if (isdigit(*path)) { + if (path == tag) { /* Group id is ok only in first section. */ + c = *next; + *next = '\0'; + id = strtoul(path, NULL, 10); + *next = c; + group = wi->hot_item; + if ((group == ZN_NO_ITEM) || (group->id != id)) { + entry = Tcl_FindHashEntry(wi->id_table, (char *) id); + if (entry != NULL) { + group = (Item) Tcl_GetHashValue(entry); + } + else { + Tcl_AppendResult(wi->interp, "unknown group in path \"", + tag, "\"", NULL); + return ZN_ERROR; + } + } + if (group->class != ZnGroup) { + Tcl_AppendResult(wi->interp, "item is not a group in path \"", + tag, "\"", NULL); + return ZN_ERROR; + } + } + else { + Tcl_AppendResult(wi->interp, "misplaced group id in path \"", + tag, "\"", NULL); + return ZN_ERROR; + } + } + else { + ZnListAdd(wi->work_strs, recursive ? &star_uid : &dot_uid, ZnListTail); + c = *next; + *next = '\0'; + path = Tk_GetUid(path); + *next = c; + ZnListAdd(wi->work_strs, &path, ZnListTail); + } + recursive = (*next == '*'); + path = next+1; + } + + group = LookupGroupFromPath(group, + ZnListArray(wi->work_strs), + ZnListSize(wi->work_strs)); + if (group == ZN_NO_ITEM) { + Tcl_AppendResult(wi->interp, "path does not lead to a valid group\"", + tag, "\"", NULL); + return ZN_ERROR; + } + + /* + * Adjust tag to strip the path. + */ + tag = path; + search->tag_len = strlen(tag); + /* + * If the tag consist only in a path description + * assume that the tag all is implied. + */ + if (search->tag_len == 0) { + tag = all_uid; + search->tag_len = strlen(tag); + } + } + + /* * Make sure there is enough buffer to hold rewritten tags (30%). */ if ((unsigned int)search->tag_len*1.3 >= search->rewrite_buf_alloc) { @@ -1265,7 +1506,7 @@ ZnTagSearchScan(WidgetInfo *wi, * is a number then it selects the single item with the matching * identifier. */ - if (search->tag_len && isdigit(*tag)) { + if (isdigit(*tag)) { char *end; search->id = strtoul(tag, &end, 0); @@ -1276,13 +1517,6 @@ ZnTagSearchScan(WidgetInfo *wi, } /* - * For all other tags and tag expressions convert to a UID. - * This UID is kept forever, but this should be thought of - * as a cache rather than as a memory leak. - */ - search->expr->uid = Tk_GetUid(tag); - - /* * Pre-scan tag for at least one unquoted "&&" "||" "^" "!" * if not found then use string as simple tag */ @@ -1325,6 +1559,11 @@ ZnTagSearchScan(WidgetInfo *wi, search->expr->length = search->expr->index; } else { + /* + * For all other tags convert to a UID. + */ + search->expr->uid = Tk_GetUid(tag); + if (search->expr->uid == all_uid) { /* * All items match. @@ -1368,7 +1607,7 @@ static Item ZnTagSearchFirst(TagSearch *search) /* Record describing tag search */ { Item item, previous; - Tk_Uid uid, *tags; + Tk_Uid *tags; int count; /* short circuit impossible searches for null tags */ @@ -1414,7 +1653,6 @@ ZnTagSearchFirst(TagSearch *search) /* Record describing tag search */ return search->current; } - uid = search->expr->uid; item = ZnGroupHead(search->group); previous = ZN_NO_ITEM; do { @@ -1423,6 +1661,7 @@ ZnTagSearchFirst(TagSearch *search) /* Record describing tag search */ /* * Optimized single-tag search */ + Tk_Uid uid = search->expr->uid; if (item->tags) { tags = (Tk_Uid *) ZnListArray(item->tags); count = ZnListSize(item->tags); @@ -1520,7 +1759,7 @@ static Item ZnTagSearchNext(TagSearch *search) /* Record describing search in progress. */ { Item item, previous; - Tk_Uid uid, *tags; + Tk_Uid *tags; int count; if (search->over) { @@ -1600,13 +1839,13 @@ ZnTagSearchNext(TagSearch *search) /* Record describing search in progress. */ return item; } - uid = search->expr->uid; do { while (item != ZN_NO_ITEM) { if (search->type == 3) { /* * Optimized single-tag search */ + Tk_Uid uid = search->expr->uid; if (item->tags) { tags = (Tk_Uid *) ZnListArray(item->tags); count = ZnListSize(item->tags); @@ -1709,13 +1948,10 @@ ZnTagSearchDestroy(TagSearch *search) /* Record describing tag search */ int ZnItemWithTagOrId(WidgetInfo *wi, Tcl_Obj *tag_or_id, - Item group, - ZnBool recursive, Item *item, TagSearch **search_var) { - if (ZnTagSearchScan(wi, tag_or_id, search_var, - group, recursive) != ZN_OK) { + if (ZnTagSearchScan(wi, tag_or_id, search_var) != ZN_OK) { return ZN_ERROR; } *item = ZnTagSearchFirst(*search_var); @@ -1776,11 +2012,14 @@ static int FindArea(WidgetInfo *wi, Tcl_Obj *CONST args[], Tk_Uid tag_uid, - ZnBool enclosed) + ZnBool enclosed, + ZnBool recursive, + Item group) { - ZnPos pos; + ZnPos pos; ZnBBox area; - + ZnToAreaStruct ta; + if (Tcl_GetDoubleFromObj(wi->interp, args[0], &area.orig.x) == ZN_ERROR) { return ZN_ERROR; } @@ -1806,7 +2045,13 @@ FindArea(WidgetInfo *wi, area.corner.x += 1; area.corner.y += 1; - wi->top_group->class->ToArea(wi->top_group, &area, tag_uid, enclosed, False); + ta.tag_uid = tag_uid; + ta.enclosed = enclosed; + ta.in_group = group; + ta.recursive = recursive; + ta.report = False; + ta.area = &area; + wi->top_group->class->ToArea(wi->top_group, &ta); return ZN_OK; } @@ -1836,15 +2081,16 @@ FindItems(WidgetInfo *wi, TagSearch **search_var) { Tk_Uid tag_uid = NULL; - ZnBool recursive = True; int index, result; - Item item, group = wi->top_group; + Item item; + ZnBool recursive = True; + ZnPickStruct ps; static char *search_cmd_strings[] = { - "above", "all", "atpriority", "below", "closest", "enclosed", + "above", "atpriority", "below", "closest", "enclosed", "overlapping", "withtag", "withtype", NULL }; enum search_cmds { - ZN_S_ABOVE, ZN_S_ALL, ZN_S_ATPRIORITY, ZN_S_BELOW, ZN_S_CLOSEST, + ZN_S_ABOVE, ZN_S_ATPRIORITY, ZN_S_BELOW, ZN_S_CLOSEST, ZN_S_ENCLOSED, ZN_S_OVERLAPPING, ZN_S_WITHTAG, ZN_S_WITHTYPE }; @@ -1863,68 +2109,19 @@ FindItems(WidgetInfo *wi, */ case ZN_S_ABOVE: { - if ((argc < first+2) || (argc > first+4)) { - Tcl_WrongNumArgs(wi->interp, first+1, args, - "tagOrId ?inGroup? ?recursive?"); + if (argc != first+2) { + Tcl_WrongNumArgs(wi->interp, first+1, args, "tagOrId"); return ZN_ERROR; } - if (argc == first+4) { - if (Tcl_GetBooleanFromObj(wi->interp, args[first+3], - &recursive) != ZN_OK) { - return ZN_ERROR; + result = ZnItemWithTagOrId(wi, args[first+1], &item, search_var); + if (result == ZN_OK) { + if ((item != ZN_NO_ITEM) && (item->previous != ZN_NO_ITEM)) { + ZnDoItem(wi->interp, item->previous, ZN_NO_PART, tag_uid); } } - if (argc > first+2) { - result = ZnItemWithTagOrId(wi, args[first+2], wi->top_group, True, - &group, search_var); - if ((result == ZN_ERROR) || (group == ZN_NO_ITEM) || - (group->class != ZnGroup)) { - return ZN_ERROR; - } - } - result = ZnItemWithTagOrId(wi, args[first+1], group, recursive, - &item, search_var); - if ((result == ZN_OK) && - (item != ZN_NO_ITEM) && (item->previous != ZN_NO_ITEM)) { - ZnDoItem(wi->interp, item->previous, ZN_NO_PART, tag_uid); - } - } - break; - /* - * all - */ - case ZN_S_ALL: - { - if ((argc < first+1) || (argc > first+3)) { - Tcl_WrongNumArgs(wi->interp, first+1, args, "?inGroup? ?recursive?"); - return ZN_ERROR; - } - if (argc == first+3) { - if (Tcl_GetBooleanFromObj(wi->interp, args[first+2], - &recursive) != ZN_OK) { - return ZN_ERROR; - } - } - if (argc > first+1) { - result = ZnItemWithTagOrId(wi, args[first+1], wi->top_group, True, - &group, search_var); - if ((result == ZN_ERROR) || (group == ZN_NO_ITEM) || - (group->class != ZnGroup)) { - return ZN_ERROR; - } - } - - /* - * Go through the item list and collect all item ids. They - * are sorted from most visible to least visible. - */ - if (ZnTagSearchScan(wi, NULL, search_var, group, recursive) == ZN_ERROR) { + else { return ZN_ERROR; } - for (item = ZnTagSearchFirst(*search_var); - item != ZN_NO_ITEM; item = ZnTagSearchNext(*search_var)) { - ZnDoItem(wi->interp, item, ZN_NO_PART, tag_uid); - } } break; /* @@ -1932,35 +2129,22 @@ FindItems(WidgetInfo *wi, */ case ZN_S_ATPRIORITY: { - int pri; + int pri; - if ((argc < first+2) || (argc > first+4)) { - Tcl_WrongNumArgs(wi->interp, first+1, args, "pri ?inGroup? ?recursive?"); + if ((argc != first+2) && (argc != first+3)) { + Tcl_WrongNumArgs(wi->interp, first+1, args, "pri ?tagOrId?"); return ZN_ERROR; } - if (argc == first+4) { - if (Tcl_GetBooleanFromObj(wi->interp, args[first+3], - &recursive) != ZN_OK) { - return ZN_ERROR; - } - } if (Tcl_GetIntFromObj(wi->interp, args[first+1], &pri) == ZN_ERROR) { return ZN_ERROR; } - if (argc > first+2) { - result = ZnItemWithTagOrId(wi, args[first+2], wi->top_group, True, - &group, search_var); - if ((result == ZN_ERROR) || (group == ZN_NO_ITEM) || - (group->class != ZnGroup)) { - return ZN_ERROR; - } - } /* * Go through the item table and collect all items with * the given priority. */ - if (ZnTagSearchScan(wi, NULL, search_var, group, recursive) == ZN_ERROR) { + if (ZnTagSearchScan(wi, (argc == first+3) ? args[first+2] : NULL, + search_var) == ZN_ERROR) { return ZN_ERROR; } for (item = ZnTagSearchFirst(*search_var); @@ -1978,28 +2162,12 @@ FindItems(WidgetInfo *wi, { Item next; - if ((argc < first+2) || (argc > first+4)) { - Tcl_WrongNumArgs(wi->interp, first+1, args, - "tagOrId $inGroup? ?recursive?"); + if (argc != first+2) { + Tcl_WrongNumArgs(wi->interp, first+1, args, "tagOrId"); return ZN_ERROR; } - if (argc == first+4) { - if (Tcl_GetBooleanFromObj(wi->interp, args[first+3], - &recursive) != ZN_OK) { - return ZN_ERROR; - } - } - if (argc > first+2) { - result = ZnItemWithTagOrId(wi, args[first+2], wi->top_group, True, - &group, search_var); - if ((result == ZN_ERROR) || (group == ZN_NO_ITEM) || - (group->class != ZnGroup)) { - return ZN_ERROR; - } - } item = ZN_NO_ITEM; - if (ZnTagSearchScan(wi, args[first+1], search_var, - group, recursive) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[first+1], search_var) == ZN_ERROR) { return ZN_ERROR; } for (next = ZnTagSearchFirst(*search_var); @@ -2018,11 +2186,9 @@ FindItems(WidgetInfo *wi, { int halo = 1; ZnPoint p; - int part = ZN_NO_PART; - Item start_item = ZN_NO_ITEM; - - if ((argc < first+3) || (argc > first+5)) { - Tcl_WrongNumArgs(wi->interp, first+1, args, "x y ?halo? ?start?"); + + if ((argc < first+3) || (argc > first+6)) { + Tcl_WrongNumArgs(wi->interp, first+1, args, "x y ?halo? ?start?, ?recursive?"); return ZN_ERROR; } if (Tcl_GetDoubleFromObj(wi->interp, args[first+1], &p.x) == ZN_ERROR) { @@ -2039,11 +2205,25 @@ FindItems(WidgetInfo *wi, halo = 0; } } + + ps.in_group = ZN_NO_ITEM; + ps.start_item = ZN_NO_ITEM; + item = ZN_NO_ITEM; if (argc > (first+4)) { - result = ZnItemWithTagOrId(wi, args[first+4], wi->top_group, True, - &start_item, search_var); - if ((result == ZN_OK) && (start_item != ZN_NO_ITEM)) { - start_item = start_item->next; + result = ZnItemWithTagOrId(wi, args[first+4], &item, search_var); + if ((result == ZN_OK) && (item != ZN_NO_ITEM)) { + if ((item->class == ZnGroup) && !ZnGroupAtomic) { + ps.in_group = item; + } + else { + ps.in_group = item->parent; + ps.start_item = item->next; + } + } + } + if (argc > first+5) { + if (Tcl_GetBooleanFromObj(wi->interp, args[first+5], &recursive) != ZN_OK) { + return ZN_ERROR; } } /* @@ -2053,13 +2233,14 @@ FindItems(WidgetInfo *wi, * to setup the correct context before calling the Pick method * for each item. */ - wi->top_group->class->Pick(wi->top_group, &p, start_item, halo, - &item, &part); + ps.aperture = halo; + ps.point = &p; + ps.recursive = recursive; + wi->top_group->class->Pick(wi->top_group, &ps); - if (item != ZN_NO_ITEM) { - ZnDoItem(wi->interp, item, part, tag_uid); - /*printf("first %d %d\n", item->id, part);*/ - return TCL_OK; + if (ps.a_item != ZN_NO_ITEM) { + ZnDoItem(wi->interp, ps.a_item, ps.a_part, tag_uid); + /*printf("first %d %d\n", ps.a_item->id, ps.a_part);*/ } } break; @@ -2068,12 +2249,23 @@ FindItems(WidgetInfo *wi, */ case ZN_S_ENCLOSED: { - if (argc != first+5) { - Tcl_WrongNumArgs(wi->interp, first+1, args, - "x1 y1 x2 y2"); + if ((argc < first+5) || (argc > first+7)) { + Tcl_WrongNumArgs(wi->interp, first+1, args, "x1 y1 x2 y2 ?inGroup? ?recursive?"); return ZN_ERROR; } - return FindArea(wi, args+first+1, tag_uid, True); + item = wi->top_group; + if (argc > first+5) { + result = ZnItemWithTagOrId(wi, args[first+5], &item, search_var); + if ((result != ZN_OK) || (item == ZN_NO_ITEM) || (item->class != ZnGroup)) { + return ZN_ERROR; + } + } + if (argc > first+6) { + if (Tcl_GetBooleanFromObj(wi->interp, args[first+6], &recursive) != ZN_OK) { + return ZN_ERROR; + } + } + return FindArea(wi, args+first+1, tag_uid, True, recursive, item); } break; /* @@ -2081,12 +2273,23 @@ FindItems(WidgetInfo *wi, */ case ZN_S_OVERLAPPING: { - if (argc != first+5) { - Tcl_WrongNumArgs(wi->interp, first+1, args, - "x1 y1 x2 y2"); + if ((argc < first+5) || (argc > first+7)) { + Tcl_WrongNumArgs(wi->interp, first+1, args, "x1 y1 x2 y2 ?inGroup? ?recursive?"); return ZN_ERROR; } - return FindArea(wi, args+first+1, tag_uid, False); + item = wi->top_group; + if (argc > first+5) { + result = ZnItemWithTagOrId(wi, args[first+5], &item, search_var); + if ((result != ZN_OK) || (item == ZN_NO_ITEM) || (item->class != ZnGroup)) { + return ZN_ERROR; + } + } + if (argc > first+6) { + if (Tcl_GetBooleanFromObj(wi->interp, args[first+6], &recursive) != ZN_OK) { + return ZN_ERROR; + } + } + return FindArea(wi, args+first+1, tag_uid, False, recursive, item); } break; /* @@ -2094,27 +2297,11 @@ FindItems(WidgetInfo *wi, */ case ZN_S_WITHTAG: { - if ((argc < first+2) || (argc > first+4)) { - Tcl_WrongNumArgs(wi->interp, first+1, args, - "tagOrId ?inGroup? ?recursive?"); + if (argc != first+2) { + Tcl_WrongNumArgs(wi->interp, first+1, args, "tagOrId"); return ZN_ERROR; } - if (argc == first+4) { - if (Tcl_GetBooleanFromObj(wi->interp, args[first+3], - &recursive) != ZN_OK) { - return ZN_ERROR; - } - } - if (argc > first+2) { - result = ZnItemWithTagOrId(wi, args[first+2], wi->top_group, True, - &group, search_var); - if ((result == ZN_ERROR) || - (group == ZN_NO_ITEM) || (group->class != ZnGroup)) { - return ZN_ERROR; - } - } - if (ZnTagSearchScan(wi, args[first+1], search_var, - group, recursive) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[first+1], search_var) == ZN_ERROR) { return ZN_ERROR; } for (item = ZnTagSearchFirst(*search_var); @@ -2130,9 +2317,8 @@ FindItems(WidgetInfo *wi, { ItemClass cls; - if ((argc < first+2) || (argc > first+4)) { - Tcl_WrongNumArgs(wi->interp, first+1, args, - "itemType ?inGroup? ?recursive?"); + if ((argc != first+2) && (argc != first+3)) { + Tcl_WrongNumArgs(wi->interp, first+1, args, "itemType ?tagOrId?"); return ZN_ERROR; } cls = ZnLookupItemClass(Tcl_GetString(args[first+1])); @@ -2141,26 +2327,13 @@ FindItems(WidgetInfo *wi, Tcl_GetString(args[first+1]), "\"", NULL); return ZN_ERROR; } - if (argc == first+4) { - if (Tcl_GetBooleanFromObj(wi->interp, args[first+3], - &recursive) != ZN_OK) { - return ZN_ERROR; - } - } - if (argc > first+2) { - result = ZnItemWithTagOrId(wi, args[first+2], wi->top_group, True, - &group, search_var); - if ((result == ZN_ERROR) || - (group == ZN_NO_ITEM) || (group->class != ZnGroup)) { - return ZN_ERROR; - } - } /* * Go through the item table and collect all items with * the given item type. */ - if (ZnTagSearchScan(wi, NULL, search_var, group, recursive) == ZN_ERROR) { + if (ZnTagSearchScan(wi, (argc == first+3) ? args[first+2] : NULL, + search_var) == ZN_ERROR) { return ZN_ERROR; } for (item = ZnTagSearchFirst(*search_var); @@ -2247,8 +2420,7 @@ Contour(WidgetInfo *wi, GPC_DIFF, GPC_INT, GPC_UNION, GPC_XOR }; - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)){ return ZN_ERROR; } @@ -2264,7 +2436,7 @@ Contour(WidgetInfo *wi, } cmd = ops[index]; - result = ZnItemWithTagOrId(wi, args[4], wi->top_group, True, &shape, search_var); + result = ZnItemWithTagOrId(wi, args[4], &shape, search_var); if ((result == ZN_ERROR) || (shape == ZN_NO_ITEM)) { Tcl_ResetResult(wi->interp); if (ParseCoordList(wi, args[4], &points, &num_points) == ZN_ERROR) { @@ -2383,8 +2555,7 @@ Coords(WidgetInfo *wi, char *str; Tcl_Obj *l; - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { Tcl_AppendResult(wi->interp, " unknown item \"", Tcl_GetString(args[2]), "\"", NULL); @@ -2668,8 +2839,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_AppendResult(interp, "unknown item type \"", str, "\"", NULL); goto error; } - result = ZnItemWithTagOrId(wi, args[3], wi->top_group, True, - &group, &search_var); + result = ZnItemWithTagOrId(wi, args[3], &group, &search_var); if ((result == ZN_ERROR) || (group == ZN_NO_ITEM) || (group->class != ZnGroup)) { Tcl_AppendResult(interp, ", group item expected, got \"", @@ -2717,8 +2887,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "anchorxy tagOrId anchor"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM) || !item->class->has_anchors) { Tcl_AppendResult(interp, "unknown item or doesn't support anchors \"", @@ -2766,8 +2935,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Update(wi); ResetBBox(&bbox); for (i = 0; i < argc; i++) { - if (ZnTagSearchScan(wi, args[i], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[i], &search_var) == ZN_ERROR) { goto error; } for (item = ZnTagSearchFirst(search_var); @@ -2929,13 +3097,11 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "chggroup tagOrIg group ?adjustTransform?"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } - result = ZnItemWithTagOrId(wi, args[3], wi->top_group, True, - &grp, &search_var); + result = ZnItemWithTagOrId(wi, args[3], &grp, &search_var); if ((result == ZN_ERROR) || (grp == ZN_NO_ITEM)|| (grp->class != ZnGroup)) { goto error; } @@ -2982,22 +3148,19 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "clone tagOrId ?option value ...?"); goto error; } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); + if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } argc -= 3; args += 3; - l = Tcl_GetObjResult(interp); - for (item = ZnTagSearchFirst(search_var); - item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) { - item2 = ITEM.CloneItem(item); - ITEM.InsertItem(item2, item->parent, ZN_NO_ITEM, True); - if (ITEM.ConfigureItem(item2, ZN_NO_PART, argc, args, False) == ZN_ERROR) { - goto error; - } - Tcl_ListObjAppendElement(interp, l, NewLongObj(item2->id)); + item2 = ITEM.CloneItem(item); + ITEM.InsertItem(item2, item->parent, ZN_NO_ITEM, True); + if (ITEM.ConfigureItem(item2, ZN_NO_PART, argc, args, False) == ZN_ERROR) { + goto error; } + l = NewLongObj(item2->id); + Tcl_SetObjResult(interp, l); } break; /* @@ -3088,8 +3251,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "cursor tagOrId ?field? index"); goto error; } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } if (argc == 5) { @@ -3136,8 +3298,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "dchars tagOrId ?field? first ?last?"); goto error; } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } if (argc == 6) { @@ -3224,8 +3385,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ else { tag = Tk_GetUid(Tcl_GetString(args[2])); } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } for (item = ZnTagSearchFirst(search_var); @@ -3311,8 +3471,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ wi->focus_field = ZN_NO_PART; break; } - if (ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var) == ZN_ERROR) { + if (ZnItemWithTagOrId(wi, args[2], &item, &search_var) == ZN_ERROR) { goto error; } if (argc == 4) { @@ -3356,8 +3515,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "gettags tagOrId"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } @@ -3402,8 +3560,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "group tagOrId"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } @@ -3429,8 +3586,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "hasanchors tagOrId"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } @@ -3447,12 +3603,11 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "hasfields tagOrId"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } - l = NewBooleanObj(item->class->has_fields?1:0); + l = NewBooleanObj(item->class->GetFieldSet?1:0); Tcl_SetObjResult(interp, l); } break; @@ -3468,8 +3623,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "hastag tagOrId tag"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } @@ -3502,8 +3656,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "index tagOrId ?field? string"); goto error; } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } if (argc == 5) { @@ -3548,8 +3701,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "insert tagOrId ?field? before string"); goto error; } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } if (argc == 6) { @@ -3606,8 +3758,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "itemcget tagOrId ?field? option"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } @@ -3642,8 +3793,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ "itemconfigure tagOrId ?field? option value ?option value? ..."); goto error; } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } if ((argc > 3) && (Tcl_GetString(args[3])[0] != '-')) { @@ -3664,14 +3814,29 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ for (item = ZnTagSearchFirst(search_var); item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) { if (argc < 2) { - result = ZnAttributesInfo(wi, item, item->class->attr_desc, argc, args); + if (field == ZN_NO_PART) { + result = ZnAttributesInfo(wi, item, item->class->attr_desc, argc, args); + } + else if (item->class->GetFieldSet) { + FieldSet fs = item->class->GetFieldSet(item); + if (field < FIELD.NumFields(fs)) { + result = ZnAttributesInfo(wi, FIELD.GetFieldStruct(fs, field), + FIELD.attr_desc, argc, args); + } + else { + Tcl_AppendResult(interp, "field index out of bound", NULL); + goto error; + } + } + else { + Tcl_AppendResult(interp, "the item does not support fields", NULL); + goto error; + } + goto done; } else { result = ITEM.ConfigureItem(item, field, argc, args, False); } - if (argc < 2) { - goto done; - } if (result == ZN_ERROR) { goto error; } @@ -3690,8 +3855,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ goto error; } if (argc == 4) { - if (ZnTagSearchScan(wi, args[3], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[3], &search_var) == ZN_ERROR) { goto error; } for (item = ZnTagSearchFirst(search_var); @@ -3704,8 +3868,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ goto error; } } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } item = ZnTagSearchFirst(search_var); @@ -3772,8 +3935,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "numparts tagOrId"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } @@ -3805,8 +3967,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ /* * Find the topmost item with the tag. */ - if (ZnTagSearchScan(wi, args[3], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[3], &search_var) == ZN_ERROR) { goto error; } mark = ZnTagSearchFirst(search_var); @@ -3816,8 +3977,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ goto error; } } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } item = ZnTagSearchFirst(search_var); @@ -3852,8 +4012,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ argc -= 2; args += 2; for (i = 0; i < argc; i++) { - if (ZnTagSearchScan(wi, args[i], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[i], &search_var) == ZN_ERROR) { goto error; } for (item = ZnTagSearchFirst(search_var); @@ -3863,7 +4022,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ } if (wi->binding_table != NULL) { Tk_DeleteAllBindings(wi->binding_table, (ClientData) item); - if (item->class->has_fields) { + if (item->class->GetFieldSet) { num_fields = FIELD.NumFields(item->class->GetFieldSet(item)); for (j = 0; j < num_fields; j++) { Tk_DeleteAllBindings(wi->binding_table, @@ -3906,8 +4065,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ t = (ZnTransfo *) Tcl_GetHashValue(entry); } else { - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } } @@ -3948,8 +4106,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ t = (ZnTransfo *) Tcl_GetHashValue(entry); } else { - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } } @@ -3983,8 +4140,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ goto error; } if (argc >= 4) { - if (ZnTagSearchScan(wi, args[3], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[3], &search_var) == ZN_ERROR) { goto error; } for (item = ZnTagSearchFirst(search_var); @@ -4159,14 +4315,12 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ } if (argc == 5) { - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &from, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &from, &search_var); if ((result == ZN_ERROR) || (from == ZN_NO_ITEM)) { goto error; } } - result = ZnItemWithTagOrId(wi, args[argc-2], wi->top_group, True, - &to, &search_var); + result = ZnItemWithTagOrId(wi, args[argc-2], &to, &search_var); if ((result == ZN_ERROR) || (to == ZN_NO_ITEM)) { Tcl_HashEntry *e; /* @@ -4225,8 +4379,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ t = (ZnTransfo *) Tcl_GetHashValue(entry); } else { - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } } @@ -4262,8 +4415,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ t = (ZnTransfo *) Tcl_GetHashValue(entry); } else { - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } } @@ -4295,8 +4447,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ goto error; } t = (ZnTransfo *) Tcl_GetHashValue(entry); - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } for (item = ZnTagSearchFirst(search_var); @@ -4317,8 +4468,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "tsave tagOrId tName ?invert?"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == ZN_ERROR) || (item == ZN_NO_ITEM)) { goto error; } @@ -4352,8 +4502,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "type tagOrId"); goto error; } - result = ZnItemWithTagOrId(wi, args[2], wi->top_group, True, - &item, &search_var); + result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if (result == ZN_ERROR) { goto error; } @@ -4375,8 +4524,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, " vertexat tagOrId x y"); goto error; } - if (ZnTagSearchScan(wi, args[2], &search_var, - wi->top_group, True) == ZN_ERROR) { + if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) { goto error; } for (item = ZnTagSearchFirst(search_var); @@ -4425,33 +4573,6 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ /* - ********************************************************************************** - * - * TileChange -- - * - ********************************************************************************** - */ -static void -TileChange(ClientData client_data, - int x, - int y, - int width, - int height, - int image_width, - int image_height) -{ - WidgetInfo *wi = (WidgetInfo *) client_data; - ZnBBox bbox; - - InvalidateImage(wi->tile_name); - bbox.orig.x = bbox.orig.y = 0; - bbox.corner.x = wi->width; - bbox.corner.y = wi->height; - ZnDamage(wi, &bbox); -} - - -/* *---------------------------------------------------------------------- * * Configure -- @@ -4555,11 +4676,6 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */ } if (CONFIG_PROBE(TILE_SPEC)) { - if (wi->tile != ZnUnspecifiedImage) { - Tk_FreeImage(wi->tile); - } - ValidateImage(wi, wi, wi->tile_name, TileChange, - &wi->tile, "zinc option -tile"); bbox.orig.x = bbox.orig.y = 0; bbox.corner.x = wi->width; bbox.corner.y = wi->height; @@ -4952,7 +5068,7 @@ DoEvent(WidgetInfo *wi, bind_part = ((wi->current_part != ZN_NO_PART) && item->class->IsSensitive(item, part) && (wi->current_item->class->num_parts || - wi->current_item->class->has_fields)); + wi->current_item->class->GetFieldSet)); /* * This is needed to avoid generating enter and leave * event on items when crossing a field boundary inside @@ -5128,14 +5244,23 @@ PickCurrentItem(WidgetInfo *wi, * object, so the check for closest item can be skipped. */ if (wi->pick_event.type != LeaveNotify) { - ZnPoint p; - ZnReal dist; - + ZnPickStruct ps; + ZnReal dist; + ZnPoint p; + p.x = wi->pick_event.xcrossing.x; p.y = wi->pick_event.xcrossing.y; - dist = wi->top_group->class->Pick(wi->top_group, &p, NULL, wi->pick_aperture, - &wi->new_item, &wi->new_part); - if (dist != 0.0) { + ps.point = &p; + ps.in_group = ZN_NO_ITEM; + ps.start_item = ZN_NO_ITEM; + ps.aperture = wi->pick_aperture; + ps.recursive = True; + dist = wi->top_group->class->Pick(wi->top_group, &ps); + if (dist == 0.0) { + wi->new_item = ps.a_item; + wi->new_part = ps.a_part; + } + else { wi->new_item = ZN_NO_ITEM; wi->new_part = ZN_NO_PART; } @@ -5577,7 +5702,7 @@ Destroy(char *mem_ptr) /* Info about the widget. */ unsigned int num; Tcl_HashSearch search; Tcl_HashEntry *entry; - + /*printf("Destroy begining\n");*/ /* * This procedure could be invoked either because the window was @@ -5602,7 +5727,15 @@ Destroy(char *mem_ptr) /* Info about the widget. */ fprintf(stderr, "Item count before cleanup: %d\n", wi->num_items); ITEM.DestroyItem(wi->top_group); fprintf(stderr, "Remaining item count: %d\n", wi->num_items); - + /* + * Remove the redisplay scheduled by the cleanup. + * It will fire when the widget will be gone and + * will corrupt memory. + */ + if (wi->update_pending) { + Tcl_CancelIdleCall(Redisplay, (ClientData) wi); + } + for (num = 0; num < NUM_ALPHA_STEPS; num++) { if (wi->alpha_stipples[num] != None) { Tk_FreeBitmap(wi->dpy, wi->alpha_stipples[num]); @@ -5610,10 +5743,10 @@ Destroy(char *mem_ptr) /* Info about the widget. */ } Tcl_DeleteHashTable(wi->id_table); - ZnFree(wi->id_table); + /* - * Free the transform table contents before the table. + * Free the transform table contents. */ entry = Tcl_FirstHashEntry(wi->t_table, &search); while (entry != NULL) { @@ -5629,7 +5762,7 @@ Destroy(char *mem_ptr) /* Info about the widget. */ /* Free the tile */ if (wi->tile != ZnUnspecifiedImage) { - Tk_FreeImage(wi->tile); + ZnFreeImage(wi->tile); wi->tile = ZnUnspecifiedImage; } @@ -5671,6 +5804,7 @@ Destroy(char *mem_ptr) /* Info about the widget. */ ZnListFree(wi->work_doubles); #endif ZnListFree(wi->work_xpts); + ZnListFree(wi->work_strs); FreeChrono(wi->total_draw_chrono); FreeChrono(wi->this_draw_chrono); @@ -5880,8 +6014,7 @@ Repair(WidgetInfo *wi) bbox.corner.x = int_width; bbox.corner.y = int_height; - RenderTile(wi, GetImageTexture(wi->win, wi->tile_name, wi->tile), - NULL, NULL, NULL, (ZnPoint *) &bbox); + ZnRenderTile(wi, wi->tile, NULL, NULL, NULL, (ZnPoint *) &bbox); } wi->top_group->class->Render(wi->top_group); @@ -5918,8 +6051,8 @@ Repair(WidgetInfo *wi) p[0] = p[4]; p[3].x = p[2].x = int_width - wi->highlight_width; p[2].y = p[1].y = int_height - wi->highlight_width; - RenderPolygonRelief(wi, wi->relief, wi->relief_grad, - False, p, 5, wi->border_width); + ZnRenderPolygonRelief(wi, wi->relief, wi->relief_grad, + False, p, 5, wi->border_width); } #ifdef GLX_DAMAGE glEnable(GL_SCISSOR_TEST); @@ -5971,7 +6104,7 @@ Repair(WidgetInfo *wi) } else { values.fill_style = FillTiled; - values.tile = GetImagePixmap(wi->win, wi->tile_name, wi->tile, NULL); + values.tile = ZnImagePixmap(wi->tile, NULL); values.ts_x_origin = values.ts_y_origin = 0; XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin, @@ -6011,8 +6144,7 @@ Repair(WidgetInfo *wi) r.x = r.y = wi->highlight_width; r.width = int_width - 2*wi->highlight_width; r.height = int_height - 2*wi->highlight_width; - DrawRectangleRelief(wi, wi->relief, wi->relief_grad, - &r, wi->border_width); + ZnDrawRectangleRelief(wi, wi->relief, wi->relief_grad, &r, wi->border_width); wi->draw_buffer = save; } if (wi->highlight_width > 0) { @@ -6140,10 +6272,10 @@ InitZinc(Tcl_Interp *interp) { /* * Add the specific bitmaps. */ - for (i = 0; i < sizeof(SYMBOLS_bits)/(SYMBOL_WIDTH*SYMBOL_HEIGHT/8); i++) { + for (i = 0; i < sizeof(SYMBOLS_BITS)/(SYMBOL_WIDTH*SYMBOL_HEIGHT/8); i++) { sprintf(name, "AtcSymbol%d", i+1); Tk_DefineBitmap(interp, Tk_GetUid(name), - SYMBOLS_bits[i], SYMBOL_WIDTH, SYMBOL_HEIGHT); + SYMBOLS_BITS[i], SYMBOL_WIDTH, SYMBOL_HEIGHT); } for (i = 0; i < NUM_ALPHA_STEPS; i++) { @@ -6198,6 +6330,8 @@ InitZinc(Tcl_Interp *interp) { neg_paren_uid = Tk_GetUid("!("); tag_val_uid = Tk_GetUid("!!"); neg_tag_val_uid = Tk_GetUid("!"); + dot_uid = Tk_GetUid("."); + star_uid = Tk_GetUid("*"); inited = True; } -- cgit v1.1