Tk Source Code

Check-in [9524a8d9]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge with trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | revised_text | tip-466
Files: files | file ages | folders
SHA3-256: 9524a8d98dc030da1fa510facacd8f2ccf8b28b07a9435e16044345ecbc721a5
User & Date: culler 2018-11-15 14:11:24
Context
2018-11-15
19:43
Fix merging from trunk: Remove unused function GenerateWidgetViewSyncEvent, in the revised_text branch this became TkTextGenerateWidgetViewSyncEvent check-in: 4d1d025c user: fvogel tags: revised_text, tip-466
14:11
Merge with trunk. check-in: 9524a8d9 user: culler tags: revised_text, tip-466
2018-11-14
13:29
Fix tests that were sporadically hanging or failing on macOS. check-in: a613a84f user: culler tags: trunk
2018-11-12
11:28
A few corrections in manual. check-in: 9cc89227 user: gcramer tags: revised_text, tip-466
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to doc/canvas.n.

309
310
311
312
313
314
315

316
317
318
319
320
321
322
....
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349


1350
1351
1352
1353
1354
1355
1356
....
1382
1383
1384
1385
1386
1387
1388




























1389
1390
1391
1392
1393
1394
1395
.PP
The second possible syntax is a character list containing only
5 possible characters
.QW "\fB.,-_ \fR" .
The space can be used
to enlarge the space between other line elements, and cannot
occur as the first position in the string. Some examples:

.CS
\-dash .     \(-> \-dash {2 4}
\-dash -     \(-> \-dash {6 4}
\-dash -.    \(-> \-dash {6 4 2 4}
\-dash -..   \(-> \-dash {6 4 2 4 2 4}
\-dash {. }  \(-> \-dash {2 8}
\-dash ,     \(-> \-dash {4 4}
................................................................................
For arcs, wide outlines will be drawn centered on the edges of the
arc's region.
.SH "STANDARD ITEM TYPES"
.SS "ARC ITEMS"
.PP
Items of type \fBarc\fR appear on the display as arc-shaped regions.
An arc is a section of an oval delimited by two angles (specified
by the \fB\-start\fR and \fB\-extent\fR options) and displayed in
one of several ways (specified by the \fB\-style\fR option).
Arcs are created with widget commands of the following form:
.CS
\fIpathName \fBcreate arc \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate arc \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
rectangular region enclosing the oval that defines the arc.


After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An arc item becomes the current item when the mouse pointer is
over any part that is painted or (when fully transparent) that would be
painted if both the \fB\-fill\fR and \fB\-outline\fR options were non-empty.
................................................................................
modulo 360 is used as the extent.
.TP
\fB\-start \fIdegrees\fR
Specifies the beginning of the angular range occupied by the
arc.
\fIDegrees\fR is given in units of degrees measured counter-clockwise
from the 3-o'clock position; it may be either positive or negative.




























.TP
\fB\-style \fItype\fR
Specifies how to draw the arc. If \fItype\fR is \fBpieslice\fR
(the default) then the arc's region is defined by a section
of the oval's perimeter plus two line segments, one between the center
of the oval and each end of the perimeter section.
If \fItype\fR is \fBchord\fR then the arc's region is defined






>







 







|
|







|
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
....
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
....
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
.PP
The second possible syntax is a character list containing only
5 possible characters
.QW "\fB.,-_ \fR" .
The space can be used
to enlarge the space between other line elements, and cannot
occur as the first position in the string. Some examples:
.PP
.CS
\-dash .     \(-> \-dash {2 4}
\-dash -     \(-> \-dash {6 4}
\-dash -.    \(-> \-dash {6 4 2 4}
\-dash -..   \(-> \-dash {6 4 2 4 2 4}
\-dash {. }  \(-> \-dash {2 8}
\-dash ,     \(-> \-dash {4 4}
................................................................................
For arcs, wide outlines will be drawn centered on the edges of the
arc's region.
.SH "STANDARD ITEM TYPES"
.SS "ARC ITEMS"
.PP
Items of type \fBarc\fR appear on the display as arc-shaped regions.
An arc is a section of an oval delimited by two angles (specified
by either the \fB\-start\fR and \fB\-extent\fR options or the \fB\-height\fR option)
and displayed in one of several ways (specified by the \fB\-style\fR option).
Arcs are created with widget commands of the following form:
.CS
\fIpathName \fBcreate arc \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate arc \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
rectangular region enclosing the oval that defines the arc (except when
\fB\-height\fR is specified - see below).
.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An arc item becomes the current item when the mouse pointer is
over any part that is painted or (when fully transparent) that would be
painted if both the \fB\-fill\fR and \fB\-outline\fR options were non-empty.
................................................................................
modulo 360 is used as the extent.
.TP
\fB\-start \fIdegrees\fR
Specifies the beginning of the angular range occupied by the
arc.
\fIDegrees\fR is given in units of degrees measured counter-clockwise
from the 3-o'clock position; it may be either positive or negative.
.TP
\fB\-height \fIdistance\fR
Provides a shortcut for creating a circular arc segment by defining the
distance of the mid-point of the arc from its chord. When this option
is used the coordinates are interpreted as the start and end coordinates
of the chord, and the options \fB\-start\fR and \fB-extent\fR are ignored.
The value of \fIdistance\fR has the following meaning:
.RS
.PP
.RS
\fIdistance\fR > 0 creates a clockwise arc
.br
\fIdistance\fR < 0 creates an counter-clockwise arc
.br
\fIdistance\fR = 0 creates an arc as if this option had not been specified
.RE
.PP
If you want the arc to have a specific radius, \fIr\fR, use the formula:
.PP
.RS
\fIdistance\fR = \fIr\fR \(+- sqrt(\fIr\fR**2 - (chordLength / 2)**2)
.RE
.PP
choosing the minus sign for the minor arc and the plus sign for the major arc.
.PP
Note that \fBitemcget \-height\fR always returns 0 so that introspection code
can be kept simple.
.RE
.TP
\fB\-style \fItype\fR
Specifies how to draw the arc. If \fItype\fR is \fBpieslice\fR
(the default) then the arc's region is defined by a section
of the oval's perimeter plus two line segments, one between the center
of the oval and each end of the perimeter section.
If \fItype\fR is \fBchord\fR then the arc's region is defined

Changes to doc/grid.n.

198
199
200
201
202
203
204








205
206
207
208
209
210
211
...
274
275
276
277
278
279
280








281
282
283
284
285
286
287
.
Removes each of the \fIslave\fRs from grid for its
master and unmaps their windows.
The slaves will no longer be managed by the grid geometry manager.
The configuration options for that window are forgotten, so that if the
slave is managed once more by the grid geometry manager, the initial
default settings are used.








.TP
\fBgrid info \fIslave\fR
.
Returns a list whose elements are the current configuration state of
the slave given by \fIslave\fR in the same option-value form that
might be specified to \fBgrid configure\fR.
The first two elements of the list are
................................................................................
Removes each of the \fIslave\fRs from grid for its
master and unmaps their windows.
The slaves will no longer be managed by the grid geometry manager.
However, the configuration options for that window are remembered,
so that if the
slave is managed once more by the grid geometry manager, the previous
values are retained.








.TP
\fBgrid size \fImaster\fR
.
Returns the size of the grid (in columns then rows) for \fImaster\fR.
The size is determined either by the \fIslave\fR occupying the largest
row or column, or the largest column or row with a \fB\-minsize\fR,
\fB\-weight\fR, or \fB\-pad\fR that is non-zero.






>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
.
Removes each of the \fIslave\fRs from grid for its
master and unmaps their windows.
The slaves will no longer be managed by the grid geometry manager.
The configuration options for that window are forgotten, so that if the
slave is managed once more by the grid geometry manager, the initial
default settings are used.
.RS
.PP
.VS TIP518
If the last slave of the master becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the master; the master
may choose to resize itself (or otherwise respond) to such a change.
.VE TIP518
.RE
.TP
\fBgrid info \fIslave\fR
.
Returns a list whose elements are the current configuration state of
the slave given by \fIslave\fR in the same option-value form that
might be specified to \fBgrid configure\fR.
The first two elements of the list are
................................................................................
Removes each of the \fIslave\fRs from grid for its
master and unmaps their windows.
The slaves will no longer be managed by the grid geometry manager.
However, the configuration options for that window are remembered,
so that if the
slave is managed once more by the grid geometry manager, the previous
values are retained.
.RS
.PP
.VS TIP518
If the last slave of the master becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the master; the master
may choose to resize itself (or otherwise respond) to such a change.
.VE TIP518
.RE
.TP
\fBgrid size \fImaster\fR
.
Returns the size of the grid (in columns then rows) for \fImaster\fR.
The size is determined either by the \fIslave\fR occupying the largest
row or column, or the largest column or row with a \fB\-minsize\fR,
\fB\-weight\fR, or \fB\-pad\fR that is non-zero.

Changes to doc/pack.n.

125
126
127
128
129
130
131








132
133
134
135
136
137
138
than receiving default values.
.RE
.TP
\fBpack forget \fIslave \fR?\fIslave ...\fR?
Removes each of the \fIslave\fRs from the packing order for its
master and unmaps their windows.
The slaves will no longer be managed by the packer.








.TP
\fBpack info \fIslave\fR
Returns a list whose elements are the current configuration state of
the slave given by \fIslave\fR in the same option-value form that
might be specified to \fBpack configure\fR.
The first two elements of the list are
.QW "\fB\-in \fImaster\fR"






>
>
>
>
>
>
>
>







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
than receiving default values.
.RE
.TP
\fBpack forget \fIslave \fR?\fIslave ...\fR?
Removes each of the \fIslave\fRs from the packing order for its
master and unmaps their windows.
The slaves will no longer be managed by the packer.
.RS
.PP
.VS TIP518
If the last slave of the master becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the master; the master
may choose to resize itself (or otherwise respond) to such a change.
.VE TIP518
.RE
.TP
\fBpack info \fIslave\fR
Returns a list whose elements are the current configuration state of
the slave given by \fIslave\fR in the same option-value form that
might be specified to \fBpack configure\fR.
The first two elements of the list are
.QW "\fB\-in \fImaster\fR"

Changes to generic/tk.decls.

801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
    int	 Tk_GetScrollInfoObj(Tcl_Interp *interp,
	    int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr)
}
declare 211 {
    int	 Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionToken, Tk_Window tkwin)
}
declare 212 {
    void  Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)
}
declare 213 {
    void  Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr)
}
declare 214 {






|







801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
    int	 Tk_GetScrollInfoObj(Tcl_Interp *interp,
	    int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr)
}
declare 211 {
    int	 Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionToken, Tk_Window tkwin)
}
declare 212 {nostub {Don't use this function in a stub-enabled extension}} {
    void  Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)
}
declare 213 {
    void  Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr)
}
declare 214 {

Changes to generic/tkBind.c.

71
72
73
74
75
76
77











78


79
80
81
82
83
84
85
 * down (and auto-repeating). There may be as many as 3 auto-repeat events
 * after each mouse button press or release (see the first large comment block
 * within Tk_BindEvent for more on this), for a total of 20 events to cover
 * the three button presses and two intervening releases. If you reduce
 * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost.
 */












#define EVENT_BUFFER_SIZE 30


typedef struct Tk_BindingTable_ {
    XEvent eventRing[EVENT_BUFFER_SIZE];
				/* Circular queue of recent events (higher
				 * indices are for more recent events). */
    Detail detailRing[EVENT_BUFFER_SIZE];
				/* "Detail" information (keySym, button,
				 * Tk_Uid, or 0) for each entry in






>
>
>
>
>
>
>
>
>
>
>
|
>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 * down (and auto-repeating). There may be as many as 3 auto-repeat events
 * after each mouse button press or release (see the first large comment block
 * within Tk_BindEvent for more on this), for a total of 20 events to cover
 * the three button presses and two intervening releases. If you reduce
 * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost.
 */

/*
 * NOTE: The changes which were needed to make Tk work on OSX 10.14 (Mojave)
 * also demand that the event ring be a bit bigger.  It might be wise to
 * augment the current double-click pattern matching by adding a new
 * DoubleClick modifier bit which could be set based on the clickCount of the
 * Apple NSEvent object.
 */

#ifndef TK_MAC_OSX
  #define EVENT_BUFFER_SIZE 45
#else
  #define EVENT_BUFFER_SIZE 30
#endif

typedef struct Tk_BindingTable_ {
    XEvent eventRing[EVENT_BUFFER_SIZE];
				/* Circular queue of recent events (higher
				 * indices are for more recent events). */
    Detail detailRing[EVENT_BUFFER_SIZE];
				/* "Detail" information (keySym, button,
				 * Tk_Uid, or 0) for each entry in

Changes to generic/tkButton.c.

875
876
877
878
879
880
881





882

883
884
885
886
887
888
889
		 * Special note: must cancel any existing idle handler for
		 * TkpDisplayButton; it's no longer needed, and
		 * TkpDisplayButton cleared the REDRAW_PENDING flag.
		 */

		Tcl_CancelIdleCall(TkpDisplayButton, butPtr);
		XFlush(butPtr->display);





		Tcl_Sleep(50);

	    }
	}
	break;

    case COMMAND_INVOKE:
	if (objc > 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "invoke");






>
>
>
>
>

>







875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
		 * Special note: must cancel any existing idle handler for
		 * TkpDisplayButton; it's no longer needed, and
		 * TkpDisplayButton cleared the REDRAW_PENDING flag.
		 */

		Tcl_CancelIdleCall(TkpDisplayButton, butPtr);
		XFlush(butPtr->display);
		#ifndef MAC_OSX_TK
		/*
		 * On the mac you can not sleep in a display proc, and the
		 * flash command doesn't do anything anyway.
		 */
		Tcl_Sleep(50);
		#endif
	    }
	}
	break;

    case COMMAND_INVOKE:
	if (objc > 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "invoke");

Changes to generic/tkCanvArc.c.

58
59
60
61
62
63
64






65
66
67
68
69
70
71
...
136
137
138
139
140
141
142


143
144
145
146
147
148
149
...
171
172
173
174
175
176
177

178
179
180
181
182
183
184
...
287
288
289
290
291
292
293

294
295
296
297
298
299
300
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
...
370
371
372
373
374
375
376











377
378
379
380
381
382
383
...
443
444
445
446
447
448
449

















450
451
452
453
454
455
456
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
...
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
...
551
552
553
554
555
556
557




















































































558
559
560
561
562
563
564
    Style style;		/* How to draw arc: arc, chord, or
				 * pieslice. */
    GC fillGC;			/* Graphics context for filling item. */
    double center1[2];		/* Coordinates of center of arc outline at
				 * start (see ComputeArcOutline). */
    double center2[2];		/* Coordinates of center of arc outline at
				 * start+extent (see ComputeArcOutline). */






} ArcItem;

/*
 * The definitions below define the sizes of the polygons used to display
 * outline information for various styles of arcs:
 */

................................................................................
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", Tk_Offset(ArcItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_DOUBLE, "-extent", NULL, NULL,
	"90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK, NULL},


    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(ArcItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	"black", Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", Tk_Offset(ArcItem, outline.tsoffset),
................................................................................
 * Prototypes for functions defined in this file:
 */

static void		ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr);
static int		ConfigureArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);

static int		CreateArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
................................................................................
    arcPtr->activeFillColor = NULL;
    arcPtr->disabledFillColor = NULL;
    arcPtr->fillStipple = None;
    arcPtr->activeFillStipple = None;
    arcPtr->disabledFillStipple = None;
    arcPtr->style = PIESLICE_STYLE;
    arcPtr->fillGC = None;


    /*
     * Process the arguments to fill in the item record.
     */

    for (i = 1; i < objc; i++) {
	const char *arg = Tcl_GetString(objv[i]);
................................................................................
	Tcl_Obj *objs[4];

	objs[0] = Tcl_NewDoubleObj(arcPtr->bbox[0]);
	objs[1] = Tcl_NewDoubleObj(arcPtr->bbox[1]);
	objs[2] = Tcl_NewDoubleObj(arcPtr->bbox[2]);
	objs[3] = Tcl_NewDoubleObj(arcPtr->bbox[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs));
    } else if ((objc == 1)||(objc == 4)) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 4) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 4, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC",
................................................................................
		    &arcPtr->bbox[1]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2],
			&arcPtr->bbox[2]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3],
			&arcPtr->bbox[3]) != TCL_OK)) {
	    return TCL_ERROR;
	}











	ComputeArcBbox(canvas, arcPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", NULL);
	return TCL_ERROR;
    }
................................................................................
	    arcPtr->activeFillColor != NULL ||
	    arcPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }


















    tsoffset = &arcPtr->outline.tsoffset;
    flags = tsoffset->flags;
    if (flags & TK_OFFSET_LEFT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);
    } else if (flags & TK_OFFSET_CENTER) {
	tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);
    } else if (flags & TK_OFFSET_RIGHT) {
................................................................................
	tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
    } else if (flags & TK_OFFSET_MIDDLE) {
	tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
    }

    i = (int) (arcPtr->start/360.0);
    arcPtr->start -= i*360.0;
    if (arcPtr->start < 0) {
	arcPtr->start += 360.0;
    }
    i = (int) (arcPtr->extent/360.0);
    arcPtr->extent -= i*360.0;

    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
    if (mask) {
	gcValues.cap_style = CapButt;
	mask |= GCCapStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = None;
................................................................................
    } else if (state==TK_STATE_DISABLED) {
	if (arcPtr->disabledFillColor!=NULL) {
	    color = arcPtr->disabledFillColor;
	}
	if (arcPtr->disabledFillStipple!=None) {
	    stipple = arcPtr->disabledFillStipple;
	}
      }

    if (arcPtr->style == ARC_STYLE) {
	newGC = None;
    } else if (color == NULL) {
	newGC = None;
    } else {
	gcValues.foreground = color->pixel;
................................................................................
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[3] + 0.5);
    }

    ComputeArcBbox(canvas, arcPtr);
    return TCL_OK;
}




















































































 
/*
 *--------------------------------------------------------------
 *
 * DeleteArc --
 *
 *	This function is called to clean up the data structure associated with






>
>
>
>
>
>







 







>
>







 







>







 







>







 







|
|







 







>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<
<
<







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
...
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
...
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
...
498
499
500
501
502
503
504








505
506
507
508
509
510
511
...
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
    Style style;		/* How to draw arc: arc, chord, or
				 * pieslice. */
    GC fillGC;			/* Graphics context for filling item. */
    double center1[2];		/* Coordinates of center of arc outline at
				 * start (see ComputeArcOutline). */
    double center2[2];		/* Coordinates of center of arc outline at
				 * start+extent (see ComputeArcOutline). */
    double height;              /* Distance from the arc's chord to its
				 * mid-point. */
    double startPoint[2];       /* Start point of arc used when specifying
				 * height. */
    double endPoint[2];         /* End point of arc used when specifying
				 * height. */
} ArcItem;

/*
 * The definitions below define the sizes of the polygons used to display
 * outline information for various styles of arcs:
 */

................................................................................
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", Tk_Offset(ArcItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_DOUBLE, "-extent", NULL, NULL,
	"90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-height", NULL, NULL,
	0, Tk_Offset(ArcItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(ArcItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	"black", Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", Tk_Offset(ArcItem, outline.tsoffset),
................................................................................
 * Prototypes for functions defined in this file:
 */

static void		ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr);
static int		ConfigureArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static void		ComputeArcFromHeight(ArcItem *arcPtr);
static int		CreateArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
................................................................................
    arcPtr->activeFillColor = NULL;
    arcPtr->disabledFillColor = NULL;
    arcPtr->fillStipple = None;
    arcPtr->activeFillStipple = None;
    arcPtr->disabledFillStipple = None;
    arcPtr->style = PIESLICE_STYLE;
    arcPtr->fillGC = None;
    arcPtr->height = 0;

    /*
     * Process the arguments to fill in the item record.
     */

    for (i = 1; i < objc; i++) {
	const char *arg = Tcl_GetString(objv[i]);
................................................................................
	Tcl_Obj *objs[4];

	objs[0] = Tcl_NewDoubleObj(arcPtr->bbox[0]);
	objs[1] = Tcl_NewDoubleObj(arcPtr->bbox[1]);
	objs[2] = Tcl_NewDoubleObj(arcPtr->bbox[2]);
	objs[3] = Tcl_NewDoubleObj(arcPtr->bbox[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs));
    } else if ((objc == 1) || (objc == 4)) {
	if (objc == 1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 4) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 4, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC",
................................................................................
		    &arcPtr->bbox[1]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2],
			&arcPtr->bbox[2]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3],
			&arcPtr->bbox[3]) != TCL_OK)) {
	    return TCL_ERROR;
	}

	/*
	 * Store bbox as start and end points so they can be used if either
	 * radius or height is specified.
	 */

	arcPtr->startPoint[0] = arcPtr->bbox[0];
	arcPtr->startPoint[1] = arcPtr->bbox[1];
	arcPtr->endPoint[0] = arcPtr->bbox[2];
	arcPtr->endPoint[1] = arcPtr->bbox[3];

	ComputeArcBbox(canvas, arcPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", NULL);
	return TCL_ERROR;
    }
................................................................................
	    arcPtr->activeFillColor != NULL ||
	    arcPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    /*
     * If either the height is provided then the start and extent will be
     * overridden.
     */
    if (arcPtr->height != 0) {
	ComputeArcFromHeight(arcPtr);
	ComputeArcBbox(canvas, arcPtr);
    }

    i = (int) (arcPtr->start/360.0);
    arcPtr->start -= i*360.0;
    if (arcPtr->start < 0) {
	arcPtr->start += 360.0;
    }
    i = (int) (arcPtr->extent/360.0);
    arcPtr->extent -= i*360.0;

    tsoffset = &arcPtr->outline.tsoffset;
    flags = tsoffset->flags;
    if (flags & TK_OFFSET_LEFT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);
    } else if (flags & TK_OFFSET_CENTER) {
	tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);
    } else if (flags & TK_OFFSET_RIGHT) {
................................................................................
	tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
    } else if (flags & TK_OFFSET_MIDDLE) {
	tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
    }









    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
    if (mask) {
	gcValues.cap_style = CapButt;
	mask |= GCCapStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = None;
................................................................................
    } else if (state==TK_STATE_DISABLED) {
	if (arcPtr->disabledFillColor!=NULL) {
	    color = arcPtr->disabledFillColor;
	}
	if (arcPtr->disabledFillStipple!=None) {
	    stipple = arcPtr->disabledFillStipple;
	}
    }

    if (arcPtr->style == ARC_STYLE) {
	newGC = None;
    } else if (color == NULL) {
	newGC = None;
    } else {
	gcValues.foreground = color->pixel;
................................................................................
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[3] + 0.5);
    }

    ComputeArcBbox(canvas, arcPtr);
    return TCL_OK;
}
 
/*
 *--------------------------------------------------------------
 *
 * ComputeArcFromHeight --
 *
 *	This function calculates the arc parameters given start-point,
 *	end-point and height (!= 0).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The height parameter is set to 0 on exit.
 *
 *--------------------------------------------------------------
 */

static void
ComputeArcFromHeight(
    ArcItem* arcPtr)
{
    double chordLen, chordDir[2], chordCen[2], arcCen[2], d, radToDeg, radius;

    /*
     * The chord.
     */

    chordLen = hypot(arcPtr->endPoint[1] - arcPtr->startPoint[1],
	    arcPtr->startPoint[0] - arcPtr->endPoint[0]);
    chordDir[0] = (arcPtr->endPoint[0] - arcPtr->startPoint[0]) / chordLen;
    chordDir[1] = (arcPtr->endPoint[1] - arcPtr->startPoint[1]) / chordLen;
    chordCen[0] = (arcPtr->startPoint[0] + arcPtr->endPoint[0]) / 2;
    chordCen[1] = (arcPtr->startPoint[1] + arcPtr->endPoint[1]) / 2;

    /*
     * Calculate the radius (assumes height != 0).
     */

    radius = (4*pow(arcPtr->height, 2) + pow(chordLen, 2))
	    / (8 * arcPtr->height);

    /*
     * The arc centre.
     */

    d = radius - arcPtr->height;
    arcCen[0] = chordCen[0] - d * chordDir[1];
    arcCen[1] = chordCen[1] + d * chordDir[0];

    /*
     * The arc start and span. Angles are negated because the coordinate
     * system is left-handed.
     */

    radToDeg = 45 / atan(1);
    arcPtr->start = atan2(arcCen[1] - arcPtr->startPoint[1],
	    arcPtr->startPoint[0] - arcCen[0]) * radToDeg;
    arcPtr->extent = -2 * asin(chordLen / (2 * radius)) * radToDeg;

    /*
     * Handle spans > 180.
     */

    if (fabs(2 * arcPtr->height) > chordLen) {
	arcPtr->extent = arcPtr->extent > 0 ? (360 - arcPtr->extent)
		: -(360 + arcPtr->extent);
    }

    /*
     * Create the bounding box.
     */

    arcPtr->bbox[0] = arcCen[0] - radius;
    arcPtr->bbox[1] = arcCen[1] - radius;
    arcPtr->bbox[2] = arcCen[0] + radius;
    arcPtr->bbox[3] = arcCen[1] + radius;

    /*
     * Set the height to 0 so that itemcget -height returns 0.
     */

    arcPtr->height = 0;
}
 
/*
 *--------------------------------------------------------------
 *
 * DeleteArc --
 *
 *	This function is called to clean up the data structure associated with

Changes to generic/tkDecls.h.

1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
    Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
    int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */
    int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */
    int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */
    int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */
    int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */
    int (*tk_InitOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
    void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */
    void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */
    int (*tk_SetOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */
    void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */
    int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */
    void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */
    void (*reserved218)(void);
    void (*reserved219)(void);






|







1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
    Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
    int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */
    int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */
    int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */
    int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */
    int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */
    int (*tk_InitOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
    TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */
    void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */
    int (*tk_SetOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */
    void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */
    int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */
    void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */
    void (*reserved218)(void);
    void (*reserved219)(void);

Changes to generic/tkGrid.c.

1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
....
2773
2774
2775
2776
2777
2778
2779



2780
2781
2782
2783
2784

2785
2786
2787
2788
2789
2790
2791
....
3505
3506
3507
3508
3509
3510
3511



3512
3513
3514
3515
3516

3517
3518
3519
3520
3521
3522
3523
    int width, height;		/* Requested size of layout, in pixels. */
    int realWidth, realHeight;	/* Actual size layout should take-up. */
    int usedX, usedY;

    masterPtr->flags &= ~REQUESTED_RELAYOUT;

    /*
     * If the master has no slaves anymore, then don't do anything at all:
     * just leave the master's size as-is. Otherwise there is no way to
     * "relinquish" control over the master so another geometry manager can
     * take over.
     */

    if (masterPtr->slavePtr == NULL) {
	return;
    }

    if (masterPtr->masterDataPtr == NULL) {
................................................................................

    SetGridSize(slavePtr->masterPtr);
    slavePtr->masterPtr = NULL;

    /*
     * If we have emptied this master from slaves it means we are no longer
     * handling it and should mark it as free.



     */

    if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) {
	TkFreeGeometryMaster(masterPtr->tkwin, "grid");
	masterPtr->flags &= ~ALLOCED_MASTER;

    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * DestroyGrid --
................................................................................
	return TCL_ERROR;
    }
    SetGridSize(masterPtr);

    /*
     * If we have emptied this master from slaves it means we are no longer
     * handling it and should mark it as free.



     */

    if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) {
	TkFreeGeometryMaster(masterPtr->tkwin, "grid");
	masterPtr->flags &= ~ALLOCED_MASTER;

    }

    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------






|
|
|
<







 







>
>
>





>







 







>
>
>





>







1728
1729
1730
1731
1732
1733
1734
1735
1736
1737

1738
1739
1740
1741
1742
1743
1744
....
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
....
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
    int width, height;		/* Requested size of layout, in pixels. */
    int realWidth, realHeight;	/* Actual size layout should take-up. */
    int usedX, usedY;

    masterPtr->flags &= ~REQUESTED_RELAYOUT;

    /*
     * If the master has no slaves anymore, then don't change the master size.
     * Otherwise there is no way to "relinquish" control over the master
     * so another geometry manager can take over.

     */

    if (masterPtr->slavePtr == NULL) {
	return;
    }

    if (masterPtr->masterDataPtr == NULL) {
................................................................................

    SetGridSize(slavePtr->masterPtr);
    slavePtr->masterPtr = NULL;

    /*
     * If we have emptied this master from slaves it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the master to inform it about there
     * being no managed children inside it.
     */

    if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) {
	TkFreeGeometryMaster(masterPtr->tkwin, "grid");
	masterPtr->flags &= ~ALLOCED_MASTER;
	TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL);
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * DestroyGrid --
................................................................................
	return TCL_ERROR;
    }
    SetGridSize(masterPtr);

    /*
     * If we have emptied this master from slaves it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the master to inform it about there
     * being no managed children inside it.
     */

    if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) {
	TkFreeGeometryMaster(masterPtr->tkwin, "grid");
	masterPtr->flags &= ~ALLOCED_MASTER;
	TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL);
    }

    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------

Changes to generic/tkImgPhInstance.c.

15
16
17
18
19
20
21



22
23
24
25
26
27
28
29
30
31
32

33
34

35
36
37
38
39
40
41
...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
...
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
...
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
...
636
637
638
639
640
641
642

643

644
645
646
647
648
649
650
651
652


















653
654
655
656
657
658
659
...
705
706
707
708
709
710
711

712
713
714
715
716
717
718
 *
 * Author: Paul Mackerras ([email protected]),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkImgPhoto.h"




/*
 * Declaration for internal Xlib function used here:
 */

extern int		_XInitImageFuncPtrs(XImage *image);

/*
 * Forward declarations
 */


static void		BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
			    int xOffset, int yOffset, int width, int height);

static int		IsValidPalette(PhotoInstance *instancePtr,
			    const char *palette);
static int		CountBits(pixel mask);
static void		GetColorTable(PhotoInstance *instancePtr);
static void		FreeColorTable(ColorTable *colorPtr, int force);
static void		AllocateColors(ColorTable *colorPtr);
static void		DisposeColorTable(ClientData clientData);
................................................................................
 *	Note that Win32 pre-defines those operations that we really need.
 *
 *	Note that on MacOS, if the background comes from a Retina display
 *	then it will be twice as wide and twice as high as the photoimage.
 *
 *----------------------------------------------------------------------
 */

#ifndef _WIN32
#define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
#define RGB(r, g, b)	((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \
	(UCHAR(b) << blue_shift)  ))
#ifdef MAC_OSX_TK
#define RGBA(r, g, b, a) ((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \
	(UCHAR(b) << blue_shift)  | \
	(UCHAR(a) << alpha_shift) ))
#endif
#define RGB15(r, g, b)	((unsigned)( \
	(((r) * red_mask / 255)   & red_mask)   | \
	(((g) * green_mask / 255) & green_mask) | \
	(((b) * blue_mask / 255)  & blue_mask)  ))
#endif /* !_WIN32 */

