/*
* Copyright © 2003, Joe English
*
* Core widget utilities.
*/
#include "tkInt.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"
/*------------------------------------------------------------------------
* +++ Internal helper routines.
*/
/* UpdateLayout --
* Call the widget's get-layout hook to recompute corePtr->layout.
* Returns TCL_OK if successful, returns TCL_ERROR and leaves
* the layout unchanged otherwise.
*/
static int UpdateLayout(Tcl_Interp *interp, WidgetCore *corePtr)
{
Ttk_Theme themePtr = Ttk_GetCurrentTheme(interp);
Ttk_Layout newLayout =
corePtr->widgetSpec->getLayoutProc(interp, themePtr,corePtr);
if (newLayout) {
if (corePtr->layout) {
Ttk_FreeLayout(corePtr->layout);
}
corePtr->layout = newLayout;
return TCL_OK;
}
return TCL_ERROR;
}
/* SizeChanged --
* Call the widget's sizeProc to compute new requested size
* and pass it to the geometry manager.
*/
static void SizeChanged(WidgetCore *corePtr)
{
int reqWidth = 1, reqHeight = 1;
if (corePtr->widgetSpec->sizeProc(corePtr,&reqWidth,&reqHeight)) {
Tk_GeometryRequest(corePtr->tkwin, reqWidth, reqHeight);
}
}
#ifndef TK_NO_DOUBLE_BUFFERING
/* BeginDrawing --
* Returns a Drawable for drawing the widget contents.
* This is normally an off-screen Pixmap, copied to
* the window by EndDrawing().
*/
static Drawable BeginDrawing(Tk_Window tkwin)
{
return Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
}
/* EndDrawing --
* Copy the drawable contents to the screen and release resources.
*/
static void EndDrawing(Tk_Window tkwin, Drawable d)
{
XGCValues gcValues;
GC gc;
gcValues.function = GXcopy;
gcValues.graphics_exposures = False;
gc = Tk_GetGC(tkwin, GCFunction|GCGraphicsExposures, &gcValues);
XCopyArea(Tk_Display(tkwin), d, Tk_WindowId(tkwin), gc,
0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
0, 0);
Tk_FreePixmap(Tk_Display(tkwin), d);
Tk_FreeGC(Tk_Display(tkwin), gc);
}
#else
/* No double-buffering: draw directly into the window. */
static Drawable BeginDrawing(Tk_Window tkwin) { return Tk_WindowId(tkwin); }
static void EndDrawing(
TCL_UNUSED(Tk_Window),
TCL_UNUSED(Drawable))
{
}
#endif
/* DrawWidget --
* Redraw a widget. Called as an idle handler.
*/
static void DrawWidget(void *recordPtr)
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
corePtr->flags &= ~REDISPLAY_PENDING;
if (Tk_IsMapped(corePtr->tkwin)) {
Drawable d = BeginDrawing(corePtr->tkwin);
corePtr->widgetSpec->layoutProc(recordPtr);
corePtr->widgetSpec->displayProc(recordPtr, d);
EndDrawing(corePtr->tkwin, d);
}
}
/* TtkRedisplayWidget --
* Schedule redisplay as an idle handler.
*/
void TtkRedisplayWidget(WidgetCore *corePtr)
{
if (corePtr->flags & WIDGET_DESTROYED) {
return;
}
if (!(corePtr->flags & REDISPLAY_PENDING)) {
Tcl_DoWhenIdle(DrawWidget, corePtr);
corePtr->flags |= REDISPLAY_PENDING;
}
}
/*
* WidgetWorldChanged --
* Default Tk_ClassWorldChangedProc() for widgets.
* Invoked whenever fonts or other system resources are changed;
* recomputes geometry.
*/
static void WidgetWorldChanged(void *clientData)
{
WidgetCore *corePtr = (WidgetCore *)clientData;
(void)UpdateLayout(corePtr->interp, corePtr);
SizeChanged(corePtr);
TtkRedisplayWidget(corePtr);
}
/* TtkResizeWidget --
* Recompute widget size, schedule geometry propagation and redisplay.
*/
void TtkResizeWidget(WidgetCore *corePtr)
{
if (corePtr->flags & WIDGET_DESTROYED) {
return;
}
WidgetWorldChanged(corePtr);
}
/* TtkWidgetChangeState --
* Set / clear the specified bits in the 'state' flag,
*/
void TtkWidgetChangeState(WidgetCore *corePtr,
unsigned int setBits, unsigned int clearBits)
{
Ttk_State oldState = corePtr->state;
corePtr->state = (oldState & ~clearBits) | setBits;
if (corePtr->state ^ oldState) {
TtkRedisplayWidget(corePtr);
}
}
/* WidgetInstanceObjCmd --
* Widget instance command implementation.
*/
static int
WidgetInstanceObjCmd(
void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
WidgetCore *corePtr = (WidgetCore *)clientData;
const Ttk_Ensemble *commands = corePtr->widgetSpec->commands;
int status;
Tcl_Preserve(clientData);
status = Ttk_InvokeEnsemble(commands,1, clientData,interp,objc,objv);
Tcl_Release(clientData);
return status;
}
/*------------------------------------------------------------------------
* +++ Widget destruction.
*
* A widget can be destroyed when the application explicitly
* destroys the window or one of its ancestors via [destroy]
* or Tk_DestroyWindow(); when the application deletes the widget
* instance command; when there is an error in the widget constructor;
* or when another application calls XDestroyWindow on the window ID.
*
* The window receives a <DestroyNotify> event in all cases,
* so we do the bulk of the cleanup there. See [#2207435] for
* further notes (esp. re: Tk_FreeConfigOptions).
*
* Widget code that reenters the interp should only do so
* when the widtget is Tcl_Preserve()d, and should check
* the WIDGET_DESTROYED flag bit upon return.
*/
/* WidgetInstanceObjCmdDeleted --
* Widget instance command deletion callback.
*/
static void
WidgetInstanceObjCmdDeleted(void *clientData)
{
WidgetCore *corePtr = (WidgetCore *)clientData;
corePtr->widgetCmd = NULL;
if (corePtr->tkwin != NULL)
Tk_DestroyWindow(corePtr->tkwin);
}
/* DestroyWidget --
* Main widget destructor; called from <DestroyNotify> event handler.
*/
static void
DestroyWidget(WidgetCore *corePtr)
{
corePtr->flags |= WIDGET_DESTROYED;
corePtr->widgetSpec->cleanupProc(corePtr);
Tk_FreeConfigOptions(
corePtr, corePtr->optionTable, corePtr->tkwin);
if (corePtr->layout) {
Ttk_FreeLayout(corePtr->layout);
}
if (corePtr->flags & REDISPLAY_PENDING) {
Tcl_CancelIdleCall(DrawWidget, corePtr);
}
corePtr->tkwin = NULL;
if (corePtr->widgetCmd) {
Tcl_Command cmd = corePtr->widgetCmd;
corePtr->widgetCmd = 0;
/* NB: this can reenter the interpreter via a command traces */
Tcl_DeleteCommandFromToken(corePtr->interp, cmd);
}
Tcl_EventuallyFree(corePtr, TCL_DYNAMIC);
}
/*
* CoreEventProc --
* Event handler for basic events.
* Processes Expose, Configure, FocusIn/Out, and Destroy events.
* Also handles <<ThemeChanged>> virtual events.
*
* For Expose and Configure, simply schedule the widget for redisplay.
* For Destroy events, handle the cleanup process.
*
* For Focus events, set/clear the focus bit in the state field.
*
* For Deactivate/Activate pseudo-events, set/clear the background state
* flag.
*/
static const unsigned CoreEventMask
= ExposureMask
| StructureNotifyMask
| FocusChangeMask
| VirtualEventMask
| ActivateMask
| EnterWindowMask
| LeaveWindowMask
;
static void CoreEventProc(void *clientData, XEvent *eventPtr)
{
WidgetCore *corePtr = (WidgetCore *)clientData;
switch (eventPtr->type)
{
case ConfigureNotify :
TtkRedisplayWidget(corePtr);
break;
case Expose :
if (eventPtr->xexpose.count == 0) {
TtkRedisplayWidget(corePtr);
}
break;
case DestroyNotify :
Tk_DeleteEventHandler(
corePtr->tkwin, CoreEventMask,CoreEventProc,clientData);
DestroyWidget(corePtr);
break;
case FocusIn:
case FocusOut:
/* Don't process "virtual crossing" events */
if ( eventPtr->xfocus.detail == NotifyInferior
|| eventPtr->xfocus.detail == NotifyAncestor
|| eventPtr->xfocus.detail == NotifyNonlinear)
{
if (eventPtr->type == FocusIn)
corePtr->state |= TTK_STATE_FOCUS;
else
corePtr->state &= ~TTK_STATE_FOCUS;
TtkRedisplayWidget(corePtr);
}
break;
case ActivateNotify:
corePtr->state &= ~TTK_STATE_BACKGROUND;
TtkRedisplayWidget(corePtr);
break;
case DeactivateNotify:
corePtr->state |= TTK_STATE_BACKGROUND;
TtkRedisplayWidget(corePtr);
break;
case LeaveNotify:
corePtr->state &= ~TTK_STATE_HOVER;
TtkRedisplayWidget(corePtr);
break;
case EnterNotify:
corePtr->state |= TTK_STATE_HOVER;
TtkRedisplayWidget(corePtr);
break;
case VirtualEvent: {
const char *name = ((XVirtualEvent *)eventPtr)->name;
if ((name != NULL) && !strcmp("ThemeChanged", name)) {
WidgetWorldChanged(corePtr);
}
break;
}
default:
/* can't happen... */
break;
}
}
static const Tk_ClassProcs widgetClassProcs = {
sizeof(Tk_ClassProcs), /* size */
WidgetWorldChanged, /* worldChangedProc */
NULL, /* createProc */
NULL /* modalProc */
};
/*
* TtkWidgetConstructorObjCmd --
* General-purpose widget constructor command implementation.
* ClientData is a WidgetSpec *.
*/
int TtkWidgetConstructorObjCmd(
void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
WidgetSpec *widgetSpec = (WidgetSpec *)clientData;
const char *className = widgetSpec->className;
Tk_OptionTable optionTable =
Tk_CreateOptionTable(interp, widgetSpec->optionSpecs);
Tk_Window tkwin;
void *recordPtr;
WidgetCore *corePtr;
Tk_SavedOptions savedOptions;
Tcl_Size i;
if (objc < 2 || objc % 2 == 1) {
Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
return TCL_ERROR;
}
/* Check if a -class option has been specified.
* We have to do this before the InitOptions() call,
* since InitOptions() is affected by the widget class.
*/
for (i = 2; i < objc; i += 2) {
if (!strcmp(Tcl_GetString(objv[i]), "-class")) {
className = Tcl_GetString(objv[i+1]);
break;
}
}
tkwin = Tk_CreateWindowFromPath(
interp, Tk_MainWindow(interp), Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL)
return TCL_ERROR;
/*
* Allocate and initialize the widget record.
*/
recordPtr = ckalloc(widgetSpec->recordSize);
memset(recordPtr, 0, widgetSpec->recordSize);
corePtr = (WidgetCore *)recordPtr;
corePtr->tkwin = tkwin;
corePtr->interp = interp;
corePtr->widgetSpec = widgetSpec;
corePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin),
WidgetInstanceObjCmd, recordPtr, WidgetInstanceObjCmdDeleted);
corePtr->optionTable = optionTable;
corePtr->layout = NULL;
corePtr->flags = 0;
corePtr->state = 0;
Tk_SetClass(tkwin, className);
Tk_SetClassProcs(tkwin, &widgetClassProcs, recordPtr);
Tk_SetWindowBackgroundPixmap(tkwin, ParentRelative);
widgetSpec->initializeProc(interp, recordPtr);
Tk_CreateEventHandler(tkwin, CoreEventMask, CoreEventProc, recordPtr);
/*
* Initial configuration.
*/
Tcl_Preserve(corePtr);
if (Tk_InitOptions(interp, recordPtr, optionTable, tkwin) != TCL_OK) {
goto error;
}
if (Tk_SetOptions(interp, recordPtr, optionTable,
objc - 2, objv + 2, tkwin, &savedOptions, NULL) != TCL_OK) {
Tk_RestoreSavedOptions(&savedOptions);
goto error;
} else {
Tk_FreeSavedOptions(&savedOptions);
}
if (widgetSpec->configureProc(interp, recordPtr, ~0) != TCL_OK)
goto error;
if (widgetSpec->postConfigureProc(interp, recordPtr, ~0) != TCL_OK)
goto error;
if (WidgetDestroyed(corePtr))
goto error;
Tcl_Release(corePtr);
SizeChanged(corePtr);
Tk_MakeWindowExist(tkwin);
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin), -1));
return TCL_OK;
error:
if (WidgetDestroyed(corePtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"widget has been destroyed", -1));
} else {
Tk_DestroyWindow(tkwin);
}
Tcl_Release(corePtr);
return TCL_ERROR;
}
/*------------------------------------------------------------------------
* +++ Default implementations for widget hook procedures.
*/
/* TtkWidgetGetLayout --
* Default getLayoutProc.
* Looks up the layout based on the -style resource (if specified),
* otherwise use the widget class.
*/
Ttk_Layout TtkWidgetGetLayout(
Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr)
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
const char *styleName = 0;
if (corePtr->styleObj)
styleName = Tcl_GetString(corePtr->styleObj);
if (!styleName || *styleName == '\0')
styleName = corePtr->widgetSpec->className;
return Ttk_CreateLayout(interp, themePtr, styleName,
recordPtr, corePtr->optionTable, corePtr->tkwin);
}
/*
* TtkWidgetGetOrientedLayout --
* Helper routine. Same as TtkWidgetGetLayout, but prefixes
* "Horizontal." or "Vertical." to the style name, depending
* on the value of the 'orient' option.
*/
Ttk_Layout TtkWidgetGetOrientedLayout(
Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr, Tcl_Obj *orientObj)
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
const char *baseStyleName = 0;
Tcl_DString styleName;
Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
Ttk_Layout layout;
Tcl_DStringInit(&styleName);
/* Prefix:
*/
TtkGetOrientFromObj(NULL, orientObj, &orient);
if (orient == TTK_ORIENT_HORIZONTAL)
Tcl_DStringAppend(&styleName, "Horizontal.", TCL_INDEX_NONE);
else
Tcl_DStringAppend(&styleName, "Vertical.", TCL_INDEX_NONE);
/* Add base style name:
*/
if (corePtr->styleObj)
baseStyleName = Tcl_GetString(corePtr->styleObj);
if (!baseStyleName || *baseStyleName == '\0')
baseStyleName = corePtr->widgetSpec->className;
Tcl_DStringAppend(&styleName, baseStyleName, TCL_INDEX_NONE);
/* Create layout:
*/
layout= Ttk_CreateLayout(interp, themePtr, Tcl_DStringValue(&styleName),
recordPtr, corePtr->optionTable, corePtr->tkwin);
Tcl_DStringFree(&styleName);
return layout;
}
/* TtkNullInitialize --
* Default widget initializeProc (no-op)
*/
void TtkNullInitialize(
TCL_UNUSED(Tcl_Interp *),
TCL_UNUSED(void *))
{
}
/* TtkNullPostConfigure --
* Default widget postConfigureProc (no-op)
*/
int TtkNullPostConfigure(
TCL_UNUSED(Tcl_Interp *),
TCL_UNUSED(void *),
TCL_UNUSED(int))
{
return TCL_OK;
}
/* TtkCoreConfigure --
* Default widget configureProc.
* Handles -style option.
*/
int TtkCoreConfigure(Tcl_Interp *interp, void *clientData, int mask)
{
WidgetCore *corePtr = (WidgetCore *)clientData;
int status = TCL_OK;
if (mask & STYLE_CHANGED) {
status = UpdateLayout(interp, corePtr);
}
return status;
}
/* TtkNullCleanup --
* Default widget cleanupProc (no-op)
*/
void TtkNullCleanup(
TCL_UNUSED(void *))
{
return;
}
/* TtkWidgetDoLayout --
* Default widget layoutProc.
*/
void TtkWidgetDoLayout(void *clientData)
{
WidgetCore *corePtr = (WidgetCore *)clientData;
Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));
}
/* TtkWidgetDisplay --
* Default widget displayProc.
*/
void TtkWidgetDisplay(void *recordPtr, Drawable d)
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
Ttk_DrawLayout(corePtr->layout, corePtr->state, d);
}
/* TtkWidgetSize --
* Default widget sizeProc()
*/
int TtkWidgetSize(void *recordPtr, int *widthPtr, int *heightPtr)
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
Ttk_LayoutSize(corePtr->layout, corePtr->state, widthPtr, heightPtr);
return 1;
}
/*------------------------------------------------------------------------
* +++ Default implementations for widget subcommands.
*/
/* $w cget -option
*/
int TtkWidgetCgetCommand(
void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
Tcl_Obj *result;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "option");
return TCL_ERROR;
}
result = Tk_GetOptionValue(interp, recordPtr,
corePtr->optionTable, objv[2], corePtr->tkwin);
if (result == NULL)
return TCL_ERROR;
Tcl_SetObjResult(interp, result);
return TCL_OK;
}
/* $w configure ?-option ?value ....??
*/
int TtkWidgetConfigureCommand(
void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
Tcl_Obj *result;
if (objc == 2) {
result = Tk_GetOptionInfo(interp, recordPtr,
corePtr->optionTable, NULL, corePtr->tkwin);
} else if (objc == 3) {
result = Tk_GetOptionInfo(interp, recordPtr,
corePtr->optionTable, objv[2], corePtr->tkwin);
} else {
Tk_SavedOptions savedOptions;
int status;
int mask = 0;
status = Tk_SetOptions(interp, recordPtr,
corePtr->optionTable, objc - 2, objv + 2,
corePtr->tkwin, &savedOptions, &mask);
if (status != TCL_OK)
return status;
if (mask & READONLY_OPTION) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to change read-only option", -1));
Tk_RestoreSavedOptions(&savedOptions);
return TCL_ERROR;
}
status = corePtr->widgetSpec->configureProc(interp, recordPtr, mask);
if (status != TCL_OK) {
Tk_RestoreSavedOptions(&savedOptions);
return status;
}
Tk_FreeSavedOptions(&savedOptions);
status = corePtr->widgetSpec->postConfigureProc(interp,recordPtr,mask);
if (WidgetDestroyed(corePtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"widget has been destroyed", -1));
status = TCL_ERROR;
}
if (status != TCL_OK) {
return status;
}
if (mask & (STYLE_CHANGED | GEOMETRY_CHANGED)) {
SizeChanged(corePtr);
}
TtkRedisplayWidget(corePtr);
result = Tcl_NewObj();
}
if (result == 0) {
return TCL_ERROR;
}
Tcl_SetObjResult(interp, result);
return TCL_OK;
}
/* $w state ? $stateSpec ?
*
* If $stateSpec is specified, modify the widget state accordingly,
* return a new stateSpec representing the changed bits.
*
* Otherwise, return a statespec matching all the currently-set bits.
*/
int TtkWidgetStateCommand(
void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
Ttk_StateSpec spec;
int status;
Ttk_State oldState, changed;
if (objc == 2) {
Tcl_SetObjResult(interp,
Ttk_NewStateSpecObj(corePtr->state, 0ul));
return TCL_OK;
}
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "state-spec");
return TCL_ERROR;
}
status = Ttk_GetStateSpecFromObj(interp, objv[2], &spec);
if (status != TCL_OK)
return status;
oldState = corePtr->state;
corePtr->state = Ttk_ModifyState(corePtr->state, &spec);
changed = corePtr->state ^ oldState;
TtkRedisplayWidget(corePtr);
Tcl_SetObjResult(interp,
Ttk_NewStateSpecObj(oldState & changed, ~oldState & changed));
return status;
}
/* $w instate $stateSpec ?$script?
*
* Tests if widget state matches $stateSpec.
* If $script is specified, execute script if state matches.
* Otherwise, return true/false
*/
int TtkWidgetInstateCommand(
void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
Ttk_State state = corePtr->state;
Ttk_StateSpec spec;
int status = TCL_OK;
if (objc < 3 || objc > 4) {
Tcl_WrongNumArgs(interp, 2, objv, "state-spec ?script?");
return TCL_ERROR;
}
status = Ttk_GetStateSpecFromObj(interp, objv[2], &spec);
if (status != TCL_OK)
return status;
if (objc == 3) {
Tcl_SetObjResult(interp,
Tcl_NewBooleanObj(Ttk_StateMatches(state,&spec)));
} else if (objc == 4) {
if (Ttk_StateMatches(state,&spec)) {
status = Tcl_EvalObjEx(interp, objv[3], 0);
}
}
return status;
}
/* $w identify $x $y
* $w identify element $x $y
* Returns: name of element at $x, $y
*/
int TtkWidgetIdentifyCommand(
void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
Ttk_Element element;
static const char *const whatTable[] = { "element", NULL };
int x, y, what;
if (objc < 4 || objc > 5) {
Tcl_WrongNumArgs(interp, 2, objv, "?what? x y");
return TCL_ERROR;
}
if (objc == 5) {
/* $w identify element $x $y */
if (Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable,
sizeof(char *), "option", 0, &what) != TCL_OK)
{
return TCL_ERROR;
}
}
if (Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
|| Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK) {
return TCL_ERROR;
}
element = Ttk_IdentifyElement(corePtr->layout, x, y);
if (element) {
const char *elementName = Ttk_ElementName(element);
Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1));
}
return TCL_OK;
}
/* $w style
* Return the style currently applied to the widget.
*/
int TtkWidgetStyleCommand(
void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
WidgetCore *corePtr = (WidgetCore *)recordPtr;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 2, objv, "");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(
Ttk_StyleName(Ttk_LayoutStyle(corePtr->layout)), -1));
return TCL_OK;
}
/*EOF*/