From 343a12a735abd601b4cd5c087be337a51851adb6 Mon Sep 17 00:00:00 2001 From: tmh Date: Fri, 12 Oct 2001 13:30:31 +0000 Subject: implementation of TIP 63 (accepted) -compound option to menu items. --- ChangeLog | 21 ++++++ doc/menu.n | 13 +++- generic/tkMenu.c | 14 +++- generic/tkMenu.h | 14 +++- generic/tkMenubutton.c | 4 +- generic/tkMenubutton.h | 17 ++--- mac/tkMacDefault.h | 3 +- mac/tkMacMenu.c | 174 ++++++++++++++++++++++++++++++++++++++++++------- mac/tkMacMenubutton.c | 47 ++++++++++--- tests/menu.test | 39 ++++++++++- unix/tkUnixDefault.h | 3 +- unix/tkUnixMenu.c | 165 ++++++++++++++++++++++++++++++++++++++++------ win/makefile.vc | 11 ++-- win/tkWinDefault.h | 3 +- win/tkWinMenu.c | 168 ++++++++++++++++++++++++++++++++++++++++------- win/tkWinWm.c | 6 +- 16 files changed, 598 insertions(+), 104 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca1a05f..9ec92b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2001-10-12 Todd M. Helfter + + * ChangeLog: + * doc/menu.n: + * generic/tkMenu.c: + * generic/tkMenu.h: + * generic/tkMenubutton.c: + * generic/tkMenubutton.h: + * mac/tkMacDefault.h: + * mac/tkMacMenu.c: + * mac/tkMacMenubutton.c: + * tests/menu.test: + * unix/tkUnixDefault.h: + * unix/tkUnixMenu.c: + * win/makefile.vc: + * win/tkWinDefault.h: + * win/tkWinMenu.c: + * win/tkWinWm.c: Implementation of TIP #63, the addition of + a -compound option to menu entries allowing text and an image to + be displayed at the same time. + 2001-10-09 Jeff Hobbs * library/console.tcl: added more smarts extracted from tkcon to diff --git a/doc/menu.n b/doc/menu.n index 352dbc4..0bdd2f1 100644 --- a/doc/menu.n +++ b/doc/menu.n @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: menu.n,v 1.5 2001/08/01 16:21:11 dgp Exp $ +'\" RCS: @(#) $Id: menu.n,v 1.6 2001/10/12 13:30:31 tmh Exp $ '\" .so man.macros .TH menu n 4.1 Tk "Tk Built-In Commands" @@ -427,6 +427,17 @@ menu. Specifies a Tcl command to execute when the menu entry is invoked. Not available for separator or tear-off entries. .TP +.VS 8.4 +.fB\-compound \fIvalue\fR +Specifies whether the menu entry should display both an image and text, +and if so, where the image should be placed relative to the text. +Valid values for this option are \fBbottom\fR, \fBcenter\fR, +\fBleft\fR, \fBnone\fR, \fBright\fR and \fBtop\fR. The default value +is \fBnone\fR, meaning that the button will display either an image or +text, depending on the values of the \fB\-image\fR and \fB\-bitmap\fR +options. +.VE +.TP \fB\-font \fIvalue\fR Specifies the font to use when drawing the label or accelerator string in this entry. diff --git a/generic/tkMenu.c b/generic/tkMenu.c index 84e338d..ff50130 100644 --- a/generic/tkMenu.c +++ b/generic/tkMenu.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenu.c,v 1.12 2001/09/14 20:35:58 andreas_kupries Exp $ + * RCS: @(#) $Id: tkMenu.c,v 1.13 2001/10/12 13:30:31 tmh Exp $ */ /* @@ -108,6 +108,15 @@ char *tkMenuStateStrings[] = {"active", "normal", "disabled", (char *) NULL}; static char *menuEntryTypeStrings[] = {"cascade", "checkbutton", "command", "radiobutton", "separator", (char *) NULL}; +/* + * The following table defines the legal values for the -compound option. + * It is used with the "enum compound" declaration in tkMenu.h + */ + +static char *compoundStrings[] = { + "bottom", "center", "left", "none", "right", "top", (char *) NULL +}; + Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = { {TK_OPTION_BORDER, "-activebackground", (char *) NULL, (char *) NULL, DEF_MENU_ENTRY_ACTIVE_BG, Tk_Offset(TkMenuEntry, activeBorderPtr), -1, @@ -130,6 +139,9 @@ Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = { {TK_OPTION_STRING, "-command", (char *) NULL, (char *) NULL, DEF_MENU_ENTRY_COMMAND, Tk_Offset(TkMenuEntry, commandPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound", + DEF_MENU_ENTRY_COMPOUND, -1, Tk_Offset(TkMenuEntry, compound), 0, + (ClientData) compoundStrings, 0}, {TK_OPTION_FONT, "-font", (char *) NULL, (char *) NULL, DEF_MENU_ENTRY_FONT, Tk_Offset(TkMenuEntry, fontPtr), -1, TK_OPTION_NULL_OK}, diff --git a/generic/tkMenu.h b/generic/tkMenu.h index 9ec63f4..9553bc0 100644 --- a/generic/tkMenu.h +++ b/generic/tkMenu.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenu.h,v 1.5 1999/04/16 01:51:19 stanton Exp $ + * RCS: @(#) $Id: tkMenu.h,v 1.6 2001/10/12 13:30:31 tmh Exp $ */ #ifndef _TKMENU @@ -39,6 +39,15 @@ typedef struct TkMenuPlatformData_ *TkMenuPlatformData; typedef struct TkMenuPlatformEntryData_ *TkMenuPlatformEntryData; /* + * Legal values for the "compound" field of TkMenuEntry and TkMenuButton records. + */ + +enum compound { + COMPOUND_BOTTOM, COMPOUND_CENTER, COMPOUND_LEFT, COMPOUND_NONE, + COMPOUND_RIGHT, COMPOUND_TOP +}; + +/* * One of the following data structures is kept for each entry of each * menu managed by this file: */ @@ -115,6 +124,9 @@ typedef struct TkMenuEntry { * entry. */ int labelWidth; /* Number of pixels to allow for displaying * labels in menu entries. */ + int compound; /* Value of -compound option; specifies whether + * the entry should show both an image and + * text, and, if so, how. */ /* * Information used to implement this entry's action: diff --git a/generic/tkMenubutton.c b/generic/tkMenubutton.c index 815837f..28d82a9 100644 --- a/generic/tkMenubutton.c +++ b/generic/tkMenubutton.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenubutton.c,v 1.7 2001/08/29 23:22:24 hobbs Exp $ + * RCS: @(#) $Id: tkMenubutton.c,v 1.8 2001/10/12 13:30:31 tmh Exp $ */ #include "tkMenubutton.h" @@ -38,7 +38,7 @@ static char *stateStrings[] = { /* * The following table defines the legal values for the -compound option. - * It is used with the "enum compound" declaration in tkButton.h + * It is used with the "enum compound" declaration in tkMenuButton.h */ static char *compoundStrings[] = { diff --git a/generic/tkMenubutton.h b/generic/tkMenubutton.h index a4a8a05..332d770 100644 --- a/generic/tkMenubutton.h +++ b/generic/tkMenubutton.h @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenubutton.h,v 1.7 2001/05/21 14:07:33 tmh Exp $ + * RCS: @(#) $Id: tkMenubutton.h,v 1.8 2001/10/12 13:30:31 tmh Exp $ */ #ifndef _TKMENUBUTTON @@ -19,21 +19,16 @@ #include "tkInt.h" #endif +#ifndef _TKMENU +#include "tkMenu.h" +#endif + #ifdef BUILD_tk # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT #endif /* - * Legal values for the "compound" field of TkButton records. - */ - -enum compound { - COMPOUND_BOTTOM, COMPOUND_CENTER, COMPOUND_LEFT, COMPOUND_NONE, - COMPOUND_RIGHT, COMPOUND_TOP -}; - -/* * Legal values for the "orient" field of TkMenubutton records. */ @@ -172,7 +167,7 @@ typedef struct { */ int compound; /* Value of -compound option; specifies whether - * the button should show both an image and + * the menubutton should show both an image and * text, and, if so, how. */ enum direction direction; /* Direction for where to pop the menu. diff --git a/mac/tkMacDefault.h b/mac/tkMacDefault.h index aaa5082..269bff2 100644 --- a/mac/tkMacDefault.h +++ b/mac/tkMacDefault.h @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacDefault.h,v 1.10 2001/09/26 21:36:19 pspjuth Exp $ + * RCS: @(#) $Id: tkMacDefault.h,v 1.11 2001/10/12 13:30:31 tmh Exp $ */ #ifndef _TKMACDEFAULT @@ -250,6 +250,7 @@ #define DEF_MENU_ENTRY_BITMAP None #define DEF_MENU_ENTRY_COLUMN_BREAK "0" #define DEF_MENU_ENTRY_COMMAND (char *) NULL +#define DEF_MENU_ENTRY_COMPOUND "none" #define DEF_MENU_ENTRY_FG (char *) NULL #define DEF_MENU_ENTRY_FONT (char *) NULL #define DEF_MENU_ENTRY_HIDE_MARGIN "0" diff --git a/mac/tkMacMenu.c b/mac/tkMacMenu.c index 152bb1e..44897c9 100644 --- a/mac/tkMacMenu.c +++ b/mac/tkMacMenu.c @@ -8,12 +8,12 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacMenu.c,v 1.19 2001/08/01 16:21:11 dgp Exp $ + * RCS: @(#) $Id: tkMacMenu.c,v 1.20 2001/10/12 13:30:31 tmh Exp $ */ #include "tkMacInt.h" -#include "tkMenuButton.h" #include "tkMenu.h" +#include "tkMenuButton.h" #include "tkColor.h" #include "tkMacInt.h" #undef Status @@ -707,9 +707,9 @@ GetEntryText( Tcl_DStringInit(dStringPtr); if (mePtr->type == TEAROFF_ENTRY) { Tcl_DStringAppend(dStringPtr, "(Tear-off)", -1); - } else if (mePtr->imagePtr != NULL) { + } else if ((mePtr->imagePtr != NULL) && (mePtr->compound == COMPOUND_NONE)) { Tcl_DStringAppend(dStringPtr, "(Image)", -1); - } else if (mePtr->bitmapPtr != NULL) { + } else if ((mePtr->bitmapPtr != NULL) && (mePtr->compound == COMPOUND_NONE)) { Tcl_DStringAppend(dStringPtr, "(Pixmap)", -1); } else if (mePtr->labelPtr == NULL || mePtr->labelLength == 0) { /* @@ -3945,39 +3945,117 @@ DrawMenuEntryLabel( int width, /* width of entry */ int height) /* height of entry */ { - int baseline; int indicatorSpace = mePtr->indicatorSpace; int leftEdge = x + indicatorSpace; int imageHeight, imageWidth; + int textHeight, textWidth; + int haveImage = 0, haveText = 0; + int imageXOffset = 0, imageYOffset = 0; + int textXOffset = 0, textYOffset = 0; + + /* + * Work out what we will need to draw first. + */ + + if (mePtr->image != NULL) { + Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); + haveImage = 1; + } else if (mePtr->bitmapPtr != NULL) { + Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); + Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight); + haveImage = 1; + } + if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { + if (mePtr->labelLength > 0) { + Tcl_DString itemTextDString; + textHeight = fmPtr->linespace; + GetEntryText(mePtr, &itemTextDString); + textWidth = Tk_TextWidth(tkfont, + Tcl_DStringValue(&itemTextDString), + Tcl_DStringLength(&itemTextDString)); + Tcl_DStringFree(&itemTextDString); + haveText = 1; + } + } + + /* + * Now work out what the relative positions are. + */ + + if (haveImage && haveText) { + int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth); + switch ((enum compound) mePtr->compound) { + case COMPOUND_TOP: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = imageHeight/2 + 2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = -textHeight/2; + break; + } + case COMPOUND_BOTTOM: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = -imageHeight/2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = textHeight/2 + 2; + break; + } + case COMPOUND_LEFT: { + textXOffset = imageWidth + 2; + textYOffset = 0; + imageXOffset = 0; + imageYOffset = 0; + break; + } + case COMPOUND_RIGHT: { + textXOffset = 0; + textYOffset = 0; + imageXOffset = textWidth + 2; + imageYOffset = 0; + break; + } + case COMPOUND_CENTER: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = 0; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = 0; + break; + } + case COMPOUND_NONE: {break;} + } + } else { + textXOffset = 0; + textYOffset = 0; + imageXOffset = 0; + imageYOffset = 0; + } /* - * Draw label or bitmap or image for entry. + * Draw label and/or bitmap or image for entry. */ - baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; if (mePtr->image != NULL) { Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); if ((mePtr->selectImage != NULL) && (mePtr->entryFlags & ENTRY_SELECTED)) { Tk_RedrawImage(mePtr->selectImage, 0, 0, - imageWidth, imageHeight, d, leftEdge, - (int) (y + (mePtr->height - imageHeight)/2)); + imageWidth, imageHeight, d, leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); } else { Tk_RedrawImage(mePtr->image, 0, 0, imageWidth, - imageHeight, d, leftEdge, - (int) (y + (mePtr->height - imageHeight)/2)); + imageHeight, d, leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); } } else if (mePtr->bitmapPtr != NULL) { - int width, height; Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - Tk_SizeOfBitmap(menuPtr->display, - bitmap, &width, &height); XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, - (unsigned) width, (unsigned) height, leftEdge, - (int) (y + (mePtr->height - height)/2), 1); - } else { + (unsigned) imageWidth, (unsigned) imageHeight, + leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1); + } + if ((mePtr->compound != COMPOUND_NONE) || !haveImage) { if (mePtr->labelLength > 0) { Tcl_DString itemTextDString, convertedTextDString; + int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; GetEntryText(mePtr, &itemTextDString); @@ -3987,7 +4065,8 @@ DrawMenuEntryLabel( exactly is going on, this will have to do: */ TkMacSetUpGraphicsPort(gc); - MoveTo((short) leftEdge, (short) baseline); + MoveTo((short) leftEdge + textXOffset, + (short) baseline + textYOffset); Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&itemTextDString), Tcl_DStringLength(&itemTextDString), &convertedTextDString); DrawText(Tcl_DStringValue(&convertedTextDString), 0, @@ -4011,8 +4090,8 @@ DrawMenuEntryLabel( } else if ((mePtr->image != NULL) && (menuPtr->disabledImageGC != None)) { XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC, - leftEdge, - (int) (y + (mePtr->height - imageHeight)/2), + leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), (unsigned) imageWidth, (unsigned) imageHeight); } } @@ -4090,25 +4169,72 @@ GetMenuLabelGeometry( * portion */ { TkMenu *menuPtr = mePtr->menuPtr; + int haveImage = 0, haveText = 0; if (mePtr->image != NULL) { Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr); + haveImage = 1; } else if (mePtr->bitmapPtr != NULL) { Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr); + haveImage = 1; } else { - *heightPtr = fmPtr->linespace; + *heightPtr = 0; + *widthPtr = 0; + } + if (haveImage && (mePtr->compound == COMPOUND_NONE)) { + /* We don't care about the text in this case */ + } else { + /* Either it is compound or we don't have an image */ if (mePtr->labelPtr != NULL) { Tcl_DString itemTextDString; - + int textWidth; GetEntryText(mePtr, &itemTextDString); - *widthPtr = Tk_TextWidth(tkfont, + textWidth = Tk_TextWidth(tkfont, Tcl_DStringValue(&itemTextDString), Tcl_DStringLength(&itemTextDString)); Tcl_DStringFree(&itemTextDString); + + if ((mePtr->compound != COMPOUND_NONE) && haveImage) { + switch ((enum compound) mePtr->compound) { + case COMPOUND_TOP: + case COMPOUND_BOTTOM: { + if (textWidth > *widthPtr) { + *widthPtr = textWidth; + } + /* Add text and padding */ + *heightPtr += fmPtr->linespace + 2; + break; + } + case COMPOUND_LEFT: + case COMPOUND_RIGHT: { + if (fmPtr->linespace > *heightPtr) { + *heightPtr = fmPtr->linespace; + } + /* Add text and padding */ + *widthPtr += textWidth + 2; + break; + } + case COMPOUND_CENTER: { + if (fmPtr->linespace > *heightPtr) { + *heightPtr = fmPtr->linespace; + } + if (textWidth > *widthPtr) { + *widthPtr = textWidth; + } + break; + } + case COMPOUND_NONE: {break;} + } } else { - *widthPtr = 0; + /* We don't have an image or we're not compound */ + *heightPtr = fmPtr->linespace; + *widthPtr = textWidth; + } + } else { + /* An empty entry still has this height */ + *heightPtr = fmPtr->linespace; } } *heightPtr += 1; diff --git a/mac/tkMacMenubutton.c b/mac/tkMacMenubutton.c index 1acc521..7cdb16a 100644 --- a/mac/tkMacMenubutton.c +++ b/mac/tkMacMenubutton.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacMenubutton.c,v 1.8 2001/05/21 14:07:33 tmh Exp $ + * RCS: @(#) $Id: tkMacMenubutton.c,v 1.9 2001/10/12 13:30:31 tmh Exp $ */ #include "tkMenubutton.h" @@ -396,7 +396,7 @@ void TkpComputeMenuButtonGeometry(mbPtr) register TkMenuButton *mbPtr; /* Widget record for menu button. */ { - int width, height, mm, pixels; + int width=0, height=0, textwidth=0, textheight=0, mm, pixels, noimage=0; mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth; if (mbPtr->image != None) { @@ -416,23 +416,54 @@ TkpComputeMenuButtonGeometry(mbPtr) height = mbPtr->height; } } else { + noimage=1; + } + + if ( noimage || mbPtr->compound != COMPOUND_NONE ) { Tk_FreeTextLayout(mbPtr->textLayout); mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text, -1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth, &mbPtr->textHeight); - width = mbPtr->textWidth; - height = mbPtr->textHeight; + textwidth = mbPtr->textWidth; + textheight = mbPtr->textHeight; if (mbPtr->width > 0) { - width = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, "0", 1); + textwidth = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, "0", 1); } if (mbPtr->height > 0) { Tk_FontMetrics fm; Tk_GetFontMetrics(mbPtr->tkfont, &fm); - height = mbPtr->height * fm.linespace; + textheight = mbPtr->height * fm.linespace; + } + textwidth += 2*mbPtr->padX; + textheight += 2*mbPtr->padY; + } + + switch ((enum compound) mbPtr->compound) { + case COMPOUND_TOP: + case COMPOUND_BOTTOM: { + height += textheight + mbPtr->padY; + width = (width > textwidth ? width : textwidth); + break; + } + case COMPOUND_LEFT: + case COMPOUND_RIGHT: { + height = (height > textheight ? height : textheight); + width += textwidth + mbPtr->padX; + break; + } + case COMPOUND_CENTER: { + height = (height > textheight ? height : textheight); + width = (width > textwidth ? width : textwidth); + break; + } + case COMPOUND_NONE: { + if (noimage) { + height = textheight; + width = textwidth; + } + break; } - width += 2*mbPtr->padX; - height += 2*mbPtr->padY; } if (mbPtr->indicatorOn) { diff --git a/tests/menu.test b/tests/menu.test index a298e79..273b133 100644 --- a/tests/menu.test +++ b/tests/menu.test @@ -5,7 +5,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: menu.test,v 1.8 2001/08/30 01:51:42 hobbs Exp $ +# RCS: @(#) $Id: menu.test,v 1.9 2001/10/12 13:30:31 tmh Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { source [file join [pwd] [file dirname [info script]] defs.tcl] @@ -732,7 +732,7 @@ test menu-3.36 {MenuWidgetCmd procedure, "entryconfigure" option} { menu .m1 .m1 add command -label "test" list [catch {llength [.m1 entryconfigure 1]} msg] $msg [destroy .m1] -} {0 14 {}} +} {0 15 {}} test menu-3.37 {MenuWidgetCmd procedure, "entryconfigure" option} { catch {destroy .m1} menu .m1 @@ -2426,6 +2426,41 @@ test menu-32.7 {DeleteMenuCloneEntries - one entry} { .m1 add command -label Hello list [catch {.m1 delete Hello} msg] $msg [destroy .m1] } {0 {} {}} +test menu-32.8 {Ensure all menu clone commands are deleted} { + catch {destroy .menubar} + catch {destroy .menubar.test} + menu .menubar + . configure -menu .menubar + menu .menubar.test + .menubar.test add command -label "hi" + for {set i 0} {$i < 10} {incr i} { + .menubar add cascade -menu .menubar.test -label "Test" + .menubar delete Test + } + + info commands .#menubar*test* +} {} +test menu-32.9 {Ensure deleting of clones doesn't corrupt menu refs} { + catch {destroy .menubar} + catch {destroy .menubar.test} + + menu .menubar + . configure -menu .menubar + menu .menubar.test + .menubar add cascade -menu .menubar.test -label "Test" + menu .menubar.cascade + + .menubar.test add cascade -menu .menubar.cascade -label "Cascade" + set res {} + lappend res [.menubar.test entrycget 1 -menu] + lappend res [.#menubar.#menubar#test entrycget 1 -menu] + destroy .menubar.test + menu .menubar.test + .menubar.test add cascade -menu .menubar.cascade -label "Cascade" + lappend res [.menubar.test entrycget 1 -menu] + lappend res [.#menubar.#menubar#test entrycget 1 -menu] + set res +} {.menubar.cascade .#menubar.#menubar#test.#menubar#cascade .menubar.cascade .#menubar.#menubar#test.#menubar#cascade} set l [interp hidden] eval destroy [winfo children .] diff --git a/unix/tkUnixDefault.h b/unix/tkUnixDefault.h index 40113e8..c58179c 100644 --- a/unix/tkUnixDefault.h +++ b/unix/tkUnixDefault.h @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnixDefault.h,v 1.10 2001/09/26 21:36:19 pspjuth Exp $ + * RCS: @(#) $Id: tkUnixDefault.h,v 1.11 2001/10/12 13:30:31 tmh Exp $ */ #ifndef _TKUNIXDEFAULT @@ -245,6 +245,7 @@ #define DEF_MENU_ENTRY_BITMAP None #define DEF_MENU_ENTRY_COLUMN_BREAK "0" #define DEF_MENU_ENTRY_COMMAND (char *) NULL +#define DEF_MENU_ENTRY_COMPOUND "none" #define DEF_MENU_ENTRY_FG (char *) NULL #define DEF_MENU_ENTRY_FONT (char *) NULL #define DEF_MENU_ENTRY_HIDE_MARGIN "0" diff --git a/unix/tkUnixMenu.c b/unix/tkUnixMenu.c index cf392e4..10e0659 100644 --- a/unix/tkUnixMenu.c +++ b/unix/tkUnixMenu.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnixMenu.c,v 1.4 1999/12/21 23:56:34 hobbs Exp $ + * RCS: @(#) $Id: tkUnixMenu.c,v 1.5 2001/10/12 13:30:31 tmh Exp $ */ #include "tkPort.h" @@ -703,11 +703,14 @@ DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) int width; /* width of entry. */ int height; /* height of entry. */ { - int baseline; int indicatorSpace = mePtr->indicatorSpace; int activeBorderWidth; int leftEdge; int imageHeight, imageWidth; + int textHeight, textWidth; + int haveImage = 0, haveText = 0; + int imageXOffset = 0, imageYOffset = 0; + int textXOffset = 0, textYOffset = 0; Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, &activeBorderWidth); @@ -717,35 +720,108 @@ DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) } /* - * Draw label or bitmap or image for entry. + * Work out what we will need to draw first. */ - baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; if (mePtr->image != NULL) { Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); + haveImage = 1; + } else if (mePtr->bitmapPtr != NULL) { + Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); + Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight); + haveImage = 1; + } + if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { + if (mePtr->labelLength > 0) { + char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); + textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); + textHeight = fmPtr->linespace; + haveText = 1; + } + } + + /* + * Now work out what the relative positions are. + */ + + if (haveImage && haveText) { + int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth); + switch ((enum compound) mePtr->compound) { + case COMPOUND_TOP: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = imageHeight/2 + 2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = -textHeight/2; + break; + } + case COMPOUND_BOTTOM: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = -imageHeight/2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = textHeight/2 + 2; + break; + } + case COMPOUND_LEFT: { + textXOffset = imageWidth + 2; + textYOffset = 0; + imageXOffset = 0; + imageYOffset = 0; + break; + } + case COMPOUND_RIGHT: { + textXOffset = 0; + textYOffset = 0; + imageXOffset = textWidth + 2; + imageYOffset = 0; + break; + } + case COMPOUND_CENTER: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = 0; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = 0; + break; + } + case COMPOUND_NONE: {break;} + } + } else { + textXOffset = 0; + textYOffset = 0; + imageXOffset = 0; + imageYOffset = 0; + } + + /* + * Draw label and/or bitmap or image for entry. + */ + + if (mePtr->image != NULL) { if ((mePtr->selectImage != NULL) && (mePtr->entryFlags & ENTRY_SELECTED)) { Tk_RedrawImage(mePtr->selectImage, 0, 0, - imageWidth, imageHeight, d, leftEdge, - (int) (y + (mePtr->height - imageHeight)/2)); + imageWidth, imageHeight, d, leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); } else { Tk_RedrawImage(mePtr->image, 0, 0, imageWidth, - imageHeight, d, leftEdge, - (int) (y + (mePtr->height - imageHeight)/2)); + imageHeight, d, leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); } } else if (mePtr->bitmapPtr != None) { - int width, height; Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - Tk_SizeOfBitmap(menuPtr->display,bitmap, &width, &height); - XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, (unsigned) width, - (unsigned) height, leftEdge, - (int) (y + (mePtr->height - height)/2), 1); - } else { + XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, + (unsigned) imageWidth, (unsigned) imageHeight, + leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1); + } + if ((mePtr->compound != COMPOUND_NONE) || !haveImage) { + int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; if (mePtr->labelLength > 0) { char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, - mePtr->labelLength, leftEdge, baseline); - DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, + mePtr->labelLength, leftEdge + textXOffset, + baseline + textYOffset); + DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, + x + textXOffset, y + textYOffset, width, height); } } @@ -757,8 +833,8 @@ DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) } else if ((mePtr->image != NULL) && (menuPtr->disabledImageGC != None)) { XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC, - leftEdge, - (int) (y + (mePtr->height - imageHeight)/2), + leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), (unsigned) imageWidth, (unsigned) imageHeight); } } @@ -1397,21 +1473,68 @@ GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr) * portion */ { TkMenu *menuPtr = mePtr->menuPtr; + int haveImage = 0, haveText = 0; if (mePtr->image != NULL) { Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr); + haveImage = 1; } else if (mePtr->bitmapPtr != NULL) { Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr); + haveImage = 1; } else { - *heightPtr = fmPtr->linespace; + *heightPtr = 0; + *widthPtr = 0; + } + if (haveImage && (mePtr->compound == COMPOUND_NONE)) { + /* We don't care about the text in this case */ + } else { + /* Either it is compound or we don't have an image */ if (mePtr->labelPtr != NULL) { + int textWidth; char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); + textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); - *widthPtr = Tk_TextWidth(tkfont, label, mePtr->labelLength); + if ((mePtr->compound != COMPOUND_NONE) && haveImage) { + switch ((enum compound) mePtr->compound) { + case COMPOUND_TOP: + case COMPOUND_BOTTOM: { + if (textWidth > *widthPtr) { + *widthPtr = textWidth; + } + /* Add text and padding */ + *heightPtr += fmPtr->linespace + 2; + break; + } + case COMPOUND_LEFT: + case COMPOUND_RIGHT: { + if (fmPtr->linespace > *heightPtr) { + *heightPtr = fmPtr->linespace; + } + /* Add text and padding */ + *widthPtr += textWidth + 2; + break; + } + case COMPOUND_CENTER: { + if (fmPtr->linespace > *heightPtr) { + *heightPtr = fmPtr->linespace; + } + if (textWidth > *widthPtr) { + *widthPtr = textWidth; + } + break; + } + case COMPOUND_NONE: {break;} + } } else { - *widthPtr = 0; + /* We don't have an image or we're not compound */ + *heightPtr = fmPtr->linespace; + *widthPtr = textWidth; + } + } else { + /* An empty entry still has this height */ + *heightPtr = fmPtr->linespace; } } *heightPtr += 1; diff --git a/win/makefile.vc b/win/makefile.vc index 48fc1e0..efde149 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -7,7 +7,7 @@ # Copyright (c) 1998-2000 Ajuba Solutions. # Copyright (c) 2001 ActiveState Corporation. # -# RCS: @(#) $Id: makefile.vc,v 1.41 2001/10/01 21:04:37 hobbs Exp $ +# RCS: @(#) $Id: makefile.vc,v 1.42 2001/10/12 13:30:32 tmh Exp $ # Does not depend on the presence of any environment variables in # order to compile tcl; all needed information is derived from @@ -52,12 +52,12 @@ lib32 = "$(TOOLS32)\bin\Win64\lib.exe" !ELSE # Visual Studio 5 default -#TOOLS32 = C:\Progra~1\devstudio\vc -#TOOLS32_rc = C:\Progra~1\devstudio\sharedide +TOOLS32 = C:\Progra~1\devstudio\vc +TOOLS32_rc = C:\Progra~1\devstudio\sharedide # Visual Studio 6 default -TOOLS32 = C:\Progra~1\Microsoft Visual Studio\VC98 -TOOLS32_rc = C:\Progra~1\Microsoft Visual Studio\common\MSDev98 +#TOOLS32 = C:\Progra~1\Microsoft Visual Studio\VC98 +#TOOLS32_rc = C:\Progra~1\Microsoft Visual Studio\common\MSDev98 cc32 = "$(TOOLS32)\bin\cl.exe" link32 = "$(TOOLS32)\bin\link.exe" @@ -77,6 +77,7 @@ NODEBUG = 1 # uncomment the following two lines to compile with TCL_MEM_DEBUG #DEBUGDEFINES =-DTCL_MEM_DEBUG +#DEBUGDEFINES = -DTCL_MEM_DEBUG -DUSE_TCLALLOC=0 -DPURIFY ###################################################################### # Do not modify below this line diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h index b1ea6cb..d1d1286 100644 --- a/win/tkWinDefault.h +++ b/win/tkWinDefault.h @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinDefault.h,v 1.10 2001/09/26 21:36:19 pspjuth Exp $ + * RCS: @(#) $Id: tkWinDefault.h,v 1.11 2001/10/12 13:30:32 tmh Exp $ */ #ifndef _TKWINDEFAULT @@ -250,6 +250,7 @@ #define DEF_MENU_ENTRY_BITMAP None #define DEF_MENU_ENTRY_COLUMN_BREAK "0" #define DEF_MENU_ENTRY_COMMAND (char *) NULL +#define DEF_MENU_ENTRY_COMPOUND "none" #define DEF_MENU_ENTRY_FG (char *) NULL #define DEF_MENU_ENTRY_FONT (char *) NULL #define DEF_MENU_ENTRY_HIDE_MARGIN "0" diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index 3108ccc..f612690 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinMenu.c,v 1.15 2001/09/21 21:34:10 hobbs Exp $ + * RCS: @(#) $Id: tkWinMenu.c,v 1.16 2001/10/12 13:30:32 tmh Exp $ */ #define OEMRESOURCE @@ -1889,7 +1889,6 @@ TkpInitializeMenuBindings(interp, bindingTable) * *---------------------------------------------------------------------- */ - static void DrawMenuEntryLabel( TkMenu *menuPtr, /* The menu we are drawing */ @@ -1903,46 +1902,122 @@ DrawMenuEntryLabel( int width, /* width of entry */ int height) /* height of entry */ { - int baseline; int indicatorSpace = mePtr->indicatorSpace; int activeBorderWidth; int leftEdge; int imageHeight, imageWidth; + int textHeight, textWidth; + int haveImage = 0, haveText = 0; + int imageXOffset = 0, imageYOffset = 0; + int textXOffset = 0, textYOffset = 0; Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, &activeBorderWidth); leftEdge = x + indicatorSpace + activeBorderWidth; /* - * Draw label or bitmap or image for entry. + * Work out what we will need to draw first. */ - baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; if (mePtr->image != NULL) { Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); + haveImage = 1; + } else if (mePtr->bitmapPtr != NULL) { + Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); + Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight); + haveImage = 1; + } + if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { + if (mePtr->labelLength > 0) { + char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); + textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); + textHeight = fmPtr->linespace; + haveText = 1; + } + } + + /* + * Now work out what the relative positions are. + */ + + if (haveImage && haveText) { + int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth); + switch ((enum compound) mePtr->compound) { + case COMPOUND_TOP: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = imageHeight/2 + 2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = -textHeight/2; + break; + } + case COMPOUND_BOTTOM: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = -imageHeight/2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = textHeight/2 + 2; + break; + } + case COMPOUND_LEFT: { + textXOffset = imageWidth + 2; + textYOffset = 0; + imageXOffset = 0; + imageYOffset = 0; + break; + } + case COMPOUND_RIGHT: { + textXOffset = 0; + textYOffset = 0; + imageXOffset = textWidth + 2; + imageYOffset = 0; + break; + } + case COMPOUND_CENTER: { + textXOffset = (fullWidth - textWidth)/2; + textYOffset = 0; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = 0; + break; + } + case COMPOUND_NONE: {break;} + } + } else { + textXOffset = 0; + textYOffset = 0; + imageXOffset = 0; + imageYOffset = 0; + } + + /* + * Draw label and/or bitmap or image for entry. + */ + + if (mePtr->image != NULL) { if ((mePtr->selectImage != NULL) && (mePtr->entryFlags & ENTRY_SELECTED)) { Tk_RedrawImage(mePtr->selectImage, 0, 0, - imageWidth, imageHeight, d, leftEdge, - (int) (y + (mePtr->height - imageHeight)/2)); + imageWidth, imageHeight, d, leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); } else { Tk_RedrawImage(mePtr->image, 0, 0, imageWidth, - imageHeight, d, leftEdge, - (int) (y + (mePtr->height - imageHeight)/2)); + imageHeight, d, leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); } } else if (mePtr->bitmapPtr != NULL) { - int width, height; Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - Tk_SizeOfBitmap(menuPtr->display, bitmap, &width, &height); - XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, (unsigned) width, - (unsigned) height, leftEdge, - (int) (y + (mePtr->height - height)/2), 1); - } else { + XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, + (unsigned) imageWidth, (unsigned) imageHeight, + leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1); + } + if ((mePtr->compound != COMPOUND_NONE) || !haveImage) { if (mePtr->labelLength > 0) { + int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, - mePtr->labelLength, leftEdge, baseline); - DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, + mePtr->labelLength, leftEdge + textXOffset, + baseline + textYOffset); + DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, + x + textXOffset, y + textYOffset, width, height); } } @@ -1954,8 +2029,8 @@ DrawMenuEntryLabel( } else if ((mePtr->image != NULL) && (menuPtr->disabledImageGC != None)) { XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC, - leftEdge, - (int) (y + (mePtr->height - imageHeight)/2), + leftEdge + imageXOffset, + (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), (unsigned) imageWidth, (unsigned) imageHeight); } } @@ -2237,21 +2312,68 @@ GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr) * portion */ { TkMenu *menuPtr = mePtr->menuPtr; + int haveImage = 0, haveText = 0; if (mePtr->image != NULL) { Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr); + haveImage = 1; } else if (mePtr->bitmapPtr != NULL) { Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr); + haveImage = 1; } else { - *heightPtr = fmPtr->linespace; + *heightPtr = 0; + *widthPtr = 0; + } + if (haveImage && (mePtr->compound == COMPOUND_NONE)) { + /* We don't care about the text in this case */ + } else { + /* Either it is compound or we don't have an image */ if (mePtr->labelPtr != NULL) { + int textWidth; char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); - - *widthPtr = Tk_TextWidth(tkfont, label, mePtr->labelLength); + textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); + + if ((mePtr->compound != COMPOUND_NONE) && haveImage) { + switch ((enum compound) mePtr->compound) { + case COMPOUND_TOP: + case COMPOUND_BOTTOM: { + if (textWidth > *widthPtr) { + *widthPtr = textWidth; + } + /* Add text and padding */ + *heightPtr += fmPtr->linespace + 2; + break; + } + case COMPOUND_LEFT: + case COMPOUND_RIGHT: { + if (fmPtr->linespace > *heightPtr) { + *heightPtr = fmPtr->linespace; + } + /* Add text and padding */ + *widthPtr += textWidth + 2; + break; + } + case COMPOUND_CENTER: { + if (fmPtr->linespace > *heightPtr) { + *heightPtr = fmPtr->linespace; + } + if (textWidth > *widthPtr) { + *widthPtr = textWidth; + } + break; + } + case COMPOUND_NONE: {break;} + } } else { - *widthPtr = 0; + /* We don't have an image or we're not compound */ + *heightPtr = fmPtr->linespace; + *widthPtr = textWidth; + } + } else { + /* An empty entry still has this height */ + *heightPtr = fmPtr->linespace; } } *heightPtr += 1; diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 421c139..b2041c5 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinWm.c,v 1.30 2001/09/21 20:38:35 hobbs Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.31 2001/10/12 13:30:32 tmh Exp $ */ #include "tkWinInt.h" @@ -766,7 +766,7 @@ InitWm(void) * *---------------------------------------------------------------------- */ -int +static int WinSetIcon(interp, titlebaricon, tkw) Tcl_Interp *interp; WinIconPtr titlebaricon; @@ -1091,10 +1091,12 @@ BlockOfIconImagesPtr ReadIconFromICOFile(Tcl_Interp* interp, char* fileName){ } if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") != TCL_OK) { + Tcl_Close(NULL, channel); return NULL; } if (Tcl_SetChannelOption(interp, channel, "-encoding", "binary") != TCL_OK) { + Tcl_Close(NULL, channel); return NULL; } /* Allocate memory for the resource structure */ -- cgit v0.12