static void
................................................................................
				 * draw. */
    int width, int height)	/* Width & height of image to draw. */
{
    int x, y, line;
    unsigned long pixel;
    unsigned char r, g, b, alpha, unalpha, *masterPtr;
    unsigned char *alphaAr = iPtr->masterPtr->pix32;
#if defined(MAC_OSX_TK)
    /* Background "pixels" are actually 2^pp x 2^pp blocks of subpixels.  Each
     * block gets blended with the color of one image pixel.  Since we iterate
     * over the background subpixels, we reset the width and height to the
     * subpixel dimensions of the background image we are using.
     */
    int pp = bgImg->pixelpower;
    width = width << pp;
    height = height << pp;
#endif

    /*
     * This blending is an integer version of the Source-Over compositing rule
     * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
     * 1984) that has been hard-coded (for speed) to work with targetting a
     * solid surface.
     *
     * The 'unalpha' field must be 255-alpha; it is separated out to encourage
................................................................................
    }
    while ((0x0001 & (green_mask >> green_shift)) == 0) {
	green_shift++;
    }
    while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
	blue_shift++;
    }
#ifdef MAC_OSX_TK
    unsigned long alpha_mask = visual->alpha_mask;
    unsigned long alpha_shift = 0;
    while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) {
	alpha_shift++;
    }
#endif
#endif /* !_WIN32 */

    /*
     * Only UNIX requires the special case for <24bpp. It varies with 3 extra
     * shifts and uses RGB15. The 24+bpp version could also then be further
     * optimized.
     */

#if !(defined(_WIN32) || defined(MAC_OSX_TK))
    if (bgImg->depth < 24) {
	unsigned char red_mlen, green_mlen, blue_mlen;

	red_mlen = 8 - CountBits(red_mask >> red_shift);
	green_mlen = 8 - CountBits(green_mask >> green_shift);
	blue_mlen = 8 - CountBits(blue_mask >> blue_shift);
	for (y = 0; y < height; y++) {
................................................................................
		    }
		    XPutPixel(bgImg, x, y, RGB15(r, g, b));
		}
	    }
	}
	return;
    }
#endif /* !_WIN32 && !MAC_OSX_TK */

    for (y = 0; y < height; y++) {
# if !defined(MAC_OSX_TK)
	line = (y + yOffset) * iPtr->masterPtr->width;
	for (x = 0; x < width; x++) {
	    masterPtr = alphaAr + ((line + x + xOffset) * 4);
#else
	/* Repeat each image row and column 2^pp times. */
	line = ((y>>pp) + yOffset) * iPtr->masterPtr->width;
	for (x = 0; x < width; x++) {
	    masterPtr = alphaAr + ((line + (x>>pp) + xOffset) * 4);
#endif
	    alpha = masterPtr[3];

	    /*
	     * Ignore pixels that are fully transparent
	     */

	    if (alpha) {
................................................................................
		    ga = GetGValue(pixel);
		    ba = GetBValue(pixel);
		    unalpha = 255 - alpha;	/* Calculate once. */
		    r = ALPHA_BLEND(ra, r, alpha, unalpha);
		    g = ALPHA_BLEND(ga, g, alpha, unalpha);
		    b = ALPHA_BLEND(ba, b, alpha, unalpha);
		}
#ifndef MAC_OSX_TK
		XPutPixel(bgImg, x, y, RGB(r, g, b));
#else
		XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha));
#endif
	    }
	}
    }
#undef ALPHA_BLEND
}

 
/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
................................................................................
				 * draw. */
    int width, int height,	/* Dimensions of region within image to
				 * draw. */
    int drawableX,int drawableY)/* Coordinates within drawable that correspond
				 * to imageX and imageY. */
{
    PhotoInstance *instancePtr = clientData;

    XVisualInfo visInfo = instancePtr->visualInfo;


    /*
     * If there's no pixmap, it means that an error occurred while creating
     * the image instance so it can't be displayed.
     */

    if (instancePtr->pixels == None) {
	return;
    }



















    if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

................................................................................
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);
    }
    XFlush(display);

}
 
/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoFree --
 *






>
>
>











>


>







 







|








<
<
<
<
<
<
<







 







<
<
<
<
<
<
<
<
<
<
>







 







<
<
<
<
<
<
<








|







 







|


<



<
<
<
<
<
<







 







<

<
<
<





>







 







>

>
|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425







426
427
428
429
430
431
432
...
437
438
439
440
441
442
443










444
445
446
447
448
449
450
451
...
477
478
479
480
481
482
483







484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
...
533
534
535
536
537
538
539
540
541
542

543
544
545






546
547
548
549
550
551
552
...
570
571
572
573
574
575
576

577



578
579
580
581
582
583
584
585
586
587
588
589
590
...
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
 *
 * Author: Paul Mackerras ([email protected]),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkImgPhoto.h"
#ifdef MAC_OSX_TK
#define TKPUTIMAGE_CAN_BLEND
#endif

/*
 * Declaration for internal Xlib function used here:
 */

extern int		_XInitImageFuncPtrs(XImage *image);

/*
 * Forward declarations
 */

#ifndef TKPUTIMAGE_CAN_BLEND 
static void		BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
			    int xOffset, int yOffset, int width, int height);
#endif
static int		IsValidPalette(PhotoInstance *instancePtr,
			    const char *palette);
static int		CountBits(pixel mask);
static void		GetColorTable(PhotoInstance *instancePtr);
static void		FreeColorTable(ColorTable *colorPtr, int force);
static void		AllocateColors(ColorTable *colorPtr);
static void		DisposeColorTable(ClientData clientData);
................................................................................
 *	Note that Win32 pre-defines those operations that we really need.
 *
 *	Note that on MacOS, if the background comes from a Retina display
 *	then it will be twice as wide and twice as high as the photoimage.
 *
 *----------------------------------------------------------------------
 */
#ifndef TKPUTIMAGE_CAN_BLEND
#ifndef _WIN32
#define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
#define RGB(r, g, b)	((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \
	(UCHAR(b) << blue_shift)  ))







#define RGB15(r, g, b)	((unsigned)( \
	(((r) * red_mask / 255)   & red_mask)   | \
	(((g) * green_mask / 255) & green_mask) | \
	(((b) * blue_mask / 255)  & blue_mask)  ))
#endif /* !_WIN32 */

static void
................................................................................
				 * draw. */
    int width, int height)	/* Width & height of image to draw. */
{
    int x, y, line;
    unsigned long pixel;
    unsigned char r, g, b, alpha, unalpha, *masterPtr;
    unsigned char *alphaAr = iPtr->masterPtr->pix32;











    /*
     * This blending is an integer version of the Source-Over compositing rule
     * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
     * 1984) that has been hard-coded (for speed) to work with targetting a
     * solid surface.
     *
     * The 'unalpha' field must be 255-alpha; it is separated out to encourage
................................................................................
    }
    while ((0x0001 & (green_mask >> green_shift)) == 0) {
	green_shift++;
    }
    while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
	blue_shift++;
    }







#endif /* !_WIN32 */

    /*
     * Only UNIX requires the special case for <24bpp. It varies with 3 extra
     * shifts and uses RGB15. The 24+bpp version could also then be further
     * optimized.
     */

#if !defined(_WIN32)
    if (bgImg->depth < 24) {
	unsigned char red_mlen, green_mlen, blue_mlen;

	red_mlen = 8 - CountBits(red_mask >> red_shift);
	green_mlen = 8 - CountBits(green_mask >> green_shift);
	blue_mlen = 8 - CountBits(blue_mask >> blue_shift);
	for (y = 0; y < height; y++) {
................................................................................
		    }
		    XPutPixel(bgImg, x, y, RGB15(r, g, b));
		}
	    }
	}
	return;
    }
#endif /* !_WIN32 */

    for (y = 0; y < height; y++) {

	line = (y + yOffset) * iPtr->masterPtr->width;
	for (x = 0; x < width; x++) {
	    masterPtr = alphaAr + ((line + x + xOffset) * 4);






	    alpha = masterPtr[3];

	    /*
	     * Ignore pixels that are fully transparent
	     */

	    if (alpha) {
................................................................................
		    ga = GetGValue(pixel);
		    ba = GetBValue(pixel);
		    unalpha = 255 - alpha;	/* Calculate once. */
		    r = ALPHA_BLEND(ra, r, alpha, unalpha);
		    g = ALPHA_BLEND(ga, g, alpha, unalpha);
		    b = ALPHA_BLEND(ba, b, alpha, unalpha);
		}

		XPutPixel(bgImg, x, y, RGB(r, g, b));



	    }
	}
    }
#undef ALPHA_BLEND
}
#endif /* TKPUTIMAGE_CAN_BLEND */
 
/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
................................................................................
				 * draw. */
    int width, int height,	/* Dimensions of region within image to
				 * draw. */
    int drawableX,int drawableY)/* Coordinates within drawable that correspond
				 * to imageX and imageY. */
{
    PhotoInstance *instancePtr = clientData;
#ifndef TKPUTIMAGE_CAN_BLEND
    XVisualInfo visInfo = instancePtr->visualInfo;
#endif
    
    /*
     * If there's no pixmap, it means that an error occurred while creating
     * the image instance so it can't be displayed.
     */

    if (instancePtr->pixels == None) {
	return;
    }

#ifdef TKPUTIMAGE_CAN_BLEND
    /*
     * If TkPutImage can handle RGBA Ximages directly there is
     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
     */

    unsigned char *rgbaPixels = instancePtr->masterPtr->pix32;
    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
				 (unsigned int)instancePtr->width,
				 (unsigned int)instancePtr->height,
				 0, (unsigned int)(4 * instancePtr->width));
    TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
	       photo, imageX, imageY, drawableX, drawableY,
	       (unsigned int) width, (unsigned int) height);
    photo->data = NULL;
    XDestroyImage(photo);
#else

    if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

................................................................................
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);
    }
    XFlush(display);
#endif
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoFree --
 *

Changes to generic/tkInt.h.

559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
...
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
...
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
....
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
#ifdef TK_USE_INPUT_METHODS
    XIM inputMethod;		/* Input method for this display. */
    XIMStyle inputStyle;	/* Input style selected for this display. */
    XFontSet inputXfs;		/* XFontSet cached for over-the-spot XIM. */
#endif /* TK_USE_INPUT_METHODS */
    Tcl_HashTable winTable;	/* Maps from X window ids to TkWindow ptrs. */

    size_t refCount;		/* Reference count of how many Tk applications
				 * are using this display. Used to clean up
				 * the display when we no longer have any Tk
				 * applications using it. */

    /*
     * The following field were all added for Tk8.3
     */
................................................................................
/*
 * Tk keeps one of the following data structures for each main window (created
 * by a call to TkCreateMainWindow). It stores information that is shared by
 * all of the windows associated with a particular main window.
 */

typedef struct TkMainInfo {
    size_t refCount;		/* Number of windows whose "mainPtr" fields
				 * point here. When this becomes zero, can
				 * free up the structure (the reference count
				 * is zero because windows can get deleted in
				 * almost any order; the main window isn't
				 * necessarily the last one deleted). */
    struct TkWindow *winPtr;	/* Pointer to main window. */
    Tcl_Interp *interp;		/* Interpreter associated with application. */
................................................................................
typedef struct {
    XKeyEvent keyEvent;	/* The real event from X11. */
    char *charValuePtr;	/* A pointer to a string that holds the key's
				 * %A substitution text (before backslash
				 * adding), or NULL if that has not been
				 * computed yet. If non-NULL, this string was
				 * allocated with ckalloc(). */
    size_t charValueLen;	/* Length of string in charValuePtr when that
				 * is non-NULL. */
    KeySym keysym;		/* Key symbol computed after input methods
				 * have been invoked */
} TkKeyEvent;

/*
 * Flags passed to TkpMakeMenuWindow's 'transient' argument.
................................................................................
#   define TkUtfToUniChar (size_t)Tcl_UtfToUniChar
#   define TkUniCharToUtf (size_t)Tcl_UniCharToUtf
#else
    MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
#endif

#ifdef TCL_TYPE_I
/* With TIP #481 available, we don't need to do anything special here */
#define TkGetStringFromObj(objPtr, lenPtr) \
	Tcl_GetStringFromObj(objPtr, lenPtr)
#define TkGetByteArrayFromObj(objPtr, lenPtr) \
	Tcl_GetByteArrayFromObj(objPtr, lenPtr)
#else
#define TkGetStringFromObj(objPtr, lenPtr) \
	(((objPtr)->bytes ? 0 : Tcl_GetString(objPtr)), \
	*(lenPtr) = (objPtr)->length, (objPtr)->bytes)

MODULE_SCOPE unsigned char *TkGetByteArrayFromObj(Tcl_Obj *objPtr,
	size_t *lengthPtr);
#endif

/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,






|







 







|







 







|







 







<
<
<
<
<
<
<






<







559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
...
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
...
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
....
1342
1343
1344
1345
1346
1347
1348







1349
1350
1351
1352
1353
1354

1355
1356
1357
1358
1359
1360
1361
#ifdef TK_USE_INPUT_METHODS
    XIM inputMethod;		/* Input method for this display. */
    XIMStyle inputStyle;	/* Input style selected for this display. */
    XFontSet inputXfs;		/* XFontSet cached for over-the-spot XIM. */
#endif /* TK_USE_INPUT_METHODS */
    Tcl_HashTable winTable;	/* Maps from X window ids to TkWindow ptrs. */

    TkSizeT refCount;		/* Reference count of how many Tk applications
				 * are using this display. Used to clean up
				 * the display when we no longer have any Tk
				 * applications using it. */

    /*
     * The following field were all added for Tk8.3
     */
................................................................................
/*
 * Tk keeps one of the following data structures for each main window (created
 * by a call to TkCreateMainWindow). It stores information that is shared by
 * all of the windows associated with a particular main window.
 */

typedef struct TkMainInfo {
    TkSizeT refCount;		/* Number of windows whose "mainPtr" fields
				 * point here. When this becomes zero, can
				 * free up the structure (the reference count
				 * is zero because windows can get deleted in
				 * almost any order; the main window isn't
				 * necessarily the last one deleted). */
    struct TkWindow *winPtr;	/* Pointer to main window. */
    Tcl_Interp *interp;		/* Interpreter associated with application. */
................................................................................
typedef struct {
    XKeyEvent keyEvent;	/* The real event from X11. */
    char *charValuePtr;	/* A pointer to a string that holds the key's
				 * %A substitution text (before backslash
				 * adding), or NULL if that has not been
				 * computed yet. If non-NULL, this string was
				 * allocated with ckalloc(). */
    TkSizeT charValueLen;	/* Length of string in charValuePtr when that
				 * is non-NULL. */
    KeySym keysym;		/* Key symbol computed after input methods
				 * have been invoked */
} TkKeyEvent;

/*
 * Flags passed to TkpMakeMenuWindow's 'transient' argument.
................................................................................
#   define TkUtfToUniChar (size_t)Tcl_UtfToUniChar
#   define TkUniCharToUtf (size_t)Tcl_UniCharToUtf
#else
    MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
#endif








#define TkGetStringFromObj(objPtr, lenPtr) \
	(((objPtr)->bytes ? 0 : Tcl_GetString(objPtr)), \
	*(lenPtr) = (objPtr)->length, (objPtr)->bytes)

MODULE_SCOPE unsigned char *TkGetByteArrayFromObj(Tcl_Obj *objPtr,
	size_t *lengthPtr);


/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,

Changes to generic/tkMenu.h.

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
388
389
390
391
392
393
394

395
396
397
398
399
400
401
    int type;			/* Type of menu entry; see below for valid
				 * types. */
    struct TkMenu *menuPtr;	/* Menu with which this entry is
				 * associated. */
    Tk_OptionTable optionTable;	/* Option table for this menu entry. */
    Tcl_Obj *labelPtr;		/* Main text label displayed in entry (NULL if
				 * no label). */
#if TK_MAJOR_VERSION > 8
    size_t labelLength;		/* Number of non-NULL characters in label. */
#else
    unsigned int labelLength;		/* Number of non-NULL characters in label. */
#endif
    int state;			/* State of button for display purposes:
				 * normal, active, or disabled. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline (-1 means don't
				 * underline anything). */
    Tcl_Obj *underlinePtr;	/* Index of character to underline. */
    Tcl_Obj *bitmapPtr;		/* Bitmap to display in menu entry, or None.
................................................................................
    Tcl_Obj *selectImagePtr;	/* Name of image to display when selected, or
				 * NULL. */
    Tk_Image selectImage;	/* Image to display in entry when selected, or
				 * NULL if none. Ignored if image is NULL. */
    Tcl_Obj *accelPtr;		/* Accelerator string displayed at right of
				 * menu entry. NULL means no such accelerator.
				 * Malloc'ed. */
#if TK_MAJOR_VERSION > 8
    size_t accelLength;		/* Number of non-NULL characters in
				 * accelerator. */
#else
    unsigned int accelLength;		/* Number of non-NULL characters in
				 * accelerator. */
#endif
    int indicatorOn;		/* True means draw indicator, false means
				 * don't draw it. This field is ignored unless
				 * the entry is a radio or check button. */
    /*
     * Display attributes
     */

................................................................................
				 * background for menu. */
    Tcl_Obj *borderWidthPtr;	/* Width of border around whole menu. */
    Tcl_Obj *activeBorderPtr;	/* Used to draw background and border for
				 * active element (if any). */
    Tcl_Obj *activeBorderWidthPtr;
				/* Width of border around active element. */
    Tcl_Obj *reliefPtr;		/* 3-d effect: TK_RELIEF_RAISED, etc. */
    Tcl_Obj *activeReliefPtr;	/* 3-d effect for active element. */
    Tcl_Obj *fontPtr;		/* Text font for menu entries. */
    Tcl_Obj *fgPtr;		/* Foreground color for entries. */
    Tcl_Obj *disabledFgPtr;	/* Foreground color when disabled. NULL means
				 * use normalFg with a 50% stipple instead. */
    Tcl_Obj *activeFgPtr;	/* Foreground color for active entry. */
    Tcl_Obj *indicatorFgPtr;	/* Color for indicators in radio and check
				 * button entries. */
................................................................................
				 * of options are in this structure. */
    Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for
				 * this widget to be extended. */
    Tk_SavedOptions *errorStructPtr;
				/* We actually have to allocate these because
				 * multiple menus get changed during one
				 * ConfigureMenu call. */

} TkMenu;

/*
 * When the toplevel configure -menu command is executed, the menu may not
 * exist yet. We need to keep a linked list of windows that reference a
 * particular menu.
 */






<
|
<
<
<







 







<
|

<
<
<
<







 







<







 







>







64
65
66
67
68
69
70

71



72
73
74
75
76
77
78
..
85
86
87
88
89
90
91

92
93




94
95
96
97
98
99
100
...
284
285
286
287
288
289
290

291
292
293
294
295
296
297
...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
    int type;			/* Type of menu entry; see below for valid
				 * types. */
    struct TkMenu *menuPtr;	/* Menu with which this entry is
				 * associated. */
    Tk_OptionTable optionTable;	/* Option table for this menu entry. */
    Tcl_Obj *labelPtr;		/* Main text label displayed in entry (NULL if
				 * no label). */

    TkSizeT labelLength;	/* Number of non-NULL characters in label. */



    int state;			/* State of button for display purposes:
				 * normal, active, or disabled. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline (-1 means don't
				 * underline anything). */
    Tcl_Obj *underlinePtr;	/* Index of character to underline. */
    Tcl_Obj *bitmapPtr;		/* Bitmap to display in menu entry, or None.
................................................................................
    Tcl_Obj *selectImagePtr;	/* Name of image to display when selected, or
				 * NULL. */
    Tk_Image selectImage;	/* Image to display in entry when selected, or
				 * NULL if none. Ignored if image is NULL. */
    Tcl_Obj *accelPtr;		/* Accelerator string displayed at right of
				 * menu entry. NULL means no such accelerator.
				 * Malloc'ed. */

    TkSizeT accelLength;	/* Number of non-NULL characters in
				 * accelerator. */




    int indicatorOn;		/* True means draw indicator, false means
				 * don't draw it. This field is ignored unless
				 * the entry is a radio or check button. */
    /*
     * Display attributes
     */

................................................................................
				 * background for menu. */
    Tcl_Obj *borderWidthPtr;	/* Width of border around whole menu. */
    Tcl_Obj *activeBorderPtr;	/* Used to draw background and border for
				 * active element (if any). */
    Tcl_Obj *activeBorderWidthPtr;
				/* Width of border around active element. */
    Tcl_Obj *reliefPtr;		/* 3-d effect: TK_RELIEF_RAISED, etc. */

    Tcl_Obj *fontPtr;		/* Text font for menu entries. */
    Tcl_Obj *fgPtr;		/* Foreground color for entries. */
    Tcl_Obj *disabledFgPtr;	/* Foreground color when disabled. NULL means
				 * use normalFg with a 50% stipple instead. */
    Tcl_Obj *activeFgPtr;	/* Foreground color for active entry. */
    Tcl_Obj *indicatorFgPtr;	/* Color for indicators in radio and check
				 * button entries. */
................................................................................
				 * of options are in this structure. */
    Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for
				 * this widget to be extended. */
    Tk_SavedOptions *errorStructPtr;
				/* We actually have to allocate these because
				 * multiple menus get changed during one
				 * ConfigureMenu call. */
    Tcl_Obj *activeReliefPtr;	/* 3-d effect for active element. */
} TkMenu;

/*
 * When the toplevel configure -menu command is executed, the menu may not
 * exist yet. We need to keep a linked list of windows that reference a
 * particular menu.
 */

Changes to generic/tkOption.c.

991
992
993
994
995
996
997



998
999
1000
1001
1002
1003
1004
....
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
	/*
	 * Skip white space between the name and the value.
	 */

	src++;
	while ((*src == ' ') || (*src == '\t')) {
	    src++;



	}
	if (*src == '\0') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "missing value on line %d", lineNum));
	    Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "VALUE", NULL);
	    return TCL_ERROR;
	}
................................................................................
		    src += 2;
		    lineNum++;
		    continue;
		} else if (src[1] == 'n') {
		    src += 2;
		    *dst++ = '\n';
		    continue;
		} else if (src[1] == '\t' || src[1] == ' ' || src[1] == '\\') {
		    ++src;
		} else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
			src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
		    *dst++ = ((src[1]&7)<<6) | ((src[2]&7)<<3) | (src[3]&7);
		    src += 4;
		    continue;
		}






>
>
>







 







|







991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
....
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
	/*
	 * Skip white space between the name and the value.
	 */

	src++;
	while ((*src == ' ') || (*src == '\t')) {
	    src++;
	}
	if (*src == '\\' && (src[1] == '\t' || src[1] == ' ')) {
	    src++;
	}
	if (*src == '\0') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "missing value on line %d", lineNum));
	    Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "VALUE", NULL);
	    return TCL_ERROR;
	}
................................................................................
		    src += 2;
		    lineNum++;
		    continue;
		} else if (src[1] == 'n') {
		    src += 2;
		    *dst++ = '\n';
		    continue;
		} else if (src[1] == '\\') {
		    ++src;
		} else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
			src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
		    *dst++ = ((src[1]&7)<<6) | ((src[2]&7)<<3) | (src[3]&7);
		    src += 4;
		    continue;
		}

Changes to generic/tkPack.c.

606
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
....
1369
1370
1371
1372
1373
1374
1375



1376
1377
1378
1379
1380

1381
1382
1383
1384
1385
1386
1387
    int borderTop, borderBtm;
    int borderLeft, borderRight;
    int maxWidth, maxHeight, tmp;

    masterPtr->flags &= ~REQUESTED_REPACK;

    /*
     * If the master has no slaves anymore, then don't do anything at all:
     * just leave the master's size as-is.

     */

    if (masterPtr->slavePtr == NULL) {
	return;
    }

    /*
................................................................................
    }

    packPtr->masterPtr = NULL;

    /*
     * If we have emptied this master from slaves it means we are no longer
     * handling it and should mark it as free.



     */

    if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) {
	TkFreeGeometryMaster(masterPtr->tkwin, "pack");
	masterPtr->flags &= ~ALLOCED_MASTER;

    }

}
 
/*
 *----------------------------------------------------------------------
 *






|
|
>







 







>
>
>





>







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
....
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
    int borderTop, borderBtm;
    int borderLeft, borderRight;
    int maxWidth, maxHeight, tmp;

    masterPtr->flags &= ~REQUESTED_REPACK;

    /*
     * If the master has no slaves anymore, then leave the master's size as-is.
     * Otherwise there is no way to "relinquish" control over the master
     * so another geometry manager can take over.
     */

    if (masterPtr->slavePtr == NULL) {
	return;
    }

    /*
................................................................................
    }

    packPtr->masterPtr = NULL;

    /*
     * If we have emptied this master from slaves it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the master to inform it about there
     * being no managed children inside it.
     */

    if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) {
	TkFreeGeometryMaster(masterPtr->tkwin, "pack");
	masterPtr->flags &= ~ALLOCED_MASTER;
	TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL);
    }

}
 
/*
 *----------------------------------------------------------------------
 *

Changes to generic/tkScale.h.

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
				 * commands because the scale value changed.
				 * NULL means don't invoke commands. */
    int repeatDelay;		/* How long to wait before auto-repeating on
				 * scrolling actions (in ms). */
    int repeatInterval;		/* Interval between autorepeats (in ms). */
    char *label;		/* Label to display above or to right of
				 * scale; NULL means don't display a label. */
#if TK_MAJOR_VERSION > 8
    size_t labelLength;		/* Number of non-NULL chars. in label. */
#else
    unsigned int labelLength;		/* Number of non-NULL chars. in label. */
#endif
    enum state state;		/* Values are active, normal, or disabled.
				 * Value of scale cannot be changed when
				 * disabled. */

    /*
     * Information used when displaying widget:
     */






<
|
<
<
<







81
82
83
84
85
86
87

88



89
90
91
92
93
94
95
				 * commands because the scale value changed.
				 * NULL means don't invoke commands. */
    int repeatDelay;		/* How long to wait before auto-repeating on
				 * scrolling actions (in ms). */
    int repeatInterval;		/* Interval between autorepeats (in ms). */
    char *label;		/* Label to display above or to right of
				 * scale; NULL means don't display a label. */

    TkSizeT labelLength;	/* Number of non-NULL chars. in label. */



    enum state state;		/* Values are active, normal, or disabled.
				 * Value of scale cannot be changed when
				 * disabled. */

    /*
     * Information used when displaying widget:
     */

Changes to generic/tkTest.c.

27
28
29
30
31
32
33



34
35
36
37
38
39
40
....
1556
1557
1558
1559
1560
1561
1562

















1563
1564
1565
1566
1567
1568
1569
1570
1571
1572


1573
1574
1575
1576
1577
1578
1579
#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"



#endif

#ifdef __UNIX__
#include "tkUnixInt.h"
#endif

/*
................................................................................
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    TImageInstance *instPtr = (TImageInstance *) clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];


















    sprintf(buffer, "%s display %d %d %d %d",
	    instPtr->masterPtr->imageName, imageX, imageY, width, height);
    Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    if (width > (instPtr->masterPtr->width - imageX)) {
	width = instPtr->masterPtr->width - imageX;
    }
    if (height > (instPtr->masterPtr->height - imageY)) {
	height = instPtr->masterPtr->height - imageY;
    }


    XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
	    (unsigned) (width-1), (unsigned) (height-1));
    XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
	    (int) (drawableX + width - 1), (int) (drawableY + height - 1));
    XDrawLine(display, drawable, instPtr->gc, drawableX,
	    (int) (drawableY + height - 1),
	    (int) (drawableX + width - 1), drawableY);






>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|






>
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
....
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"
#define SIMULATE_DRAWING TkTestSimulateDrawing(true);
#else
#define SIMULATE_DRAWING
#endif

#ifdef __UNIX__
#include "tkUnixInt.h"
#endif

/*
................................................................................
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    TImageInstance *instPtr = (TImageInstance *) clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];

    /*
     * The purpose of the test image type is to track the calls to an image
     * display proc and record the parameters passed in each call.  On macOS
     * these tests will fail because of the asynchronous drawing.  The low
     * level graphics calls below which are supposed to draw a rectangle will
     * not draw anything to the screen because the idle task will not be
     * processed inside of the drawRect method and hence will not be able to
     * obtain a valid graphics context. Instead, the window will be marked as
     * needing display, and will be redrawn during a future asynchronous call
     * to drawRect.  This will generate an other call to this display proc,
     * and the recorded data will show extra calls, causing the test to fail.
     * To avoid this, we can set the [NSApp simulateDrawing] flag, which will
     * cause all low level drawing routines to return immediately and not
     * schedule the window for drawing later.  This flag is cleared by the
     * next call to XSync, which is called by the update command.
     */

    sprintf(buffer, "%s display %d %d %d %d",
	    instPtr->masterPtr->imageName, imageX, imageY, width, height);
    Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
		buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    if (width > (instPtr->masterPtr->width - imageX)) {
	width = instPtr->masterPtr->width - imageX;
    }
    if (height > (instPtr->masterPtr->height - imageY)) {
	height = instPtr->masterPtr->height - imageY;
    }

    SIMULATE_DRAWING
    XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
	    (unsigned) (width-1), (unsigned) (height-1));
    XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
	    (int) (drawableX + width - 1), (int) (drawableY + height - 1));
    XDrawLine(display, drawable, instPtr->gc, drawableX,
	    (int) (drawableY + height - 1),
	    (int) (drawableX + width - 1), drawableY);

Changes to generic/tkText.c.

80
81
82
83
84
85
86






87
88
89
90
91
92
93
.....
10285
10286
10287
10288
10289
10290
10291












10292
10293
10294
10295
10296
10297
10298
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR NULL
# else /* X11 */
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR BLACK
# endif
# define DEF_TEXT_INACTIVE_SELECT_BG_COLOR DEF_TEXT_INACTIVE_SELECT_COLOR
#endif







/*
 * For compatibility with Tk 4.0 through 8.4.x, we allow tabs to be
 * mis-specified with non-increasing values. These are converted into tabs
 * which are the equivalent of at least a character width apart.
 */

#if TK_MAJOR_VERSION < 9
................................................................................
    if (syncState) {
	textPtr->sendSyncEvent = false;
    }
    textPtr->prevSyncState = syncState;

    interp = textPtr->interp;
    Tcl_Preserve((ClientData) interp);












    SendVirtualEvent(textPtr->tkwin, "WidgetViewSync", Tcl_NewBooleanObj(syncState));
    Tcl_Release((ClientData) interp);
}

void
TkTextGenerateWidgetViewSyncEvent(
    TkText *textPtr,		/* Information about text widget. */






>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
.....
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR NULL
# else /* X11 */
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR BLACK
# endif
# define DEF_TEXT_INACTIVE_SELECT_BG_COLOR DEF_TEXT_INACTIVE_SELECT_COLOR
#endif

#if defined(MAC_OSX_TK)
# define FORCE_DISPLAY(winPtr) TkpDisplayWindow(winPtr)
#else
# define FORCE_DISPLAY(winPtr)
#endif

/*
 * For compatibility with Tk 4.0 through 8.4.x, we allow tabs to be
 * mis-specified with non-increasing values. These are converted into tabs
 * which are the equivalent of at least a character width apart.
 */

#if TK_MAJOR_VERSION < 9
................................................................................
    if (syncState) {
	textPtr->sendSyncEvent = false;
    }
    textPtr->prevSyncState = syncState;

    interp = textPtr->interp;
    Tcl_Preserve((ClientData) interp);
    /*
     * OSX 10.14 needs to be told to display the window when the Text Widget
     * is in sync.  (That is, to run DisplayText inside of the drawRect
     * method.)  Otherwise the screen might not get updated until an event
     * like a mouse click is received.  But that extra drawing corrupts the
     * data that the test suite is trying to collect.
     */
    
    if (!tkTextDebug) {
	FORCE_DISPLAY(textPtr->tkwin);
    }

    SendVirtualEvent(textPtr->tkwin, "WidgetViewSync", Tcl_NewBooleanObj(syncState));
    Tcl_Release((ClientData) interp);
}

void
TkTextGenerateWidgetViewSyncEvent(
    TkText *textPtr,		/* Information about text widget. */

Changes to generic/tkTextDisp.c.

29
30
31
32
33
34
35


36
37
38
39
40
41
42
43


44
45
46
47
48
49
50
....
7173
7174
7175
7176
7177
7178
7179










































7180
7181
7182
7183
7184
7185
7186
# include "tkWinInt.h"
#elif defined(__CYGWIN__)
# include "tkUnixInt.h"
#endif

#ifdef MAC_OSX_TK
# include "tkMacOSXInt.h"


/* Version 8.5 has forgotten to define this constant. */
# ifndef TK_DO_NOT_DRAW
#  define TK_DO_NOT_DRAW 0x80
# endif
# ifndef DEF_TEXT_INACTIVE_SELECT_COLOR_DISABLED
#  define DEF_TEXT_INACTIVE_SELECT_COLOR_DISABLED "1"
# endif
#else /* for portability to 8.5/6 */


# ifndef DEF_TEXT_INACTIVE_SELECT_COLOR_DISABLED
#  define DEF_TEXT_INACTIVE_SELECT_COLOR_DISABLED "0"
# endif
#endif

#include <stdlib.h>
#include <assert.h>
................................................................................
	    }
	}

	/* The update process has removed the finished lines. */
	range = TkRangeListFirst(dInfoPtr->lineMetricUpdateRanges);
    }
}










































 
/*
 *----------------------------------------------------------------------
 *
 * TkTextUpdateLineMetrics --
 *
 *	This function updates the pixel height calculations of a range of






>
>








>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
....
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
# include "tkWinInt.h"
#elif defined(__CYGWIN__)
# include "tkUnixInt.h"
#endif

#ifdef MAC_OSX_TK
# include "tkMacOSXInt.h"
#define OK_TO_LOG (!TkpAppIsDrawing())
#define FORCE_DISPLAY(winPtr) TkpDisplayWindow(winPtr)
/* Version 8.5 has forgotten to define this constant. */
# ifndef TK_DO_NOT_DRAW
#  define TK_DO_NOT_DRAW 0x80
# endif
# ifndef DEF_TEXT_INACTIVE_SELECT_COLOR_DISABLED
#  define DEF_TEXT_INACTIVE_SELECT_COLOR_DISABLED "1"
# endif
#else /* for portability to 8.5/6 */
#define OK_TO_LOG 1
#define FORCE_DISPLAY(winPtr)
# ifndef DEF_TEXT_INACTIVE_SELECT_COLOR_DISABLED
#  define DEF_TEXT_INACTIVE_SELECT_COLOR_DISABLED "0"
# endif
#endif

#include <stdlib.h>
#include <assert.h>
................................................................................
	    }
	}

	/* The update process has removed the finished lines. */
	range = TkRangeListFirst(dInfoPtr->lineMetricUpdateRanges);
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * GenerateWidgetViewSyncEvent --
 *
 *      Send the <<WidgetViewSync>> event related to the text widget
 *      line metrics asynchronous update.
 *      This is equivalent to:
 *         event generate $textWidget <<WidgetViewSync>> -data $s
 *      where $s is the sync status: true (when the widget view is in
 *      sync with its internal data) or false (when it is not).
 *
 * Results:
 *      None
 *
 * Side effects:
 *      If corresponding bindings are present, they will trigger.
 *
 *----------------------------------------------------------------------
 */

static void
GenerateWidgetViewSyncEvent(
    TkText *textPtr,		/* Information about text widget. */
    Bool InSync)                /* true if in sync, false otherwise */
{
    /*
     * OSX 10.14 needs to be told to display the window when the Text Widget
     * is in sync.  (That is, to run DisplayText inside of the drawRect
     * method.)  Otherwise the screen might not get updated until an event
     * like a mouse click is received.  But that extra drawing corrupts the
     * data that the test suite is trying to collect.
     */
    
    if (!tkTextDebug) {
	FORCE_DISPLAY(textPtr->tkwin);
    }
    
    TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
        Tcl_NewBooleanObj(InSync));
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkTextUpdateLineMetrics --
 *
 *	This function updates the pixel height calculations of a range of

Changes to generic/tkUtil.c.

1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
    }
    return size;
}


#endif

#ifndef TCL_TYPE_I
unsigned char *
TkGetByteArrayFromObj(
	Tcl_Obj *objPtr,
	size_t *lengthPtr
) {
    int length;

    unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, &length);
#if TK_MAJOR_VERSION > 8
    if (sizeof(TCL_HASH_TYPE) > sizeof(int)) {
	/* 64-bit and TIP #494 situation: */
	 *lengthPtr = *(TCL_HASH_TYPE *) objPtr->internalRep.twoPtrValue.ptr1;
    } else
#endif
	/* 32-bit or without TIP #494 */
    *lengthPtr = (size_t) (unsigned) length;
    return result;
}
#endif /* !TCL_TYPE_I */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */






<








|









<








1268
1269
1270
1271
1272
1273
1274

1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292

1293
1294
1295
1296
1297
1298
1299
1300
    }
    return size;
}


#endif


unsigned char *
TkGetByteArrayFromObj(
	Tcl_Obj *objPtr,
	size_t *lengthPtr
) {
    int length;

    unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, &length);
#if TCL_MAJOR_VERSION > 8
    if (sizeof(TCL_HASH_TYPE) > sizeof(int)) {
	/* 64-bit and TIP #494 situation: */
	 *lengthPtr = *(TCL_HASH_TYPE *) objPtr->internalRep.twoPtrValue.ptr1;
    } else
#endif
	/* 32-bit or without TIP #494 */
    *lengthPtr = (size_t) (unsigned) length;
    return result;
}


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkWindow.c.

2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
....
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
#if defined(_WIN32)

static HMODULE tkcygwindll = NULL;

/*
 * Run Tk_MainEx from libtk8.?.dll
 *
 * This function is only ever called from wish8.4.exe, the cygwin port of Tcl.
 * This means that the system encoding is utf-8, so we don't have to do any
 * encoding conversions.
 */

int
TkCygwinMainEx(
    int argc,			/* Number of arguments. */
................................................................................
    Tcl_AppInitProc *appInitProc,
				/* Application-specific initialization
				 * procedure to call after most initialization
				 * but before starting to execute commands. */
    Tcl_Interp *interp)
{
    TCHAR name[MAX_PATH];
    int len;
    void (*tkmainex)(int, char **, Tcl_AppInitProc *, Tcl_Interp *);

    /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */
    len = GetModuleFileNameW(Tk_GetHINSTANCE(), name, MAX_PATH);
    name[len-2] = TEXT('.');
    name[len-1] = name[len-5];
    _tcscpy(name+len, TEXT(".dll"));






|







 







|







2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
....
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
#if defined(_WIN32)

static HMODULE tkcygwindll = NULL;

/*
 * Run Tk_MainEx from libtk8.?.dll
 *
 * This function is only ever called from wish8.?.exe, the cygwin port of Tcl.
 * This means that the system encoding is utf-8, so we don't have to do any
 * encoding conversions.
 */

int
TkCygwinMainEx(
    int argc,			/* Number of arguments. */
................................................................................
    Tcl_AppInitProc *appInitProc,
				/* Application-specific initialization
				 * procedure to call after most initialization
				 * but before starting to execute commands. */
    Tcl_Interp *interp)
{
    TCHAR name[MAX_PATH];
    size_t len;
    void (*tkmainex)(int, char **, Tcl_AppInitProc *, Tcl_Interp *);

    /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */
    len = GetModuleFileNameW(Tk_GetHINSTANCE(), name, MAX_PATH);
    name[len-2] = TEXT('.');
    name[len-1] = name[len-5];
    _tcscpy(name+len, TEXT(".dll"));

Changes to library/ttk/treeview.tcl.

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
## ActivateHeading -- track active heading element
#
proc ttk::treeview::ActivateHeading {w heading} {
    variable State

    if {$w != $State(activeWidget) || $heading != $State(activeHeading)} {
	if {$State(activeHeading) != {}} {
	    $State(activeWidget) heading $State(activeHeading) state !active
	}
	if {$heading != {}} {
	    $w heading $heading state active
	}
	set State(activeHeading) $heading
	set State(activeWidget) $w






|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
## ActivateHeading -- track active heading element
#
proc ttk::treeview::ActivateHeading {w heading} {
    variable State

    if {$w != $State(activeWidget) || $heading != $State(activeHeading)} {
	if {[winfo exists $State(activeWidget)] && $State(activeHeading) != {}} {
	    $State(activeWidget) heading $State(activeHeading) state !active
	}
	if {$heading != {}} {
	    $w heading $heading state active
	}
	set State(activeHeading) $heading
	set State(activeWidget) $w

Changes to macosx/README.

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572

inefficient to iterate through all embedded windows in a Text widget,
looking for those which meet the scrolling area, the damage region
constructed by TkScrollWindow contains only the difference between the
source and destination rectangles for the scrolling.  The embedded
windows are redrawn within the DisplayText function by some
conditional code which is only used for macOS.

5.0 Virtual events on 10.14
~~~~~~~~~~~~~~~~~~~~~~~~~~~

10.14 supports system appearance changes, and has added a "Dark Mode"
that casts all window frames and menus as black. Tk 8.6.9 has added two
virtual events, <<LightAqua>> and <<DarkAqua>>, to allow you to update
your Tk app's appearance when the system appearance changes. Just bind
your appearance-updating code to these virtual events and you will see
it triggered when the system appearance toggles between dark and light.







|



|
|
|
|
|
>
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
inefficient to iterate through all embedded windows in a Text widget,
looking for those which meet the scrolling area, the damage region
constructed by TkScrollWindow contains only the difference between the
source and destination rectangles for the scrolling.  The embedded
windows are redrawn within the DisplayText function by some
conditional code which is only used for macOS.

5.0 Dark Mode on 10.14
~~~~~~~~~~~~~~~~~~~~~~~~~~~

10.14 supports system appearance changes, and has added a "Dark Mode"
that casts all window frames and menus as black. Tk 8.6.9 supports Dark
Mode by having the window decorations, menus, and dialogs automatically
take on the appropriate appearance when the system appearance is changed. 
Because the window content itself is drawn by Tk, it will not change when
the system mode changes.

Changes to macosx/tkMacOSXButton.c.

416
417
418
419
420
421
422



423
424
425
426
427
428
429
....
1194
1195
1196
1197
1198
1199
1200








    } else {
        height += butPtr->borderWidth*2;
        width += butPtr->borderWidth*2;
    }

    width += butPtr->inset*2;
    height += butPtr->inset*2;




    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
................................................................................
{
    MacButton *mbPtr = (MacButton *)clientData;
    TkpDisplayButton(clientData);
    mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
            PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData);
}















>
>
>







 







>
>
>
>
>
>
>
>
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
....
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
    } else {
        height += butPtr->borderWidth*2;
        width += butPtr->borderWidth*2;
    }

    width += butPtr->inset*2;
    height += butPtr->inset*2;
    if ([NSApp macMinorVersion] == 6) {
      width += 12;
    }

    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
................................................................................
{
    MacButton *mbPtr = (MacButton *)clientData;
    TkpDisplayButton(clientData);
    mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler(
            PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXClipboard.c.

8
9
10
11
12
13
14

15
16
17
18
19
20
21
 * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"

#include "tkSelect.h"

static NSInteger changeCount = -1;
static Tk_Window clipboardOwner = NULL;

#pragma mark TKApplication(TKClipboard)







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
#include "tkSelect.h"

static NSInteger changeCount = -1;
static Tk_Window clipboardOwner = NULL;

#pragma mark TKApplication(TKClipboard)

Changes to macosx/tkMacOSXConfig.c.

37
38
39
40
41
42
43









TkpGetSystemDefault(
    Tk_Window tkwin,			/* A window to use. */
    const char *dbName,			/* The option database name. */
    const char *className)		/* The name of the option class. */
{
    return NULL;
}















>
>
>
>
>
>
>
>
>
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
TkpGetSystemDefault(
    Tk_Window tkwin,			/* A window to use. */
    const char *dbName,			/* The option database name. */
    const char *className)		/* The name of the option class. */
{
    return NULL;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXConstants.h.

11
12
13
14
15
16
17




18
19
20
21
22





23
24
25
26




27
28
29

30
31
32
33
34
35
36
..
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95






96




 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMACCONSTANTS
#define _TKMACCONSTANTS





/*
 * Let's raise a glass for the project manager who improves our lives by
 * generating deprecation warnings about pointless changes of the names
 * of constants.
 */






#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
#define NSOKButton NSModalResponseOK
#endif





#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
#define NSAppKitDefined NSEventTypeAppKitDefined

#define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated
#define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated
#define NSWindowExposedEventType NSEventSubtypeWindowExposed
#define NSScreenChangedEventType NSEventSubtypeScreenChanged
#define NSWindowMovedEventType NSEventSubtypeWindowMoved
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
................................................................................
#define NSFunctionKeyMask NSEventModifierFlagFunction
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
#define NSFlagsChanged NSEventTypeFlagsChanged
#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
#define NSShiftKeyMask NSEventModifierFlagShift
#define NSAnyEventMask NSEventMaskAny

#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow
#define NSHUDWindowMask NSWindowStyleMaskHUDWindow
#define NSTitledWindowMask NSWindowStyleMaskTitled
#define NSClosableWindowMask NSWindowStyleMaskClosable
#define NSResizableWindowMask NSWindowStyleMaskResizable
#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar
#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
#define NSBorderlessWindowMask NSWindowStyleMaskBorderless
#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen
#endif







#endif










>
>
>
>





>
>
>
>
>




>
>
>
>



>







 







>














>
>
>
>
>
>

>
>
>
>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMACCONSTANTS
#define _TKMACCONSTANTS

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
#define NSFullScreenWindowMask (1 << 14)
#endif

/*
 * Let's raise a glass for the project manager who improves our lives by
 * generating deprecation warnings about pointless changes of the names
 * of constants.
 */

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
#define kCTFontDefaultOrientation kCTFontOrientationDefault
#define kCTFontVerticalOrientation kCTFontOrientationVertical
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
#define NSOKButton NSModalResponseOK
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
#define kCTFontUserFixedPitchFontType kCTFontUIFontUserFixedPitch
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
#define NSAppKitDefined NSEventTypeAppKitDefined
#define NSApplicationDefined NSEventTypeApplicationDefined
#define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated
#define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated
#define NSWindowExposedEventType NSEventSubtypeWindowExposed
#define NSScreenChangedEventType NSEventSubtypeScreenChanged
#define NSWindowMovedEventType NSEventSubtypeWindowMoved
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
................................................................................
#define NSFunctionKeyMask NSEventModifierFlagFunction
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
#define NSFlagsChanged NSEventTypeFlagsChanged
#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
#define NSShiftKeyMask NSEventModifierFlagShift
#define NSAnyEventMask NSEventMaskAny
#define NSApplicationDefinedMask NSEventMaskApplicationDefined
#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow
#define NSHUDWindowMask NSWindowStyleMaskHUDWindow
#define NSTitledWindowMask NSWindowStyleMaskTitled
#define NSClosableWindowMask NSWindowStyleMaskClosable
#define NSResizableWindowMask NSWindowStyleMaskResizable
#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar
#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
#define NSBorderlessWindowMask NSWindowStyleMaskBorderless
#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define NSStringPboardType NSPasteboardTypeString
#define NSOnState NSControlStateValueOn
#define NSOffState NSControlStateValueOff
// Now we are also changing names of methods!
#define graphicsContextWithGraphicsPort graphicsContextWithCGContext
#endif


#endif

Changes to macosx/tkMacOSXDialog.c.

1194
1195
1196
1197
1198
1199
1200
1201
1202

1203
1204

1205
1206
1207




1208
1209
1210
1211
1212
1213
1214
1215
1216


1217
1218
1219
1220
1221
1222
1223
1224
1225
1226

1227
1228
1229
1230






1231
1232
1233
1234
1235
1236
1237
....
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
    [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormatter setDateFormat:@"Y"];

    NSString *year = [dateFormatter stringFromDate:[NSDate date]];

    [dateFormatter release];

    NSMutableParagraphStyle *style =

	    [[[NSParagraphStyle defaultParagraphStyle] mutableCopy]
	    autorelease];


    [style setAlignment:NSCenterTextAlignment];





    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
	    @"Tcl & Tk", @"ApplicationName",
	    @"Tcl " TCL_VERSION " & Tk " TK_VERSION, @"ApplicationVersion",
	    @TK_PATCH_LEVEL, @"Version",
	    image, @"ApplicationIcon",
	    [NSString stringWithFormat:@"Copyright %1$C 1987-%[email protected]", 0xA9,
	    year], @"Copyright",
	    [[[NSAttributedString alloc] initWithString:
	    [NSString stringWithFormat:


	    @"%1$C 1987-%[email protected] Tcl Core Team." "\n\n"
		"%1$C 1989-%[email protected] Contributors." "\n\n"
		"%1$C 2011-%[email protected] Kevin Walzer/WordTech Communications LLC." "\n\n"
		"%1$C 2014-%[email protected] Marc Culler." "\n\n"
		"%1$C 2002-%[email protected] Daniel A. Steffen." "\n\n"
		"%1$C 2001-2009 Apple Inc." "\n\n"
		"%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n"
		"%1$C 1998-2000 Jim Ingham & Ray Johnson" "\n\n"
		"%1$C 1998-2000 Scriptics Inc." "\n\n"
		"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] attributes:

	    [NSDictionary dictionaryWithObject:style
	    forKey:NSParagraphStyleAttributeName]] autorelease], @"Credits",
	    nil];
    [NSApp orderFrontStandardAboutPanelWithOptions:options];






}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXStandardAboutPanelObjCmd --
 *
................................................................................
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]];
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --






|
<
>
|
|
>
|
<
<
>
>
>
>
|
<
<
<
|
<
<
|
|
>
>
|
<
|
|
|
|
|
|
|
|
>
|
|
|
|
>
>
>
>
>
>







 







|







1194
1195
1196
1197
1198
1199
1200
1201

1202
1203
1204
1205
1206


1207
1208
1209
1210
1211



1212


1213
1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
....
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
    [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormatter setDateFormat:@"Y"];

    NSString *year = [dateFormatter stringFromDate:[NSDate date]];

    [dateFormatter release];
   

    /*
     * This replaces the old about dialog with a standard alert that displays
     * correctly on 10.14.
     */
    


    NSString *version =  @"Tcl " TCL_PATCH_LEVEL " & Tk " TCL_PATCH_LEVEL;
    NSString *url =   @"www.tcl-lang.org";
    NSTextView *credits = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,300,300)];
    NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
    NSDictionary *textAttributes = [NSDictionary dictionaryWithObject:font



					        forKey:NSFontAttributeName];


    [credits insertText: [[NSAttributedString alloc]
		 initWithString:[NSString stringWithFormat: @"\n"
		"Tcl and Tk are distributed under a modified BSD license: "
		"www.tcl.tk/software/tcltk/license.html\n\n"
		"%1$C 1987-%[email protected] Tcl Core Team and Contributers.\n\n"

		"%1$C 2011-%[email protected] Kevin Walzer/WordTech Communications LLC.\n\n"
		"%1$C 2014-%[email protected] Marc Culler.\n\n"
		"%1$C 2002-2012 Daniel A. Steffen.\n\n"
		"%1$C 2001-2009 Apple Inc.\n\n"
		"%1$C 2001-2002 Jim Ingham & Ian Reid\n\n"
		"%1$C 1998-2000 Jim Ingham & Ray Johnson\n\n"
		"%1$C 1998-2000 Scriptics Inc.\n\n"
		"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year]
	     attributes:textAttributes]
             replacementRange:NSMakeRange(0,0)];
    [credits setDrawsBackground:NO];
    [credits setEditable:NO];
     NSAlert *about = [[NSAlert alloc] init];
    [[about window] setTitle:@"About Tcl & Tk"];
    [about setMessageText: version];
    [about setInformativeText:url];
    about.accessoryView = credits;
    [about runModal];
    [about release];
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXStandardAboutPanelObjCmd --
 *
................................................................................
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    TkAboutDlg();
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --

Changes to macosx/tkMacOSXDraw.c.

14
15
16
17
18
19
20






21
22
23
24
25
26
27
...
101
102
103
104
105
106
107



















108
109
110
111
112
113
114
...
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151

152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167








168
169
170
171
172
173
174
...
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239


240
241
242
243
244
245
246
247
248
249
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
...
329
330
331
332
333
334
335
336
337
338
339


340
341
342
343
344
345
346
...
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
...
592
593
594
595
596
597
598
599
600
601
602
603


604
605
606
607
608
609
610
....
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484

1485
1486
1487





















1488
1489
1490
1491
1492
1493

1494
1495
1496
1497
1498
1499
1500





1501

1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513















1514
1515
1516
1517

1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529





1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
....
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
....
1603
1604
1605
1606
1607
1608
1609

1610







1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
....
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
....
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
....
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
....
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkButton.h"







/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
#endif
*/

................................................................................
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXBitmapRepFromDrawableRect
 *
 *	Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
 *



















 * Results:
 *	Returns an NSBitmapRep representing the image of the given
 *      rectangle of the given drawable.  This object is retained.
 *      The caller is responsible for releasing it.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system with
 *      origin at the top left, as used by XImage and CGImage, not bottom
................................................................................
        Drawable drawable,
	int x,
	int y,
	unsigned int width,
	unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *) drawable;
    CGContextRef cg_context=NULL;
    CGImageRef cg_image=NULL, sub_cg_image=NULL;
    NSBitmapImageRep *bitmap_rep=NULL;
    NSView *view=NULL;
    if ( mac_drawable->flags & TK_IS_PIXMAP ) {

	/*
	 * This means that the MacDrawable is functioning as a
	 * Tk Pixmap, so its view field is NULL.
	*/

	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
	CGRect image_rect = CGRectMake(x, y, width, height);
	cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context);
	sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect);
	if ( sub_cg_image ) {
	    bitmap_rep = [NSBitmapImageRep alloc];
	    [bitmap_rep initWithCGImage:sub_cg_image];
	}
	if ( cg_image ) {
	    CGImageRelease(cg_image);
	}
    } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) {

	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
			       view_height - height - y - mac_drawable->yOff,
			       width, height);

	if ( [view lockFocusIfCanDraw] ) {
	    bitmap_rep = [NSBitmapImageRep alloc];
	    bitmap_rep = [bitmap_rep initWithFocusedViewRect:view_rect];
	    [view unlockFocus];
	} else {
	    TkMacOSXDbgMsg("Could not lock focus on view.");
	}









    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    }
    return bitmap_rep;
}
 
/*
................................................................................
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    NSBitmapImageRep *bitmap_rep = NULL;
    CGImageRef img = NULL;


    display->request++;

    if (!width || !height) {
	/* This happens all the time.
	TkMacOSXDbgMsg("Drawing of empty area requested");
	*/
	return;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	return;
	/*TkMacOSXDbgMsg("Failed to setup drawing context.");*/
    }

    if ( dc.context ) {
	if (srcDraw->flags & TK_IS_PIXMAP) {
	    img = TkMacOSXCreateCGImageWithDrawable(src);
	}else if (TkMacOSXDrawableWindow(src)) {
	    bitmap_rep =  TkMacOSXBitmapRepFromDrawableRect(src, src_x, src_y, width, height);

	    if ( bitmap_rep ) {
		img = [bitmap_rep CGImage];
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
	}

	if (img) {
	    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background,
			CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
			CGRectMake(src_x, src_y, width, height),
			CGRectMake(dest_x, dest_y, width, height));


	    CFRelease(img);


	} else {
	    TkMacOSXDbgMsg("Failed to construct CGImage.");
	}

    } else {
	TkMacOSXDbgMsg("Invalid destination drawable - no context.");
	return;
................................................................................
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    MacDrawable *dstDraw = (MacDrawable *) dst;

    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
................................................................................
	CGContextRef context = dc.context;
	if (context) {
	    CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src);
	    if (img) {
		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
		unsigned long imageBackground  = gc->background;
                if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){
		    CGRect srcRect = CGRectMake(src_x, src_y, width, height);
		    CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
		    CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect);
		    CGRect rect = CGRectMake(dest_x, dest_y, width, height);
		    rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
		    CGContextSaveGState(context);
		    /* Move the origin of the destination to top left. */
		    CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect));
................................................................................
		    CGContextFillRect(context, rect);
		    CGContextRestoreGState(context);
		    CGImageRelease(img);
		    CGImageRelease(mask);
		    CGImageRelease(submask);
		    CGImageRelease(subimage);
		} else {
		    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
				CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
				CGRectMake(src_x, src_y, width, height),
				CGRectMake(dest_x, dest_y, width, height));


		    CGImageRelease(img);
		}
	    } else { /* no image */
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context.");
................................................................................
TkMacOSXGetNSImageWithTkImage(
    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    MacDrawable *macDraw = (MacDrawable *) pixmap;
    NSImage *nsImage;

    macDraw->flags |= TK_USE_XIMAGE_ALPHA;
    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageWithPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}
 
................................................................................
	    subImage = CGImageCreateWithImageInRect(image, CGRectOffset(
		    srcBounds, -imageBounds.origin.x, -imageBounds.origin.y));
	    if (subImage) {
		image = subImage;
	    }
	}
	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);

	if (CGImageIsMask(image)) {
	    /*CGContextSaveGState(context);*/
	    if (macDraw->flags & TK_IS_BW_PIXMAP) {
		/* Set fill color to black, background comes from the context, or is transparent. */


		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    CGContextClearRect(context, dstBounds);
		}
		CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
	    } else {
		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    TkMacOSXSetColorInContext(gc, imageBackground, context);
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXSetupDrawingContext(
    Drawable d,
    GC gc,
    int useCG, /* advisory only ! */
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = ((MacDrawable*)d);
    int dontDraw = 0, isWin = 0;

    TkMacOSXDrawingContext dc = {};
    CGRect clipBounds;






















    dc.clipRgn = TkMacOSXGetClipRgn(d);
    if (!dontDraw) {
	ClipToGC(d, gc, &dc.clipRgn);
	dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0;
    }
    if (dontDraw) {

	goto end;
    }
    if (useCG) {
	dc.context = TkMacOSXGetCGContextForDrawable(d);
    }
    if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) {
	isWin = (TkMacOSXDrawableWindow(d) != nil);





    }

    if (dc.context) {
	dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context);
    } else if (isWin) {
	NSView *view = TkMacOSXDrawableView(macDraw);
	if (view) {
	    if (view != [NSView focusView]) {
		dc.focusLocked = [view lockFocusIfCanDraw];
		dontDraw = !dc.focusLocked;
	    } else {
		dontDraw = ![view canDraw];
	    }
	    if (dontDraw) {















		goto end;
	    }
	    dc.view = view;
	    dc.context = [[NSGraphicsContext currentContext] graphicsPort];

	    dc.portBounds = NSRectToCGRect([view bounds]);
	    if (dc.clipRgn) {
		clipBounds = CGContextGetClipBoundingBox(dc.context);
	    }
	} else {
	    Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		    "no NSView to draw into !");
	}
    } else {
	Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		"no context to draw into !");
    }





    if (dc.context) {
	CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
		.ty = dc.portBounds.size.height};
	dc.portBounds.origin.x += macDraw->xOff;
	dc.portBounds.origin.y += macDraw->yOff;
	if (!dc.focusLocked) {
	    CGContextSaveGState(dc.context);
	}
	CGContextSetTextDrawingMode(dc.context, kCGTextFill);
	CGContextConcatCTM(dc.context, t);
	if (dc.clipRgn) {
#ifdef TK_MAC_DEBUG_DRAWING
	    CGContextSaveGState(dc.context);
	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	    CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
................................................................................
		[JoinRound] = kCGLineJoinRound,
		[JoinBevel] = kCGLineJoinBevel,
	    };
	    bool shouldAntialias;
	    double w = gc->line_width;

	    TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	    if (isWin) {
		CGContextSetPatternPhase(dc.context, CGSizeMake(
			dc.portBounds.size.width, dc.portBounds.size.height));
	    }
	    if(gc->function != GXcopy) {
		TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			"not supported for CG drawing!");
	    }
................................................................................
	    }
	    if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
		CGContextSetLineJoin(dc.context,
			cgJoin[(unsigned)gc->join_style]);
	    }
	}
    }

end:







    if (dontDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
    *dcPtr = dc;
    return !dontDraw;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRestoreDrawingContext --
 *
................................................................................

void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);
	[[dcPtr->view window] setViewsNeedDisplay:YES];
	if (dcPtr->focusLocked) {
	    [dcPtr->view unlockFocus];
	} else {
	    CGContextRestoreGState(dcPtr->context);
	}
    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);
    }
#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif /* TK_MAC_DEBUG */
................................................................................
    HIShapeRef clipRgn = NULL;

    if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macDraw->winPtr);
#ifdef TK_MAC_DEBUG_DRAWING
	TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName);
	NSView *view = TkMacOSXDrawableView(macDraw);
	if ([view lockFocusIfCanDraw]) {
	    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
	    CGContextSaveGState(context);
	    CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
		    -1.0, 0.0, [view bounds].size.height));
	    ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
	    CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
	    CGContextEOFillPath(context);
	    CGContextRestoreGState(context);
	    [view unlockFocus];
	}
#endif /* TK_MAC_DEBUG_DRAWING */
    }

    if (macDraw->drawRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->drawRgn);
    } else if (macDraw->visRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->visRgn);
................................................................................
TkpClipDrawableToRect(
    Display *display,
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *) d;
    NSView *view = TkMacOSXDrawableView(macDraw);

    if (macDraw->drawRgn) {
	CFRelease(macDraw->drawRgn);
	macDraw->drawRgn = NULL;
    }

    if (width >= 0 && height >= 0) {
	CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
		width, height);
	HIShapeRef drawRgn = HIShapeCreateWithRect(&clipRect);

	if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	    TkMacOSXUpdateClipRgn(macDraw->winPtr);
................................................................................
	if (macDraw->visRgn) {
	    macDraw->drawRgn = HIShapeCreateIntersection(macDraw->visRgn,
		    drawRgn);
	    CFRelease(drawRgn);
	} else {
	    macDraw->drawRgn = drawRgn;
	}
	if (view && view != [NSView focusView] && [view lockFocusIfCanDraw]) {
	    clipRect.origin.y = [view bounds].size.height -
		    (clipRect.origin.y + clipRect.size.height);
	    NSRectClip(NSRectFromCGRect(clipRect));
	    macDraw->flags |= TK_FOCUSED_VIEW;
	}
    } else {
	if (view && (macDraw->flags & TK_FOCUSED_VIEW)) {
	    [view unlockFocus];
	    macDraw->flags &= ~TK_FOCUSED_VIEW;
	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * ClipToGC --






>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|


>

<
|
|
>












>



>





|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>







 







>


<

<
<
<





|






|
>








<
|
|
|
>
>

<
<







 







|







 







|







 







<
|
|
|
>
>







 







<


<







 







|
|
|
|
|
>
>







 







|







|
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
|
|
<
<
>


<
<
|
<
<
>
>
>
>
>
|
>


|


<
<
<
<
<
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

<
>












>
>
>
>
>





<
|
<







 







|







 







>

>
>
>
>
>
>
>
|




|







 







<
<
<
<
|
<







 







<
<
|
|
|
|
|
|
|
<
<







 







<





<







 







<
<
<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
237
238
239
240
241
242
243
244
245
246

247



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275


276
277
278
279
280
281
282
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
...
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
...
470
471
472
473
474
475
476

477
478

479
480
481
482
483
484
485
...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
....
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544

1545
1546


1547
1548
1549


1550


1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562





1563

1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581

1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604

1605

1606
1607
1608
1609
1610
1611
1612
....
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
....
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
....
1710
1711
1712
1713
1714
1715
1716




1717

1718
1719
1720
1721
1722
1723
1724
....
1749
1750
1751
1752
1753
1754
1755


1756
1757
1758
1759
1760
1761
1762


1763
1764
1765
1766
1767
1768
1769
....
1815
1816
1817
1818
1819
1820
1821

1822
1823
1824
1825
1826

1827
1828
1829
1830
1831
1832
1833
....
1835
1836
1837
1838
1839
1840
1841











1842
1843
1844
1845
1846
1847
1848
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkButton.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] CGContext]
#else
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] graphicsPort]
#endif

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
#endif
*/

................................................................................
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXBitmapRepFromDrawableRect
 *
 *	Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
 *
 *      This is only used by XGetImage, which is never called.  And this
 *      implementation does not work correctly.  Originally it relied on
 *      [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
 *      deprecated by Apple in OSX 10.14 and also required the use of other
 *      deprecated functions such as [NSView lockFocus]. Apple's suggested
 *      replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
 *      is what is being used here.  However, that method only works when the
 *      view has a valid CGContext, and a view is only guaranteed to have a
 *      valid context during a call to [NSView drawRect].  To further
 *      complicate matters, cacheDisplayInRect calls [NSView drawRect].
 *      Essentially it is asking the view to draw a subrectangle of itself into
 *      a special graphics context which is linked to the BitmapImageRep.  But
 *      our implementation of [NSView drawRect] does not allow recursive calls.
 *      If called recursively it returns immediately without doing any drawing.
 *      So the bottom line is that this function either returns a NULL pointer
 *      or a black image.  To make it useful would require a significant amount
 *      of rewriting of the drawRect method.  Perhaps the next release of OSX
 *      will include some more helpful ways of doing this.
 *
 * Results:
 *	Returns an NSBitmapRep representing the image of the given
 *      rectangle of the given drawable.  This object is retained.
 *      The caller is responsible for releasing it.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system with
 *      origin at the top left, as used by XImage and CGImage, not bottom
................................................................................
        Drawable drawable,
	int x,
	int y,
	unsigned int width,
	unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *) drawable;
    CGContextRef cg_context = NULL;
    CGImageRef cg_image=NULL, sub_cg_image = NULL;
    NSBitmapImageRep *bitmap_rep = NULL;
    NSView *view=NULL;
    if ( mac_drawable->flags & TK_IS_PIXMAP ) {

	/*

	 * This MacDrawable is a bitmap, so its view is NULL.
	 */

	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
	CGRect image_rect = CGRectMake(x, y, width, height);
	cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context);
	sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect);
	if ( sub_cg_image ) {
	    bitmap_rep = [NSBitmapImageRep alloc];
	    [bitmap_rep initWithCGImage:sub_cg_image];
	}
	if ( cg_image ) {
	    CGImageRelease(cg_image);
	}
    } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) {

	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
			       view_height - height - y - mac_drawable->yOff,
			       width, height);

	/*
	 * Attempt to copy from the view to a bitmapImageRep.  If the view does
	 * not have a valid CGContext, doing this will silently corrupt memory
	 * and make a big mess. So, in that case, we mark the view as needing
	 * display and return NULL.
	 */

	if (view == [NSView focusView]) {
	    bitmap_rep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
	    [bitmap_rep retain];
	    [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmap_rep];
	} else {
	    TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
	    [view setNeedsDisplay:YES];
	    return NULL;
	}
    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    }
    return bitmap_rep;
}
 
/*
................................................................................
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    NSBitmapImageRep *bitmap_rep = NULL;
    CGImageRef img = NULL;
    CGRect bounds, srcRect, dstRect;

    display->request++;

    if (!width || !height) {



	return;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	return;
	TkMacOSXDbgMsg("Failed to setup drawing context.");
    }

    if ( dc.context ) {
	if (srcDraw->flags & TK_IS_PIXMAP) {
	    img = TkMacOSXCreateCGImageWithDrawable(src);
	}else if (TkMacOSXDrawableWindow(src)) {
	    bitmap_rep =  TkMacOSXBitmapRepFromDrawableRect(src,
				   src_x, src_y, width, height);
	    if ( bitmap_rep ) {
		img = [bitmap_rep CGImage];
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
	}

	if (img) {

	    bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
	    srcRect = CGRectMake(src_x, src_y, width, height);
	    dstRect = CGRectMake(dest_x, dest_y, width, height);
	    TkMacOSXDrawCGImage(dst, gc, dc.context, img,
		     gc->foreground, gc->background, bounds, srcRect, dstRect);
	    CFRelease(img);


	} else {
	    TkMacOSXDbgMsg("Failed to construct CGImage.");
	}

    } else {
	TkMacOSXDbgMsg("Invalid destination drawable - no context.");
	return;
................................................................................
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    MacDrawable *dstDraw = (MacDrawable *) dst;
    CGRect bounds, srcRect, dstRect;
    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
................................................................................
	CGContextRef context = dc.context;
	if (context) {
	    CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src);
	    if (img) {
		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
		unsigned long imageBackground  = gc->background;
                if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
		    CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect);
		    CGRect rect = CGRectMake(dest_x, dest_y, width, height);
		    rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
		    CGContextSaveGState(context);
		    /* Move the origin of the destination to top left. */
		    CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect));
................................................................................
		    CGContextFillRect(context, rect);
		    CGContextRestoreGState(context);
		    CGImageRelease(img);
		    CGImageRelease(mask);
		    CGImageRelease(submask);
		    CGImageRelease(subimage);
		} else {

		    bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    dstRect = CGRectMake(dest_x, dest_y, width, height);
		    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground,
					imageBackground, bounds, srcRect, dstRect);
		    CGImageRelease(img);
		}
	    } else { /* no image */
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context.");
................................................................................
TkMacOSXGetNSImageWithTkImage(
    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);

    NSImage *nsImage;


    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageWithPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}
 
................................................................................
	    subImage = CGImageCreateWithImageInRect(image, CGRectOffset(
		    srcBounds, -imageBounds.origin.x, -imageBounds.origin.y));
	    if (subImage) {
		image = subImage;
	    }
	}
	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);
	if (CGImageIsMask(image)) {
	    if (macDraw->flags & TK_IS_BW_PIXMAP) {

		/* Set fill color to black; background comes from the context,
		 * or is transparent.
		 */

		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    CGContextClearRect(context, dstBounds);
		}
		CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
	    } else {
		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    TkMacOSXSetColorInContext(gc, imageBackground, context);
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Bool
TkMacOSXSetupDrawingContext(
    Drawable d,
    GC gc,
    int useCG, /* advisory only ! */
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = ((MacDrawable*)d);
    Bool canDraw = true;
    NSWindow *win = NULL;
    TkMacOSXDrawingContext dc = {};
    CGRect clipBounds;

    /*
     * If we are simulating drawing for tests, just return false.
     */

    if ([NSApp simulateDrawing]) {
	return false;
    }

    /*
     * If the drawable is not a pixmap and it has an associated
     * NSWindow then we know we are drawing to a window.
     */

    if (!(macDraw->flags & TK_IS_PIXMAP)) {
	win = TkMacOSXDrawableWindow(d);
    }

    /*
     * Check that we have a non-empty clipping region.
     */

    dc.clipRgn = TkMacOSXGetClipRgn(d);

    ClipToGC(d, gc, &dc.clipRgn);
    if (dc.clipRgn && HIShapeIsEmpty(dc.clipRgn)) {


	canDraw = false;
	goto end;
    }





    /*
     * If we already have a CGContext, use it.  Otherwise, if we
     * are drawing to a window then we can get one from the
     * window.
     */

    dc.context = TkMacOSXGetCGContextForDrawable(d);
    if (dc.context) {
	dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context);
    } else if (win) {
	NSView *view = TkMacOSXDrawableView(macDraw);
	if (view) {







	    /*
	     * We can only draw into the view when the current CGContext is
	     * valid and belongs to the view.  Validity can only be guaranteed
	     * inside of a view's drawRect or setFrame methods.  The isDrawing
	     * attribute tells us whether we are being called from one of those
	     * methods.
	     *
	     * If the CGContext is not valid, or belongs to a different View,
	     * then we mark our view as needing display and return failure.
	     * It should get drawn in a later call to drawRect.
	     */

           if (view != [NSView focusView]) {
	       [view setNeedsDisplay:YES];
	       canDraw = false;
	       goto end;
	   }
	    dc.view = view;

	    dc.context = GET_CGCONTEXT;
	    dc.portBounds = NSRectToCGRect([view bounds]);
	    if (dc.clipRgn) {
		clipBounds = CGContextGetClipBoundingBox(dc.context);
	    }
	} else {
	    Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		    "no NSView to draw into !");
	}
    } else {
	Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		"no context to draw into !");
    }

    /*
     * Configure the drawing context.
     */

    if (dc.context) {
	CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
		.ty = dc.portBounds.size.height};
	dc.portBounds.origin.x += macDraw->xOff;
	dc.portBounds.origin.y += macDraw->yOff;

	CGContextSaveGState(dc.context);

	CGContextSetTextDrawingMode(dc.context, kCGTextFill);
	CGContextConcatCTM(dc.context, t);
	if (dc.clipRgn) {
#ifdef TK_MAC_DEBUG_DRAWING
	    CGContextSaveGState(dc.context);
	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	    CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
................................................................................
		[JoinRound] = kCGLineJoinRound,
		[JoinBevel] = kCGLineJoinBevel,
	    };
	    bool shouldAntialias;
	    double w = gc->line_width;

	    TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	    if (win) {
		CGContextSetPatternPhase(dc.context, CGSizeMake(
			dc.portBounds.size.width, dc.portBounds.size.height));
	    }
	    if(gc->function != GXcopy) {
		TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			"not supported for CG drawing!");
	    }
................................................................................
	    }
	    if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
		CGContextSetLineJoin(dc.context,
			cgJoin[(unsigned)gc->join_style]);
	    }
	}
    }

end:
#ifdef TK_MAC_DEBUG_DRAWING
    if (!canDraw && win != NULL) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);
	if (winPtr) fprintf(stderr, "Cannot draw in %s - postponing.\n",
			    Tk_PathName(winPtr));
    }
#endif
    if (!canDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
    *dcPtr = dc;
    return canDraw;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRestoreDrawingContext --
 *
................................................................................

void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);




	CGContextRestoreGState(dcPtr->context);

    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);
    }
#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif /* TK_MAC_DEBUG */
................................................................................
    HIShapeRef clipRgn = NULL;

    if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macDraw->winPtr);
#ifdef TK_MAC_DEBUG_DRAWING
	TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName);
	NSView *view = TkMacOSXDrawableView(macDraw);


	CGContextSaveGState(context);
	CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
	      -1.0, 0.0, [view bounds].size.height));
	ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
	CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
	CGContextEOFillPath(context);
	CGContextRestoreGState(context);


#endif /* TK_MAC_DEBUG_DRAWING */
    }

    if (macDraw->drawRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->drawRgn);
    } else if (macDraw->visRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->visRgn);
................................................................................
TkpClipDrawableToRect(
    Display *display,
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *) d;


    if (macDraw->drawRgn) {
	CFRelease(macDraw->drawRgn);
	macDraw->drawRgn = NULL;
    }

    if (width >= 0 && height >= 0) {
	CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
		width, height);
	HIShapeRef drawRgn = HIShapeCreateWithRect(&clipRect);

	if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	    TkMacOSXUpdateClipRgn(macDraw->winPtr);
................................................................................
	if (macDraw->visRgn) {
	    macDraw->drawRgn = HIShapeCreateIntersection(macDraw->visRgn,
		    drawRgn);
	    CFRelease(drawRgn);
	} else {
	    macDraw->drawRgn = drawRgn;
	}











    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * ClipToGC --

Changes to macosx/tkMacOSXEvent.c.

108
109
110
111
112
113
114
115
116








117
118
119
120
121
122

123
124
125
126
127
128
129
130



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#pragma mark -
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXFlushWindows --
 *
 *	This routine flushes all the visible windows of the application. It is
 *	called by XSync().








 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Flushes all visible Cocoa windows

 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void
TkMacOSXFlushWindows(void)
{
    NSArray *macWindows = [NSApp orderedWindows];




    for (NSWindow *w in macWindows) {
	if (TkMacOSXGetXWindow(w)) {
	    [w displayIfNeeded];
	}
    }
}

 
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */






|
|
>
>
>
>
>
>
>
>





|
>








>
>
>
|

|
|
|












108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#pragma mark -
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXFlushWindows --
 *
 *	This routine is a stub called by XSync, which is called during the Tk
 *      update command.  The language specification does not require that the
 *      update command be synchronous but many of the tests assume that is the
 *      case.  It is not naturally the case on macOS since many idle tasks are
 *      run inside of the drawRect method of a window's contentView, and that
 *      method will not be called until after this function returns.  To make
 *      the tests work, we attempt to force this to be synchronous by waiting
 *      until drawRect has been called for each window.  The mechanism we use
 *      for this is to have drawRect post an ApplicationDefined NSEvent on the
 *      AppKit event queue when it finishes drawing, and wait for it here.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Calls the drawRect method of the contentView of each visible
 *      window.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void
TkMacOSXFlushWindows(void)
{
    NSArray *macWindows = [NSApp orderedWindows];
    if ([NSApp simulateDrawing]) {
	[NSApp setSimulateDrawing:NO];
	return;
    }
    for (NSWindow *w in macWindows) {
    	if (TkMacOSXGetXWindow(w)) {
    	    [w displayIfNeeded];
    	}
    }
}

 
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXFont.c.

10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"


#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
#define defaultOrientation kCTFontDefaultOrientation
#define verticalOrientation kCTFontVerticalOrientation
#else
#define defaultOrientation kCTFontOrientationDefault
#define verticalOrientation kCTFontOrientationVertical
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
#define fixedPitch kCTFontUserFixedPitchFontType
#else
#define fixedPitch kCTFontUIFontUserFixedPitch
#endif

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#endif
*/







>

<


<
<
<
<
<

<
<
<







10
11
12
13
14
15
16
17
18

19
20





21



22
23
24
25
26
27
28
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXConstants.h"


#define defaultOrientation kCTFontDefaultOrientation
#define verticalOrientation kCTFontVerticalOrientation





#define fixedPitch kCTFontUserFixedPitchFontType




/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#endif
*/

Changes to macosx/tkMacOSXImage.c.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
..
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
..
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
124
125
126
127
128
129
130
131





132
133
134
135
136
137
138
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183

184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241

242
243
244
245
246
247
248
...
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
...
538
539
540
541
542
543
544
545
546
547
548
549
550
551

552





553


554

555





556
557
558
559
560
561



562
563
564
565
566
567
568
 * tkMacOSXImage.c --
 *
 *	The code in this file provides an interface for XImages,
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright 2017 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "xbytes.h"
................................................................................
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithXImage --
 *
 *	Create CGImage from XImage, copying the image data.

 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
................................................................................

static void ReleaseData(void *info, const void *data, size_t size) {
    ckfree(info);
}

CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image,
    int use_ximage_alpha)
{
    CGImageRef img = NULL;
    size_t bitsPerComponent, bitsPerPixel;
    size_t len = image->bytes_per_line * image->height;
    const CGFloat *decode = NULL;
    CGBitmapInfo bitmapInfo;
    CGDataProviderRef provider = NULL;
................................................................................
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
				    bitsPerPixel, image->bytes_per_line, provider, decode, 0);
	}
    } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {

	/*
	 * Color image
	 */

	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

	bitsPerComponent = 8;
	bitsPerPixel = 32;
	bitmapInfo = (image->byte_order == MSBFirst ?
		      kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little);
	if (use_ximage_alpha) {
	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	} else {
	    bitmapInfo |= kCGImageAlphaNoneSkipFirst;
	}
	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
................................................................................
 

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.





 *
 * Results:
 *	Returns a newly allocated XImage containing the data from the given
 *	rectangle of the given drawable, or NULL if the XImage could not be
 *	constructed.  NOTE: If we are copying from a window on a Retina
 *	display, the dimensions of the XImage will be 2*width x 2*height.
 *
................................................................................
    XImage* imagePtr = NULL;
    char* bitmap = NULL;
    char R, G, B, A;
    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;
    unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
    NSWindow *win = TkMacOSXDrawableWindow(drawable);
    MacDrawable *macDraw = ((MacDrawable*)drawable);
    static enum {unknown, no, yes} has_retina = unknown;

    if (win && has_retina == unknown) {
#ifdef __clang__
	has_retina = [win respondsToSelector:@selector(backingScaleFactor)]?
	    yes : no;
#else
	has_retina = no;
#endif
    }

    if (has_retina == yes) {

	/*
	 * We only allow scale factors 1 or 2, as Apple currently does.
	 */

#ifdef __clang__
	scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
#endif
	scaled_height *= scalefactor;
	scaled_width *= scalefactor;
    }

    if (format == ZPixmap) {
	if (width == 0 || height == 0) {
	    return NULL;
	}

	bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
		         x, y, width, height);
	if (!bitmap_rep) {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
	    return NULL;
	}
	bitmap_fmt = [bitmap_rep bitmapFormat];
	size = [bitmap_rep bytesPerPlane];
	bytes_per_row = [bitmap_rep bytesPerRow];
	bitmap = ckalloc(size);
	if (!bitmap                              ||
	    (bitmap_fmt != 0 && bitmap_fmt != 1) ||
	    [bitmap_rep samplesPerPixel] != 4    ||
	    [bitmap_rep isPlanar] != 0           ||
	    bytes_per_row != 4 * scaled_width    ||
	    size != bytes_per_row*scaled_height  ) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    CFRelease(bitmap_rep);
	    return NULL;
	}

	if (macDraw->flags & TK_USE_XIMAGE_ALPHA) {
	    /*
	     * When called by TkImgPhotoDisplay we are being asked to return a
	     * background image to be blended with the photoimage using its
	     * alpha channel, if it has one.  Returning a black pixmap here
	     * makes TkImgPhotoDisplay create an XImage with a premultiplied
	     * alpha channel, as favored by Apple.  When TkImgPhotoDisplay
	     * passes this XImage to TkPutImage, targeting a pixmap, it creates
	     * an image with correct transparency.  This is used, for example,
	     * when creating an iconphoto or a menu image from a PNG
	     * photoimage.
	     */
	    bzero(bitmap, size);
	} else {
	    memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
	}
	CFRelease(bitmap_rep);

	/*
	 * When Apple extracts a bitmap from an NSView, it may be in
	 * either BGRA or ABGR format.  For an XImage we need RGBA.
	 */

	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;

	for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
	    for (m=n; m<n+bytes_per_row; m+=4) {

		R = *(bitmap + m + pixel.r);
		G = *(bitmap + m + pixel.g);
		B = *(bitmap + m + pixel.b);
		A = *(bitmap + m + pixel.a);

		*(bitmap + m)     = R;
		*(bitmap + m + 1) = G;
................................................................................
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkPutImage --
 *
 *	Copies a subimage from an in-memory image to a rectangle of
 *	of the specified drawable.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
................................................................................
    int src_y,
    int dest_x,			/* Destination X & Y. */
    int dest_y,
    unsigned int width,	        /* Same width & height for both */
    unsigned int height)	/* distination and source. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *macDraw = ((MacDrawable*)drawable);

    display->request++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {

	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image,





			     macDraw->flags & TK_USE_XIMAGE_ALPHA);


	if (img) {

	    /* If the XImage has big pixels, rescale the source dimensions.*/





	    int pp = image->pixelpower;
	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
		    img, gc->foreground, gc->background,
		    CGRectMake(0, 0, image->width<<pp, image->height<<pp),
		    CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp),
		    CGRectMake(dest_x, dest_y, width, height));



	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
    }






|







 







|
>







 







|
<







 







>





<



|
<
<
<
|
<







 







|
>
>
>
>
>







 







<












>



>











>

|












|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<






>


<
|
>







 







|
|
>







 







|






>
|
>
>
>
>
>
|
>
>

>
|
>
>
>
>
>

<
<
|
|
|
>
>
>







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
..
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
..
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100



101

102
103
104
105
106
107
108
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217















218

219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
...
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559


560
561
562
563
564
565
566
567
568
569
570
571
572
 * tkMacOSXImage.c --
 *
 *	The code in this file provides an interface for XImages,
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright 2017-2018 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "xbytes.h"
................................................................................
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithXImage --
 *
 *	Create CGImage from XImage, copying the image data.  Called
 *      in Tk_PutImage and (currently) nowhere else.
 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
................................................................................

static void ReleaseData(void *info, const void *data, size_t size) {
    ckfree(info);
}

CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image)

{
    CGImageRef img = NULL;
    size_t bitsPerComponent, bitsPerPixel;
    size_t len = image->bytes_per_line * image->height;
    const CGFloat *decode = NULL;
    CGBitmapInfo bitmapInfo;
    CGDataProviderRef provider = NULL;
................................................................................
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
				    bitsPerPixel, image->bytes_per_line, provider, decode, 0);
	}
    } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {

	/*
	 * Color image
	 */

	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

	bitsPerComponent = 8;
	bitsPerPixel = 32;
	bitmapInfo = (image->byte_order == MSBFirst ?
		      kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big);



	bitmapInfo |= kCGImageAlphaLast;

	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
................................................................................
 

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.  It
 *      is essentially never used. At one time it was called by
 *      pTkImgPhotoDisplay, but that is no longer the case. Currently it is
 *      called two places, one of which is requesting an XY image which we do
 *      not support.  It probably does not work correctly -- see the comments
 *      for TkMacOSXBitmapRepFromDrawableRect.
 *
 * Results:
 *	Returns a newly allocated XImage containing the data from the given
 *	rectangle of the given drawable, or NULL if the XImage could not be
 *	constructed.  NOTE: If we are copying from a window on a Retina
 *	display, the dimensions of the XImage will be 2*width x 2*height.
 *
................................................................................
    XImage* imagePtr = NULL;
    char* bitmap = NULL;
    char R, G, B, A;
    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;
    unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
    NSWindow *win = TkMacOSXDrawableWindow(drawable);

    static enum {unknown, no, yes} has_retina = unknown;

    if (win && has_retina == unknown) {
#ifdef __clang__
	has_retina = [win respondsToSelector:@selector(backingScaleFactor)]?
	    yes : no;
#else
	has_retina = no;
#endif
    }

    if (has_retina == yes) {

	/*
	 * We only allow scale factors 1 or 2, as Apple currently does.
	 */

#ifdef __clang__
	scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
#endif
	scaled_height *= scalefactor;
	scaled_width *= scalefactor;
    }

    if (format == ZPixmap) {
	if (width == 0 || height == 0) {
	    return NULL;
	}

	bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
			  x, y, width, height);
	if (!bitmap_rep) {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
	    return NULL;
	}
	bitmap_fmt = [bitmap_rep bitmapFormat];
	size = [bitmap_rep bytesPerPlane];
	bytes_per_row = [bitmap_rep bytesPerRow];
	bitmap = ckalloc(size);
	if (!bitmap                              ||
	    (bitmap_fmt != 0 && bitmap_fmt != 1) ||
	    [bitmap_rep samplesPerPixel] != 4    ||
	    [bitmap_rep isPlanar] != 0           ||
	    bytes_per_row < 4 * scaled_width    ||
	    size != bytes_per_row*scaled_height  ) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    CFRelease(bitmap_rep);
	    return NULL;
	}















	memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);

	CFRelease(bitmap_rep);

	/*
	 * When Apple extracts a bitmap from an NSView, it may be in
	 * either BGRA or ABGR format.  For an XImage we need RGBA.
	 */

	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;


	for (row = 0, n = 0; row < scaled_height; row++, n += bytes_per_row) {
	    for (m = n; m < n + 4*scaled_width; m += 4) {
		R = *(bitmap + m + pixel.r);
		G = *(bitmap + m + pixel.g);
		B = *(bitmap + m + pixel.b);
		A = *(bitmap + m + pixel.a);

		*(bitmap + m)     = R;
		*(bitmap + m + 1) = G;
................................................................................
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkPutImage --
 *
 *	Copies a rectangular subimage of an XImage into a drawable.
 *      Currently this is only called by TkImgPhotoDisplay, using
 *      a Window as the drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
................................................................................
    int src_y,
    int dest_x,			/* Destination X & Y. */
    int dest_y,
    unsigned int width,	        /* Same width & height for both */
    unsigned int height)	/* distination and source. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *macDraw = (MacDrawable *) drawable;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect bounds, srcRect, dstRect;
	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);

	/*
	 * The CGContext for a pixmap is RGB only, with A = 0.
	 */

	if (!(macDraw->flags & TK_IS_PIXMAP)) {
	    CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
	}
	if (img) {

	    /* If the XImage has big pixels, the source is rescaled to reflect
	     * the actual pixel dimensions.  This is not currently used, but
	     * could arise if the image were copied from a retina monitor and
	     * redrawn on an ordinary monitor.
	     */

	    int pp = image->pixelpower;


	    bounds = CGRectMake(0, 0, image->width, image->height);
	    srcRect = CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp);
	    dstRect = CGRectMake(dest_x, dest_y, width, height);
	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
				img, gc->foreground, gc->background,
				bounds, srcRect, dstRect);
	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
    }

Changes to macosx/tkMacOSXInit.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
..
44
45
46
47
48
49
50



51
52
53
54
55
56
57
...
147
148
149
150
151
152
153




















154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
...
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"

#include <sys/stat.h>
#include <sys/utsname.h>
#include <dlfcn.h>
#include <objc/objc-auto.h>

static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */

static char scriptPath[PATH_MAX + 1] = "";

long tkMacOSXMacOSXVersion = 0;

#pragma mark TKApplication(TKInit)

@interface TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification;
@end

#define TKApplication_NSApplicationDelegate <NSApplicationDelegate>
................................................................................

@interface TKApplication(TKMenus)
- (void) _setupMenus;
@end

@implementation TKApplication
@synthesize poolLock = _poolLock;



@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK
................................................................................

    /*
     * Install the global autoreleasePool.
     */
    _mainPool = [NSAutoreleasePool new];
    [NSApp setPoolLock:0];





















    /*
     * Be our own delegate.
     */
    [self setDelegate:self];

    /*
     * Make sure we are allowed to open windows.
     */

    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

    /*
     * If no icon has been set from an Info.plist file, use the Wish icon from
     * the Tk framework.
     */
    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
................................................................................
    /*
     * Since it is possible for TkInit to be called multiple times and we
     * don't want to do the following initialization multiple times we protect
     * against doing it more than once.
     */

    if (!initialized) {
	struct utsname name;
	struct stat st;

	initialized = 1;

	/*
	 * Initialize/check OS version variable for runtime checks.
	 */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
#   error Mac OS X 10.6 required
#endif

	if (!uname(&name)) {
	    tkMacOSXMacOSXVersion = (strtod(name.release, NULL) + 96) * 10;
	}
       /*Check for new versioning scheme on Yosemite (10.10) and later.*/
	if (MAC_OS_X_VERSION_MIN_REQUIRED > 100000) {
		tkMacOSXMacOSXVersion = MAC_OS_X_VERSION_MIN_REQUIRED/100;
	    }
	if (tkMacOSXMacOSXVersion && MAC_OS_X_VERSION_MIN_REQUIRED < 100000 &&
		tkMacOSXMacOSXVersion/10 < MAC_OS_X_VERSION_MIN_REQUIRED/10) {
	    Tcl_Panic("Mac OS X 10.%d or later required !",
		    (MAC_OS_X_VERSION_MIN_REQUIRED/10)-100);
	}


#ifdef TK_FRAMEWORK
	/*
	 * When Tk is in a framework, force tcl_findLibrary to look in the
	 * framework scripts directory.
	 * FIXME: Should we come up with a more generic way of doing this?
	 */






<












<
<







 







>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>







 







<











<
<
<
<
<
<
<
<
<
<
<
<
<
<







12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30


31
32
33
34
35
36
37
..
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288














289
290
291
292
293
294
295
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"

#include <sys/stat.h>

#include <dlfcn.h>
#include <objc/objc-auto.h>

static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */

static char scriptPath[PATH_MAX + 1] = "";



#pragma mark TKApplication(TKInit)

@interface TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification;
@end

#define TKApplication_NSApplicationDelegate <NSApplicationDelegate>
................................................................................

@interface TKApplication(TKMenus)
- (void) _setupMenus;
@end

@implementation TKApplication
@synthesize poolLock = _poolLock;
@synthesize macMinorVersion = _macMinorVersion;
@synthesize isDrawing = _isDrawing;
@synthesize simulateDrawing = _simulateDrawing;
@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK
................................................................................

    /*
     * Install the global autoreleasePool.
     */
    _mainPool = [NSAutoreleasePool new];
    [NSApp setPoolLock:0];

    /*
     * Record the OS version we are running on.
     */
    int minorVersion;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
    Gestalt(gestaltSystemVersionMinor, (SInt32*)&minorVersion);
#else
    NSOperatingSystemVersion systemVersion;
    systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
    minorVersion = systemVersion.minorVersion;
#endif
    [NSApp setMacMinorVersion: minorVersion];

    /*
     * We are not drawing yet.
     */

    [NSApp setIsDrawing:NO];
    [NSApp setSimulateDrawing:NO];

    /*
     * Be our own delegate.
     */
    [self setDelegate:self];

    /*
     * Make sure we are allowed to open windows.
     */

    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

    /*
     * If no icon has been set from an Info.plist file, use the Wish icon from
     * the Tk framework.
     */
    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
................................................................................
    /*
     * Since it is possible for TkInit to be called multiple times and we
     * don't want to do the following initialization multiple times we protect
     * against doing it more than once.
     */

    if (!initialized) {

	struct stat st;

	initialized = 1;

	/*
	 * Initialize/check OS version variable for runtime checks.
	 */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
#   error Mac OS X 10.6 required
#endif















#ifdef TK_FRAMEWORK
	/*
	 * When Tk is in a framework, force tcl_findLibrary to look in the
	 * framework scripts directory.
	 * FIXME: Should we come up with a more generic way of doing this?
	 */

Changes to macosx/tkMacOSXInt.h.

79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
...
195
196
197
198
199
200
201




202
203
204
205
206
207
208
 * Defines use for the flags field of the MacDrawable data structure.
 */

#define TK_SCROLLBAR_GROW	0x01
#define TK_CLIP_INVALID		0x02
#define TK_HOST_EXISTS		0x04
#define TK_DRAWN_UNDER_MENU	0x08
#define TK_FOCUSED_VIEW		0x10
#define TK_IS_PIXMAP		0x20
#define TK_IS_BW_PIXMAP		0x40
#define TK_DO_NOT_DRAW          0x80
#define TK_USE_XIMAGE_ALPHA     0x100

/*
 * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
 * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
 * TkWindow structure for the window, but in the MacWin. This way we can
 * still tell what the correct port is after the TKWindow structure has been
 * freed. This actually happens when you bind destroy of a toplevel to
 * Destroy of a child.
................................................................................
	int clip_y_origin, XRectangle* rectangles, int n, int ordering);
#endif
MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
	int y, int width, int height);
MODULE_SCOPE void TkpRetainRegion(TkRegion r);
MODULE_SCOPE void TkpReleaseRegion(TkRegion r);
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);




/*
 * Include the stubbed internal platform-specific API.
 */

#include "tkIntPlatDecls.h"

#endif /* _TKMACINT */






<
|
|
|
<
>







 







>
>
>
>







79
80
81
82
83
84
85

86
87
88

89
90
91
92
93
94
95
96
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
 * Defines use for the flags field of the MacDrawable data structure.
 */

#define TK_SCROLLBAR_GROW	0x01
#define TK_CLIP_INVALID		0x02
#define TK_HOST_EXISTS		0x04
#define TK_DRAWN_UNDER_MENU	0x08

#define TK_IS_PIXMAP		0x10
#define TK_IS_BW_PIXMAP		0x20
#define TK_DO_NOT_DRAW          0x40


/*
 * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
 * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
 * TkWindow structure for the window, but in the MacWin. This way we can
 * still tell what the correct port is after the TKWindow structure has been
 * freed. This actually happens when you bind destroy of a toplevel to
 * Destroy of a child.
................................................................................
	int clip_y_origin, XRectangle* rectangles, int n, int ordering);
#endif
MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
	int y, int width, int height);
MODULE_SCOPE void TkpRetainRegion(TkRegion r);
MODULE_SCOPE void TkpReleaseRegion(TkRegion r);
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);
MODULE_SCOPE Bool TkpAppIsDrawing(void);
MODULE_SCOPE void TkpDisplayWindow(Tk_Window tkwin);
MODULE_SCOPE void TkTestSimulateDrawing(Bool);

/*
 * Include the stubbed internal platform-specific API.
 */

#include "tkIntPlatDecls.h"

#endif /* _TKMACINT */

Changes to macosx/tkMacOSXKeyEvent.c.

63
64
65
66
67
68
69









70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
...
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
...
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
...
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
...
427
428
429
430
431
432
433



434
435
436
437
438
439
440
    static NSMutableArray *nsEvArray;

    if (nsEvArray == nil)
      {
        nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
        processingCompose = NO;
      }










    switch (type) {
    case NSKeyUp:

	/*Fix for bug #1ba71a86bb: key release firing on key press.*/
	w = [theEvent window];
	XEvent xEvent;
	setupXEvent(&xEvent, w, 0);
	TkWindow *winPtr = TkMacOSXGetTkWindow(w);
	Tk_Window tkwin = (Tk_Window) winPtr;
	xEvent.xany.type = KeyRelease;
	xEvent.xkey.keycode = releaseCode;
	xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    case NSKeyDown:
	repeat = [theEvent isARepeat];
	characters = [theEvent characters];
	charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers];
        len = [charactersIgnoringModifiers length];
    case NSFlagsChanged:
	modifiers = [theEvent modifierFlags];
	keyCode = [theEvent keyCode];
	//	w = [self windowWithWindowNumber:[theEvent windowNumber]];
	w = [theEvent window];

#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
	NSLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", [self class], self, _cmd, repeat, modifiers, characters, charactersIgnoringModifiers, keyCode,([charactersIgnoringModifiers length] == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0], w, type);
#endif
	break;

    default:
	return theEvent; /* Unrecognized key event. */
    }

................................................................................
         by doCommandBySelector: deleteBackward: */
- (void)insertText: (id)aString
{
  int i, len = [(NSString *)aString length];
  XEvent xEvent;

  if (NS_KEYLOG)
    NSLog (@"insertText '%@'\tlen = %d", aString, len);
  processingCompose = NO;
  finishedCompose = YES;

  /* first, clear any working text */
  if (privateWorkingText != nil)
    [self deleteWorkingText];

................................................................................

/* <NSTextInput>: inserts display of composing characters */
- (void)setMarkedText: (id)aString selectedRange: (NSRange)selRange
{
  NSString *str = [aString respondsToSelector: @selector (string)] ?
    [aString string] : aString;
  if (NS_KEYLOG)
    NSLog (@"setMarkedText '%@' len =%lu range %lu from %lu", str,
	   (unsigned long) [str length], (unsigned long) selRange.length,
	   (unsigned long) selRange.location);

  if (privateWorkingText != nil)
    [self deleteWorkingText];
  if ([str length] == 0)
    return;
................................................................................


- (NSRange)markedRange
{
  NSRange rng = privateWorkingText != nil
    ? NSMakeRange (0, [privateWorkingText length]) : NSMakeRange (NSNotFound, 0);
  if (NS_KEYLOG)
    NSLog (@"markedRange request");
  return rng;
}


- (void)unmarkText
{
  if (NS_KEYLOG)
    NSLog (@"unmark (accept) text");
  [self deleteWorkingText];
  processingCompose = NO;
}


/* used to position char selection windows, etc. */
- (NSRect)firstRectForCharacterRange: (NSRange)theRange
................................................................................
  NSRect rect;
  NSPoint pt;

  pt.x = caret_x;
  pt.y = caret_y;

  pt = [self convertPoint: pt toView: nil];
  pt = [[self window] convertPointToScreen: pt];
  pt.y -= caret_height;

  rect.origin = pt;
  rect.size.width = caret_height;
  rect.size.height = caret_height;
  return rect;
}
................................................................................
  return (NSInteger)self;
}


- (void)doCommandBySelector: (SEL)aSelector
{
  if (NS_KEYLOG)
    NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector));
  processingCompose = NO;
  if (aSelector == @selector (deleteBackward:))
    {
      /* happens when user backspaces over an ongoing composition:
         throw a 'delete' into the event queue */
      XEvent xEvent;
      setupXEvent(&xEvent, [self window], 0);
................................................................................
  return arr;
}


- (NSRange)selectedRange
{
  if (NS_KEYLOG)
    NSLog (@"selectedRange request");
  return NSMakeRange (NSNotFound, 0);
}


- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
{
  if (NS_KEYLOG)
    NSLog (@"characterIndexForPoint request");
  return 0;
}


- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
{
  static NSAttributedString *str = nil;
  if (str == nil) str = [NSAttributedString new];
  if (NS_KEYLOG)
    NSLog (@"attributedSubstringFromRange request");
  return str;
}
/* End <NSTextInput> impl. */
@end
 

@implementation TKContentView(TKKeyEvent)
/* delete display of composing characters [not in <NSTextInput>] */
- (void)deleteWorkingText
{
  if (privateWorkingText == nil)
    return;
  if (NS_KEYLOG)
    NSLog(@"deleteWorkingText len = %lu\n",
	    (unsigned long)[privateWorkingText length]);
  [privateWorkingText release];
  privateWorkingText = nil;
  processingCompose = NO;

  //PENDING: delete working text
}
................................................................................
 *  Set up basic fields in xevent for keyboard input.
 */
static void
setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;




    memset(xEvent, 0, sizeof(XEvent));
    xEvent->xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    xEvent->xany.send_event = false;
    xEvent->xany.display = Tk_Display(tkwin);
    xEvent->xany.window = Tk_WindowId(tkwin);







>
>
>
>
>
>
>
>
>



<

<
<

<
<











<
<
>

|







 







|







 







|







 







|







|







 







|







 







|







 







|







|









|













|







 







>
>
>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82


83


84
85
86
87
88
89
90
91
92
93
94


95
96
97
98
99
100
101
102
103
104
...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
...
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
    static NSMutableArray *nsEvArray;

    if (nsEvArray == nil)
      {
        nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
        processingCompose = NO;
      }

    w = [theEvent window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;
    XEvent xEvent;

    if (!winPtr) {
	return theEvent;
    }

    switch (type) {
    case NSKeyUp:

	/*Fix for bug #1ba71a86bb: key release firing on key press.*/


	setupXEvent(&xEvent, w, 0);


	xEvent.xany.type = KeyRelease;
	xEvent.xkey.keycode = releaseCode;
	xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    case NSKeyDown:
	repeat = [theEvent isARepeat];
	characters = [theEvent characters];
	charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers];
        len = [charactersIgnoringModifiers length];
    case NSFlagsChanged:
	modifiers = [theEvent modifierFlags];
	keyCode = [theEvent keyCode];



#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
	TKLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", [self class], self, _cmd, repeat, modifiers, characters, charactersIgnoringModifiers, keyCode,([charactersIgnoringModifiers length] == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0], w, type);
#endif
	break;

    default:
	return theEvent; /* Unrecognized key event. */
    }

................................................................................
         by doCommandBySelector: deleteBackward: */
- (void)insertText: (id)aString
{
  int i, len = [(NSString *)aString length];
  XEvent xEvent;

  if (NS_KEYLOG)
    TKLog (@"insertText '%@'\tlen = %d", aString, len);
  processingCompose = NO;
  finishedCompose = YES;

  /* first, clear any working text */
  if (privateWorkingText != nil)
    [self deleteWorkingText];

................................................................................

/* <NSTextInput>: inserts display of composing characters */
- (void)setMarkedText: (id)aString selectedRange: (NSRange)selRange
{
  NSString *str = [aString respondsToSelector: @selector (string)] ?
    [aString string] : aString;
  if (NS_KEYLOG)
    TKLog (@"setMarkedText '%@' len =%lu range %lu from %lu", str,
	   (unsigned long) [str length], (unsigned long) selRange.length,
	   (unsigned long) selRange.location);

  if (privateWorkingText != nil)
    [self deleteWorkingText];
  if ([str length] == 0)
    return;
................................................................................


- (NSRange)markedRange
{
  NSRange rng = privateWorkingText != nil
    ? NSMakeRange (0, [privateWorkingText length]) : NSMakeRange (NSNotFound, 0);
  if (NS_KEYLOG)
    TKLog (@"markedRange request");
  return rng;
}


- (void)unmarkText
{
  if (NS_KEYLOG)
    TKLog (@"unmark (accept) text");
  [self deleteWorkingText];
  processingCompose = NO;
}


/* used to position char selection windows, etc. */
- (NSRect)firstRectForCharacterRange: (NSRange)theRange
................................................................................
  NSRect rect;
  NSPoint pt;

  pt.x = caret_x;
  pt.y = caret_y;

  pt = [self convertPoint: pt toView: nil];
  pt = [[self window] tkConvertPointToScreen: pt];
  pt.y -= caret_height;

  rect.origin = pt;
  rect.size.width = caret_height;
  rect.size.height = caret_height;
  return rect;
}
................................................................................
  return (NSInteger)self;
}


- (void)doCommandBySelector: (SEL)aSelector
{
  if (NS_KEYLOG)
    TKLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector));
  processingCompose = NO;
  if (aSelector == @selector (deleteBackward:))
    {
      /* happens when user backspaces over an ongoing composition:
         throw a 'delete' into the event queue */
      XEvent xEvent;
      setupXEvent(&xEvent, [self window], 0);
................................................................................
  return arr;
}


- (NSRange)selectedRange
{
  if (NS_KEYLOG)
    TKLog (@"selectedRange request");
  return NSMakeRange (NSNotFound, 0);
}


- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
{
  if (NS_KEYLOG)
    TKLog (@"characterIndexForPoint request");
  return 0;
}


- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
{
  static NSAttributedString *str = nil;
  if (str == nil) str = [NSAttributedString new];
  if (NS_KEYLOG)
    TKLog (@"attributedSubstringFromRange request");
  return str;
}
/* End <NSTextInput> impl. */
@end
 

@implementation TKContentView(TKKeyEvent)
/* delete display of composing characters [not in <NSTextInput>] */
- (void)deleteWorkingText
{
  if (privateWorkingText == nil)
    return;
  if (NS_KEYLOG)
    TKLog(@"deleteWorkingText len = %lu\n",
	    (unsigned long)[privateWorkingText length]);
  [privateWorkingText release];
  privateWorkingText = nil;
  processingCompose = NO;

  //PENDING: delete working text
}
................................................................................
 *  Set up basic fields in xevent for keyboard input.
 */
static void
setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;
    if (!winPtr) {
	return;
    }

    memset(xEvent, 0, sizeof(XEvent));
    xEvent->xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    xEvent->xany.send_event = false;
    xEvent->xany.display = Tk_Display(tkwin);
    xEvent->xany.window = Tk_WindowId(tkwin);

Changes to macosx/tkMacOSXMenu.c.

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
    }

    int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
    NSView *view = [win contentView];
    NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);

    frame.origin = [view convertPoint:
	    [win convertPointFromScreen:frame.origin] fromView:nil];

    NSMenu *menu = (NSMenu *) menuPtr->platformData;
    NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc]
	    initTextCell:@"" pullsDown:NO];

    [popUpButtonCell setAltersStateOfSelectedItem:NO];
    [popUpButtonCell setMenu:menu];






|







781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
    }

    int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
    NSView *view = [win contentView];
    NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);

    frame.origin = [view convertPoint:
	    [win tkConvertPointFromScreen:frame.origin] fromView:nil];

    NSMenu *menu = (NSMenu *) menuPtr->platformData;
    NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc]
	    initTextCell:@"" pullsDown:NO];

    [popUpButtonCell setAltersStateOfSelectedItem:NO];
    [popUpButtonCell setMenu:menu];

Changes to macosx/tkMacOSXMenubutton.c.

839
840
841
842
843
844
845








    } else {
        dpPtr->gc = butPtr->normalTextGC;
    }

    return 1;
}















>
>
>
>
>
>
>
>
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
    } else {
        dpPtr->gc = butPtr->normalTextGC;
    }

    return 1;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXMenus.c.

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
static void
GenerateEditEvent(
    const char *name)
{
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
    Tk_Window tkwin = (Tk_Window) winPtr;

    if (tkwin == NULL) {
	return;
    }
    tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
    if (tkwin == NULL) {
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);






|

|



|







375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
static void
GenerateEditEvent(
    const char *name)
{
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
    Tk_Window tkwin;

    if (!winPtr) {
	return;
    }
    tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
    if (!tkwin) {
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);

Changes to macosx/tkMacOSXMouseEvent.c.

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
	_windowWithMouse = eventWindow;
	[_windowWithMouse retain];
    }

    /* Create an Xevent to add to the Tk queue. */
    NSPoint global, local = [theEvent locationInWindow];
    if (eventWindow) { /* local will be in window coordinates. */
	global = [eventWindow convertPointToScreen: local];
	local.y = [eventWindow frame].size.height - local.y;
	global.y = tkMacOSXZeroScreenHeight - global.y;
    } else { /* local will be in screen coordinates. */
	if (_windowWithMouse ) {
	    eventWindow = _windowWithMouse;
	    global = local;
	    local = [eventWindow convertPointFromScreen: local];
	    local.y = [eventWindow frame].size.height - local.y;
	    global.y = tkMacOSXZeroScreenHeight - global.y;
	} else { /* We have no window. Use the screen???*/
	    local.y = tkMacOSXZeroScreenHeight - local.y;
	    global = local;
	}
    }
................................................................................
	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *) w;
	    NSWindow *win = TkMacOSXDrawableWindow(w);

	    if (win) {
		NSPoint local;

		local = [win convertPointFromScreen:global];
		local.y = [win frame].size.height - local.y;
		if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
		    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
		    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
		}
		*win_x_return = local.x;
		*win_y_return = local.y;
................................................................................
    med.global.h = x;
    med.global.v = y;
    med.local = med.global;

    if (win) {
	NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);

	local = [win convertPointFromScreen:local];
	local.y = [win frame].size.height - local.y;
	if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
	    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
	    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
	}
	med.local.h = local.x;
	med.local.v = tkMacOSXZeroScreenHeight - local.y;






|






|







 







|







 







|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
	_windowWithMouse = eventWindow;
	[_windowWithMouse retain];
    }

    /* Create an Xevent to add to the Tk queue. */
    NSPoint global, local = [theEvent locationInWindow];
    if (eventWindow) { /* local will be in window coordinates. */
	global = [eventWindow tkConvertPointToScreen: local];
	local.y = [eventWindow frame].size.height - local.y;
	global.y = tkMacOSXZeroScreenHeight - global.y;
    } else { /* local will be in screen coordinates. */
	if (_windowWithMouse ) {
	    eventWindow = _windowWithMouse;
	    global = local;
	    local = [eventWindow tkConvertPointFromScreen: local];
	    local.y = [eventWindow frame].size.height - local.y;
	    global.y = tkMacOSXZeroScreenHeight - global.y;
	} else { /* We have no window. Use the screen???*/
	    local.y = tkMacOSXZeroScreenHeight - local.y;
	    global = local;
	}
    }
................................................................................
	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *) w;
	    NSWindow *win = TkMacOSXDrawableWindow(w);

	    if (win) {
		NSPoint local;

		local = [win tkConvertPointFromScreen:global];
		local.y = [win frame].size.height - local.y;
		if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
		    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
		    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
		}
		*win_x_return = local.x;
		*win_y_return = local.y;
................................................................................
    med.global.h = x;
    med.global.v = y;
    med.local = med.global;

    if (win) {
	NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);

	local = [win tkConvertPointFromScreen:local];
	local.y = [win frame].size.height - local.y;
	if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
	    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
	    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
	}
	med.local.h = local.x;
	med.local.v = tkMacOSXZeroScreenHeight - local.y;

Changes to macosx/tkMacOSXNotify.c.

27
28
29
30
31
32
33
34
35









































36
37
38
39
40




41
42
43




44
45
46




47


48
49















50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65




66




















67
68
69
70
71
72
73
74




75
76
77
78
79
80
81
..
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
#define TSD_INIT() ThreadSpecificData *tsdPtr = \
	Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData))

static void TkMacOSXNotifyExitHandler(ClientData clientData);
static void TkMacOSXEventsSetupProc(ClientData clientData, int flags);
static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);

#pragma mark TKApplication(TKNotify)










































@interface NSApplication(TKNotify)
/* We need to declare this hidden method. */
- (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event;
@end





@implementation NSWindow(TKNotify)
- (id) tkDisplayIfNeeded




{
    if (![self isAutodisplay]) {
	[self displayIfNeeded];




    }


    return nil;
}















@end

@implementation TKApplication(TKNotify)
/* Display all windows each time an event is removed from the queue.*/
- (NSEvent *) nextEventMatchingMask: (NSUInteger) mask
	untilDate: (NSDate *) expiration inMode: (NSString *) mode
	dequeue: (BOOL) deqFlag
{
    NSEvent *event = [super nextEventMatchingMask:mask
					untilDate:expiration
					   inMode:mode
					  dequeue:deqFlag];
    /* Retain this event for later use. Must be released.*/
    [event retain];
    [NSApp makeWindowsPerform:@selector(tkDisplayIfNeeded) inOrder:NO];
    return event;




}





















/*
 * Call super then check the pasteboard.
 */
- (void) sendEvent: (NSEvent *) theEvent
{
    [super sendEvent:theEvent];
    [NSApp tkCheckPasteboard];




}
@end

#pragma mark -
 
/*
 *----------------------------------------------------------------------
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static NSString *
GetRunLoopMode(NSModalSession modalSession)
{
    NSString *runLoopMode = nil;

    if (modalSession) {
	runLoopMode = NSModalPanelRunLoopMode;
    } else if (TkMacOSXGetCapture()) {
................................................................................
				       untilDate:[NSDate distantPast]
				       inMode:GetRunLoopMode(TkMacOSXGetModalSession())
				       dequeue:NO];
	if (currentEvent) {
	    if (currentEvent.type > 0) {
		Tcl_SetMaxBlockTime(&zeroBlockTime);
	    }
	    [currentEvent release];
	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
#endif
		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];
		    } else {
			[NSApp sendEvent:currentEvent];
		    }
		}
		[currentEvent release];
	    } else {
		break;
	    }
	} while (1);
	/* Now we can unlock the pool. */
	[NSApp _unlockAutoreleasePool];
    }







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
<
<
<
>
>
>
>
|
<
<
>
>
>
>
|
<
<
>
>
>
>

>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
<
<
<
<
|
<
<
<
<
<
<
<
<
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>







 







|







 







<







 







<







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77




78
79
80
81
82


83
84
85
86
87


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114




115








116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
...
303
304
305
306
307
308
309

310
311
312
313
314
315
316
...
371
372
373
374
375
376
377

378
379
380
381
382
383
384
#define TSD_INIT() ThreadSpecificData *tsdPtr = \
	Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData))

static void TkMacOSXNotifyExitHandler(ClientData clientData);
static void TkMacOSXEventsSetupProc(ClientData clientData, int flags);
static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);

#ifdef TK_MAC_DEBUG_EVENTS
static char* Tk_EventName[39] = {
    "",
    "",
    "KeyPress",		/*2*/
    "KeyRelease",      	/*3*/
    "ButtonPress",     	/*4*/
    "ButtonRelease",	/*5*/
    "MotionNotify",    	/*6*/
    "EnterNotify",     	/*7*/
    "LeaveNotify",     	/*8*/
    "FocusIn",		/*9*/
    "FocusOut",		/*10*/
    "KeymapNotify",    	/*11*/
    "Expose",		/*12*/
    "GraphicsExpose",	/*13*/
    "NoExpose",		/*14*/
    "VisibilityNotify",	/*15*/
    "CreateNotify",    	/*16*/
    "DestroyNotify",	/*17*/
    "UnmapNotify",     	/*18*/
    "MapNotify",       	/*19*/
    "MapRequest",      	/*20*/
    "ReparentNotify",	/*21*/
    "ConfigureNotify",	/*22*/
    "ConfigureRequest",	/*23*/
    "GravityNotify",	/*24*/
    "ResizeRequest",	/*25*/
    "CirculateNotify",	/*26*/
    "CirculateRequest",	/*27*/
    "PropertyNotify",	/*28*/
    "SelectionClear",	/*29*/
    "SelectionRequest",	/*30*/
    "SelectionNotify",	/*31*/
    "ColormapNotify",	/*32*/
    "ClientMessage",	/*33*/
    "MappingNotify",	/*34*/
    "VirtualEvent",    	/*35*/
    "ActivateNotify",	/*36*/
    "DeactivateNotify",	/*37*/
    "MouseWheelEvent"	/*38*/
};





static Tk_RestrictAction
InspectQueueRestrictProc(
     ClientData arg,
     XEvent *eventPtr)
{


    XVirtualEvent* ve = (XVirtualEvent*) eventPtr;
    const char *name;
    long serial = ve->serial;
    long time = eventPtr->xkey.time;
    


    if (eventPtr->type == VirtualEvent) {
	name = ve->name;
    } else {
	name = Tk_EventName[eventPtr->type];
    }
    fprintf(stderr, "    > %s;serial = %lu; time=%lu)\n",
	    name, serial, time);
    return TK_DEFER_EVENT;
}

/*
 * Debugging tool which prints the current Tcl queue.
 */

void DebugPrintQueue(void)
{
    ClientData oldArg;
    Tk_RestrictProc *oldProc;

    oldProc = Tk_RestrictEvents(InspectQueueRestrictProc, NULL, &oldArg);
    fprintf(stderr, "Current queue:\n");
    while (Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT)) {};
    Tk_RestrictEvents(oldProc, oldArg, &oldArg);
}
# endif

#pragma mark TKApplication(TKNotify)













@interface NSApplication(TKNotify)
/* We need to declare this hidden method. */
- (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event;
@end

@implementation TKApplication(TKNotify)
/*
 * Earlier versions of Tk would override nextEventMatchingMask here, adding a
 * call to displayIfNeeded on all windows after calling super. This would cause
 * windows to be redisplayed (if necessary) each time that an event was
 * received.  This was intended to replace Apple's default autoDisplay
 * mechanism, which the earlier versions of Tk would disable.  When autoDisplay
 * is set to the default value of YES, the Apple event loop will call
 * displayIfNeeded on all windows at the beginning of each iteration of their
 * event loop.  Since Tk does not call the Apple event loop, it was thought
 * that the autoDisplay behavior needed to be replicated.
 *
 * However, as of OSX 10.14 (Mojave) the autoDisplay property became
 * deprecated.  Luckily it turns out that, even though we don't ever start the
 * Apple event loop, the Apple window manager still calls displayIfNeeded on
 * all windows on a regular basis, perhaps each time the queue is empty.  So we
 * no longer, and perhaps never did need to set autoDisplay to NO, nor call
 * displayIfNeeded on our windows.  We can just leave all of that to the window
 * manager.
 */

/*
 * Call super then check the pasteboard.
 */
- (void) sendEvent: (NSEvent *) theEvent
{
    [super sendEvent:theEvent];
    [NSApp tkCheckPasteboard];
#ifdef TK_MAC_DEBUG_EVENTS
    fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]); 
    DebugPrintQueue();
#endif
}
@end

#pragma mark -
 
/*
 *----------------------------------------------------------------------
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSString *
GetRunLoopMode(NSModalSession modalSession)
{
    NSString *runLoopMode = nil;

    if (modalSession) {
	runLoopMode = NSModalPanelRunLoopMode;
    } else if (TkMacOSXGetCapture()) {
................................................................................
				       untilDate:[NSDate distantPast]
				       inMode:GetRunLoopMode(TkMacOSXGetModalSession())
				       dequeue:NO];
	if (currentEvent) {
	    if (currentEvent.type > 0) {
		Tcl_SetMaxBlockTime(&zeroBlockTime);
	    }

	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
#endif
		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];
		    } else {
			[NSApp sendEvent:currentEvent];
		    }
		}

	    } else {
		break;
	    }
	} while (1);
	/* Now we can unlock the pool. */
	[NSApp _unlockAutoreleasePool];
    }

Changes to macosx/tkMacOSXPrivate.h.

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
...
261
262
263
264
265
266
267



268
269
270



271
272
273
274
275
276
277
...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
 */

typedef struct TkMacOSXDrawingContext {
    CGContextRef context;
    NSView *view;
    HIShapeRef clipRgn;
    CGRect portBounds;
    int focusLocked;
} TkMacOSXDrawingContext;

/*
 * Variables internal to TkAqua.
 */

MODULE_SCOPE CGFloat tkMacOSXZeroScreenHeight;
................................................................................
			    int activeFlag);
MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
MODULE_SCOPE int	TkMacOSXIsWindowZoomed(TkWindow *winPtr);
MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
			    int x, int y, unsigned int width, unsigned int height);
MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image,
			    int use_ximage_alpha);
MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
			    CGImageRef image, unsigned long imageForeground,
			    unsigned long imageBackground, CGRect imageBounds,
			    CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    int useCG, TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
................................................................................
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems;
    NSWindow *_windowWithMouse;
    NSAutoreleasePool *_mainPool;
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    int _poolLock;



#endif
}
@property int poolLock;




@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;
................................................................................

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
@end

@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
- (void) generateExposeEvents: (HIShapeRef) shape;
- (void) viewDidChangeEffectiveAppearance;
- (void) updateAppearanceEvent;
- (void) tkToolbarButton: (id) sender;
- (BOOL) isOpaque;
- (BOOL) wantsDefaultClipping;
- (BOOL) acceptsFirstResponder;
- (void) keyDown: (NSEvent *) theEvent;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
@end

@interface NSWindow(TKWm)
- (NSPoint) convertPointToScreen:(NSPoint)point;
- (NSPoint) convertPointFromScreen:(NSPoint)point;
@end

#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;






<







 







|
<







 







>
>
>



>
>
>







 







|
<
<












|
|







127
128
129
130
131
132
133

134
135
136
137
138
139
140
...
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
...
329
330
331
332
333
334
335
336


337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
 */

typedef struct TkMacOSXDrawingContext {
    CGContextRef context;
    NSView *view;
    HIShapeRef clipRgn;
    CGRect portBounds;

} TkMacOSXDrawingContext;

/*
 * Variables internal to TkAqua.
 */

MODULE_SCOPE CGFloat tkMacOSXZeroScreenHeight;
................................................................................
			    int activeFlag);
MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
MODULE_SCOPE int	TkMacOSXIsWindowZoomed(TkWindow *winPtr);
MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
			    int x, int y, unsigned int width, unsigned int height);
MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image);

MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
			    CGImageRef image, unsigned long imageForeground,
			    unsigned long imageBackground, CGRect imageBounds,
			    CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    int useCG, TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
................................................................................
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems;
    NSWindow *_windowWithMouse;
    NSAutoreleasePool *_mainPool;
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    int _poolLock;
    int _macMinorVersion;
    Bool _isDrawing;
    Bool _simulateDrawing;
#endif
}
@property int poolLock;
@property int macMinorVersion;
@property Bool isDrawing;
@property Bool simulateDrawing;

@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;
................................................................................

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
@end

@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
- (void) generateExposeEvents: (HIShapeRef) shape; 


- (void) tkToolbarButton: (id) sender;
- (BOOL) isOpaque;
- (BOOL) wantsDefaultClipping;
- (BOOL) acceptsFirstResponder;
- (void) keyDown: (NSEvent *) theEvent;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
@end

@interface NSWindow(TKWm)
- (NSPoint) tkConvertPointToScreen:(NSPoint)point;
- (NSPoint) tkConvertPointFromScreen:(NSPoint)point;
@end

#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;

Changes to macosx/tkMacOSXScrlbr.c.

4
5
6
7
8
9
10

11
12
13
14
15
16
17
..
22
23
24
25
26
27
28
29
30
31
32
33
34
35




36
37
38
39

40
41
42
43
44
45



46








47
48
49
50
51
52
53
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
...
108
109
110
111
112
113
114


115
116










117
118
119
120
121
122
123
...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
...
184
185
186
187
188
189
190
191
192
193


194
195
196
197
198
199
200
201
202
203
...
224
225
226
227
228
229
230
231
232
233
234
235
236




237
238
239
240
241
242
243
244



245

246
247
248
249
250
251
252
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
...
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
...
393
394
395
396
397
398
399
400

401
402
403
404
405
406


407
408
409
410
411
412
413
414
415
416
417
418
419
420



421
422
423
424
425
426
427
428
429
430
...
443
444
445
446
447
448
449

450
451
452
453
454
455
456
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532

533












534

535





536

















537







538


539
540

541


542
543

544
545
546
547
548
549
550
551
...
579
580
581
582
583
584
585
586
587
588
589
590
591









 *	This file implements the Macintosh specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
 * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC.

 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScrollbar.h"
#include "tkMacOSXPrivate.h"
................................................................................
/*
 * Minimum slider length, in pixels (designed to make sure that the slider is
 * always easy to grab with the mouse).
 */

#define MIN_SLIDER_LENGTH	5

/*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/
#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */





#define MOUNTAIN_LION_STYLE (NSAppKitVersionNumber < 1138)

/*
 * Declaration of Mac specific scrollbar structure.

 */

typedef struct MacScrollbar {
    TkScrollbar information;	 /* Generic scrollbar info. */
    GC troughGC;		/* For drawing trough. */
    GC copyGC;			/* Used for copying from pixmap onto screen. */



} MacScrollbar;









/*
 * The class procedure table for the scrollbar widget. All fields except size
 * are left initialized to NULL, which should happen automatically since the
 * variable is declared at this scope.
 */

................................................................................
    sizeof(Tk_ClassProcs),	/* size */
    NULL,					/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};


/*Information on scrollbar layout, metrics, and draw info.*/
typedef struct ScrollbarMetrics {
    SInt32 width, minThumbHeight;
    int minHeight, topArrowHeight, bottomArrowHeight;
    NSControlSize controlSize;
} ScrollbarMetrics;


static ScrollbarMetrics metrics = {
  15, 54, 26, 14, 14, kControlSizeNormal /* kThemeScrollBarMedium */
};

HIThemeTrackDrawInfo info = {
    .version = 0,
    .min = 0.0,
    .max = 100.0,
    .attributes = kThemeTrackShowThumb,
};


/*
 * Forward declarations for procedures defined later in this file:
 */

static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr);
static int ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr);
static void UpdateControlValues(TkScrollbar  *scrollPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
................................................................................
		   Tk_Window tkwin)
{

    MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar));

    scrollPtr->troughGC = None;
    scrollPtr->copyGC = None;



    Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr);











    return (TkScrollbar *) scrollPtr;
}
 
/*
 *--------------------------------------------------------------
 *
................................................................................
 *	invoked as a do-when-idle handler, so it only runs when there's
 *	nothing else for the application to do.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
		    ClientData clientData)	/* Information about window. */
{
    register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;

    register Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;

    scrollPtr->flags &= ~REDRAW_PENDING;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
................................................................................
    }

    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
			    .ty = viewHeight};
    CGContextConcatCTM(dc.context, t);

    /*Draw Unix-style scroll trough to provide rect for native scrollbar.*/
    if (scrollPtr->highlightWidth != 0) {
    	GC fgGC, bgGC;

    	bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, (Pixmap) macWin);
    	if (scrollPtr->flags & GOT_FOCUS) {
    	    fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, (Pixmap) macWin);
    	} else {
................................................................................
    		       Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
    		       scrollPtr->borderWidth, scrollPtr->relief);
    Tk_Fill3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
    		       scrollPtr->inset, scrollPtr->inset,
    		       Tk_Width(tkwin) - 2*scrollPtr->inset,
    		       Tk_Height(tkwin) - 2*scrollPtr->inset, 0, TK_RELIEF_FLAT);

    /*Update values and draw in native rect.*/
    UpdateControlValues(scrollPtr);
    if (MOUNTAIN_LION_STYLE) {


      HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationInverted);
    } else {
      HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationNormal);
    }
    TkMacOSXRestoreDrawingContext(&dc);

    scrollPtr->flags &= ~REDRAW_PENDING;
}

/*
................................................................................
TkpComputeScrollbarGeometry(
    register TkScrollbar *scrollPtr)
                           /* Scrollbar whose geometry may have
                           * changed. */
{

   /*
    * Using code from tkUnixScrlbr.c because Unix scroll bindings are
    * driving the display at the script level. All the Mac scrollbar
    * has to do is re-draw itself.
    * There is a difference with Unix however: on macOS later than 10.6
    * (Snow Leopard) the scrollbars have no arrows at all. This is
    * handled by having scrollPtr->arrowLength set to zero.




    */

    int fieldLength;

    if (scrollPtr->highlightWidth < 0) {
       scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;



    scrollPtr->arrowLength = 0;

    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
           : Tk_Width(scrollPtr->tkwin))
           - 2*(scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
       fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
................................................................................
    }
    if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) {
       scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderLast > fieldLength) {
       scrollPtr->sliderLast = fieldLength;
    }
    scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
    scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;

    /*
     * Register the desired geometry for the window (leave enough space for
     * the two arrows plus a minimum-size slider, plus border around the whole
     * window, if any). Then arrange for the window to be redisplayed.

     */

      if (scrollPtr->vertical) {
       Tk_GeometryRequest(scrollPtr->tkwin,
              scrollPtr->width + 2*scrollPtr->inset,
              2*(scrollPtr->arrowLength + scrollPtr->borderWidth
              + scrollPtr->inset) + metrics.minThumbHeight);
................................................................................

    if (macScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }

    macScrollPtr=NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpConfigureScrollbar --
 *
 *	This procedure is called after the generic code has finished
 *	processing configuration options, in order to configure platform
 *	specific options.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Configuration info may get changed.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
		      register TkScrollbar *scrollPtr)
/* Information about widget; may or may not
 * already have values for some fields. */
{

}

/*
 *--------------------------------------------------------------
 *
................................................................................
TkpScrollbarPosition(
    register TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{

   /*
   * Using code from tkUnixScrlbr.c because Unix scroll bindings are
   * driving the display at the script level. All the Mac scrollbar
   * has to do is re-draw itself.
   */

    int length, width, tmp;
    register const int inset = scrollPtr->inset;

    if (scrollPtr->vertical) {
  	length = Tk_Height(scrollPtr->tkwin);
................................................................................
  	tmp = x;
  	x = y;
  	y = tmp;
  	length = Tk_Width(scrollPtr->tkwin);
  	width = Tk_Height(scrollPtr->tkwin);
    }

    if (x<inset || x>=width-inset || y<inset || y>=length-inset) {

  	return OUTSIDE;
    }

    /*
     * All of the calculations in this procedure mirror those in
     * TkpDisplayScrollbar. Be sure to keep the two consistent.


     */

    if (y < inset + scrollPtr->arrowLength) {
  	return TOP_ARROW;
    }
    if (y < scrollPtr->sliderFirst) {
  	return TOP_GAP;
    }
    if (y < scrollPtr->sliderLast) {
  	return SLIDER;
    }
    if (y >= length - (scrollPtr->arrowLength + inset)) {
  	return BOTTOM_ARROW;
    }




    return BOTTOM_GAP;

}

/*
 *--------------------------------------------------------------
 *
 * UpdateControlValues --
 *
................................................................................
 *--------------------------------------------------------------
 */

static void
UpdateControlValues(
		    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{

    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect  contrlRect;
    short width, height;

    NSView *view = TkMacOSXDrawableView(macWin);
................................................................................
    NSRect frame;
    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
		       Tk_Height(tkwin));
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    info.bounds = contrlRect;

    width = contrlRect.size.width;
    height = contrlRect.size.height;

    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */

    info.bounds = contrlRect;
    if (scrollPtr->vertical) {
      info.attributes &= ~kThemeTrackHorizontal;
    } else {
      info.attributes |= kThemeTrackHorizontal;
    }

    /*
     * Given the Tk parameters for the fractions of the start and end of the
     * thumb, the following calculation determines the location for the
     * Macintosh thumb. The Aqua scroll control works as follows. The
     * scrollbar's value is the position of the left (or top) side of the view
................................................................................
     * the view area.
     */

    double maximum = 100,  factor;
    factor = RangeToFactor(maximum);
    dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction)
	* factor;
    info.max =  MIN_SCROLLBAR_VALUE +
	factor - dViewSize;
    info.trackInfo.scrollbar.viewsize = dViewSize;
    if (scrollPtr->vertical) {
      if (MOUNTAIN_LION_STYLE) {
	info.value = factor * scrollPtr->firstFraction;
      } else {
	info.value = info.max - factor * scrollPtr->firstFraction;
      }
    } else {
	 info.value =  MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction;
    }

    if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
       || height <= metrics.minHeight) {
    	info.enableState = kThemeTrackHideTrack;
    } else {
    	info.enableState = kThemeTrackActive;
    	info.attributes = kThemeTrackShowThumb |  kThemeTrackThumbRgnIsNotGhost;
    }

}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarPress --
 *
 *	This procedure is invoked in response to <ButtonPress>, <ButtonRelease>,
 *      <EnterNotify>, and <LeaveNotify> events. Scrollbar appearance is modified.

 *
 *--------------------------------------------------------------
 */

static int
ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr)
{














  if (eventPtr->type == ButtonPress) {

    UpdateControlValues(scrollPtr);





    info.trackInfo.scrollbar.pressState = 1;

















  }







   if (eventPtr->type == EnterNotify) {


    info.trackInfo.scrollbar.pressState = 1;
  }

  if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) {


    info.trackInfo.scrollbar.pressState = 0;
  }

  return TCL_OK;
}



/*
 *--------------------------------------------------------------
 *
................................................................................
    case DeactivateNotify:
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    case ButtonPress:
    case ButtonRelease:
    case EnterNotify:
    case LeaveNotify:
    	ScrollbarPress(clientData, eventPtr);
	break;
    default:
	TkScrollbarEventProc(clientData, eventPtr);
    }
}















>







 







|






>
>
>
>
|


<
>



|


>
>
>

>
>
>
>
>
>
>
>







 







|











<
<
<
<
<
<

<

|



|







 







>
>
|
<
>
>
>
>
>
>
>
>
>
>







 







|









>







 







|







 







|

<
>
>
|

|







 







|
|
|
|
|
|
>
>
>
>








>
>
>
|
>







 







|
|


|
|
|
>







 







<
<









|





|







<
<







 







|
|
<







 







|
>




|
|
>
>


<
<
<
|

|
|

|
|
|
|
>
>
>
|
|
<







 







>







 







|









|

|

|







 







|

|

|
|

|


|




|

|
|







|


|
>





|

>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
|
|
>
|
>
>
|
|
>
|







 







|





>
>
>
>
>
>
>
>
>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
..
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89






90

91
92
93
94
95
96
97
98
99
100
101
102
103
...
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
...
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
...
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
...
348
349
350
351
352
353
354


355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377


378
379
380
381
382
383
384
...
401
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
...
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437



438
439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
...
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
...
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
...
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
...
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
 *	This file implements the Macintosh specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
 * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC.
 * Copyright (c) 2018 Marc Culler
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScrollbar.h"
#include "tkMacOSXPrivate.h"
................................................................................
/*
 * Minimum slider length, in pixels (designed to make sure that the slider is
 * always easy to grab with the mouse).
 */

#define MIN_SLIDER_LENGTH	5

/*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling.*/
#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */

/*
 * Apple reversed the scroll direction with the release of OSX 10.7 Lion.
 */

#define SNOW_LEOPARD_STYLE (NSAppKitVersionNumber < 1138)

/*

 * Declaration of an extended scrollbar structure with Mac specific additions.
 */

typedef struct MacScrollbar {
    TkScrollbar information;	/* Generic scrollbar info. */
    GC troughGC;		/* For drawing trough. */
    GC copyGC;			/* Used for copying from pixmap onto screen. */
    Bool buttonDown;            /* Is the mouse button down? */  
    Bool mouseOver;             /* Is the pointer over the scrollbar. */
    HIThemeTrackDrawInfo info;  /* Controls how the scrollbar is drawn. */
} MacScrollbar;

/* Used to initialize a MacScrollbar's info field. */
HIThemeTrackDrawInfo defaultInfo = {
    .version = 0,
    .min = 0.0,
    .max = 100.0,
    .attributes = kThemeTrackShowThumb,
};

/*
 * The class procedure table for the scrollbar widget. All fields except size
 * are left initialized to NULL, which should happen automatically since the
 * variable is declared at this scope.
 */

................................................................................
    sizeof(Tk_ClassProcs),	/* size */
    NULL,					/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};


/* Information on scrollbar layout, metrics, and draw info.*/
typedef struct ScrollbarMetrics {
    SInt32 width, minThumbHeight;
    int minHeight, topArrowHeight, bottomArrowHeight;
    NSControlSize controlSize;
} ScrollbarMetrics;


static ScrollbarMetrics metrics = {
  15, 54, 26, 14, 14, kControlSizeNormal /* kThemeScrollBarMedium */
};









/*
 * Declarations of static functions defined later in this file:
 */

static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr);
static int ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr);
static void UpdateControlValues(TkScrollbar  *scrollPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
................................................................................
		   Tk_Window tkwin)
{

    MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar));

    scrollPtr->troughGC = None;
    scrollPtr->copyGC = None;
    scrollPtr->info = defaultInfo;
    scrollPtr->buttonDown = false;
    

    Tk_CreateEventHandler(tkwin,
			  ExposureMask        |
			  StructureNotifyMask |
			  FocusChangeMask     |
			  ButtonPressMask     |
			  ButtonReleaseMask   |
			  EnterWindowMask     |
			  LeaveWindowMask     |
			  VisibilityChangeMask,
			  ScrollbarEventProc, scrollPtr);

    return (TkScrollbar *) scrollPtr;
}
 
/*
 *--------------------------------------------------------------
 *
................................................................................
 *	invoked as a do-when-idle handler, so it only runs when there's
 *	nothing else for the application to do.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a scrollbar on the screen.
 *
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
		    ClientData clientData)	/* Information about window. */
{
    register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    register Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;

    scrollPtr->flags &= ~REDRAW_PENDING;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
................................................................................
    }

    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
			    .ty = viewHeight};
    CGContextConcatCTM(dc.context, t);

    /*Draw a 3D rectangle to provide a base for the native scrollbar.*/
    if (scrollPtr->highlightWidth != 0) {
    	GC fgGC, bgGC;

    	bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, (Pixmap) macWin);
    	if (scrollPtr->flags & GOT_FOCUS) {
    	    fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, (Pixmap) macWin);
    	} else {
................................................................................
    		       Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
    		       scrollPtr->borderWidth, scrollPtr->relief);
    Tk_Fill3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
    		       scrollPtr->inset, scrollPtr->inset,
    		       Tk_Width(tkwin) - 2*scrollPtr->inset,
    		       Tk_Height(tkwin) - 2*scrollPtr->inset, 0, TK_RELIEF_FLAT);

    /* Update values and then draw the native scrollbar over the rectangle.*/
    UpdateControlValues(scrollPtr);


    if (SNOW_LEOPARD_STYLE) {
	HIThemeDrawTrack (&(msPtr->info), 0, dc.context, kHIThemeOrientationInverted);
    } else {
	HIThemeDrawTrack (&(msPtr->info), 0, dc.context, kHIThemeOrientationNormal);
    }
    TkMacOSXRestoreDrawingContext(&dc);

    scrollPtr->flags &= ~REDRAW_PENDING;
}

/*
................................................................................
TkpComputeScrollbarGeometry(
    register TkScrollbar *scrollPtr)
                           /* Scrollbar whose geometry may have
                           * changed. */
{

   /*
    * The code below is borrowed from tkUnixScrlbr.c but has been adjusted to
    * account for some differences between macOS and X11. The Unix scrollbar
    * has an arrow button on each end.  On macOS 10.6 (Snow Leopard) the
    * scrollbars by default have both arrow buttons at the bottom or right.
    * (There is a preferences setting to use the Unix layout, but we are not
    * supporting that!)  On more recent versions of macOS there are no arrow
    * buttons at all. The case of no arrow buttons can be handled as a special
    * case of having both buttons at the end, but where scrollPtr->arrowLength
    * happens to be zero.  To adjust for having both arrows at the same end we
    * shift the scrollbar up by the arrowLength.
    */

    int fieldLength;

    if (scrollPtr->highlightWidth < 0) {
       scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
    if ([NSApp macMinorVersion] == 6) {
      scrollPtr->arrowLength = scrollPtr->width;
    } else {
      scrollPtr->arrowLength = 0;
    }
    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
           : Tk_Width(scrollPtr->tkwin))
           - 2*(scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
       fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
................................................................................
    }
    if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) {
       scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderLast > fieldLength) {
       scrollPtr->sliderLast = fieldLength;
    }
    scrollPtr->sliderFirst += -scrollPtr->arrowLength + scrollPtr->inset;
    scrollPtr->sliderLast += scrollPtr->inset;

    /*
     * Register the desired geometry for the window. Leave enough space for the
     * two arrows, if there are any arrows, plus a minimum-size slider, plus
     * border around the whole window, if any. Then arrange for the window to
     * be redisplayed.
     */

      if (scrollPtr->vertical) {
       Tk_GeometryRequest(scrollPtr->tkwin,
              scrollPtr->width + 2*scrollPtr->inset,
              2*(scrollPtr->arrowLength + scrollPtr->borderWidth
              + scrollPtr->inset) + metrics.minThumbHeight);
................................................................................

    if (macScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }


}

/*
 *----------------------------------------------------------------------
 *
 * TkpConfigureScrollbar --
 *
 *	This procedure is called after the generic code has finished
 *	processing configuration options, in order to configure platform
 *	specific options.  There are no such option on the Mac, however.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Currently, none.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
		      register TkScrollbar *scrollPtr)


{

}

/*
 *--------------------------------------------------------------
 *
................................................................................
TkpScrollbarPosition(
    register TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{

   /*
   * The code below is borrowed from tkUnixScrlbr.c and needs no adjustment
   * since it does not involve the arrow buttons.

   */

    int length, width, tmp;
    register const int inset = scrollPtr->inset;

    if (scrollPtr->vertical) {
  	length = Tk_Height(scrollPtr->tkwin);
................................................................................
  	tmp = x;
  	x = y;
  	y = tmp;
  	length = Tk_Width(scrollPtr->tkwin);
  	width = Tk_Height(scrollPtr->tkwin);
    }

    if (x < inset || x >= width - inset ||
	y < inset || y >= length - inset) {
  	return OUTSIDE;
    }

    /*
     * Here we assume that the scrollbar is layed out with both arrow buttons
     * at the bottom (or right).  Except on 10.6, however, the arrows do not
     * actually exist, i.e. the arrowLength is 0.  These are the same
     * assumptions which are being made in TkpComputeScrollbarGeometry.
     */




    if (y < scrollPtr->sliderFirst + scrollPtr->arrowLength) {
  	return TOP_GAP;
      }
      if (y < scrollPtr->sliderLast) {
  	return SLIDER;
      }
      if (y < length - (2*scrollPtr->arrowLength + inset)) {
  	return BOTTOM_GAP;
      }
      /* On systems newer than 10.6 we have already returned. */
      if (y < length - (scrollPtr->arrowLength + inset)) {
  	return TOP_ARROW;
      }
      return BOTTOM_ARROW;

}

/*
 *--------------------------------------------------------------
 *
 * UpdateControlValues --
 *
................................................................................
 *--------------------------------------------------------------
 */

static void
UpdateControlValues(
		    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{
    MacScrollbar *msPtr = (MacScrollbar *)scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect  contrlRect;
    short width, height;

    NSView *view = TkMacOSXDrawableView(macWin);
................................................................................
    NSRect frame;
    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
		       Tk_Height(tkwin));
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    msPtr->info.bounds = contrlRect;

    width = contrlRect.size.width;
    height = contrlRect.size.height;

    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */

    msPtr->info.bounds = contrlRect;
    if (scrollPtr->vertical) {
      msPtr->info.attributes &= ~kThemeTrackHorizontal;
    } else {
      msPtr->info.attributes |= kThemeTrackHorizontal;
    }

    /*
     * Given the Tk parameters for the fractions of the start and end of the
     * thumb, the following calculation determines the location for the
     * Macintosh thumb. The Aqua scroll control works as follows. The
     * scrollbar's value is the position of the left (or top) side of the view
................................................................................
     * the view area.
     */

    double maximum = 100,  factor;
    factor = RangeToFactor(maximum);
    dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction)
	* factor;
    msPtr->info.max =  MIN_SCROLLBAR_VALUE +
	factor - dViewSize;
    msPtr->info.trackInfo.scrollbar.viewsize = dViewSize;
    if (scrollPtr->vertical) {
      if (SNOW_LEOPARD_STYLE) {
	msPtr->info.value = factor * scrollPtr->firstFraction;
      } else {
	msPtr->info.value = msPtr->info.max - factor * scrollPtr->firstFraction;
      }
    } else {
	 msPtr->info.value =  MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction;
    }

    if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
       || height <= metrics.minHeight) {
    	msPtr->info.enableState = kThemeTrackHideTrack;
    } else {
        msPtr->info.enableState = kThemeTrackActive;
    	msPtr->info.attributes = kThemeTrackShowThumb |  kThemeTrackThumbRgnIsNotGhost;
    }

}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarEvent --
 *
 *	This procedure is invoked in response to <ButtonPress>, <ButtonRelease>,
 *      <EnterNotify>, and <LeaveNotify> events. The Scrollbar appearance is
 *      modified for each event.
 *
 *--------------------------------------------------------------
 */

static int
ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr)
{
    MacScrollbar *msPtr = (MacScrollbar *)scrollPtr;
    
    /* The pressState does not indicate whether the moused button was
     * pressed at some location in the Scrollbar.  Rather, it indicates
     * that the scrollbar should appear as if it were pressed in that
     * location. The standard Mac behavior is that once the button is
     * pressed inside the Scrollbar the appearance should not change until
     * the button is released, even if the mouse moves outside of the
     * scrollbar.  However, if the mouse lies over the scrollbar but the
     * button is not pressed then the appearance should be the same as if
     * the button had been pressed on the slider, i.e. kThemeThumbPressed.
     * See the file Appearance.r, or HIToolbox.bridgesupport on 10.14.
     */

    if (eventPtr->type == ButtonPress) {
	msPtr->buttonDown = true;
	UpdateControlValues(scrollPtr);
	int where = TkpScrollbarPosition(scrollPtr,
					 eventPtr->xbutton.x,
					 eventPtr->xbutton.y);
	switch(where) {
	case OUTSIDE:
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	    break;
	case TOP_GAP:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeTopTrackPressed;
	    break;
	case SLIDER:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	    break;
	case BOTTOM_GAP:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeBottomTrackPressed;
	    break;
	case TOP_ARROW:
	    /* This looks wrong and the docs say it is wrong but it works. */
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeTopInsideArrowPressed;
	    break;
	case BOTTOM_ARROW:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeBottomOutsideArrowPressed;
	    break;
	}
    }
    if (eventPtr->type == ButtonRelease) {
	msPtr->buttonDown = false;
	if (!msPtr->mouseOver) {
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	}
    }
    if (eventPtr->type == EnterNotify) {
	msPtr->mouseOver = true;
	if (!msPtr->buttonDown) {
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	}
    }
    if (eventPtr->type == LeaveNotify) {
	msPtr->mouseOver = false;
	if (!msPtr->buttonDown) {
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	}
    }
    return TCL_OK;
}



/*
 *--------------------------------------------------------------
 *
................................................................................
    case DeactivateNotify:
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    case ButtonPress:
    case ButtonRelease:
    case EnterNotify:
    case LeaveNotify:
    	ScrollbarEvent(clientData, eventPtr);
	break;
    default:
	TkScrollbarEventProc(clientData, eventPtr);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXTest.c.

75
76
77
78
79
80
81





























82
83
84
85
86
87
88
89
    int objc,				/* Not used. */
    Tcl_Obj *const objv[])			/* Not used. */
{
    Debugger();
    return TCL_OK;
}
 





























/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    int objc,				/* Not used. */
    Tcl_Obj *const objv[])			/* Not used. */
{
    Debugger();
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkTestSimulateDrawing --
 *
 *      A test widget display procedure which records calls can use this to
 *      avoid duplicate calls which would occur due to fact that no valid
 *      graphics context is available to the idle task which is running the
 *      display proc.  Note that no actual drawing to the screen will take
 *      place when this flag is set.  This is just a wrapper for the NSApp
 *      property.
 *
 *
 * Results:
 *      Calls to low level drawing routines will return without actually
 *	drawing anything to the screen.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */
MODULE_SCOPE void
TkTestSimulateDrawing(Bool yesno) {
    [NSApp setSimulateDrawing:yesno];
}

 

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXWindowEvent.c.

293
294
295
296
297
298
299

























300
301
302
303
304
305
306
...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
...
797
798
799
800
801
802
803
804
805
806


807
808
809
810
811
812

















813
814
815
816
817






818
819
820
821
822





823
824
825
826
827
828
829
830
831







832
833
834
835
836
837
838
...
869
870
871
872
873
874
875
876


877
878
879
880
881
882
883
...
886
887
888
889
890
891
892
893


894
895
896
897
898
899
900
901
902
...
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
...
928
929
930
931
932
933
934
935
936
937
938
939
940
941

942
943
944
945
946
947
948
949
950
951
952

953
954
955
956
957
958




959
960
961
962
963
964
965
...
991
992
993
994
995
996
997



998
999
1000
1001
1002
1003
1004
@end

#pragma mark -
 
/*
 *----------------------------------------------------------------------
 *

























 * GenerateUpdates --
 *
 *	Given a Macintosh update region and a Tk window this function geneates
 *	an X Expose event for the window if it meets the update region. The
 *	function will then recursivly have each damaged window generate Expose
 *	events for its child windows.
 *
................................................................................
	return 0;
    }
    if (!HIShapeIntersectsRect(updateRgn, &bounds)) {
	return 0;
    }

    /*
     * Compute the bounding box of the area that the damage occurred in.
     */

    boundsRgn = HIShapeCreateWithRect(&bounds);
    damageRgn = HIShapeCreateIntersection(updateRgn, boundsRgn);
    if (HIShapeIsEmpty(damageRgn)) {
	CFRelease(damageRgn);
	CFRelease(boundsRgn);
................................................................................
    event.xexpose.y = damageBounds.origin.y - bounds.origin.y;
    event.xexpose.width = damageBounds.size.width;
    event.xexpose.height = damageBounds.size.height;
    event.xexpose.count = 0;
    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

#ifdef TK_MAC_DEBUG_DRAWING
    NSLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
	event.xexpose.y, event.xexpose.width, event.xexpose.height);
#endif

    /*
     * Generate updates for the children of this window
     */

................................................................................
@implementation TKContentView(TKWindowEvent)

- (void) drawRect: (NSRect) rect
{
    const NSRect *rectsBeingDrawn;
    NSInteger rectsBeingDrawnCount;

    [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];

#ifdef TK_MAC_DEBUG_DRAWING


    TKLog(@"-[%@(%p) %s%@]", [self class], self, _cmd, NSStringFromRect(rect));
    [[NSColor colorWithDeviceRed:0.0 green:1.0 blue:0.0 alpha:.1] setFill];
    NSRectFillListUsingOperation(rectsBeingDrawn, rectsBeingDrawnCount,
	    NSCompositeSourceOver);
#endif


















    CGFloat height = [self bounds].size.height;
    HIMutableShapeRef drawShape = HIShapeCreateMutable();

    while (rectsBeingDrawnCount--) {
	CGRect r = NSRectToCGRect(*rectsBeingDrawn++);






	r.origin.y = height - (r.origin.y + r.size.height);
	HIShapeUnionWithRect(drawShape, &r);
    }
    [self generateExposeEvents:(HIShapeRef)drawShape];
    CFRelease(drawShape);





}

-(void) setFrameSize: (NSSize)newsize
{
    [super setFrameSize: newsize];
    if ([self inLiveResize]) {
	NSWindow *w = [self window];
	TkWindow *winPtr = TkMacOSXGetTkWindow(w);
	Tk_Window tkwin = (Tk_Window) winPtr;







	unsigned int width = (unsigned int)newsize.width;
	unsigned int height=(unsigned int)newsize.height;
	ClientData oldArg;
    	Tk_RestrictProc *oldProc;

	/*
	 * This can be called from outside the Tk event loop.
................................................................................
	  * Finally, generate and process expose events to redraw the window.
	  */

	HIRect bounds = NSRectToCGRect([self bounds]);
	HIShapeRef shape = HIShapeCreateWithRect(&bounds);
	[self generateExposeEvents: shape];
	[w displayIfNeeded];
	[NSApp _unlockAutoreleasePool];


    }
}

/*
 * Core method of this class: generates expose events for redrawing.  The
 * expose events are immediately removed from the Tcl event loop and processed.
 * This causes drawing procedures to be scheduled as idle events.  Then all
................................................................................

- (void) generateExposeEvents: (HIShapeRef) shape
{
    unsigned long serial;
    CGRect updateBounds;
    int updatesNeeded;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);



    if (!winPtr) {
		return;
    }

    /*
     * Generate Tk Expose events.
     */

    HIShapeGetBounds(shape, &updateBounds);
................................................................................

    if (updatesNeeded) {

	/*
	 * First process all of the Expose events.
	 */

	ClientData oldArg;
    	Tk_RestrictProc *oldProc = Tk_RestrictEvents(ExposeRestrictProc,
						     UINT2PTR(serial), &oldArg);
    	while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {};
    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);

	/*
	 * Starting with OSX 10.14, which uses Core Animation to draw windows,
	 * all drawing must be done within the drawRect method.  (The CGContext
	 * which draws to the backing CALayer is created by the NSView before
................................................................................
	 * with the current CGContext outside of the drawRect method has no
	 * effect.)
	 *
	 * Fortunately, Tk schedules all drawing to be done while Tcl is idle.
	 * So we can do the drawing by processing all of the idle events that
	 * were created when the expose events were processed.
	 */

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
}


/*

 * These two methods allow Tk to register a virtual event which fires when the
 * appearance changes on 10.14.
 */

- (void) viewDidChangeEffectiveAppearance
{
    [self updateAppearanceEvent];
}

- (void) updateAppearanceEvent
{

    NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
    NSWindow *w = [self window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    XVirtualEvent event;
    int x, y;
    Tk_Window tkwin = (Tk_Window) winPtr;




    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
................................................................................
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd);
#endif
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window) winPtr;



    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







 







<
<

>
>
|
<
<
<


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>





>
>
>
>
>





<
|
|
|
>
>
>
>
>
>
>







 







|
>
>







 







<
>
>

|







 







<
|
<







 







<




<

>
|
|




|
<
<
<
<
>



<
<

>
>
>
>







 







>
>
>







293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
...
822
823
824
825
826
827
828


829
830
831
832



833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877

878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
...
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
...
944
945
946
947
948
949
950

951
952
953
954
955
956
957
958
959
960
961
...
969
970
971
972
973
974
975

976

977
978
979
980
981
982
983
...
985
986
987
988
989
990
991

992
993
994
995

996
997
998
999
1000
1001
1002
1003
1004




1005
1006
1007
1008


1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
....
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
@end

#pragma mark -
 
/*
 *----------------------------------------------------------------------
 *
 * TkpAppIsDrawing --
 *
 *      A widget display procedure can call this to determine whether it
 *      is being run inside of the drawRect method.  This is needed for
 *      some tests, especially of the Text widget, which record data in
 *      a global Tcl variable and assume that display procedures will be
 *      run in a predictable sequence as Tcl idle tasks.
 *
 * Results:
 *	True only while running the drawRect method of a TKContentView;
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */
MODULE_SCOPE Bool
TkpAppIsDrawing(void) {
    return [NSApp isDrawing];
}

 
/*
 *----------------------------------------------------------------------
 *
 * GenerateUpdates --
 *
 *	Given a Macintosh update region and a Tk window this function geneates
 *	an X Expose event for the window if it meets the update region. The
 *	function will then recursivly have each damaged window generate Expose
 *	events for its child windows.
 *
................................................................................
	return 0;
    }
    if (!HIShapeIntersectsRect(updateRgn, &bounds)) {
	return 0;
    }

    /*
     * Compute the bounding box of the area that the damage occured in.
     */

    boundsRgn = HIShapeCreateWithRect(&bounds);
    damageRgn = HIShapeCreateIntersection(updateRgn, boundsRgn);
    if (HIShapeIsEmpty(damageRgn)) {
	CFRelease(damageRgn);
	CFRelease(boundsRgn);
................................................................................
    event.xexpose.y = damageBounds.origin.y - bounds.origin.y;
    event.xexpose.width = damageBounds.size.width;
    event.xexpose.height = damageBounds.size.height;
    event.xexpose.count = 0;
    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

#ifdef TK_MAC_DEBUG_DRAWING
    TKLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
	event.xexpose.y, event.xexpose.width, event.xexpose.height);
#endif

    /*
     * Generate updates for the children of this window
     */

................................................................................
@implementation TKContentView(TKWindowEvent)

- (void) drawRect: (NSRect) rect
{
    const NSRect *rectsBeingDrawn;
    NSInteger rectsBeingDrawnCount;



#ifdef TK_MAC_DEBUG_DRAWING
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    if (winPtr) fprintf(stderr, "drawRect: drawing %s\n",
			Tk_PathName(winPtr));



#endif

    if ([NSApp simulateDrawing]) {
    	return;
    }

    /*
     * We do not allow recursive calls to drawRect, but we only log
     * them on OSX > 10.13, where they should never happen.
     */

    if ([NSApp isDrawing] && [NSApp macMinorVersion] > 13) {
	TKLog(@"WARNING: a recursive call to drawRect was aborted.");
	return;
    }

    [NSApp setIsDrawing: YES];

    [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];
    CGFloat height = [self bounds].size.height;
    HIMutableShapeRef drawShape = HIShapeCreateMutable();

    while (rectsBeingDrawnCount--) {
	CGRect r = NSRectToCGRect(*rectsBeingDrawn++);

#ifdef TK_MAC_DEBUG_DRAWING
	fprintf(stderr, "drawRect: %dx%[email protected](%d,%d)\n", (int)r.size.width,
	       (int)r.size.height, (int)r.origin.x, (int)r.origin.y);
#endif

	r.origin.y = height - (r.origin.y + r.size.height);
	HIShapeUnionWithRect(drawShape, &r);
    }
    [self generateExposeEvents:(HIShapeRef)drawShape];
    CFRelease(drawShape);
    [NSApp setIsDrawing: NO];

#ifdef TK_MAC_DEBUG_DRAWING
    fprintf(stderr, "drawRect: done.\n");
#endif
}

-(void) setFrameSize: (NSSize)newsize
{
    [super setFrameSize: newsize];

    NSWindow *w = [self window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;
    if (winPtr) {
	/* On OSX versions below 10.14 setFrame calls drawRect.
	 * On 10.14 it does its own drawing.
	 */
	if ([NSApp macMinorVersion] > 13) {
	    [NSApp setIsDrawing:YES];
	}
	unsigned int width = (unsigned int)newsize.width;
	unsigned int height=(unsigned int)newsize.height;
	ClientData oldArg;
    	Tk_RestrictProc *oldProc;

	/*
	 * This can be called from outside the Tk event loop.
................................................................................
	  * Finally, generate and process expose events to redraw the window.
	  */

	HIRect bounds = NSRectToCGRect([self bounds]);
	HIShapeRef shape = HIShapeCreateWithRect(&bounds);
	[self generateExposeEvents: shape];
	[w displayIfNeeded];
	if ([NSApp macMinorVersion] > 13) {
	    [NSApp setIsDrawing:NO];
	}
    }
}

/*
 * Core method of this class: generates expose events for redrawing.  The
 * expose events are immediately removed from the Tcl event loop and processed.
 * This causes drawing procedures to be scheduled as idle events.  Then all
................................................................................

- (void) generateExposeEvents: (HIShapeRef) shape
{
    unsigned long serial;
    CGRect updateBounds;
    int updatesNeeded;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);

    ClientData oldArg;
    Tk_RestrictProc *oldProc;
    if (!winPtr) {
	return;
    }

    /*
     * Generate Tk Expose events.
     */

    HIShapeGetBounds(shape, &updateBounds);
................................................................................

    if (updatesNeeded) {

	/*
	 * First process all of the Expose events.
	 */


    	oldProc = Tk_RestrictEvents(ExposeRestrictProc, UINT2PTR(serial), &oldArg);

    	while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {};
    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);

	/*
	 * Starting with OSX 10.14, which uses Core Animation to draw windows,
	 * all drawing must be done within the drawRect method.  (The CGContext
	 * which draws to the backing CALayer is created by the NSView before
................................................................................
	 * with the current CGContext outside of the drawRect method has no
	 * effect.)
	 *
	 * Fortunately, Tk schedules all drawing to be done while Tcl is idle.
	 * So we can do the drawing by processing all of the idle events that
	 * were created when the expose events were processed.
	 */

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
}


/*
 * This method is called when a user changes between light and dark mode.
 * The implementation here generates a Tk virtual event which can be bound
 * to a function that redraws the window in an appropriate style.
 */

- (void) viewDidChangeEffectiveAppearance
{
    XVirtualEvent event;




    int x, y;
    NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
    NSWindow *w = [self window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);


    Tk_Window tkwin = (Tk_Window) winPtr;

    if (!winPtr) {
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
................................................................................
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd);
#endif
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window) winPtr;
    if (!winPtr){
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);

Changes to macosx/tkMacOSXWm.c.

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
...
383
384
385
386
387
388
389
390

391
392
393
394



395
396
397

398
399
400
401
402

403


404
405
406
407
408


409
410

411
412
413
414


415

416
417
418
419
420
421
422
423
424
425
426
427


428

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
...
594
595
596
597
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613
614
615
616
...
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
...
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
....
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
....
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678



























5679
5680
5681
5682
5683
5684
5685
....
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
....
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572





6573
6574

6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
/*
 * Conversion of coordinates between window and screen.
 */

@implementation NSWindow(TKWm)
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- (NSPoint) convertPointToScreen: (NSPoint) point
{
    return [self convertBaseToScreen:point];
}
- (NSPoint) convertPointFromScreen: (NSPoint)point
{
    return [self convertScreenToBase:point];
}
#else
- (NSPoint) convertPointToScreen: (NSPoint) point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectToScreen:pointrect].origin;
}
- (NSPoint) convertPointFromScreen: (NSPoint)point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectFromScreen:pointrect].origin;
}
................................................................................
{
    id _i1, _i2;
}
@end


@implementation TKWindow: NSWindow
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12

/*
 * Override automatic fullscreen button on >10.12 because system fullscreen API
 * confuses Tk window geometry. Custom implementation setting fullscreen status using
 * Tk API and NSStatusItem in menubar to exit fullscreen status.



 */

NSStatusItem *exitFullScreen;


- (void)toggleFullScreen:(id)sender
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
    Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);




    if (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask) {
    	TkMacOSXMakeFullscreen(winPtr, self, 0, interp);
    } else {
    	TkMacOSXMakeFullscreen(winPtr, self, 1, interp);
    }


}


-(void)restoreOldScreen:(id)sender {

    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
    Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);




    TkMacOSXMakeFullscreen(winPtr, self, 0, interp);
    [[NSStatusBar systemStatusBar] removeStatusItem: exitFullScreen];
}

#endif
@end

@implementation TKWindow(TKWm)

- (BOOL) canBecomeKeyWindow
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);




    return (winPtr && winPtr->wmInfoPtr && (winPtr->wmInfoPtr->macClass ==
	    kHelpWindowClass || winPtr->wmInfoPtr->attributes &
	    kWindowNoActivatesAttribute)) ? NO : YES;
}



#if DEBUG_ZOMBIES
- (id) retain
{
    id result = [super retain];
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 1){

	printf("Retained <%s>. Count is: %lu\n", title, [self retainCount]);
    }
    return result;
}

- (id) autorelease
{
    id result = [super autorelease];
................................................................................

static TkWindow*
FrontWindowAtPoint(
    int x, int y)
{
    NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
    NSArray *windows = [NSApp orderedWindows];
    TkWindow *front = NULL;

    for (NSWindow *w in windows) {
	    if (w && NSMouseInRect(p, [w frame], NO)) {
		front = TkMacOSXGetTkWindow(w);

		break;
	    }
	}
    return front;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
................................................................................

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Create the underlying Mac window for this Tk window.
	 */

	if (!TkMacOSXHostToplevelExists(winPtr)) {
	    TkMacOSXMakeRealWindowExist(winPtr);
................................................................................
     */

    XMapWindow(winPtr->display, winPtr->window);

    /*Add window to Window menu.*/
    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    [win setExcludedFromWindowsMenu:NO];

}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWmUnmapWindow --
 *
................................................................................
    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];
    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setReleasedWhenClosed:NO];
    [window setAutodisplay:NO];
    if (styleMask & NSUtilityWindowMask) {
	[(NSPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
	 * Workaround for [Bug 2824538]: Textured windows are draggable
................................................................................
    TkMacOSXApplyWindowAttributes(winPtr, window);

    NSRect geometry = InitialWindowBounds(winPtr, window);
    geometry.size.width +=  structureRect.size.width;
    geometry.size.height += structureRect.size.height;
    geometry.origin.y = tkMacOSXZeroScreenHeight - (geometry.origin.y +
	    geometry.size.height);
    [window setFrame:geometry display:NO];
    TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
    macWin->flags |= TK_HOST_EXISTS;
}



























 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRegisterOffScreenWindow --
 *
 *	This function adds the passed in Off Screen Port to the hash table
................................................................................
TkMacOSXMakeFullscreen(
    TkWindow *winPtr,
    NSWindow *window,
    int fullscreen,
    Tcl_Interp *interp)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN);
    static unsigned long prevMask = 0, prevPres = 0;


    if (fullscreen) {
	int screenWidth =  WidthOfScreen(Tk_Screen(winPtr));
	int screenHeight = HeightOfScreen(Tk_Screen(winPtr));

	/*
	 * Check max width and height if set by the user.
	 */

	if ((wmPtr->maxWidth > 0 && wmPtr->maxWidth < screenWidth)
		|| (wmPtr->maxHeight > 0 && wmPtr->maxHeight < screenHeight)) {
................................................................................
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set fullscreen attribute for \"%s\": max"
			" width/height is too small", winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "FULLSCREEN",
			"CONSTRAINT_FAILURE", NULL);
	    }
	    result = TCL_ERROR;
	    wmPtr->flags &= ~WM_FULLSCREEN;
	} else {
	    Tk_UnmapWindow((Tk_Window) winPtr);
	    NSRect bounds = [window contentRectForFrameRect:[window frame]];
	    NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight);

	    if (!NSEqualRects(bounds, screenBounds) && !wasFullscreen) {
		wmPtr->configX = wmPtr->x;
		wmPtr->configY = wmPtr->y;
		wmPtr->configAttributes = wmPtr->attributes;
		wmPtr->attributes &= ~kWindowResizableAttribute;
		ApplyWindowAttributeFlagChanges(winPtr, window,
			wmPtr->configAttributes, wmPtr->flags, 1, 0);
		wmPtr->flags |= WM_SYNC_PENDING;
		[window setFrame:[window frameRectForContentRect:
					   screenBounds] display:YES];
		wmPtr->flags &= ~WM_SYNC_PENDING;
	    }
	    wmPtr->flags |= WM_FULLSCREEN;
	}

	prevMask = [window styleMask];
	prevPres = [NSApp presentationOptions];
	[window setStyleMask: NSFullScreenWindowMask];
	[NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar];

	/*Fullscreen implementation for 10.13 and later.*/
	#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12
	exitFullScreen = [[[NSStatusBar systemStatusBar]
				   statusItemWithLength:NSVariableStatusItemLength] retain];
	NSImage *exitIcon = [NSImage imageNamed:@"NSExitFullScreenTemplate"];
	[exitFullScreen setImage:exitIcon];
	[exitFullScreen setHighlightMode:YES];
	[exitFullScreen setToolTip:@"Exit Full Screen"];
	[exitFullScreen setTarget:window];
	[exitFullScreen setAction:@selector(restoreOldScreen:)];
	#endif

	Tk_MapWindow((Tk_Window) winPtr);
    } else {
	wmPtr->flags &= ~WM_FULLSCREEN;
	[NSApp setPresentationOptions: prevPres];
	[window setStyleMask: prevMask];
    }

    if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) {
	Tk_UnmapWindow((Tk_Window) winPtr);
	UInt64 oldAttributes = wmPtr->attributes;
	NSRect bounds = NSMakeRect(wmPtr->configX, tkMacOSXZeroScreenHeight -
		(wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight),
		wmPtr->xInParent + wmPtr->configWidth,
		wmPtr->yInParent + wmPtr->configHeight);

	wmPtr->attributes |= wmPtr->configAttributes &
		kWindowResizableAttribute;
	ApplyWindowAttributeFlagChanges(winPtr, window, oldAttributes,
		wmPtr->flags, 1, 0);





	wmPtr->flags |= WM_SYNC_PENDING;
	[window setFrame:[window frameRectForContentRect:bounds] display:YES];

	wmPtr->flags &= ~WM_SYNC_PENDING;
       Tk_MapWindow((Tk_Window) winPtr);
    }
    return result;
}
 
/*
 *----------------------------------------------------------------------
 *
 * GetMinSize --
 *






|



|




|







|







 







<
>
|
|
|
|
>
>
>
|


>



|
|
>
|
>
>
|
|
|
|
|
>
>
|
|
>
|
|

<
>
>
|
>




<







>
>
|
>
|
|
|

<
<










>
|







 







|


<
|
>
|
|
|
|







 







<







 







<







 







<







 







|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|

<

<
<







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<




>
>
>
>
>

<
>

<

|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
...
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446


447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
...
607
608
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626
627
628
629
...
743
744
745
746
747
748
749

750
751
752
753
754
755
756
...
814
815
816
817
818
819
820

821
822
823
824
825
826
827
....
5656
5657
5658
5659
5660
5661
5662

5663
5664
5665
5666
5667
5668
5669
....
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
....
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533

6534


6535
6536
6537
6538
6539
6540
6541
....
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601

6602
6603
6604
6605
6606
6607
6608
6609
6610
6611

6612
6613

6614
6615
6616
6617
6618
6619
6620
6621
6622
/*
 * Conversion of coordinates between window and screen.
 */

@implementation NSWindow(TKWm)
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    return [self convertBaseToScreen:point];
}
- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    return [self convertScreenToBase:point];
}
#else
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectToScreen:pointrect].origin;
}
- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectFromScreen:pointrect].origin;
}
................................................................................
{
    id _i1, _i2;
}
@end


@implementation TKWindow: NSWindow


/* Custom fullscreen implementation on 10.13 and above. On older versions of
 * macOS dating back to 10.7, the NSWindow fullscreen API was opt-in, requiring
 * explicit calls to toggleFullScreen. On 10.13, the API became implicit,
 * applying to all NSWindows unless they were marked non-resizable; this caused
 * issues with Tk, which was not aware of changes in screen geometry. Here we
 * override the toggleFullScreen call to hook directly into Tk's own fullscreen
 * API, allowing Tk to function smoothly with the Mac's fullscreen button.
*/

NSStatusItem *exitFullScreen;


- (void)toggleFullScreen:(id)sender
{
  TkWindow *winPtr = TkMacOSXGetTkWindow(self);
  if (!winPtr) {
      return;
  }
  Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);
  if ([NSApp macMinorVersion] > 12) {
      if (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask) {
	  TkMacOSXMakeFullscreen(winPtr, self, 0, interp);
      } else {
	  TkMacOSXMakeFullscreen(winPtr, self, 1, interp);
      }
  } else {
      TKLog (@"toggleFullScreen is ignored by Tk on OSX versions < 10.13");
  }
}

-(void)restoreOldScreen:(id)sender
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);

    if (!winPtr) {
	return;
    }
    Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);
    TkMacOSXMakeFullscreen(winPtr, self, 0, interp);
    [[NSStatusBar systemStatusBar] removeStatusItem: exitFullScreen];
}


@end

@implementation TKWindow(TKWm)

- (BOOL) canBecomeKeyWindow
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
    if (!winPtr) {
	return NO;
    }
    return (winPtr->wmInfoPtr &&
	    (winPtr->wmInfoPtr->macClass == kHelpWindowClass ||
	     winPtr->wmInfoPtr->attributes & kWindowNoActivatesAttribute)
	    ) ? NO : YES;
}



#if DEBUG_ZOMBIES
- (id) retain
{
    id result = [super retain];
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 1){
	fprintf(stderr, "Retained <%s>. Count is: %lu\n",
		title, [self retainCount]);
    }
    return result;
}

- (id) autorelease
{
    id result = [super autorelease];
................................................................................

static TkWindow*
FrontWindowAtPoint(
    int x, int y)
{
    NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
    NSArray *windows = [NSApp orderedWindows];
    TkWindow *winPtr = NULL;

    for (NSWindow *w in windows) {

	winPtr = TkMacOSXGetTkWindow(w);
	if (winPtr && NSMouseInRect(p, [w frame], NO)) {
	    break;
	}
    }
    return winPtr;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
................................................................................

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Create the underlying Mac window for this Tk window.
	 */

	if (!TkMacOSXHostToplevelExists(winPtr)) {
	    TkMacOSXMakeRealWindowExist(winPtr);
................................................................................
     */

    XMapWindow(winPtr->display, winPtr->window);

    /*Add window to Window menu.*/
    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    [win setExcludedFromWindowsMenu:NO];

}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWmUnmapWindow --
 *
................................................................................
    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];
    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setReleasedWhenClosed:NO];

    if (styleMask & NSUtilityWindowMask) {
	[(NSPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
	 * Workaround for [Bug 2824538]: Textured windows are draggable
................................................................................
    TkMacOSXApplyWindowAttributes(winPtr, window);

    NSRect geometry = InitialWindowBounds(winPtr, window);
    geometry.size.width +=  structureRect.size.width;
    geometry.size.height += structureRect.size.height;
    geometry.origin.y = tkMacOSXZeroScreenHeight - (geometry.origin.y +
	    geometry.size.height);
    [window setFrame:geometry display:YES];
    TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
    macWin->flags |= TK_HOST_EXISTS;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWindow --
 *
 *      Mark the contentView of this window as needing display so the
 *      window will be drawn by the window manager.  If this is called
 *      within the drawRect method, do nothing.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      The window's contentView is marked as needing display.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void
TkpDisplayWindow(Tk_Window tkwin) {
    if (![NSApp isDrawing]) {
    	TkWindow *winPtr = (TkWindow*)tkwin;
    	NSWindow *w = TkMacOSXDrawableWindow(winPtr->window);
    	[[w contentView] setNeedsDisplay: YES];
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRegisterOffScreenWindow --
 *
 *	This function adds the passed in Off Screen Port to the hash table
................................................................................
TkMacOSXMakeFullscreen(
    TkWindow *winPtr,
    NSWindow *window,
    int fullscreen,
    Tcl_Interp *interp)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int screenWidth =  WidthOfScreen(Tk_Screen(winPtr));
    int screenHeight = HeightOfScreen(Tk_Screen(winPtr));


    if (fullscreen) {



	/*
	 * Check max width and height if set by the user.
	 */

	if ((wmPtr->maxWidth > 0 && wmPtr->maxWidth < screenWidth)
		|| (wmPtr->maxHeight > 0 && wmPtr->maxHeight < screenHeight)) {
................................................................................
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set fullscreen attribute for \"%s\": max"
			" width/height is too small", winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "FULLSCREEN",
			"CONSTRAINT_FAILURE", NULL);
	    }
	    wmPtr->flags &= ~WM_FULLSCREEN;
	    return TCL_ERROR;
	}

	/*
	 * Save the current window state.
	 */

	wmPtr->cachedBounds = [window frame];
	wmPtr->cachedStyle = [window styleMask];
	wmPtr->cachedPresentation = [NSApp presentationOptions];

	/*
	 * Adjust the window style so it looks like a Fullscreen window.
	 */

	[window setStyleMask: NSFullScreenWindowMask];
	[NSApp setPresentationOptions: (NSApplicationPresentationAutoHideDock |
					NSApplicationPresentationAutoHideMenuBar)];

	/*For 10.13 and later add a button for exiting Fullscreen.*/
	if ([NSApp macMinorVersion] > 12) {
#if MAC_OS_X_VERSION_MAX_ALLOWED > 101200
	    exitFullScreen = [[[NSStatusBar systemStatusBar]
				   statusItemWithLength:NSVariableStatusItemLength] retain];
	    NSImage *exitIcon = [NSImage imageNamed:@"NSExitFullScreenTemplate"];
	    exitFullScreen.button.image = exitIcon;
	    exitFullScreen.button.cell.highlighted = NO;
	    exitFullScreen.button.toolTip = @"Exit Full Screen";
	    exitFullScreen.button.target = window;
	    exitFullScreen.button.action = @selector(restoreOldScreen:);
#endif
	}

	/*
	 * Resize the window to fill the screen. (After setting the style!)
	 */

	wmPtr->flags |= WM_SYNC_PENDING;
	NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight);
	[window setFrame:screenBounds display:YES];
	wmPtr->flags &= ~WM_SYNC_PENDING;
	wmPtr->flags |= WM_FULLSCREEN;
    } else {

	/*
	 * Restore the previous styles and attributes.
	 */

	[NSApp setPresentationOptions: wmPtr->cachedPresentation];
	[window setStyleMask: wmPtr->cachedStyle];
	UInt64 oldAttributes = wmPtr->attributes;
	wmPtr->flags &= ~WM_FULLSCREEN;

	wmPtr->attributes |= wmPtr->configAttributes &
		kWindowResizableAttribute;
	ApplyWindowAttributeFlagChanges(winPtr, window, oldAttributes,
		wmPtr->flags, 1, 0);

	/*
	 * Resize the window to its previous size.
	 */

	wmPtr->flags |= WM_SYNC_PENDING;

	[window setFrame:wmPtr->cachedBounds display:YES];
	wmPtr->flags &= ~WM_SYNC_PENDING;

    }
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *
 * GetMinSize --
 *

Changes to macosx/tkMacOSXWm.h.

181
182
183
184
185
186
187









188
189
190
191
192
193
194
     */

    WindowClass macClass;
    UInt64 attributes, configAttributes;
    TkWindow *scrollWinPtr;	/* Ptr to scrollbar handling grow widget. */
    TkMenu *menuPtr;
    NSWindow *window;









} WmInfo;

/*
 * Flag values for WmInfo structures:
 *
 * WM_NEVER_MAPPED -		non-zero means window has never been mapped;
 *				need to update all info when window is first






>
>
>
>
>
>
>
>
>







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
     */

    WindowClass macClass;
    UInt64 attributes, configAttributes;
    TkWindow *scrollWinPtr;	/* Ptr to scrollbar handling grow widget. */
    TkMenu *menuPtr;
    NSWindow *window;

    /*
     * Space to cache current window state when window becomes Fullscreen.
     */

    unsigned long cachedStyle;
    unsigned long cachedPresentation;
    NSRect cachedBounds;

} WmInfo;

/*
 * Flag values for WmInfo structures:
 *
 * WM_NEVER_MAPPED -		non-zero means window has never been mapped;
 *				need to update all info when window is first

Changes to macosx/tkMacOSXXStubs.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
 * tkMacOSXXStubs.c --
 *
 *	This file contains most of the X calls called by Tk. Many of these
 *	calls are just stubs and either don't make sense on the Macintosh or
 *	their implamentation just doesn't do anything. Other calls will
 *	eventually be moved into other files.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright 2014 Marc Culler.
 *
................................................................................
	snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
		NSAppKitVersionNumber);
    }
    display->vendor = vendor;
    {
	int major, minor, patch;

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = systemVersion.majorVersion;
	minor = systemVersion.minorVersion;
................................................................................
    screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
    screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24;
    screen->ext_data	= (XExtData *) &maxBounds;

    screen->root_visual = ckalloc(sizeof(Visual));
    screen->root_visual->visualid     = 0;
    screen->root_visual->class	      = TrueColor;
    screen->root_visual->alpha_mask   = 0xFF000000;
    screen->root_visual->red_mask     = 0x00FF0000;
    screen->root_visual->green_mask   = 0x0000FF00;
    screen->root_visual->blue_mask    = 0x000000FF;
    screen->root_visual->bits_per_rgb = 24;
    screen->root_visual->map_entries  = 256;

    /*




|







 







|







 







<







1
2
3
4
5
6
7
8
9
10
11
12
13
...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
199
200
201
202
203
204
205

206
207
208
209
210
211
212
/*
 * tkMacOSXXStubs.c --
 *
 *	This file contains most of the X calls called by Tk. Many of these
 *	calls are just stubs and either don't make sense on the Macintosh or
 *	their implementation just doesn't do anything. Other calls will
 *	eventually be moved into other files.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright 2014 Marc Culler.
 *
................................................................................
	snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
		NSAppKitVersionNumber);
    }
    display->vendor = vendor;
    {
	int major, minor, patch;

#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = systemVersion.majorVersion;
	minor = systemVersion.minorVersion;
................................................................................
    screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
    screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24;
    screen->ext_data	= (XExtData *) &maxBounds;

    screen->root_visual = ckalloc(sizeof(Visual));
    screen->root_visual->visualid     = 0;
    screen->root_visual->class	      = TrueColor;

    screen->root_visual->red_mask     = 0x00FF0000;
    screen->root_visual->green_mask   = 0x0000FF00;
    screen->root_visual->blue_mask    = 0x000000FF;
    screen->root_visual->bits_per_rgb = 24;
    screen->root_visual->map_entries  = 256;

    /*

Changes to tests/bind.test.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}

# This function fills the pattern matcher's ring buffer with events of
# the specified type.  This can be used when testing with generated
# events to make sure that there are no stray events in the ring
# buffer which might cause the pattern matcher to find unintended
# matches.  The size of the ring buffer is EVENT_BUFFER_SIZE, which is
# currently set to 30.  If this changes, the code below will need to
# change.
proc clearRingBuffer {{event}} {
    for {set i 0} {$i < 30} {incr i} {
	event generate . $event
    }
}

# move the mouse pointer away of the testing area
# otherwise some spurious events may pollute the tests
toplevel .top






|
|

|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}

# This function fills the pattern matcher's ring buffer with events of
# the specified type.  This can be used when testing with generated
# events to make sure that there are no stray events in the ring
# buffer which might cause the pattern matcher to find unintended
# matches.  The size of the ring buffer is EVENT_BUFFER_SIZE, which is
# currently set to 30 (or 45 on macOS).  If this changes, the code
# below will need to change.
proc clearRingBuffer {{event}} {
    for {set i 0} {$i < 45} {incr i} {
	event generate . $event
    }
}

# move the mouse pointer away of the testing area
# otherwise some spurious events may pollute the tests
toplevel .top

Changes to tests/canvImg.test.

718
719
720
721
722
723
724

725
726
727
728
729
730
731
...
733
734
735
736
737
738
739

740
741
742
743
744
745
746
...
764
765
766
767
768
769
770

771
772
773
774
775
776
777
} -cleanup {
	.c delete all
	image delete foo
} -result {75 150 105 165}

test canvImg-10.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all

} -body {
	image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    foo changed 2 4 6 8 30 15
    update
................................................................................
} -cleanup {
	.c delete all
	image delete foo
} -result {{foo display 2 4 6 8}}

test canvImg-11.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all

} -body {
	image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    foo changed 2 4 6 8 40 50
    update
................................................................................
	.c delete all
	image delete foo
} -result {30 75 70 125}
test canvImg-11.3 {ImageChangedProc procedure} -constraints {
	testImageType
} -setup {
    .c delete all

} -body {
    image create test foo -variable x
	image create test foo2 -variable y
    foo changed 0 0 0 0 40 50
    foo2 changed 0 0 0 0 80 60

    .c create image 50 100 -image foo -tags image -anchor nw






>







 







>







 







>







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
...
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
} -cleanup {
	.c delete all
	image delete foo
} -result {75 150 105 165}

test canvImg-10.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all
    update
} -body {
	image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    foo changed 2 4 6 8 30 15
    update
................................................................................
} -cleanup {
	.c delete all
	image delete foo
} -result {{foo display 2 4 6 8}}

test canvImg-11.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all
    update
} -body {
	image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    foo changed 2 4 6 8 40 50
    update
................................................................................
	.c delete all
	image delete foo
} -result {30 75 70 125}
test canvImg-11.3 {ImageChangedProc procedure} -constraints {
	testImageType
} -setup {
    .c delete all
    update
} -body {
    image create test foo -variable x
	image create test foo2 -variable y
    foo changed 0 0 0 0 40 50
    foo2 changed 0 0 0 0 80 60

    .c create image 50 100 -image foo -tags image -anchor nw

Changes to tests/canvas.test.

336
337
338
339
340
341
342


343
344
345
346
347
348
349
350
351
} -body {
    .c create arc -100 10 100 210 -start 10 -extent 50 -style arc -tags arc1
    set arcBox [.c bbox arc1]
    .c create arc 100 10 300 210 -start 10 -extent 50 -style chord -tags arc2
    set coordBox [.c bbox arc2]
    .c create arc 300 10 500 210 -start 10 -extent 50 -style pieslice -tags arc3
    set pieBox [.c bbox arc3]


    list $arcBox $coordBox $pieBox
} -result {{48 21 100 94} {248 21 300 94} {398 21 500 112}}

test canvas-9.1 {canvas id creation and deletion} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    # With Tk 8.0.4 the ids are now stored in a hash table. You can use this
    # test as a performance test with older versions by changing the value of






>
>
|
|







336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
} -body {
    .c create arc -100 10 100 210 -start 10 -extent 50 -style arc -tags arc1
    set arcBox [.c bbox arc1]
    .c create arc 100 10 300 210 -start 10 -extent 50 -style chord -tags arc2
    set coordBox [.c bbox arc2]
    .c create arc 300 10 500 210 -start 10 -extent 50 -style pieslice -tags arc3
    set pieBox [.c bbox arc3]
    .c create arc 100 200 300 200 -height [expr {(1-0.5*sqrt(3))*200}] -style arc -tags arc4
    set arcSegBox [.c bbox arc4]
    list $arcBox $coordBox $pieBox $arcSegBox
} -result {{48 21 100 94} {248 21 300 94} {398 21 500 112} {98 171 302 202}}

test canvas-9.1 {canvas id creation and deletion} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    # With Tk 8.0.4 the ids are now stored in a hash table. You can use this
    # test as a performance test with older versions by changing the value of

Changes to tests/grid.test.

1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
....
2013
2014
2015
2016
2017
2018
2019
2020



















































































































2021
2022
2023
2024
2025
2026
2027
    frame .t.f
    label .t.f.l -text foobar
    grid .t.f.l
    destroy .t
    set result ok
} -result ok


test grid-18.1 {test respect for internalborder} -body {
    toplevel .pack
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
................................................................................
    pack .f
    update
    pack forget .f
    update
    winfo ismapped .t ; # must return 1
} {1}
grid_reset 23
 



















































































































# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:






<







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1796
1797
1798
1799
1800
1801
1802

1803
1804
1805
1806
1807
1808
1809
....
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
    frame .t.f
    label .t.f.l -text foobar
    grid .t.f.l
    destroy .t
    set result ok
} -result ok


test grid-18.1 {test respect for internalborder} -body {
    toplevel .pack
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
................................................................................
    pack .f
    update
    pack forget .f
    update
    winfo ismapped .t ; # must return 1
} {1}
grid_reset 23

test grid-24.1 {<<NoManagedChild>> fires on last grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    update
    bind . <<NoManagedChild>> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.1
} -result {1}
test grid-24.2 {<<NoManagedChild>> fires on last grid remove} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    update
    bind . <<NoManagedChild>> {set A 1}
    grid remove .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.2
} -result {1}
test grid-24.3 {<<NoManagedChild>> fires on last gridded child destruction} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    update
    bind . <<NoManagedChild>> {incr A}
    destroy .1
    update
    set A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.3
} -result {1}
test grid-24.4 {<Configure> does not fire on last grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    update
    bind . <Configure> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <Configure> {}
    grid_reset 24.4
} -result {0}
test grid-24.5 {<Configure> fires on forelast grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    grid [frame .2]
    update
    bind . <Configure> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <Configure> {}
    grid_reset 24.5
} -result {1}
test grid-24.6 {<<NoManagedChild>> does not fire on forelast grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    grid [frame .2]
    update
    bind . <<NoManagedChild>> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.6
} -result {0}
test grid-24.7 {<<NoManagedChild>> does not fire on grid anchor} -setup {
    global A
    unset -nocomplain A
} -body {
    bind . <<NoManagedChild>> {set A 1}
    grid anchor . w
    update
    info exists A
} -cleanup {
    grid anchor . nw
    bind . <<NoManagedChild>> {}
    grid_reset 24.7
} -result {0}
test grid-24.8 {<<NoManagedChild>> does not fire on last grid forget if propagation is off} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]
    grid propagate . 0
    update
    bind . <<NoManagedChild>> {set A 1}
    grid forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    grid_reset 24.8
} -result {0}
 
# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:

Changes to tests/image.test.

345
346
347
348
349
350
351

352
353
354
355
356
357
358
...
360
361
362
363
364
365
366

367
368
369
370
371
372
373
    catch {destroy .b}
} -result [list 0 1]


test image-9.1 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup

} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15
    update
................................................................................
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo display 5 6 7 8}}
test image-9.2 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup

} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    .c create image 90 100 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15






>







 







>







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
    catch {destroy .b}
} -result [list 0 1]


test image-9.1 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
    update
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15
    update
................................................................................
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo display 5 6 7 8}}
test image-9.2 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
    update
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    .c create image 90 100 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15

Changes to tests/option.test.

382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
...
410
411
412
413
414
415
416
















417
418
419
420
421
422
423
424
425
test option-15.6 {database files} -body {
    option read $option1
	option get . x6 color
} -result {}
test option-15.7 {database files} -body {
    option read $option1
	option get . x9 color
} -result " \t\\A\n"
test option-15.8 {database files} -body {
    option read $option1 widget foo
} -returnCodes error -result {wrong # args: should be "option readfile fileName ?priority?"}
test option-15.9 {database files} -body {
    option add *x3 burgundy
    catch {option read $option1 userDefault}
    option get . x3 color
................................................................................
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option4 userDefault
    list [option get . x7 color] [option get . x8 color]
} -cleanup {
    removeFile $option4
} -result {true false}

















deleteWindows

# cleanup
cleanupTests
return









|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
test option-15.6 {database files} -body {
    option read $option1
	option get . x6 color
} -result {}
test option-15.7 {database files} -body {
    option read $option1
	option get . x9 color
} -result " \\\t\\A\n"
test option-15.8 {database files} -body {
    option read $option1 widget foo
} -returnCodes error -result {wrong # args: should be "option readfile fileName ?priority?"}
test option-15.9 {database files} -body {
    option add *x3 burgundy
    catch {option read $option1 userDefault}
    option get . x3 color
................................................................................
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option4 userDefault
    list [option get . x7 color] [option get . x8 color]
} -cleanup {
    removeFile $option4
} -result {true false}

set opt162val {label {
  foo bar
}
}
set opt162list [split $opt162val \n]

test option-16.2 {ticket 766ef52f3} {
    set option5 [makeFile {} option.file4]
    set file [open $option5 w]
    fconfigure $file -translation crlf
    puts $file "*notok: $opt162list"
    close $file
    option read $option5 userDefault
    option get . notok notok
} $opt162list

deleteWindows

# cleanup
cleanupTests
return



Changes to tests/pack.test.

1
2
3
4
5
6
7
8
9
..
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
...
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
...
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
...
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
...
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
...
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
....
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
....
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
....
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
....
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
....
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
....
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
....
1622
1623
1624
1625
1626
1627
1628























































































1629
1630
1631
1632
1633
1634
1635



# This file is a Tcl script to test out the "pack" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
................................................................................
    label .pack.$i.label -text $i -relief raised
    place .pack.$i.label -relwidth 1.0 -relheight 1.0
}
.pack.a config -width 20 -height 40
.pack.b config -width 50 -height 30
.pack.c config -width 80 -height 80
.pack.d config -width 40 -height 30

test pack-1.1 {-side option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
................................................................................
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx {5 15} -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {280x40+5+0 300x160+0+40}

test pack-2.22 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -padx]+1]]
    set res2 [winfo pixels .pack 1c]
................................................................................
} -body {
    pack .pack.a -ipadx 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -ipadx]+1]]
    set res2 [winfo pixels .pack 1c]
    expr {$res1 eq $res2}
} -result 1


test pack-3.1 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -pady 20
    pack .pack.b -expand yes -fill both
    update
................................................................................
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipady 5 -pady {1 19} -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x50+140+1 300x130+0+70}

test pack-3.22 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -pady]+1]]
    set res2 [winfo pixels .pack 1c]
................................................................................
} -body {
    pack .pack.a -ipady 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -ipady]+1]]
    set res2 [winfo pixels .pack 1c]
    expr {$res1 eq $res2}
} -result 1


test pack-4.1 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor n
    update
    winfo geometry .pack.a
................................................................................
test pack-4.9 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor center
    update
    winfo geometry .pack.a
} -result {30x70+135+65}


# Repeat above tests, but with a frame that isn't at (0,0), so that
# we can be sure that the frame offset is being added in correctly.

test pack-5.1 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
................................................................................
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor center
    update
    winfo geometry .pack.b
} -result {60x60+160+90}


test pack-6.1 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side left
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
................................................................................
    pack .pack.b -side top -expand yes -fill both
    pack .pack.c -side right -expand 1 -fill both
    pack .pack.d -side bottom -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {100x200+0+0 200x100+100+0 160x100+140+100 40x100+100+100}

test pack-6.12 {-expand option} -setup {
    toplevel .pack2 -height 400 -width 400
    wm geometry .pack2 +0+0
    pack propagate .pack2 0
    foreach i {w1 w2 w3} {
        frame .pack2.$i -width 30 -height 30 -bd 2 -relief raised
        label .pack2.$i.l -text $i
................................................................................
    pack .pack2.w1 .pack2.w2 .pack2.w3 -padx 5 -ipadx 4 -pady 2 \
        -ipady 6 -expand 1 -side top
    update
    list [winfo geometry .pack2.w1] [winfo geometry .pack2.w2] [winfo geometry .pack2.w3]
} -cleanup {
    destroy .pack2
} -result {38x42+181+45 38x42+181+178 38x42+181+312}


wm geometry .pack {}
test pack-7.1 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side left -padx 5 -pady 10
    update
................................................................................
} -body {
    pack .pack.a -side right
    pack .pack.c -side bottom
    pack .pack.d -side top
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {100 110}


# For the tests below, create a couple of "pad" windows to shrink
# the available space for the remaining windows.  The tests have to
# be done this way rather than shrinking the whole window, because
# some window managers like mwm won't let a top-level window get
# very small.

................................................................................
test pack-8.9 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x40+0+20 1 50x30+100+25 1 80x80+20+0 1}
pack forget .pack.right .pack.bottom


test pack-9.1 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -after .pack.b
    pack slaves .pack
} -result {.pack.b .pack.a .pack.c .pack.d}
................................................................................
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d
    pack .pack.a .pack.c .pack.d .pack.b -after .pack.a
    pack slaves .pack
} -result {.pack.a .pack.c .pack.d .pack.b}


test pack-10.1 {retaining/clearing configuration state} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom -anchor n -padx 1 -pady 2 -ipadx 3 -ipady 4 \
    -fill both -expand 1
    pack forget .pack.a
    pack .pack.a
................................................................................
} -result {{} {}}
test pack-10.4 {bad -in window does not change master} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    winfo manager .pack.a
    pack .pack.a -in .pack.a
} -returnCodes error -result {can't pack .pack.a inside itself}


test pack-11.1 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -in .pack
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -in]+1]
................................................................................
test pack-11.19 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -side]+1]
} -result right


test pack-12.1 {command options and errors} -body {
    pack
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test pack-12.2 {command options and errors} -body {
    pack foo
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
................................................................................
} -returnCodes ok -result {}
test pack-12.46 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack lousy .pack
} -returnCodes error -result {bad option "lousy": must be configure, forget, info, propagate, or slaves}


test pack-13.1 {window deletion} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d .pack.right .pack.bottom
} -body {
    pack .pack.right -side right
    pack .pack.bottom -side bottom
    pack .pack.a .pack.d .pack.b .pack.c -side top
    update
    destroy .pack.d
    update
    set result [list [pack slaves .pack] [winfo geometry .pack.a] \
        [winfo geometry .pack.b] [winfo geometry .pack.c]]
} -result {{.pack.right .pack.bottom .pack.a .pack.b .pack.c} 20x40+30+0 50x30+15+40 80x80+0+70}


test pack-14.1 {respond to changes in expansion} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d .pack.right .pack.bottom
} -body {
    pack .pack.right -side right
    pack .pack.bottom -side bottom
    wm geom .pack {}
................................................................................
    pack .pack.a -before .pack.b -side top
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
} -cleanup {
    destroy .pack.f1 .pack.f2
} -result {50x16+25+22 1 50x16+25+22 0}


test pack-16.1 {geometry manager name} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
    set result {}
} -body {
    lappend result [winfo manager .pack.a]
    pack .pack.a
    lappend result [winfo manager .pack.a]
    pack forget .pack.a
    lappend result [winfo manager .pack.a]
} -result {{} pack {}}


test pack-17.1 {PackLostSlaveProc procedure} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a
    update
    place .pack.a -x 40 -y 10
................................................................................
    place .pack.a -x 40 -y 10
    update
    winfo manager .pack.a
    winfo geometry .pack.a
    pack info .pack.a
} -returnCodes error -result {window ".pack.a" isn't packed}


test pack-18.1 {unmap slaves when master unmapped} -constraints {
    tempNotPc
} -setup {
    eval destroy [winfo child .pack]
} -body {

    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100

    # On the PC, when the width/height is configured while the window is
................................................................................
    wm deiconify .pack
    update
    lappend result [winfo ismapped .pack.a]
} -result {1 0 200 75 0 1}
test pack-18.2 {unmap slaves when master unmapped} -setup {
    eval destroy [winfo child .pack]
} -body {

    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100
    frame .pack.a -relief raised -bd 2
    frame .pack.b -width 70 -height 30 -relief sunken -bd 2
................................................................................
    update
    lappend result [winfo width .pack.b ] [winfo height .pack.b] \
    [winfo ismapped .pack.b]
    wm deiconify .pack
    update
    lappend result [winfo ismapped .pack.b]
} -result {1 0 100 30 0 1}


test pack-19.1 {test respect for internalborder} -setup {
    catch {eval pack forget [pack slaves .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
................................................................................
    .pack.lf configure -labelanchor ws
    update
    lappend res [winfo geometry .pack.lf]
} -cleanup {
    destroy .pack.l .pack.lf
} -result {162x127+0+0 172x112+0+0}

























































































# cleanup
cleanupTests
return






|
|







 







|







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<












<







 







<










<







 







<





<







 







<







 







<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|




<
<
>
>
>
1
2
3
4
5
6
7
8
9
..
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
...
227
228
229
230
231
232
233

234
235
236
237
238
239
240
...
245
246
247
248
249
250
251

252
253
254
255
256
257
258
...
414
415
416
417
418
419
420

421
422
423
424
425
426
427
...
432
433
434
435
436
437
438

439
440
441
442
443
444
445
...
496
497
498
499
500
501
502

503
504
505
506
507
508
509
...
581
582
583
584
585
586
587

588
589
590
591
592
593
594
...
687
688
689
690
691
692
693

694
695
696
697
698
699
700
...
720
721
722
723
724
725
726

727
728
729
730
731
732
733
...
778
779
780
781
782
783
784

785
786
787
788
789
790
791
...
859
860
861
862
863
864
865

866
867
868
869
870
871
872
...
931
932
933
934
935
936
937

938
939
940
941
942
943
944
...
961
962
963
964
965
966
967

968
969
970
971
972
973
974
....
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
....
1337
1338
1339
1340
1341
1342
1343

1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
....
1475
1476
1477
1478
1479
1480
1481

1482
1483
1484
1485
1486
1487
1488
1489
1490
1491

1492
1493
1494
1495
1496
1497
1498
....
1507
1508
1509
1510
1511
1512
1513

1514
1515
1516
1517
1518

1519
1520
1521
1522
1523
1524
1525
....
1541
1542
1543
1544
1545
1546
1547

1548
1549
1550
1551
1552
1553
1554
....
1563
1564
1565
1566
1567
1568
1569

1570
1571
1572
1573
1574
1575
1576
....
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699


1700
1701
1702
# This file is a Tcl script to test out the "pack" command of Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
................................................................................
    label .pack.$i.label -text $i -relief raised
    place .pack.$i.label -relwidth 1.0 -relheight 1.0
}
.pack.a config -width 20 -height 40
.pack.b config -width 50 -height 30
.pack.c config -width 80 -height 80
.pack.d config -width 40 -height 30
 
test pack-1.1 {-side option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
................................................................................
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx {5 15} -fill x
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {280x40+5+0 300x160+0+40}

test pack-2.22 {x padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -padx 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -padx]+1]]
    set res2 [winfo pixels .pack 1c]
................................................................................
} -body {
    pack .pack.a -ipadx 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -ipadx]+1]]
    set res2 [winfo pixels .pack 1c]
    expr {$res1 eq $res2}
} -result 1


test pack-3.1 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right -pady 20
    pack .pack.b -expand yes -fill both
    update
................................................................................
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipady 5 -pady {1 19} -fill y
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
} -result {20x50+140+1 300x130+0+70}

test pack-3.22 {y padding and filling} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -pady 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -pady]+1]]
    set res2 [winfo pixels .pack 1c]
................................................................................
} -body {
    pack .pack.a -ipady 1c
    set x [pack info .pack.a]
    set res1 [lindex $x [expr [lsearch -exact $x -ipady]+1]]
    set res2 [winfo pixels .pack 1c]
    expr {$res1 eq $res2}
} -result 1


test pack-4.1 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor n
    update
    winfo geometry .pack.a
................................................................................
test pack-4.9 {anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor center
    update
    winfo geometry .pack.a
} -result {30x70+135+65}


# Repeat above tests, but with a frame that isn't at (0,0), so that
# we can be sure that the frame offset is being added in correctly.

test pack-5.1 {more anchors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
................................................................................
} -body {
    pack .pack.a -side  top
    pack .pack.c -side left
    pack .pack.b -side top -ipadx 5 -padx 10 -ipady 15 -pady 20 -expand y -anchor center
    update
    winfo geometry .pack.b
} -result {60x60+160+90}


test pack-6.1 {-expand option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side left
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
................................................................................
    pack .pack.b -side top -expand yes -fill both
    pack .pack.c -side right -expand 1 -fill both
    pack .pack.d -side bottom -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b] \
        [winfo geometry .pack.c] [winfo geometry .pack.d]
} -result {100x200+0+0 200x100+100+0 160x100+140+100 40x100+100+100}

test pack-6.12 {-expand option} -setup {
    toplevel .pack2 -height 400 -width 400
    wm geometry .pack2 +0+0
    pack propagate .pack2 0
    foreach i {w1 w2 w3} {
        frame .pack2.$i -width 30 -height 30 -bd 2 -relief raised
        label .pack2.$i.l -text $i
................................................................................
    pack .pack2.w1 .pack2.w2 .pack2.w3 -padx 5 -ipadx 4 -pady 2 \
        -ipady 6 -expand 1 -side top
    update
    list [winfo geometry .pack2.w1] [winfo geometry .pack2.w2] [winfo geometry .pack2.w3]
} -cleanup {
    destroy .pack2
} -result {38x42+181+45 38x42+181+178 38x42+181+312}


wm geometry .pack {}
test pack-7.1 {requesting size for parent} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side left -padx 5 -pady 10
    update
................................................................................
} -body {
    pack .pack.a -side right
    pack .pack.c -side bottom
    pack .pack.d -side top
    update
    list [winfo reqwidth .pack] [winfo reqheight .pack]
} -result {100 110}


# For the tests below, create a couple of "pad" windows to shrink
# the available space for the remaining windows.  The tests have to
# be done this way rather than shrinking the whole window, because
# some window managers like mwm won't let a top-level window get
# very small.

................................................................................
test pack-8.9 {insufficient space} -body {
    list [winfo geometry .pack.a] [winfo ismapped .pack.a] \
        [winfo geometry .pack.b] [winfo ismapped .pack.b] \
        [winfo geometry .pack.c] [winfo ismapped .pack.c]
} -result {20x40+0+20 1 50x30+100+25 1 80x80+20+0 1}
pack forget .pack.right .pack.bottom


test pack-9.1 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -after .pack.b
    pack slaves .pack
} -result {.pack.b .pack.a .pack.c .pack.d}
................................................................................
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d
    pack .pack.a .pack.c .pack.d .pack.b -after .pack.a
    pack slaves .pack
} -result {.pack.a .pack.c .pack.d .pack.b}


test pack-10.1 {retaining/clearing configuration state} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom -anchor n -padx 1 -pady 2 -ipadx 3 -ipady 4 \
    -fill both -expand 1
    pack forget .pack.a
    pack .pack.a
................................................................................
} -result {{} {}}
test pack-10.4 {bad -in window does not change master} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    winfo manager .pack.a
    pack .pack.a -in .pack.a
} -returnCodes error -result {can't pack .pack.a inside itself}


test pack-11.1 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -in .pack
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -in]+1]
................................................................................
test pack-11.19 {info option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side right
    set i [pack info .pack.a]
    lindex $i [expr [lsearch -exact $i -side]+1]
} -result right


test pack-12.1 {command options and errors} -body {
    pack
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test pack-12.2 {command options and errors} -body {
    pack foo
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
................................................................................
} -returnCodes ok -result {}
test pack-12.46 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack lousy .pack
} -returnCodes error -result {bad option "lousy": must be configure, forget, info, propagate, or slaves}


test pack-13.1 {window deletion} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d .pack.right .pack.bottom
} -body {
    pack .pack.right -side right
    pack .pack.bottom -side bottom
    pack .pack.a .pack.d .pack.b .pack.c -side top
    update
    destroy .pack.d
    update
    set result [list [pack slaves .pack] [winfo geometry .pack.a] \
        [winfo geometry .pack.b] [winfo geometry .pack.c]]
} -result {{.pack.right .pack.bottom .pack.a .pack.b .pack.c} 20x40+30+0 50x30+15+40 80x80+0+70}


test pack-14.1 {respond to changes in expansion} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d .pack.right .pack.bottom
} -body {
    pack .pack.right -side right
    pack .pack.bottom -side bottom
    wm geom .pack {}
................................................................................
    pack .pack.a -before .pack.b -side top
    update
    lappend result [winfo geometry .pack.b] [winfo ismapped .pack.b]
} -cleanup {
    destroy .pack.f1 .pack.f2
} -result {50x16+25+22 1 50x16+25+22 0}


test pack-16.1 {geometry manager name} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
    set result {}
} -body {
    lappend result [winfo manager .pack.a]
    pack .pack.a
    lappend result [winfo manager .pack.a]
    pack forget .pack.a
    lappend result [winfo manager .pack.a]
} -result {{} pack {}}


test pack-17.1 {PackLostSlaveProc procedure} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a
    update
    place .pack.a -x 40 -y 10
................................................................................
    place .pack.a -x 40 -y 10
    update
    winfo manager .pack.a
    winfo geometry .pack.a
    pack info .pack.a
} -returnCodes error -result {window ".pack.a" isn't packed}


test pack-18.1 {unmap slaves when master unmapped} -constraints {
    tempNotPc
} -setup {
    eval destroy [winfo child .pack]
} -body {

    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100

    # On the PC, when the width/height is configured while the window is
................................................................................
    wm deiconify .pack
    update
    lappend result [winfo ismapped .pack.a]
} -result {1 0 200 75 0 1}
test pack-18.2 {unmap slaves when master unmapped} -setup {
    eval destroy [winfo child .pack]
} -body {

    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100
    frame .pack.a -relief raised -bd 2
    frame .pack.b -width 70 -height 30 -relief sunken -bd 2
................................................................................
    update
    lappend result [winfo width .pack.b ] [winfo height .pack.b] \
    [winfo ismapped .pack.b]
    wm deiconify .pack
    update
    lappend result [winfo ismapped .pack.b]
} -result {1 0 100 30 0 1}


test pack-19.1 {test respect for internalborder} -setup {
    catch {eval pack forget [pack slaves .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
................................................................................
    .pack.lf configure -labelanchor ws
    update
    lappend res [winfo geometry .pack.lf]
} -cleanup {
    destroy .pack.l .pack.lf
} -result {162x127+0+0 172x112+0+0}

test pack-20.1 {<<NoManagedChild>> fires on last pack forget} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    update
    bind . <<NoManagedChild>> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    destroy .1
} -result {1}
test pack-20.2 {<<NoManagedChild>> fires on last packed child destruction} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    update
    bind . <<NoManagedChild>> {incr A}
    destroy .1
    update
    set A
} -cleanup {
    bind . <<NoManagedChild>> {}
    destroy .1
} -result {1}
test pack-20.3 {<Configure> does not fire on last pack forget} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    update
    bind . <Configure> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <Configure> {}
    destroy .1
} -result {0}
test pack-20.4 {<<NoManagedChild>> does not fire on forelast pack forget} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    pack [frame .2]
    update
    bind . <<NoManagedChild>> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    destroy .1 .2
} -result {0}
test pack-20.5 {<Configure> does not fire on last pack forget} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    pack [frame .2]
    update
    bind . <Configure> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <Configure> {}
    destroy .1 .2
} -result {1}
test pack-20.6 {<<NoManagedChild>> does not fire on last pack forget if propagation is off} -setup {
    global A
    unset -nocomplain A
} -body {
    pack [frame .1]
    pack propagate . 0
    update
    bind . <<NoManagedChild>> {set A 1}
    pack forget .1
    update
    info exists A
} -cleanup {
    bind . <<NoManagedChild>> {}
    destroy .1
} -result {0}
 
# cleanup
cleanupTests
return



# Local Variables:
# mode: tcl
# End:

Changes to tests/text.test.

3243
3244
3245
3246
3247
3248
3249

3250
3251
3252
3253
3254
3255
3256
....
3334
3335
3336
3337
3338
3339
3340

3341
3342
3343
3344
3345
3346
3347
....
6869
6870
6871
6872
6873
6874
6875


6876
6877
6878
6879
6880
6881
6882
test text-11a.22 {TextWidgetCmd procedure, "sync" option with -command} -setup {
    destroy .top.yt .top
} -body {
    set res {}
    set ::x 0
    toplevel .top
    pack [text .top.yt]

    set content {}
    for {set i 1} {$i < 30} {incr i} {
        append content [string repeat "$i " 15] \n
    }
    .top.yt insert 1.0 $content
    # first case: line metrics calculation still running when launching 'sync -command'
    lappend res [.top.yt pendingsync]
................................................................................
} -result {0}

test text-11a.31 {"<<WidgetViewSync>>" event} -setup {
    destroy .top.yt .top
} -body {
    toplevel .top
    pack [text .top.yt]

    set content {}
    for {set i 1} {$i < 300} {incr i} {
        append content [string repeat "$i " 15] \n
    }
    .top.yt insert 1.0 $content
    update
    bind .top.yt <<WidgetViewSync>> { if {%d} {set yud(%W) 1} }
................................................................................
    .t edit modified
} -cleanup {
    destroy .t
} -result {1}
test text-27.11 {TextEditCmd procedure, set modified flag repeat} -setup {
    text .t
    pack .t


    set ::retval {}
    update
} -body {
    bind .t <<Modified>> "lappend ::retval modified"
# Shouldn't require [update idle] to trigger event [Bug 1809538]
    lappend ::retval [.t edit modified]
    .t edit modified 1






>







 







>







 







>
>







3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
....
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
....
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
test text-11a.22 {TextWidgetCmd procedure, "sync" option with -command} -setup {
    destroy .top.yt .top
} -body {
    set res {}
    set ::x 0
    toplevel .top
    pack [text .top.yt]
    update
    set content {}
    for {set i 1} {$i < 30} {incr i} {
        append content [string repeat "$i " 15] \n
    }
    .top.yt insert 1.0 $content
    # first case: line metrics calculation still running when launching 'sync -command'
    lappend res [.top.yt pendingsync]
................................................................................
} -result {0}

test text-11a.31 {"<<WidgetViewSync>>" event} -setup {
    destroy .top.yt .top
} -body {
    toplevel .top
    pack [text .top.yt]
    update
    set content {}
    for {set i 1} {$i < 300} {incr i} {
        append content [string repeat "$i " 15] \n
    }
    .top.yt insert 1.0 $content
    update
    bind .top.yt <<WidgetViewSync>> { if {%d} {set yud(%W) 1} }
................................................................................
    .t edit modified
} -cleanup {
    destroy .t
} -result {1}
test text-27.11 {TextEditCmd procedure, set modified flag repeat} -setup {
    text .t
    pack .t
# Make sure the Text is mapped before we start
    update
    set ::retval {}
    update
} -body {
    bind .t <<Modified>> "lappend ::retval modified"
# Shouldn't require [update idle] to trigger event [Bug 1809538]
    lappend ::retval [.t edit modified]
    .t edit modified 1

Changes to tests/textWind.test.

941
942
943
944
945
946
947


948
949
950
951
952
953
954
...
959
960
961
962
963
964
965


966
967
968
969
970
971
972
...
978
979
980
981
982
983
984


985
986
987
988
989
990
991
    {}]

test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t


} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
................................................................................
} -result [list 30x20+[expr {$padx+30+12*$fixedWidth}]+[expr {$pady+50}]]

test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .t.f
    place forget .t
    pack .t


} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .t.f
    update
................................................................................
} -result [list 30x20+[expr {$padx+12*$fixedWidth}]+$pady]

test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t


} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    bind .f <Configure> {set x ".f configured"}
    set x {no configures}






>
>







 







>
>







 







>
>







941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
...
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
...
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
    {}]

test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
................................................................................
} -result [list 30x20+[expr {$padx+30+12*$fixedWidth}]+[expr {$pady+50}]]

test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .t.f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .t.f
    update
................................................................................
} -result [list 30x20+[expr {$padx+12*$fixedWidth}]+$pady]

test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    bind .f <Configure> {set x ".f configured"}
    set x {no configures}

Changes to unix/configure.

5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
....
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
....
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
fi
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    # The -pthread needs to go in the CFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS -pthread"
	    LDFLAGS="$LDFLAGS -pthread"
	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\[email protected]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
................................................................................
    if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then :

	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*) ;;
	    IRIX*) ;;
	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac
fi

    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
................................................................................
$as_echo "$ac_cv_header_time" >&6; }
if test $ac_cv_header_time = yes; then

$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h

fi


#--------------------------------------------------------------------
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#--------------------------------------------------------------------


    ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod"
if test "x$ac_cv_func_strtod" = xyes; then :
  tcl_strtod=1
else
  tcl_strtod=0
fi

    if test "$tcl_strtod" = 1; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris2.4/Tru64 strtod bugs" >&5
$as_echo_n "checking for Solaris2.4/Tru64 strtod bugs... " >&6; }
if ${tcl_cv_strtod_buggy+:} false; then :
  $as_echo_n "(cached) " >&6
else

	    if test "$cross_compiling" = yes; then :
  tcl_cv_strtod_buggy=buggy
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		extern double strtod();
		int main() {
		    char *infString="Inf", *nanString="NaN", *spaceString=" ";
		    char *term;
		    double value;
		    value = strtod(infString, &term);
		    if ((term != infString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(nanString, &term);
		    if ((term != nanString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(spaceString, &term);
		    if (term == (spaceString+1)) {
			exit(1);
		    }
		    exit(0);
		}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
  tcl_cv_strtod_buggy=ok
else
  tcl_cv_strtod_buggy=buggy
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtod_buggy" >&5
$as_echo "$tcl_cv_strtod_buggy" >&6; }
	if test "$tcl_cv_strtod_buggy" = buggy; then
	    case " $LIBOBJS " in
  *" fixstrtod.$ac_objext "* ) ;;
  *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext"
 ;;
esac

	    USE_COMPAT=1

$as_echo "#define strtod fixstrtod" >>confdefs.h

	fi
    fi


#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"






|







 







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
....
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
....
6754
6755
6756
6757
6758
6759
6760











































































6761
6762
6763
6764
6765
6766
6767
fi
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    # The -pthread needs to go in the CFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS -pthread"
	    LDFLAGS="$LDFLAGS -pthread"
	    ;;
	DragonFly-*|FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\[email protected]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
................................................................................
    if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then :

	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*) ;;
	    IRIX*) ;;
	    NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac
fi

    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
................................................................................
$as_echo "$ac_cv_header_time" >&6; }
if test $ac_cv_header_time = yes; then

$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h

fi













































































#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"

Changes to unix/configure.ac.

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

AC_CHECK_HEADERS(sys/time.h)
AC_HEADER_TIME

#--------------------------------------------------------------------
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#--------------------------------------------------------------------

SC_BUGGY_STRTOD

#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T






<
<
<
<
<
<
<
<
<







185
186
187
188
189
190
191









192
193
194
195
196
197
198
#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

AC_CHECK_HEADERS(sys/time.h)
AC_HEADER_TIME










#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T

Changes to unix/tcl.m4.

1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
....
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
....
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    # The -pthread needs to go in the CFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS -pthread"
	    LDFLAGS="$LDFLAGS -pthread"
	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
................................................................................

    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*) ;;
	    IRIX*) ;;
	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
................................................................................
		[extern time_t timezone;
		timezone += 1;
		exit (0);],
		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_BUGGY_STRTOD
#
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#	Also, on Compaq's Tru64 Unix 5.0,
#	strtod(" ") returns 0.0 instead of a failure to convert.
#
# Arguments:
#	none
#
# Results:
#
#	Might defines some of the following vars:
#		strtod (=fixstrtod)
#
#--------------------------------------------------------------------

AC_DEFUN([SC_BUGGY_STRTOD], [
    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
    if test "$tcl_strtod" = 1; then
	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
	    AC_TRY_RUN([
		extern double strtod();
		int main() {
		    char *infString="Inf", *nanString="NaN", *spaceString=" ";
		    char *term;
		    double value;
		    value = strtod(infString, &term);
		    if ((term != infString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(nanString, &term);
		    if ((term != nanString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(spaceString, &term);
		    if (term == (spaceString+1)) {
			exit(1);
		    }
		    exit(0);
		}], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
		    tcl_cv_strtod_buggy=buggy)])
	if test "$tcl_cv_strtod_buggy" = buggy; then
	    AC_LIBOBJ([fixstrtod])
	    USE_COMPAT=1
	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.






|







 







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
....
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
....
2174
2175
2176
2177
2178
2179
2180





















































2181
2182
2183
2184
2185
2186
2187
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    # The -pthread needs to go in the CFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS -pthread"
	    LDFLAGS="$LDFLAGS -pthread"
	    ;;
	DragonFly-*|FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
................................................................................

    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*) ;;
	    IRIX*) ;;
	    NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
................................................................................
		[extern time_t timezone;
		timezone += 1;
		exit (0);],
		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi





















































    fi
])

#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.

Changes to xlib/X11/Xlib.h.

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
	VisualID visualid;	/* visual id of this visual */
#if defined(__cplusplus) || defined(c_plusplus)
	int c_class;		/* C++ class of screen (monochrome, etc.) */
#else
	int class;		/* class of screen (monochrome, etc.) */
#endif
	unsigned long red_mask, green_mask, blue_mask;	/* mask values */
#if defined(MAC_OSX_TK)
        unsigned long alpha_mask;
#endif
	int bits_per_rgb;	/* log base 2 of distinct color values */
	int map_entries;	/* color map entries */
} Visual;

/*
 * Depth structure; contains information for each possible depth.
 */
................................................................................
    int bits_per_pixel;		/* bits per pixel (ZPixmap) */
    unsigned long red_mask;	/* bits in z arrangment */
    unsigned long green_mask;
    unsigned long blue_mask;
    XPointer obdata;		/* hook for the object routines to hang on */
#if defined(MAC_OSX_TK)
    int pixelpower;		/* n such that pixels are 2^n x 2^n blocks*/
    unsigned long alpha_mask;
#endif
    struct funcs {		/* image manipulation routines */
	struct _XImage *(*create_image)();
#if NeedFunctionPrototypes
	int (*destroy_image)        (struct _XImage *);
	unsigned long (*get_pixel)  (struct _XImage *, int, int);
	int (*put_pixel)            (struct _XImage *, int, int, unsigned long);






<
<
<







 







<







192
193
194
195
196
197
198



199
200
201
202
203
204
205
...
321
322
323
324
325
326
327

328
329
330
331
332
333
334
	VisualID visualid;	/* visual id of this visual */
#if defined(__cplusplus) || defined(c_plusplus)
	int c_class;		/* C++ class of screen (monochrome, etc.) */
#else
	int class;		/* class of screen (monochrome, etc.) */
#endif
	unsigned long red_mask, green_mask, blue_mask;	/* mask values */



	int bits_per_rgb;	/* log base 2 of distinct color values */
	int map_entries;	/* color map entries */
} Visual;

/*
 * Depth structure; contains information for each possible depth.
 */
................................................................................
    int bits_per_pixel;		/* bits per pixel (ZPixmap) */
    unsigned long red_mask;	/* bits in z arrangment */
    unsigned long green_mask;
    unsigned long blue_mask;
    XPointer obdata;		/* hook for the object routines to hang on */
#if defined(MAC_OSX_TK)
    int pixelpower;		/* n such that pixels are 2^n x 2^n blocks*/

#endif
    struct funcs {		/* image manipulation routines */
	struct _XImage *(*create_image)();
#if NeedFunctionPrototypes
	int (*destroy_image)        (struct _XImage *);
	unsigned long (*get_pixel)  (struct _XImage *, int, int);
	int (*put_pixel)            (struct _XImage *, int, int, unsigned long);