Tk Source Code

Check-in [08fb5a44]
Login

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

Overview
Comment:merge 8.5
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-5-19-rc
Files: files | file ages | folders
SHA1: 08fb5a442d0e08cc4b8306bda129f6b047ff3fe1
User & Date: dgp 2015-11-30 21:21:48
Context
2015-12-10
13:38
merge 8.5 check-in: f2a00f19 user: dgp tags: core-8-5-19-rc
2015-11-30
21:21
merge 8.5 check-in: 08fb5a44 user: dgp tags: core-8-5-19-rc
2015-11-29
14:21
Fixed bug [1997299fff] - Tag borderwidth leaking check-in: 9046f1cb user: fvogel tags: core-8-5-branch
2015-10-23
18:50
merge 8.5 check-in: c6967f00 user: dgp tags: core-8-5-19-rc
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to changes.

7024
7025
7026
7027
7028
7029
7030


















7031
7032
7033
7034
2015-10-09 (bug)[2262711] [text] RE search Unicode+elided (kaitzschu,vogel)

2015-10-09 (bug)[1815161] [$text count -ypixels] needs management (vogel)

2015-10-22 (bug)[1520118] Document spinbox validate expectations (vogel)

2015-10-22 (bug)[1414025] $entry insertion cursor visibility (vogel)



















Tk Cocoa 2.0: More drawing internals refinements (culler,walzer)

--- Released 8.5.19, December 1, 2015 --- http://core.tcl.tk/tk/ for details







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




7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
2015-10-09 (bug)[2262711] [text] RE search Unicode+elided (kaitzschu,vogel)

2015-10-09 (bug)[1815161] [$text count -ypixels] needs management (vogel)

2015-10-22 (bug)[1520118] Document spinbox validate expectations (vogel)

2015-10-22 (bug)[1414025] $entry insertion cursor visibility (vogel)

2015-10-25 (bug)[477949] Unicode-enable [option readfile] (androwish,nijtmans)

2015-10-26 (bug) PNG rendering on El Capitan (meier,walzer)

2015-11-08 (bug)[2160206] menubutton panic (vogel)

2015-11-08 (bug)[220854] Display trailing TAB in entry (vogel)

2015-11-08 (bug)[542199] double click on lone char in entry (vogel)

2015-11-08 (bug)[297442d] strict motif binding on <Control-underscore> (vogel)

2015-11-08 (bug)[3601604] $listbox -takefocus (vogel)

2015-11-09 (bug)[5ee8af] X, Win: 64-bit enable embedded windows (vogel)

2015-11-29 (bug)[1997299] [text] tag borderwidth leak (vogel)

Tk Cocoa 2.0: More drawing internals refinements (culler,walzer)

--- Released 8.5.19, December 1, 2015 --- http://core.tcl.tk/tk/ for details

Changes to doc/event.n.

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
\fB<<Paste>>\fR binding will be invoked, because the
\fBMeta\fR modifier in the physical pattern associated with the 
virtual binding is more specific than the \fB<Control-y\fR> sequence for
the physical event.
.PP
Bindings on a virtual event may be created before the virtual event exists.
Indeed, the virtual event never actually needs to be defined, for instance,
on platforms where the specific virtual event would meaningless or
ungeneratable.
.PP
When a definition of a virtual event changes at run time, all windows
will respond immediately to the new definition.
Starting from the preceding example, if the following code is executed:
.CS
bind <Entry> <Control-y> {}







|







420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
\fB<<Paste>>\fR binding will be invoked, because the
\fBMeta\fR modifier in the physical pattern associated with the 
virtual binding is more specific than the \fB<Control-y\fR> sequence for
the physical event.
.PP
Bindings on a virtual event may be created before the virtual event exists.
Indeed, the virtual event never actually needs to be defined, for instance,
on platforms where the specific virtual event would be meaningless or
ungeneratable.
.PP
When a definition of a virtual event changes at run time, all windows
will respond immediately to the new definition.
Starting from the preceding example, if the following code is executed:
.CS
bind <Entry> <Control-y> {}

Changes to doc/listbox.n.

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
element can be selected in the listbox at once.
In both modes, clicking button 1 on an element selects
it and deselects any other selected item.
In \fBbrowse\fR mode it is also possible to drag the selection
with button 1.
.VS 8.5
On button 1, the listbox will also take focus if it has a \fBnormal\fR
state and \fB\-takefocus\fR is true.
.VE 8.5
.PP
If the selection mode is \fBmultiple\fR or \fBextended\fR,
any number of elements may be selected at once, including discontiguous
ranges.  In \fBmultiple\fR mode, clicking button 1 on an element
toggles its selection state without affecting any other elements.
In \fBextended\fR mode, pressing button 1 on an element selects







|







410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
element can be selected in the listbox at once.
In both modes, clicking button 1 on an element selects
it and deselects any other selected item.
In \fBbrowse\fR mode it is also possible to drag the selection
with button 1.
.VS 8.5
On button 1, the listbox will also take focus if it has a \fBnormal\fR
state.
.VE 8.5
.PP
If the selection mode is \fBmultiple\fR or \fBextended\fR,
any number of elements may be selected at once, including discontiguous
ranges.  In \fBmultiple\fR mode, clicking button 1 on an element
toggles its selection state without affecting any other elements.
In \fBextended\fR mode, pressing button 1 on an element selects

Changes to doc/text.n.

2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
.IP [30]
Control-x deletes whatever is selected in the text widget
after copying it to the clipboard.
.IP [31]
Control-t reverses the order of the two characters to the right of
the insertion cursor.
.IP [32]
Control-z (and Control-underscore on UNIX when \fBtk_strictMotif\fR is
true) undoes the last edit action if the \fB\-undo\fR option is true.
Does nothing otherwise.
.IP [33]
Control-Z (or Control-y on Windows) reapplies the last undone edit
action if the \fB\-undo\fR option is true. Does nothing otherwise.
.PP
If the widget is disabled using the \fB\-state\fR option, then its
view can still be adjusted and text can still be selected,
but no insertion cursor will be displayed and no text modifications will







<
|
|







2218
2219
2220
2221
2222
2223
2224

2225
2226
2227
2228
2229
2230
2231
2232
2233
.IP [30]
Control-x deletes whatever is selected in the text widget
after copying it to the clipboard.
.IP [31]
Control-t reverses the order of the two characters to the right of
the insertion cursor.
.IP [32]

Control-z (undoes the last edit action if the \fB\-undo\fR option is
true. Does nothing otherwise.
.IP [33]
Control-Z (or Control-y on Windows) reapplies the last undone edit
action if the \fB\-undo\fR option is true. Does nothing otherwise.
.PP
If the widget is disabled using the \fB\-state\fR option, then its
view can still be adjusted and text can still be selected,
but no insertion cursor will be displayed and no text modifications will

Changes to generic/tkFont.c.

2065
2066
2067
2068
2069
2070
2071


2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
	    chunkPtr = NULL;
	    if (*special == '\t') {
		newX = curX + fontPtr->tabWidth;
		newX -= newX % fontPtr->tabWidth;
		NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX,
			baseline)->numDisplayChars = -1;
		start++;


		if ((start < end) &&
			((wrapLength <= 0) || (newX <= wrapLength))) {
		    /*
		     * More chars can still fit on this line.
		     */

		    curX = newX;
		    flags &= ~TK_AT_LEAST_ONE;
		    continue;
		}
	    } else {
		NewChunk(&layoutPtr, &maxChunks, start, 1, curX, curX,
			baseline)->numDisplayChars = -1;
		start++;
		goto wrapLine;







>
>






<
<







2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079


2080
2081
2082
2083
2084
2085
2086
	    chunkPtr = NULL;
	    if (*special == '\t') {
		newX = curX + fontPtr->tabWidth;
		newX -= newX % fontPtr->tabWidth;
		NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX,
			baseline)->numDisplayChars = -1;
		start++;
		curX = newX;
		flags &= ~TK_AT_LEAST_ONE;
		if ((start < end) &&
			((wrapLength <= 0) || (newX <= wrapLength))) {
		    /*
		     * More chars can still fit on this line.
		     */



		    continue;
		}
	    } else {
		NewChunk(&layoutPtr, &maxChunks, start, 1, curX, curX,
			baseline)->numDisplayChars = -1;
		start++;
		goto wrapLine;

Changes to generic/tkImgPhoto.c.

2450
2451
2452
2453
2454
2455
2456

2457



2458
2459
2460
2461
2462
2463
2464
    case GrayScale:
    case StaticGray:
	nRed = 1 << visInfoPtr->depth;
	break;
    }
    XFree((char *) visInfoPtr);


    sprintf(buf, ((mono) ? "%d": "%d/%d/%d"), nRed, nGreen, nBlue);



    instancePtr->defaultPalette = Tk_GetUid(buf);

    /*
     * Make a GC with background = black and foreground = white.
     */

    white = Tk_GetColor(masterPtr->interp, tkwin, "white");







>
|
>
>
>







2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
    case GrayScale:
    case StaticGray:
	nRed = 1 << visInfoPtr->depth;
	break;
    }
    XFree((char *) visInfoPtr);

    if (mono) {
	sprintf(buf, "%d", nRed);
    } else {
	sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue);
    }
    instancePtr->defaultPalette = Tk_GetUid(buf);

    /*
     * Make a GC with background = black and foreground = white.
     */

    white = Tk_GetColor(masterPtr->interp, tkwin, "white");

Changes to generic/tkMenu.c.

930
931
932
933
934
935
936


937
938



939
940
941
942
943
944
945
946
	    goto error;
	}

	/*
	 * Tearoff menus are posted differently on Mac and Windows than
	 * non-tearoffs. TkpPostMenu does not actually map the menu's window
	 * on those platforms, and popup menus have to be handled specially.


	 */




	if (menuPtr->menuType != TEAROFF_MENU) {
	    result = TkpPostMenu(interp, menuPtr, x, y);
	} else {
	    result = TkPostTearoffMenu(interp, menuPtr, x, y);
	}
	break;
    }
    case MENU_POSTCASCADE: {







>
>


>
>
>
|







930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
	    goto error;
	}

	/*
	 * Tearoff menus are posted differently on Mac and Windows than
	 * non-tearoffs. TkpPostMenu does not actually map the menu's window
	 * on those platforms, and popup menus have to be handled specially.
         * Also, menubar menues are not intended to be posted (bug 1567681,
         * 2160206).
	 */

	if (menuPtr->menuType == MENUBAR) {
            Tcl_AppendResult(interp, "a menubar menu cannot be posted", NULL);
            return TCL_ERROR;
        } else if (menuPtr->menuType != TEAROFF_MENU) {
	    result = TkpPostMenu(interp, menuPtr, x, y);
	} else {
	    result = TkPostTearoffMenu(interp, menuPtr, x, y);
	}
	break;
    }
    case MENU_POSTCASCADE: {

Changes to generic/tkOption.c.

1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
				 * TK_INTERACTIVE_PRIO. Must be between 0 and
				 * TK_MAX_PRIO. */
{
    CONST char *realName;
    char *buffer;
    int result, bufferSize;
    Tcl_Channel chan;
    Tcl_DString newName;

    /*
     * Prevent file system access in a safe interpreter.
     */

    if (Tcl_IsSafe(interp)) {
	Tcl_AppendResult(interp, "can't read options from a file in a",







|







1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
				 * TK_INTERACTIVE_PRIO. Must be between 0 and
				 * TK_MAX_PRIO. */
{
    CONST char *realName;
    char *buffer;
    int result, bufferSize;
    Tcl_Channel chan;
    Tcl_DString newName, optString;

    /*
     * Prevent file system access in a safe interpreter.
     */

    if (Tcl_IsSafe(interp)) {
	Tcl_AppendResult(interp, "can't read options from a file in a",
1132
1133
1134
1135
1136
1137
1138


1139







1140
1141
1142
1143
1144
1145
1146
	Tcl_AppendResult(interp, "error reading file \"", fileName, "\":",
		Tcl_PosixError(interp), NULL);
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    Tcl_Close(NULL, chan);
    buffer[bufferSize] = 0;


    result = AddFromString(interp, tkwin, buffer, priority);







    ckfree(buffer);
    return result;
}

/*
 *--------------------------------------------------------------
 *







>
>
|
>
>
>
>
>
>
>







1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
	Tcl_AppendResult(interp, "error reading file \"", fileName, "\":",
		Tcl_PosixError(interp), NULL);
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    Tcl_Close(NULL, chan);
    buffer[bufferSize] = 0;
    if ((bufferSize>2) && !memcmp(buffer, "\357\273\277", 3)) {
	/* File starts with UTF-8 BOM */
	result = AddFromString(interp, tkwin, buffer+3, priority);
    } else {
	Tcl_DStringInit(&optString);
	Tcl_ExternalToUtfDString(NULL, buffer, bufferSize, &optString);
	result = AddFromString(interp, tkwin, Tcl_DStringValue(&optString),
		priority);
	Tcl_DStringFree(&optString);
    }
    ckfree(buffer);
    return result;
}

/*
 *--------------------------------------------------------------
 *

Changes to generic/tkText.c.

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
	textPtr->start = parent->start;
	textPtr->end = parent->end;
    } else {
	textPtr->start = NULL;
	textPtr->end = NULL;
    }

    /*
     * Register with the B-tree. In some sense it would be best if we could do
     * this later (after configuration options), so that any changes to
     * start,end do not require a total recalculation.
     */

    TkBTreeAddClient(sharedPtr->tree, textPtr, textPtr->charHeight);

    textPtr->state = TK_TEXT_STATE_NORMAL;
    textPtr->relief = TK_RELIEF_FLAT;
    textPtr->cursor = None;
    textPtr->charWidth = 1;
    textPtr->charHeight = 10;
    textPtr->wrapMode = TEXT_WRAPMODE_CHAR;
    textPtr->prevWidth = Tk_Width(newWin);
    textPtr->prevHeight = Tk_Height(newWin);









    /*
     * This will add refCounts to textPtr.
     */

    TkTextCreateDInfo(textPtr);
    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
	    &startIndex);







<
<
<
<
<
<
<
<









>
>
>
>
>
>
>
>







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
	textPtr->start = parent->start;
	textPtr->end = parent->end;
    } else {
	textPtr->start = NULL;
	textPtr->end = NULL;
    }









    textPtr->state = TK_TEXT_STATE_NORMAL;
    textPtr->relief = TK_RELIEF_FLAT;
    textPtr->cursor = None;
    textPtr->charWidth = 1;
    textPtr->charHeight = 10;
    textPtr->wrapMode = TEXT_WRAPMODE_CHAR;
    textPtr->prevWidth = Tk_Width(newWin);
    textPtr->prevHeight = Tk_Height(newWin);

    /*
     * Register with the B-tree. In some sense it would be best if we could do
     * this later (after configuration options), so that any changes to
     * start,end do not require a total recalculation.
     */

    TkBTreeAddClient(sharedPtr->tree, textPtr, textPtr->charHeight);

    /*
     * This will add refCounts to textPtr.
     */

    TkTextCreateDInfo(textPtr);
    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
	    &startIndex);
2315
2316
2317
2318
2319
2320
2321

2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332



2333
2334
2335
2336
2337
2338
2339
TextWorldChanged(
    TkText *textPtr,		/* Information about widget. */
    int mask)			/* OR'd collection of bits showing what has
				 * changed. */
{
    Tk_FontMetrics fm;
    int border;


    textPtr->charWidth = Tk_TextWidth(textPtr->tkfont, "0", 1);
    if (textPtr->charWidth <= 0) {
	textPtr->charWidth = 1;
    }
    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    textPtr->charHeight = fm.linespace;
    if (textPtr->charHeight <= 0) {
	textPtr->charHeight = 1;
    }



    border = textPtr->borderWidth + textPtr->highlightWidth;
    Tk_GeometryRequest(textPtr->tkwin,
	    textPtr->width * textPtr->charWidth + 2*textPtr->padX + 2*border,
	    textPtr->height*(fm.linespace+textPtr->spacing1+textPtr->spacing3)
		    + 2*textPtr->padY + 2*border);

    Tk_SetInternalBorderEx(textPtr->tkwin,







>











>
>
>







2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
TextWorldChanged(
    TkText *textPtr,		/* Information about widget. */
    int mask)			/* OR'd collection of bits showing what has
				 * changed. */
{
    Tk_FontMetrics fm;
    int border;
    int oldCharHeight = textPtr->charHeight;

    textPtr->charWidth = Tk_TextWidth(textPtr->tkfont, "0", 1);
    if (textPtr->charWidth <= 0) {
	textPtr->charWidth = 1;
    }
    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    textPtr->charHeight = fm.linespace;
    if (textPtr->charHeight <= 0) {
	textPtr->charHeight = 1;
    }
    if (textPtr->charHeight != oldCharHeight) {
        TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
    }
    border = textPtr->borderWidth + textPtr->highlightWidth;
    Tk_GeometryRequest(textPtr->tkwin,
	    textPtr->width * textPtr->charWidth + 2*textPtr->padX + 2*border,
	    textPtr->height*(fm.linespace+textPtr->spacing1+textPtr->spacing3)
		    + 2*textPtr->padY + 2*border);

    Tk_SetInternalBorderEx(textPtr->tkwin,

Changes to generic/tkTextBTree.c.

1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127

	string = eol;
    }

    /*
     * I don't believe it's possible for either of the two lines passed to
     * this function to be the last line of text, but the function is robust
     * to that case anyway. (We must never re-calculated the line height of
     * the last line).
     */

    TkTextInvalidateLineMetrics(treePtr->sharedTextPtr, NULL,
	    indexPtr->linePtr, changeToLineCount, TK_TEXT_INVALIDATE_INSERT);

    /*







|







1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127

	string = eol;
    }

    /*
     * I don't believe it's possible for either of the two lines passed to
     * this function to be the last line of text, but the function is robust
     * to that case anyway. (We must never re-calculate the line height of
     * the last line).
     */

    TkTextInvalidateLineMetrics(treePtr->sharedTextPtr, NULL,
	    indexPtr->linePtr, changeToLineCount, TK_TEXT_INVALIDATE_INSERT);

    /*

Changes to generic/tkTextDisp.c.

2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
	xPixelOffset = 0;
    }

    /*
     * Here's a problem: see the tests textDisp-29.2.1-4
     *
     * If the widget is being created, but has not yet been configured it will
     * have a maxY of 1 above, and we we won't have examined all the lines
     * (just the first line, in fact), and so maxOffset will not be a true
     * reflection of the widget's lines. Therefore we must not overwrite the
     * original newXPixelOffset in this case.
     */

    if (!(((Tk_FakeWin *) (textPtr->tkwin))->flags & TK_NEED_CONFIG_NOTIFY)) {
	dInfoPtr->newXPixelOffset = xPixelOffset;







|







2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
	xPixelOffset = 0;
    }

    /*
     * Here's a problem: see the tests textDisp-29.2.1-4
     *
     * If the widget is being created, but has not yet been configured it will
     * have a maxY of 1 above, and we won't have examined all the lines
     * (just the first line, in fact), and so maxOffset will not be a true
     * reflection of the widget's lines. Therefore we must not overwrite the
     * original newXPixelOffset in this case.
     */

    if (!(((Tk_FakeWin *) (textPtr->tkwin))->flags & TK_NEED_CONFIG_NOTIFY)) {
	dInfoPtr->newXPixelOffset = xPixelOffset;
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
    int rightX;			/* Right edge of chunkPtr. */
    int rightX2;		/* Right edge of chunkPtr2. */
    int matchLeft;		/* Does the style of this line match that of
				 * its neighbor just to the left of the
				 * current x coordinate? */
    int matchRight;		/* Does line's style match its neighbor just
				 * to the right of the current x-coord? */
    int minX, maxX, xOffset;
    StyleValues *sValuePtr;
    Display *display;
#ifndef TK_NO_DOUBLE_BUFFERING
    const int y = 0;
#else
    const int y = dlPtr->y;
#endif /* TK_NO_DOUBLE_BUFFERING */







|







2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
    int rightX;			/* Right edge of chunkPtr. */
    int rightX2;		/* Right edge of chunkPtr2. */
    int matchLeft;		/* Does the style of this line match that of
				 * its neighbor just to the left of the
				 * current x coordinate? */
    int matchRight;		/* Does line's style match its neighbor just
				 * to the right of the current x-coord? */
    int minX, maxX, xOffset, bw;
    StyleValues *sValuePtr;
    Display *display;
#ifndef TK_NO_DOUBLE_BUFFERING
    const int y = 0;
#else
    const int y = dlPtr->y;
#endif /* TK_NO_DOUBLE_BUFFERING */
2606
2607
2608
2609
2610
2611
2612










2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630

	    if ((leftX + xOffset) < -(sValuePtr->borderWidth)) {
		leftX = -sValuePtr->borderWidth - xOffset;
	    }
	    if ((rightX - leftX) > 32767) {
		rightX = leftX + 32767;
	    }











	    XFillRectangle(display, pixmap, chunkPtr->stylePtr->bgGC,
		    leftX + xOffset, y, (unsigned int) (rightX - leftX),
		    (unsigned int) dlPtr->height);
	    if (sValuePtr->relief != TK_RELIEF_FLAT) {
		Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
			leftX + xOffset, y, sValuePtr->borderWidth,
			dlPtr->height, 1, sValuePtr->relief);
		Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
			rightX - sValuePtr->borderWidth + xOffset,
			y, sValuePtr->borderWidth, dlPtr->height, 0,
			sValuePtr->relief);
	    }
	}
	leftX = rightX;
    }

    /*







>
>
>
>
>
>
>
>
>
>






|
|

<
|







2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631

2632
2633
2634
2635
2636
2637
2638
2639

	    if ((leftX + xOffset) < -(sValuePtr->borderWidth)) {
		leftX = -sValuePtr->borderWidth - xOffset;
	    }
	    if ((rightX - leftX) > 32767) {
		rightX = leftX + 32767;
	    }

            /*
             * Prevent the borders from leaking on adjacent characters,
             * which would happen for too large border width.
             */

            bw = sValuePtr->borderWidth;
            if (leftX + sValuePtr->borderWidth > rightX) {
                bw = rightX - leftX;
            }

	    XFillRectangle(display, pixmap, chunkPtr->stylePtr->bgGC,
		    leftX + xOffset, y, (unsigned int) (rightX - leftX),
		    (unsigned int) dlPtr->height);
	    if (sValuePtr->relief != TK_RELIEF_FLAT) {
		Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
			leftX + xOffset, y, bw, dlPtr->height, 1,
			sValuePtr->relief);
		Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,

			rightX - bw + xOffset, y, bw, dlPtr->height, 0,
			sValuePtr->relief);
	    }
	}
	leftX = rightX;
    }

    /*
2713
2714
2715
2716
2717
2718
2719




2720
2721
2722
2723
2724
2725
2726
2727
2728
2729




2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
	 * matches the current line on one side of the change but not on the
	 * other, we have to draw an L-shaped piece of bevel.
	 */

	matchRight = (nextPtr2 != NULL)
		&& SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr);
	if (matchLeft && !matchRight) {




	    if (sValuePtr->relief != TK_RELIEF_FLAT) {
		Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
			rightX2 - sValuePtr->borderWidth + xOffset, y,
			sValuePtr->borderWidth, sValuePtr->borderWidth, 0,
			sValuePtr->relief);
	    }
	    leftX = rightX2 - sValuePtr->borderWidth;
	    leftXIn = 0;
	} else if (!matchLeft && matchRight
		&& (sValuePtr->relief != TK_RELIEF_FLAT)) {




	    Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
		    rightX2 + xOffset, y, sValuePtr->borderWidth,
		    sValuePtr->borderWidth, 1, sValuePtr->relief);
	    Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
		    leftX + xOffset, y, rightX2 + sValuePtr->borderWidth - 
		    leftX, sValuePtr->borderWidth, leftXIn, 0, 1,
		    sValuePtr->relief);
	}

    nextChunk2:
	chunkPtr2 = nextPtr2;
	if (chunkPtr2 == NULL) {
	    rightX2 = INT_MAX;







>
>
>
>


|
|
<

|



>
>
>
>

|
|

|
|







2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736

2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
	 * matches the current line on one side of the change but not on the
	 * other, we have to draw an L-shaped piece of bevel.
	 */

	matchRight = (nextPtr2 != NULL)
		&& SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr);
	if (matchLeft && !matchRight) {
            bw = sValuePtr->borderWidth;
            if (rightX2 - sValuePtr->borderWidth < leftX) {
                bw = rightX2 - leftX;
            }
	    if (sValuePtr->relief != TK_RELIEF_FLAT) {
		Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
			rightX2 - bw + xOffset, y, bw,
			sValuePtr->borderWidth, 0, sValuePtr->relief);

	    }
            leftX = rightX2 - bw;
	    leftXIn = 0;
	} else if (!matchLeft && matchRight
		&& (sValuePtr->relief != TK_RELIEF_FLAT)) {
            bw = sValuePtr->borderWidth;
            if (rightX2 + sValuePtr->borderWidth > rightX) {
                bw = rightX - rightX2;
            }
	    Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
		    rightX2 + xOffset, y, bw, sValuePtr->borderWidth,
		    1, sValuePtr->relief);
	    Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
		    leftX + xOffset, y, rightX2 + bw - leftX,
		    sValuePtr->borderWidth, leftXIn, 0, 1,
		    sValuePtr->relief);
	}

    nextChunk2:
	chunkPtr2 = nextPtr2;
	if (chunkPtr2 == NULL) {
	    rightX2 = INT_MAX;
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
    rightX = chunkPtr->x + chunkPtr->width;
    if ((chunkPtr->nextPtr == NULL) && (rightX < maxX)) {
	rightX = maxX;
    }
    chunkPtr2 = NULL;
    if (dlPtr->nextPtr != NULL && dlPtr->nextPtr->chunkPtr != NULL) {
	/*
	 * Find the chunk in the previous line that covers leftX.
	 */

	nextPtr2 = dlPtr->nextPtr->chunkPtr;
	rightX2 = 0;			/* See Note A above. */
	while (rightX2 <= leftX) {
	    chunkPtr2 = nextPtr2;
	    if (chunkPtr2 == NULL) {







|







2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
    rightX = chunkPtr->x + chunkPtr->width;
    if ((chunkPtr->nextPtr == NULL) && (rightX < maxX)) {
	rightX = maxX;
    }
    chunkPtr2 = NULL;
    if (dlPtr->nextPtr != NULL && dlPtr->nextPtr->chunkPtr != NULL) {
	/*
	 * Find the chunk in the next line that covers leftX.
	 */

	nextPtr2 = dlPtr->nextPtr->chunkPtr;
	rightX2 = 0;			/* See Note A above. */
	while (rightX2 <= leftX) {
	    chunkPtr2 = nextPtr2;
	    if (chunkPtr2 == NULL) {
2816
2817
2818
2819
2820
2821
2822




2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833




2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
	    }
	    continue;
	}

	matchRight = (nextPtr2 != NULL)
		&& SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr);
	if (matchLeft && !matchRight) {




	    if (sValuePtr->relief != TK_RELIEF_FLAT) {
		Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
			rightX2 - sValuePtr->borderWidth + xOffset,
			y + dlPtr->height - sValuePtr->borderWidth,
			sValuePtr->borderWidth, sValuePtr->borderWidth, 0,
			sValuePtr->relief);
	    }
	    leftX = rightX2 - sValuePtr->borderWidth;
	    leftXIn = 1;
	} else if (!matchLeft && matchRight
		&& (sValuePtr->relief != TK_RELIEF_FLAT)) {




	    Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
		    rightX2 + xOffset, y + dlPtr->height -
		    sValuePtr->borderWidth, sValuePtr->borderWidth,
		    sValuePtr->borderWidth, 1, sValuePtr->relief);
	    Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
		    leftX + xOffset, y + dlPtr->height -
		    sValuePtr->borderWidth, rightX2 + sValuePtr->borderWidth -
		    leftX, sValuePtr->borderWidth, leftXIn, 1, 0,
		    sValuePtr->relief);
	}

    nextChunk2b:
	chunkPtr2 = nextPtr2;
	if (chunkPtr2 == NULL) {
	    rightX2 = INT_MAX;
	} else {







>
>
>
>


|

|
<

|



>
>
>
>

|
|


|
|
|
|







2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847

2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
	    }
	    continue;
	}

	matchRight = (nextPtr2 != NULL)
		&& SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr);
	if (matchLeft && !matchRight) {
            bw = sValuePtr->borderWidth;
            if (rightX2 - sValuePtr->borderWidth < leftX) {
                bw = rightX2 - leftX;
            }
	    if (sValuePtr->relief != TK_RELIEF_FLAT) {
		Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
			rightX2 - bw + xOffset,
			y + dlPtr->height - sValuePtr->borderWidth,
			bw, sValuePtr->borderWidth, 0, sValuePtr->relief);

	    }
	    leftX = rightX2 - bw;
	    leftXIn = 1;
	} else if (!matchLeft && matchRight
		&& (sValuePtr->relief != TK_RELIEF_FLAT)) {
            bw = sValuePtr->borderWidth;
            if (rightX2 + sValuePtr->borderWidth > rightX) {
                bw = rightX - rightX2;
            }
	    Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
		    rightX2 + xOffset,
		    y + dlPtr->height - sValuePtr->borderWidth, bw,
		    sValuePtr->borderWidth, 1, sValuePtr->relief);
	    Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
		    leftX + xOffset,
		    y + dlPtr->height - sValuePtr->borderWidth,
		    rightX2 + bw - leftX, sValuePtr->borderWidth, leftXIn,
		    1, 0, sValuePtr->relief);
	}

    nextChunk2b:
	chunkPtr2 = nextPtr2;
	if (chunkPtr2 == NULL) {
	    rightX2 = INT_MAX;
	} else {

Changes to library/entry.tcl.

369
370
371
372
373
374
375
376
377
378



379



380
381
382
383
384
385
386
387
388
		    $w selection range $anchor $cur
		} else {
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < [$w index anchor]} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] [expr {$anchor-1}]]



	    } else {



		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] [expr {$cur - 1}]]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }







|


>
>
>

>
>
>

|







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
		    $w selection range $anchor $cur
		} else {
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < $anchor} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] [expr {$anchor-1}]]
	    } elseif {$cur > $anchor} {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] [expr {$cur - 1}]]
	    } else {
		if {[$w index @$Priv(pressX)] < $anchor} {
		      incr anchor -1
		}
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $anchor]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }

Changes to library/tk.tcl.

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
    } else {
	set op add
    }

    event $op <<Cut>> <Control-Key-w>
    event $op <<Copy>> <Meta-Key-w> 
    event $op <<Paste>> <Control-Key-y>
    event $op <<Undo>> <Control-underscore>
}

#----------------------------------------------------------------------
# Define common dialogs on platforms where they are not implemented using
# compiled code.
#----------------------------------------------------------------------








<







304
305
306
307
308
309
310

311
312
313
314
315
316
317
    } else {
	set op add
    }

    event $op <<Cut>> <Control-Key-w>
    event $op <<Copy>> <Meta-Key-w> 
    event $op <<Paste>> <Control-Key-y>

}

#----------------------------------------------------------------------
# Define common dialogs on platforms where they are not implemented using
# compiled code.
#----------------------------------------------------------------------

Changes to macosx/tkMacOSXDialog.c.

1
2
3
4
5
6
7
8
9
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
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
/*
 * tkMacOSXDialog.c --
 *
 *	Contains the Mac implementation of the common dialog boxes.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * 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 "tkFileFilter.h"











static int TkBackgroundEvalObjv(Tcl_Interp *interp, int objc,
    Tcl_Obj *const *objv, int flags);

static const char *colorOptionStrings[] = {
    "-initialcolor", "-parent", "-title", NULL
};
enum colorOptions {
    COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
};

static const char *openOptionStrings[] = {
    "-defaultextension", "-filetypes", "-initialdir", "-initialfile",
    "-message", "-multiple", "-parent", "-title", "-typevariable",
    "-command", NULL
};
enum openOptions {
    OPEN_DEFAULT, OPEN_FILETYPES, OPEN_INITDIR, OPEN_INITFILE,
    OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE,
    OPEN_TYPEVARIABLE, OPEN_COMMAND,
};
static const char *saveOptionStrings[] = {
    "-defaultextension", "-filetypes", "-initialdir", "-initialfile",
    "-message", "-parent", "-title", "-typevariable", "-command",
    "-confirmoverwrite", NULL
};
enum saveOptions {
    SAVE_DEFAULT, SAVE_FILETYPES, SAVE_INITDIR, SAVE_INITFILE,
    SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE, SAVE_TYPEVARIABLE, SAVE_COMMAND,
    SAVE_CONFIRMOW
};
static const char *chooseOptionStrings[] = {
    "-initialdir", "-message", "-mustexist", "-parent", "-title", "-command",
    NULL
};
enum chooseOptions {
    CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST, CHOOSE_PARENT,
    CHOOSE_TITLE, CHOOSE_COMMAND,
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int multiple;
} FilePanelCallbackInfo;

static const char *alertOptionStrings[] = {
    "-default", "-detail", "-icon", "-message", "-parent", "-title",
    "-type", "-command", NULL
};
enum alertOptions {
    ALERT_DEFAULT, ALERT_DETAIL, ALERT_ICON, ALERT_MESSAGE, ALERT_PARENT,
    ALERT_TITLE, ALERT_TYPE, ALERT_COMMAND,
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int typeIndex;
} AlertCallbackInfo;
static const char *alertTypeStrings[] = {
    "abortretryignore", "ok", "okcancel", "retrycancel", "yesno",
    "yesnocancel", NULL
};
enum alertTypeOptions {
    TYPE_ABORTRETRYIGNORE, TYPE_OK, TYPE_OKCANCEL, TYPE_RETRYCANCEL,
    TYPE_YESNO, TYPE_YESNOCANCEL
};
static const char *alertIconStrings[] = {
    "error", "info", "question", "warning", NULL
};
enum alertIconOptions {
    ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING
};
static const char *alertButtonStrings[] = {
    "abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL
};

static const NSString *const alertButtonNames[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {@"Abort", @"Retry", @"Ignore"},
    [TYPE_OK] =			{@"OK"},
    [TYPE_OKCANCEL] =		{@"OK", @"Cancel"},
    [TYPE_RETRYCANCEL] =	{@"Retry", @"Cancel"},
    [TYPE_YESNO] =		{@"Yes", @"No"},
    [TYPE_YESNOCANCEL] =	{@"Yes", @"No", @"Cancel"},
};
static const NSAlertStyle alertStyles[] = {
    [ICON_ERROR] =		NSWarningAlertStyle,
    [ICON_INFO] =		NSInformationalAlertStyle,
    [ICON_QUESTION] =		NSWarningAlertStyle,
    [ICON_WARNING] =		NSCriticalAlertStyle,
};

/*
 * Need to map from 'alertButtonStrings' and its corresponding integer,
 * index to the native button index, which is 1, 2, 3, from right to left.
 * This is necessary to do for each separate '-type' of button sets.
 */

static const short alertButtonIndexAndTypeToNativeButtonIndex[][7] = {
			    /*  abort retry ignore ok   cancel yes   no */
    [TYPE_ABORTRETRYIGNORE] =   {1,    2,    3,    0,    0,    0,    0},
    [TYPE_OK] =			{0,    0,    0,    1,    0,    0,    0},
    [TYPE_OKCANCEL] =		{0,    0,    0,    1,    2,    0,    0},









|
|
|



>
>
>
>
>
>
>
>
>
>




|






|









|









|













|












|







|





|



















|
|
|







1
2
3
4
5
6
7
8
9
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
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
/*
 * tkMacOSXDialog.c --
 *
 *	Contains the Mac implementation of the common dialog boxes.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * 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 "tkFileFilter.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOK     NSOKButton
#define modalCancel NSCancelButton
#else
#define modalOK     NSModalResponseOK
#define modalCancel NSModalResponseCancel
#endif
#define modalOther  -1
#define modalError  -2

static int TkBackgroundEvalObjv(Tcl_Interp *interp, int objc,
    Tcl_Obj *const *objv, int flags);

static const char *const colorOptionStrings[] = {
    "-initialcolor", "-parent", "-title", NULL
};
enum colorOptions {
    COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
};

static const char *const openOptionStrings[] = {
    "-defaultextension", "-filetypes", "-initialdir", "-initialfile",
    "-message", "-multiple", "-parent", "-title", "-typevariable",
    "-command", NULL
};
enum openOptions {
    OPEN_DEFAULT, OPEN_FILETYPES, OPEN_INITDIR, OPEN_INITFILE,
    OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE,
    OPEN_TYPEVARIABLE, OPEN_COMMAND,
};
static const char *const saveOptionStrings[] = {
    "-defaultextension", "-filetypes", "-initialdir", "-initialfile",
    "-message", "-parent", "-title", "-typevariable", "-command",
    "-confirmoverwrite", NULL
};
enum saveOptions {
    SAVE_DEFAULT, SAVE_FILETYPES, SAVE_INITDIR, SAVE_INITFILE,
    SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE, SAVE_TYPEVARIABLE, SAVE_COMMAND,
    SAVE_CONFIRMOW
};
static const char *const chooseOptionStrings[] = {
    "-initialdir", "-message", "-mustexist", "-parent", "-title", "-command",
    NULL
};
enum chooseOptions {
    CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST, CHOOSE_PARENT,
    CHOOSE_TITLE, CHOOSE_COMMAND,
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int multiple;
} FilePanelCallbackInfo;

static const char *const alertOptionStrings[] = {
    "-default", "-detail", "-icon", "-message", "-parent", "-title",
    "-type", "-command", NULL
};
enum alertOptions {
    ALERT_DEFAULT, ALERT_DETAIL, ALERT_ICON, ALERT_MESSAGE, ALERT_PARENT,
    ALERT_TITLE, ALERT_TYPE, ALERT_COMMAND,
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int typeIndex;
} AlertCallbackInfo;
static const char *const alertTypeStrings[] = {
    "abortretryignore", "ok", "okcancel", "retrycancel", "yesno",
    "yesnocancel", NULL
};
enum alertTypeOptions {
    TYPE_ABORTRETRYIGNORE, TYPE_OK, TYPE_OKCANCEL, TYPE_RETRYCANCEL,
    TYPE_YESNO, TYPE_YESNOCANCEL
};
static const char *const alertIconStrings[] = {
    "error", "info", "question", "warning", NULL
};
enum alertIconOptions {
    ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING
};
static const char *const alertButtonStrings[] = {
    "abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL
};

static const NSString *const alertButtonNames[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {@"Abort", @"Retry", @"Ignore"},
    [TYPE_OK] =			{@"OK"},
    [TYPE_OKCANCEL] =		{@"OK", @"Cancel"},
    [TYPE_RETRYCANCEL] =	{@"Retry", @"Cancel"},
    [TYPE_YESNO] =		{@"Yes", @"No"},
    [TYPE_YESNOCANCEL] =	{@"Yes", @"No", @"Cancel"},
};
static const NSAlertStyle alertStyles[] = {
    [ICON_ERROR] =		NSWarningAlertStyle,
    [ICON_INFO] =		NSInformationalAlertStyle,
    [ICON_QUESTION] =		NSWarningAlertStyle,
    [ICON_WARNING] =		NSCriticalAlertStyle,
};

/*
 * Need to map from 'alertButtonStrings' and its corresponding integer, index
 * to the native button index, which is 1, 2, 3, from right to left. This is
 * necessary to do for each separate '-type' of button sets.
 */

static const short alertButtonIndexAndTypeToNativeButtonIndex[][7] = {
			    /*  abort retry ignore ok   cancel yes   no */
    [TYPE_ABORTRETRYIGNORE] =   {1,    2,    3,    0,    0,    0,    0},
    [TYPE_OK] =			{0,    0,    0,    1,    0,    0,    0},
    [TYPE_OKCANCEL] =		{0,    0,    0,    1,    2,    0,    0},
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
    [TYPE_OK] =			{3, 0, 0},
    [TYPE_OKCANCEL] =		{3, 4, 0},
    [TYPE_RETRYCANCEL] =	{1, 4, 0},
    [TYPE_YESNO] =		{5, 6, 0},
    [TYPE_YESNOCANCEL] =	{5, 6, 4},
};


















#pragma mark TKApplication(TKDialog)

@interface NSColorPanel(TKDialog)
- (void)_setUseModalAppearance:(BOOL)flag;
@end

@implementation TKApplication(TKDialog)
- (void)tkFilePanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode

	contextInfo:(void *)contextInfo {

    FilePanelCallbackInfo *callbackInfo = contextInfo;

    if (returnCode == NSFileHandlingPanelOKButton) {
	Tcl_Obj *resultObj;

	if (callbackInfo->multiple) {
	    resultObj = Tcl_NewListObj(0, NULL);
	    for (NSString *name in [(NSOpenPanel*)panel filenames]) {
		Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
			Tcl_NewStringObj([name UTF8String], -1));
	    }
	} else {
	    resultObj = Tcl_NewStringObj([[panel filename] UTF8String], -1);
	}
	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);
	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * (objc + 2));







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



|



|
>
|
>




>


|

|


|







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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    [TYPE_OK] =			{3, 0, 0},
    [TYPE_OKCANCEL] =		{3, 4, 0},
    [TYPE_RETRYCANCEL] =	{1, 4, 0},
    [TYPE_YESNO] =		{5, 6, 0},
    [TYPE_YESNOCANCEL] =	{5, 6, 4},
};

/*
 * Construct a file URL from directory and filename.  Either may
 * be nil.  If both are nil, returns nil.
 */
#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050
static NSURL *getFileURL(NSString *directory, NSString *filename) {
    NSURL *url = nil;
    if (directory) {
	url = [NSURL fileURLWithPath:directory];
    }
    if (filename) {
	url = [NSURL URLWithString:filename relativeToURL:url];
    }
    return url;
}
#endif

#pragma mark TKApplication(TKDialog)

@interface NSColorPanel(TKDialog)
- (void) _setUseModalAppearance: (BOOL) flag;
@end

@implementation TKApplication(TKDialog)

- (void) tkFilePanelDidEnd: (NSSavePanel *) panel
	returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
{
    FilePanelCallbackInfo *callbackInfo = contextInfo;

    if (returnCode == NSFileHandlingPanelOKButton) {
	Tcl_Obj *resultObj;

	if (callbackInfo->multiple) {
	    resultObj = Tcl_NewListObj(0, NULL);
	    for (NSURL *url in [(NSOpenPanel*)panel URLs]) {
		Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
			Tcl_NewStringObj([[url path] UTF8String], -1));
	    }
	} else {
	    resultObj = Tcl_NewStringObj([[[panel URL]path] UTF8String], -1);
	}
	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);
	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
	Tcl_ResetResult(callbackInfo->interp);
    }
    if (panel == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
	ckfree((char*) callbackInfo);
    }
}
- (void)tkAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode
	contextInfo:(void *)contextInfo {
    AlertCallbackInfo *callbackInfo = contextInfo;

    if (returnCode != NSAlertErrorReturn) {
	Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
		alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
		typeIndex][returnCode - NSAlertFirstButtonReturn]], -1);
	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);







|






|







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
	Tcl_ResetResult(callbackInfo->interp);
    }
    if (panel == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
	ckfree((char *)callbackInfo);
    }
}
- (void)tkAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode
	contextInfo:(void *)contextInfo {
    AlertCallbackInfo *callbackInfo = contextInfo;

    if (returnCode >= NSAlertFirstButtonReturn) {
	Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
		alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
		typeIndex][returnCode - NSAlertFirstButtonReturn]], -1);
	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
	}
    }
    if ([alert window] == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
	ckfree((char*) callbackInfo);
    }
}
@end

#pragma mark -

/*







|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
	}
    }
    if ([alert window] == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
	ckfree((char *) callbackInfo);
    }
}
@end

#pragma mark -

/*
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
283
284
285
286
287
288
289
290
291
292
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
332
333
334
    int i;
    NSColor *color = nil, *initialColor = nil;
    NSColorPanel *colorPanel;
    NSInteger returnCode, numberOfComponents = 0;

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *option, *value;

	if (Tcl_GetIndexFromObj(interp, objv[i], colorOptionStrings, "option",
		TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {

	    option = Tcl_GetString(objv[i]);
	    Tcl_AppendResult(interp, "value for \"", option, "\" missing",
		    NULL);
	    goto end;
	}
	value = Tcl_GetString(objv[i + 1]);

	switch (index) {
	    case COLOR_INITIAL: {
		XColor *colorPtr;

		colorPtr = Tk_GetColor(interp, tkwin, value);
		if (colorPtr == NULL) {
		    goto end;
		}
		initialColor = TkMacOSXGetNSColor(NULL, colorPtr->pixel);
		Tk_FreeColor(colorPtr);
		break;
	    }
	    case COLOR_PARENT: {
		parent = Tk_NameToWindow(interp, value, tkwin);
		if (parent == NULL) {
		    goto end;
		}
		break;
	    }
	    case COLOR_TITLE: {
		title = value;
		break;
	    }
	}
    }
    colorPanel = [NSColorPanel sharedColorPanel];
    [colorPanel orderOut:NSApp];
    [colorPanel setContinuous:NO];
    [colorPanel setBecomesKeyOnlyIfNeeded:NO];
    [colorPanel setShowsAlpha: NO];
    [colorPanel _setUseModalAppearance:YES];
    if (title) {
	NSString *s = [[NSString alloc] initWithUTF8String:title];
	[colorPanel setTitle:s];
	[s release];
    }
    if (initialColor) {
	[colorPanel setColor:initialColor];
    }
    returnCode = [NSApp runModalForWindow:colorPanel];
    if (returnCode == NSOKButton) {
	color = [[colorPanel color] colorUsingColorSpace:
		[NSColorSpace genericRGBColorSpace]];
	numberOfComponents = [color numberOfComponents];
    }
    if (color && numberOfComponents >= 3 && numberOfComponents <= 4) {
	CGFloat components[4];
	char colorstr[8];

	[color getComponents:components];
	snprintf(colorstr, 8, "#%02x%02x%02x",
		(short)(components[0] * 255),
		(short)(components[1] * 255),
		(short)(components[2] * 255));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(colorstr, 7));
    } else {
	Tcl_ResetResult(interp);
    }
    result = TCL_OK;

end:
    return result;
}

/*
 *----------------------------------------------------------------------
 *







|

|
|



>
|
<
|





|
|

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

















|


















>







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
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
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
358
359
360
361
362
363
    int i;
    NSColor *color = nil, *initialColor = nil;
    NSColorPanel *colorPanel;
    NSInteger returnCode, numberOfComponents = 0;

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *value;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], colorOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));

	    Tcl_SetErrorCode(interp, "TK", "COLORDIALOG", "VALUE", NULL);
	    goto end;
	}
	value = Tcl_GetString(objv[i + 1]);

	switch (index) {
	case COLOR_INITIAL: {
	    XColor *colorPtr;

	    colorPtr = Tk_GetColor(interp, tkwin, value);
	    if (colorPtr == NULL) {
		goto end;
	    }
	    initialColor = TkMacOSXGetNSColor(NULL, colorPtr->pixel);
	    Tk_FreeColor(colorPtr);
	    break;
	}
	case COLOR_PARENT:
	    parent = Tk_NameToWindow(interp, value, tkwin);
	    if (parent == NULL) {
		goto end;
	    }
	    break;

	case COLOR_TITLE:
	    title = value;
	    break;

	}
    }
    colorPanel = [NSColorPanel sharedColorPanel];
    [colorPanel orderOut:NSApp];
    [colorPanel setContinuous:NO];
    [colorPanel setBecomesKeyOnlyIfNeeded:NO];
    [colorPanel setShowsAlpha: NO];
    [colorPanel _setUseModalAppearance:YES];
    if (title) {
	NSString *s = [[NSString alloc] initWithUTF8String:title];
	[colorPanel setTitle:s];
	[s release];
    }
    if (initialColor) {
	[colorPanel setColor:initialColor];
    }
    returnCode = [NSApp runModalForWindow:colorPanel];
    if (returnCode == modalOK) {
	color = [[colorPanel color] colorUsingColorSpace:
		[NSColorSpace genericRGBColorSpace]];
	numberOfComponents = [color numberOfComponents];
    }
    if (color && numberOfComponents >= 3 && numberOfComponents <= 4) {
	CGFloat components[4];
	char colorstr[8];

	[color getComponents:components];
	snprintf(colorstr, 8, "#%02x%02x%02x",
		(short)(components[0] * 255),
		(short)(components[1] * 255),
		(short)(components[2] * 255));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(colorstr, 7));
    } else {
	Tcl_ResetResult(interp);
    }
    result = TCL_OK;

end:
    return result;
}

/*
 *----------------------------------------------------------------------
 *
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil;
    NSString *message, *title, *type;
    NSWindow *parent;
    NSMutableArray *fileTypes = nil;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger returnCode = NSAlertErrorReturn;

    TkInitFileFilters(&fl);
    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObj(interp, objv[i], openOptionStrings, "option",
		TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {

	    str = Tcl_GetString(objv[i]);
	    Tcl_AppendResult(interp, "value for \"", str, "\" missing", NULL);
	    goto end;
	}
	switch (index) {
	case OPEN_DEFAULT:
	    break;
	case OPEN_FILETYPES:
	    if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) {







|



|
|



>
|
|







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
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil;
    NSString *message, *title, *type;
    NSWindow *parent;
    NSMutableArray *fileTypes = nil;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;

    TkInitFileFilters(&fl);
    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case OPEN_DEFAULT:
	    break;
	case OPEN_FILETYPES:
	    if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) {
430
431
432
433
434
435
436

437
438
439
440
441
442
443
	    typeVariablePtr = objv[i + 1];
	    break;
	case OPEN_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }

    if (fl.filters) {
	fileTypes = [NSMutableArray array];
	for (FileFilter *filterPtr = fl.filters; filterPtr;
		filterPtr = filterPtr->next) {
	    for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
		    clausePtr = clausePtr->next) {
		for (GlobPattern *globPtr = clausePtr->patterns; globPtr;







>







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
	    typeVariablePtr = objv[i + 1];
	    break;
	case OPEN_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    [panel setAllowsMultipleSelection:multiple];
    if (fl.filters) {
	fileTypes = [NSMutableArray array];
	for (FileFilter *filterPtr = fl.filters; filterPtr;
		filterPtr = filterPtr->next) {
	    for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
		    clausePtr = clausePtr->next) {
		for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
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






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
			    [fileTypes addObject:type];
			}
		    }
		}
	    }
	}
    }
    [panel setAllowsMultipleSelection:multiple];
    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)
		ckalloc(sizeof(FilePanelCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = multiple;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {

	[panel beginSheetForDirectory:directory file:filename types:fileTypes


		modalForWindow:parent modalDelegate:NSApp didEndSelector:


		@selector(tkFilePanelDidEnd:returnCode:contextInfo:)
		contextInfo:callbackInfo];






	returnCode = cmdObj ? NSAlertOtherReturn :


		[NSApp runModalForWindow:panel];
    } else {

	returnCode = [panel runModalForDirectory:directory file:filename
		types:fileTypes];




	[NSApp tkFilePanelDidEnd:panel returnCode:returnCode
		contextInfo:callbackInfo];
    }
    result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
    if (typeVariablePtr && result == TCL_OK) {
	/*
	 * The -typevariable option is not really supported.
	 */

	Tcl_SetVar(interp, Tcl_GetString(typeVariablePtr), "",
		TCL_GLOBAL_ONLY);
    }

end:
    TkFreeFileFilters(&fl);
    return result;
}

/*
 *----------------------------------------------------------------------
 *







|

|
<










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

>
|
|
>
>
>
>
|


|





|
|

>
|







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
552
553
554
555
556
557
558
559
560
			    [fileTypes addObject:type];
			}
		    }
		}
	    }
	}
    }
    [panel setAllowedFileTypes:fileTypes];
    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));

	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = multiple;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	[panel beginSheetForDirectory:directory
	       file:filename
	       types:fileTypes
	       modalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:
		   @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
#else
	[panel setAllowedFileTypes:fileTypes];
	[panel setDirectoryURL:getFileURL(directory, filename)];
	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSInteger returnCode)
	       { [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ]; } ];
#endif
	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
    } else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	modalReturnCode = [panel runModalForDirectory:directory
				 file:filename];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	modalReturnCode = [panel runModal];
#endif
	[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (typeVariablePtr && result == TCL_OK) {
	/*
	 * The -typevariable option is not really supported.
	 */

	Tcl_SetVar2(interp, Tcl_GetString(typeVariablePtr), NULL,
		"", TCL_GLOBAL_ONLY);
    }

  end:
    TkFreeFileFilters(&fl);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
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
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil, *defaultType = nil;
    NSString *message, *title, *type;
    NSWindow *parent;
    NSMutableArray *fileTypes = nil;
    NSSavePanel *panel = [NSSavePanel savePanel];
    NSInteger returnCode = NSAlertErrorReturn;

    TkInitFileFilters(&fl);
    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObj(interp, objv[i], saveOptionStrings, "option",
		TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {

	    str = Tcl_GetString(objv[i]);
	    Tcl_AppendResult(interp, "value for \"", str, "\" missing",
		    NULL);
	    goto end;
	}
	switch (index) {
	case SAVE_DEFAULT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    while (*str && (*str == '*' || *str == '.')) {
		str++;







|



|
|



>
|
<
|







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
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil, *defaultType = nil;
    NSString *message, *title, *type;
    NSWindow *parent;
    NSMutableArray *fileTypes = nil;
    NSSavePanel *panel = [NSSavePanel savePanel];
    NSInteger modalReturnCode = modalError;

    TkInitFileFilters(&fl);
    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));

	    Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case SAVE_DEFAULT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    while (*str && (*str == '*' || *str == '.')) {
		str++;
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
	case SAVE_TYPEVARIABLE:
	    break;
	case SAVE_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	case SAVE_CONFIRMOW:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
				      &confirmOverwrite) != TCL_OK) {
		goto end;
	    }
	    break;
	}
    }
    if (fl.filters || defaultType) {
	fileTypes = [NSMutableArray array];







|







659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
	case SAVE_TYPEVARIABLE:
	    break;
	case SAVE_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	case SAVE_CONFIRMOW:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &confirmOverwrite) != TCL_OK) {
		goto end;
	    }
	    break;
	}
    }
    if (fl.filters || defaultType) {
	fileTypes = [NSMutableArray array];
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
679
680
681
682
683
	}
	[panel setAllowedFileTypes:fileTypes];
	[panel setAllowsOtherFileTypes:YES];
    }
    [panel setCanSelectHiddenExtension:YES];
    [panel setExtensionHidden:NO];
    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)
		ckalloc(sizeof(FilePanelCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {

	[panel beginSheetForDirectory:directory file:filename

		modalForWindow:parent modalDelegate:NSApp didEndSelector:


		@selector(tkFilePanelDidEnd:returnCode:contextInfo:)
		contextInfo:callbackInfo];





	returnCode = cmdObj ? NSAlertOtherReturn :


		[NSApp runModalForWindow:panel];
    } else {

	returnCode = [panel runModalForDirectory:directory file:filename];




	[NSApp tkFilePanelDidEnd:panel returnCode:returnCode
		contextInfo:callbackInfo];
    }
    result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;

end:
    TkFreeFileFilters(&fl);
    return result;
}

/*
 *----------------------------------------------------------------------
 *







|
<










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

>
|
>
>
>
>
|


|
>
|







694
695
696
697
698
699
700
701

702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
	}
	[panel setAllowedFileTypes:fileTypes];
	[panel setAllowsOtherFileTypes:YES];
    }
    [panel setCanSelectHiddenExtension:YES];
    [panel setExtensionHidden:NO];
    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));

	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	[panel beginSheetForDirectory:directory
	       file:filename
	       modalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:
		   @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSInteger returnCode)
	       { [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ]; } ];
#endif
	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
    } else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	modalReturnCode = [panel runModalForDirectory:directory file:filename];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	modalReturnCode = [panel runModal];
#endif
	[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;

  end:
    TkFreeFileFilters(&fl);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
    Tcl_Obj *cmdObj = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil;
    NSString *message, *title;
    NSWindow *parent;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger returnCode = NSAlertErrorReturn;

    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObj(interp, objv[i], chooseOptionStrings, "option",
		TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {

	    str = Tcl_GetString(objv[i]);
	    Tcl_AppendResult(interp, "value for \"", str, "\" missing", NULL);
	    goto end;
	}
	switch (index) {
	case CHOOSE_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[NSString alloc] initWithUTF8String:str]







|


|
|



>
|
|







775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
    Tcl_Obj *cmdObj = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil;
    NSString *message, *title;
    NSWindow *parent;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;

    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], chooseOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case CHOOSE_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[NSString alloc] initWithUTF8String:str]
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784

785

786

787
788





789


790
791

792




793
794
795
796

797
798
799
800
801
802
803
804
	}
    }
    [panel setPrompt:@"Choose"];
    [panel setCanChooseFiles:NO];
    [panel setCanChooseDirectories:YES];
    [panel setCanCreateDirectories:!mustexist];
    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)
		ckalloc(sizeof(FilePanelCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {

	[panel beginSheetForDirectory:directory file:filename

		modalForWindow:parent modalDelegate:NSApp didEndSelector:

		@selector(tkFilePanelDidEnd:returnCode:contextInfo:)
		contextInfo:callbackInfo];





	returnCode = cmdObj ? NSAlertOtherReturn :


		[NSApp runModalForWindow:panel];
    } else {

	returnCode = [panel runModalForDirectory:directory file:filename];




	[NSApp tkFilePanelDidEnd:panel returnCode:returnCode
		contextInfo:callbackInfo];
    }
    result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;

end:
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkAboutDlg --







|
<










>
|
>
|
>
|

>
>
>
>
>
|
>
>
|

>
|
>
>
>
>
|


|
>
|







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
	}
    }
    [panel setPrompt:@"Choose"];
    [panel setCanChooseFiles:NO];
    [panel setCanChooseDirectories:YES];
    [panel setCanCreateDirectories:!mustexist];
    if (cmdObj) {
	callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));

	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	[panel beginSheetForDirectory:directory
		file:filename
		modalForWindow:parent
		modalDelegate:NSApp
		didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
		contextInfo:callbackInfo];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSInteger returnCode)
	       { [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ]; } ];
#endif
	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
    } else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
	modalReturnCode = [panel runModalForDirectory:directory file:nil];
#else
	[panel setDirectoryURL:getFileURL(directory, filename)];
	modalReturnCode = [panel runModal];
#endif
	[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;

  end:
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkAboutDlg --
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
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
 *----------------------------------------------------------------------
 */

void
TkAboutDlg(void)
{
    NSImage *image;
    NSString *path = [NSApp tkFrameworkImagePath:@"Tk.tiff"];

    if (path) {
	image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
    } else {
	image = [NSApp applicationIconImage];
    }

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    [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-%2$@.", 0xA9,
	    year], @"Copyright",
	    [[[NSAttributedString alloc] initWithString:
	    [NSString stringWithFormat:
	    @"%1$C 1987-%2$@ Tcl Core Team." "\n\n"
	    "%1$C 1989-%2$@ Contributors." "\n\n"
		"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n"
		"%1$C 2014-%2$@ Marc Culler." "\n\n"
	     "%1$C 2002-%2$@ 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];
}

/*







|
>





>

>


>

>

>
|
>
|
>

>










|


|
|
|
|
|
|







895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
 *----------------------------------------------------------------------
 */

void
TkAboutDlg(void)
{
    NSImage *image;
    NSString *path = [NSApp tkFrameworkImagePath: @"Tk.tiff"];

    if (path) {
	image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
    } else {
	image = [NSApp applicationIconImage];
    }

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    [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-%2$@.", 0xA9,
	    year], @"Copyright",
	    [[[NSAttributedString alloc] initWithString:
	    [NSString stringWithFormat:
	    @"%1$C 1987-%2$@ Tcl Core Team." "\n\n"
		"%1$C 1989-%2$@ Contributors." "\n\n"
		"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n"
		"%1$C 2014-%2$@ Marc Culler." "\n\n"
		"%1$C 2002-%2$@ 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];
}

/*
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
    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:nil];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --







|







970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
    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 --
918
919
920
921
922
923
924
925
926
927
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
    int defaultNativeButtonIndex = 1; /* 1, 2, 3: right to left */
    Tcl_Obj *cmdObj = NULL;
    AlertCallbackInfo callbackInfoStruct, *callbackInfo = &callbackInfoStruct;
    NSString *message, *title;
    NSWindow *parent;
    NSArray *buttons;
    NSAlert *alert = [NSAlert new];
    NSInteger returnCode = NSAlertErrorReturn;

    iconIndex = ICON_INFO;
    typeIndex = TYPE_OK;
    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObj(interp, objv[i], alertOptionStrings, "option",
		TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {

	    str = Tcl_GetString(objv[i]);
	    Tcl_AppendResult(interp, "value for \"", str, "\" missing", NULL);
	    goto end;
	}
	switch (index) {
	case ALERT_DEFAULT:
	    /*
	     * Need to postpone processing of this option until we are sure to
	     * know the '-type' as well.
	     */

	    indexDefaultOption = i;
	    break;

	case ALERT_DETAIL:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    [alert setInformativeText:message];
	    [message release];
	    break;

	case ALERT_ICON:
	    if (Tcl_GetIndexFromObj(interp, objv[i + 1], alertIconStrings,
		    "value", TCL_EXACT, &iconIndex) != TCL_OK) {
		goto end;
	    }
	    break;

	case ALERT_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];







|




|
|



>
|
|




















|
|







1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
    int defaultNativeButtonIndex = 1; /* 1, 2, 3: right to left */
    Tcl_Obj *cmdObj = NULL;
    AlertCallbackInfo callbackInfoStruct, *callbackInfo = &callbackInfoStruct;
    NSString *message, *title;
    NSWindow *parent;
    NSArray *buttons;
    NSAlert *alert = [NSAlert new];
    NSInteger modalReturnCode = 1;

    iconIndex = ICON_INFO;
    typeIndex = TYPE_OK;
    for (i = 1; i < objc; i += 2) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], alertOptionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case ALERT_DEFAULT:
	    /*
	     * Need to postpone processing of this option until we are sure to
	     * know the '-type' as well.
	     */

	    indexDefaultOption = i;
	    break;

	case ALERT_DETAIL:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    [alert setInformativeText:message];
	    [message release];
	    break;

	case ALERT_ICON:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings,
		    sizeof(char *), "value", TCL_EXACT, &iconIndex) != TCL_OK) {
		goto end;
	    }
	    break;

	case ALERT_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
980
981
982
983
984
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
1021
1022
1023
1024
1025
1026
1027
1028
1029

1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048

1049







1050
1051

1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    [[alert window] setTitle:title];
	    [title release];
	    break;

	case ALERT_TYPE:
	    if (Tcl_GetIndexFromObj(interp, objv[i + 1], alertTypeStrings,
		    "value", TCL_EXACT, &typeIndex) != TCL_OK) {
		goto end;
	    }
	    break;
	case ALERT_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    if (indexDefaultOption) {
	/*
	 * Any '-default' option needs to know the '-type' option, which is why
	 * we do this here.
	 */

	if (Tcl_GetIndexFromObj(interp, objv[indexDefaultOption + 1],
		alertButtonStrings, "value", TCL_EXACT, &index)
		!= TCL_OK) {
	    goto end;
	}

	/*
	 * Need to map from "ok" etc. to 1, 2, 3, right to left.
	 */

	defaultNativeButtonIndex =
		alertButtonIndexAndTypeToNativeButtonIndex[typeIndex][index];
	if (!defaultNativeButtonIndex) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj("Illegal default option", -1));

	    goto end;
	}
    }
    [alert setIcon:[NSApp applicationIconImage]];
    [alert setAlertStyle:alertStyles[iconIndex]];
    i = 0;
    while (i < 3 && alertButtonNames[typeIndex][i]) {
	[alert addButtonWithTitle:(NSString*)alertButtonNames[typeIndex][i++]];
    }
    buttons = [alert buttons];
    for (NSButton *b in buttons) {
	NSString *ke = [b keyEquivalent];

	if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) &&
		![b keyEquivalentModifierMask]) {
	    [b setKeyEquivalent:@""];
	}
    }

    [[buttons objectAtIndex:[buttons count]-1] setKeyEquivalent:@"\033"];
    [[buttons objectAtIndex:defaultNativeButtonIndex-1] setKeyEquivalent:@"\r"];
    if (cmdObj) {
	callbackInfo = (AlertCallbackInfo *) ckalloc(sizeof(AlertCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->typeIndex = typeIndex;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {

	[alert beginSheetModalForWindow:parent modalDelegate:NSApp







		didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
		contextInfo:callbackInfo];

	returnCode = cmdObj ? NSAlertOtherReturn :
		[NSApp runModalForWindow:[alert window]];
    } else {
	returnCode = [alert runModal];
	[NSApp tkAlertDidEnd:alert returnCode:returnCode
		contextInfo:callbackInfo];
    }
    result = (returnCode != NSAlertErrorReturn) ? TCL_OK : TCL_ERROR;
end:
    [alert release];
    return result;
}

/*
 * ----------------------------------------------------------------------
 *







|
|










|
|


|
|
<












>












>





>
|
|

|










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

|
|


|
|







1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    [[alert window] setTitle:title];
	    [title release];
	    break;

	case ALERT_TYPE:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings,
		    sizeof(char *), "value", TCL_EXACT, &typeIndex) != TCL_OK) {
		goto end;
	    }
	    break;
	case ALERT_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    if (indexDefaultOption) {
	/*
	 * Any '-default' option needs to know the '-type' option, which is
	 * why we do this here.
	 */

	if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1],
		alertButtonStrings, sizeof(char *), "value", TCL_EXACT, &index) != TCL_OK) {

	    goto end;
	}

	/*
	 * Need to map from "ok" etc. to 1, 2, 3, right to left.
	 */

	defaultNativeButtonIndex =
		alertButtonIndexAndTypeToNativeButtonIndex[typeIndex][index];
	if (!defaultNativeButtonIndex) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj("Illegal default option", -1));
	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL);
	    goto end;
	}
    }
    [alert setIcon:[NSApp applicationIconImage]];
    [alert setAlertStyle:alertStyles[iconIndex]];
    i = 0;
    while (i < 3 && alertButtonNames[typeIndex][i]) {
	[alert addButtonWithTitle:(NSString*)alertButtonNames[typeIndex][i++]];
    }
    buttons = [alert buttons];
    for (NSButton *b in buttons) {
	NSString *ke = [b keyEquivalent];

	if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) &&
		![b keyEquivalentModifierMask]) {
	    [b setKeyEquivalent:@""];
	}
    }
    [[buttons objectAtIndex: [buttons count]-1] setKeyEquivalent: @"\033"];
    [[buttons objectAtIndex: defaultNativeButtonIndex-1]
	    setKeyEquivalent: @"\r"];
    if (cmdObj) {
	callbackInfo = (AlertCallbackInfo *)ckalloc(sizeof(AlertCallbackInfo));
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->typeIndex = typeIndex;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
#if MAC_OS_X_VERSION_MIN_REQUIRED > 1090
 	[alert beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode)
	       { [NSApp tkAlertDidEnd:alert
			returnCode:returnCode
			contextInfo:callbackInfo ]; } ];
#else
	[alert beginSheetModalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
#endif
	modalReturnCode = cmdObj ? 0 :
	    [NSApp runModalForWindow:[alert window]];
    } else {
	modalReturnCode = [alert runModal];
	[NSApp tkAlertDidEnd:alert returnCode:modalReturnCode
		contextInfo:callbackInfo];
    }
    result = (modalReturnCode < 1) ? TCL_OK : TCL_ERROR;
 end:
    [alert release];
    return result;
}

/*
 * ----------------------------------------------------------------------
 *

Changes to macosx/tkMacOSXDraw.c.

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    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.  It's context field should point to a CGImage.
	*/
	cg_context = GetCGContextForDrawable(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 ) {
	  /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/







|







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    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 = GetCGContextForDrawable(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 ) {
	  /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
 */

void
XCopyArea(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,			/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,		/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    NSBitmapImageRep *bitmap_rep = NULL;







|


|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
 */

void
XCopyArea(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,				/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,	/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    NSBitmapImageRep *bitmap_rep = NULL;
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
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
332
333
334
335
336
337
338
339
340
341
342
 */

void
XCopyPlane(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,			/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,		/* that will be copied. */
    unsigned int height,
    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;


    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }
    if (srcDraw->flags & TK_IS_PIXMAP) {
	if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	    return;
	}

	if (dc.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 &&
			clipPtr->value.pixmap == src) {






		    imageBackground = TRANSPARENT_PIXEL << 24;










		}
		DrawCGImage(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));
		CFRelease(img);

	    } else {
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable");
	}
	TkMacOSXRestoreDrawingContext(&dc);
    } else {
	XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x,
		dest_y);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage --







|


|







>













>
|

<



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



|


|
|
<







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
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
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
 */

void
XCopyPlane(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,				/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,	/* that will be copied. */
    unsigned int height,
    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");
    }
    if (srcDraw->flags & TK_IS_PIXMAP) {
	if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	    return;
	}
	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){
			CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
			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));
			CGContextScaleCTM(context, 1, -1);
			/* Fill with the background color, clipping to the mask. */
			CGContextClipToMask(context, rect, mask);
			TkMacOSXSetColorInContext(gc, gc->background, dc.context);
			CGContextFillRect(dc.context, rect);
			/* Fill with the foreground color, clipping to the intersection of img and mask. */
			CGContextClipToMask(context, rect, img);
			TkMacOSXSetColorInContext(gc, gc->foreground, context);
			CGContextFillRect(context, rect);
			CGContextRestoreGState(context);
			CGImageRelease(mask);
			CGImageRelease(img);
		} else {
		    DrawCGImage(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.");
	}
	TkMacOSXRestoreDrawingContext(&dc);
    } else { /* source drawable is a window, not a Pixmap */
	XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x, dest_y);

    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage --
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
 *
 *----------------------------------------------------------------------
 */

int
TkPutImage(
    unsigned long *colors,	/* Unused on Macintosh. */
    int ncolors,		/* Unused on Macintosh. */
    Display* display,		/* Display. */
    Drawable d,			/* Drawable to place image on. */
    GC gc,			/* GC to use. */
    XImage* image,		/* Image to place. */
    int src_x,			/* Source X & Y. */
    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;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return BadDrawable;







|


|





|







367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
 *
 *----------------------------------------------------------------------
 */

int
TkPutImage(
    unsigned long *colors,	/* Unused on Macintosh. */
    int ncolors,			/* Unused on Macintosh. */
    Display* display,		/* Display. */
    Drawable d,			/* Drawable to place image on. */
    GC gc,				/* GC to use. */
    XImage* image,		/* Image to place. */
    int src_x,			/* Source X & Y. */
    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;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
	return BadDrawable;
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
    CGDataProviderReleaseDataCallback releaseData = ReleaseData;

    if (image->bits_per_pixel == 1) {
	/*
	 * BW image
	 */


	static const CGFloat decodeWB[2] = {1, 0};


	bitsPerComponent = 1;
	bitsPerPixel = 1;
	decode = decodeWB;
	if (image->bitmap_bit_order != MSBFirst) {
	    char *srcPtr = image->data + image->xoffset;
	    char *endPtr = srcPtr + len;
	    char *destPtr = (data = ckalloc(len));

	    while (srcPtr < endPtr) {
		*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
	    }
	} else {
	    data = memcpy(ckalloc(len), image->data + image->xoffset,
		    len);
	}
	if (data) {
	    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 = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);







>

>



<









|
<






|
<







442
443
444
445
446
447
448
449
450
451
452
453
454

455
456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471

472
473
474
475
476
477
478
    CGDataProviderReleaseDataCallback releaseData = ReleaseData;

    if (image->bits_per_pixel == 1) {
	/*
	 * BW image
	 */

	/* Reverses the sense of the bits */
	static const CGFloat decodeWB[2] = {1, 0};
	decode = decodeWB;

	bitsPerComponent = 1;
	bitsPerPixel = 1;

	if (image->bitmap_bit_order != MSBFirst) {
	    char *srcPtr = image->data + image->xoffset;
	    char *endPtr = srcPtr + len;
	    char *destPtr = (data = ckalloc(len));

	    while (srcPtr < endPtr) {
		*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
	    }
	} else {
	    data = memcpy(ckalloc(len), image->data + image->xoffset, len);

	}
	if (data) {
	    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 = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
		    provider, decode, 0, kCGRenderingIntentDefault);

	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    } else {
	TkMacOSXDbgMsg("Unsupported image type");
    }
    if (provider) {
	CFRelease(provider);
    }

    return img;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithDrawable --







>







<
<
<
<







486
487
488
489
490
491
492
493
494
495
496
497
498
499
500




501
502
503
504
505
506
507
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
		    provider, decode, 0, kCGRenderingIntentDefault);
	    CFRelease(provider);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    } else {
	TkMacOSXDbgMsg("Unsupported image type");
    }




    return img;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithDrawable --
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
	CGBitmapInfo bitmapInfo =
#ifdef __LITTLE_ENDIAN__
	kCGBitmapByteOrder32Host;
#else
	kCGBitmapByteOrderDefault;
#endif
	char *data;
	CGRect bounds = CGRectMake(0, 0, macDraw->size.width,
		macDraw->size.height);

	if (macDraw->flags & TK_IS_BW_PIXMAP) {
	    bitsPerPixel = 8;
	    bitmapInfo = kCGImageAlphaOnly;
	} else {
	    colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
	    bitsPerPixel = 32;
	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	}
	bytesPerRow = ((size_t) macDraw->size.width * bitsPerPixel + 127) >> 3
		& ~15;







|
<



|







667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682
683
684
685
	CGBitmapInfo bitmapInfo =
#ifdef __LITTLE_ENDIAN__
	kCGBitmapByteOrder32Host;
#else
	kCGBitmapByteOrderDefault;
#endif
	char *data;
	CGRect bounds = CGRectMake(0, 0, macDraw->size.width, macDraw->size.height);


	if (macDraw->flags & TK_IS_BW_PIXMAP) {
	    bitsPerPixel = 8;
	    bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
	} else {
	    colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
	    bitsPerPixel = 32;
	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	}
	bytesPerRow = ((size_t) macDraw->size.width * bitsPerPixel + 127) >> 3
		& ~15;
734
735
736
737
738
739
740

741
742
743
744
745
746
747
748
749
750
751
752

753
754
755
756
757
758
759
	    }
	}
	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);

	if (CGImageIsMask(image)) {
	    /*CGContextSaveGState(context);*/
	    if (macDraw->flags & TK_IS_BW_PIXMAP) {

		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);
		    CGContextFillRect(context, dstBounds);
		}
		TkMacOSXSetColorInContext(gc, imageForeground, context);
	    }
	}

#ifdef TK_MAC_DEBUG_IMAGE_DRAWING
	CGContextSaveGState(context);
	CGContextSetLineWidth(context, 1.0);
	CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.1);
	CGContextSetRGBFillColor(context, 0, 1, 0, 0.1);
	CGContextFillRect(context, dstBounds);
	CGContextStrokeRect(context, dstBounds);







>












>







744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
	    }
	}
	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);
		    CGContextFillRect(context, dstBounds);
		}
		TkMacOSXSetColorInContext(gc, imageForeground, context);
	    }
	}

#ifdef TK_MAC_DEBUG_IMAGE_DRAWING
	CGContextSaveGState(context);
	CGContextSetLineWidth(context, 1.0);
	CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.1);
	CGContextSetRGBFillColor(context, 0, 1, 0, 0.1);
	CGContextFillRect(context, dstBounds);
	CGContextStrokeRect(context, dstBounds);
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
    int x, int y,		/* Position rectangle to be scrolled. */
    int width, int height,
    int dx, int dy,		/* Distance rectangle should be moved. */
    TkRegion damageRgn)		/* Region to accumulate damage in. */
{
    Drawable drawable = Tk_WindowId(tkwin);
    MacDrawable *macDraw = (MacDrawable *) drawable;
    NSView *view = TkMacOSXDrawableView(macDraw);
    CGRect srcRect, dstRect;
    HIShapeRef dmgRgn = NULL, extraRgn = NULL;
    NSRect bounds, visRect, scrollSrc, scrollDst;
    int result = 0;

    if ( view ) {
  	/*  Get the scroll area in NSView coordinates (origin at bottom left). */







|







1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
    int x, int y,		/* Position rectangle to be scrolled. */
    int width, int height,
    int dx, int dy,		/* Distance rectangle should be moved. */
    TkRegion damageRgn)		/* Region to accumulate damage in. */
{
    Drawable drawable = Tk_WindowId(tkwin);
    MacDrawable *macDraw = (MacDrawable *) drawable;
    TKContentView *view = (TKContentView *)TkMacOSXDrawableView(macDraw);
    CGRect srcRect, dstRect;
    HIShapeRef dmgRgn = NULL, extraRgn = NULL;
    NSRect bounds, visRect, scrollSrc, scrollDst;
    int result = 0;

    if ( view ) {
  	/*  Get the scroll area in NSView coordinates (origin at bottom left). */

Changes to macosx/tkMacOSXFont.c.

11
12
13
14
15
16
17













18
19
20
21
22
23
24
 * 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"














/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#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
 * 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
*/

/*
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
     */

    bounds = [nsFont boundingRectForFont];
    if (CTFontGetGlyphsForCharacters((CTFontRef) nsFont, ch, glyphs, nCh)) {
	fmPtr->fixed = [nsFont advancementForGlyph:glyphs[0]].width ==
		[nsFont advancementForGlyph:glyphs[1]].width;
	bounds = NSRectFromCGRect(CTFontGetBoundingRectsForGlyphs((CTFontRef)
		nsFont, kCTFontDefaultOrientation, ch, boundingRects, nCh));
	kern = [nsFont advancementForGlyph:glyphs[2]].width -
		[fontPtr->nsFont advancementForGlyph:glyphs[2]].width;
    }
    descent = floor(-bounds.origin.y + 0.5);
    ascent = floor(bounds.size.height + bounds.origin.y + 0.5);
    if (ascent > fmPtr->ascent) {
	fmPtr->ascent = ascent;







|







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
     */

    bounds = [nsFont boundingRectForFont];
    if (CTFontGetGlyphsForCharacters((CTFontRef) nsFont, ch, glyphs, nCh)) {
	fmPtr->fixed = [nsFont advancementForGlyph:glyphs[0]].width ==
		[nsFont advancementForGlyph:glyphs[1]].width;
	bounds = NSRectFromCGRect(CTFontGetBoundingRectsForGlyphs((CTFontRef)
		nsFont, defaultOrientation, ch, boundingRects, nCh));
	kern = [nsFont advancementForGlyph:glyphs[2]].width -
		[fontPtr->nsFont advancementForGlyph:glyphs[2]].width;
    }
    descent = floor(-bounds.origin.y + 0.5);
    ascent = floor(bounds.size.height + bounds.origin.y + 0.5);
    if (ascent > fmPtr->ascent) {
	fmPtr->ascent = ascent;
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
		CreateNamedSystemFont(interp, tkwin, systemFont->tkName1, &fa);
	    }
	    CFRelease(nsFont);
	}
	systemFont++;
    }
    TkInitFontAttributes(&fa);
    nsFont = (NSFont*) CTFontCreateUIFontForLanguage(
	    kCTFontUserFixedPitchFontType, 11, NULL);
    if (nsFont) {
	GetTkFontAttributesForNSFont(nsFont, &fa);
	CFRelease(nsFont);
    } else {
	fa.family = Tk_GetUid("Monaco");
	fa.size = 11;
	fa.weight = TK_FW_NORMAL;







|
<







391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
		CreateNamedSystemFont(interp, tkwin, systemFont->tkName1, &fa);
	    }
	    CFRelease(nsFont);
	}
	systemFont++;
    }
    TkInitFontAttributes(&fa);
    nsFont = (NSFont*) CTFontCreateUIFontForLanguage(fixedPitch, 11, NULL);

    if (nsFont) {
	GetTkFontAttributesForNSFont(nsFont, &fa);
	CFRelease(nsFont);
    } else {
	fa.family = Tk_GetUid("Monaco");
	fa.size = 11;
	fa.weight = TK_FW_NORMAL;

Changes to macosx/tkMacOSXHLEvents.c.

1
2
3
4
5
6
7
8
9

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
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
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
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
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
290
291
292
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
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
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
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
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
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
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
/*
 * tkMacOSXHLEvents.c --
 *
 *	Implements high level event support for the Macintosh. Currently, the
 *	only event that really does anything is the Quit event.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * 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"



/*
 * This is a Tcl_Event structure that the Quit AppleEvent handler uses to
 * schedule the ReallyKillMe function.
 */

typedef struct KillEvent {
    Tcl_Event header;		/* Information that is standard for all
				 * events. */
    Tcl_Interp *interp;		/* Interp that was passed to the Quit
				 * AppleEvent */
} KillEvent;

/*
 * Static functions used only in this file.
 */

static OSErr		QuitHandler(const AppleEvent *event,
			    AppleEvent *reply, SRefCon handlerRefcon);
static OSErr		OappHandler(const AppleEvent *event,
			    AppleEvent *reply, SRefCon handlerRefcon);
static OSErr		RappHandler(const AppleEvent *event,
			    AppleEvent *reply, SRefCon handlerRefcon);
static OSErr		OdocHandler(const AppleEvent *event,
			    AppleEvent *reply, SRefCon handlerRefcon);
static OSErr		PrintHandler(const AppleEvent *event,
			    AppleEvent *reply, SRefCon handlerRefcon);
static OSErr		ScriptHandler(const AppleEvent *event,
			    AppleEvent *reply, SRefCon handlerRefcon);
static OSErr		PrefsHandler(const AppleEvent *event,
			    AppleEvent *reply, SRefCon handlerRefcon);
static int		MissedAnyParameters(const AppleEvent *theEvent);
static int		ReallyKillMe(Tcl_Event *eventPtr, int flags);
static OSStatus		FSRefToDString(const FSRef *fsref, Tcl_DString *ds);

#pragma mark TKApplication(TKHLEvents)

@implementation TKApplication(TKHLEvents)




- (void)terminate:(id)sender {










    QuitHandler(NULL, NULL, (SRefCon) _eventInterp);







}







- (void)preferences:(id)sender {





































    PrefsHandler(NULL, NULL, (SRefCon) _eventInterp);





}




































































































































@end

#pragma mark -














































































































/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitAppleEvents --
 *
 *	Initilize the Apple Events on the Macintosh. This registers the core
 *	event handlers.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXInitAppleEvents(
    Tcl_Interp *interp)		/* Interp to handle basic events. */
{
    AEEventHandlerUPP OappHandlerUPP, RappHandlerUPP, OdocHandlerUPP;
    AEEventHandlerUPP PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP;
    AEEventHandlerUPP PrefsHandlerUPP;
    static Boolean initialized = FALSE;

    if (!initialized) {
	initialized = TRUE;

	/*
	 * Install event handlers for the core apple events.
	 */

	QuitHandlerUPP = NewAEEventHandlerUPP(QuitHandler);
	ChkErr(AEInstallEventHandler, kCoreEventClass, kAEQuitApplication,
		QuitHandlerUPP, (SRefCon) interp, false);

	OappHandlerUPP = NewAEEventHandlerUPP(OappHandler);

	ChkErr(AEInstallEventHandler, kCoreEventClass, kAEOpenApplication,
		OappHandlerUPP, (SRefCon) interp, false);

	RappHandlerUPP = NewAEEventHandlerUPP(RappHandler);

	ChkErr(AEInstallEventHandler, kCoreEventClass, kAEReopenApplication,
		RappHandlerUPP, (SRefCon) interp, false);

	OdocHandlerUPP = NewAEEventHandlerUPP(OdocHandler);

	ChkErr(AEInstallEventHandler, kCoreEventClass, kAEOpenDocuments,
		OdocHandlerUPP, (SRefCon) interp, false);

	PrintHandlerUPP = NewAEEventHandlerUPP(PrintHandler);

	ChkErr(AEInstallEventHandler, kCoreEventClass, kAEPrintDocuments,
		PrintHandlerUPP, (SRefCon) interp, false);

	PrefsHandlerUPP = NewAEEventHandlerUPP(PrefsHandler);

	ChkErr(AEInstallEventHandler, kCoreEventClass, kAEShowPreferences,
		PrefsHandlerUPP, (SRefCon) interp, false);

	if (interp) {
	    ScriptHandlerUPP = NewAEEventHandlerUPP(ScriptHandler);

	    ChkErr(AEInstallEventHandler, kAEMiscStandards, kAEDoScript,
		    ScriptHandlerUPP, (SRefCon) interp, false);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDoHLEvent --
 *
 *	Dispatch incomming highlevel events.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Depends on the incoming event.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXDoHLEvent(
    void *theEvent)
{
    return AEProcessAppleEvent((EventRecord *)theEvent);
}

/*
 *----------------------------------------------------------------------
 *
 * QuitHandler --
 *
 *	This is the 'quit' core Apple event handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSErr
QuitHandler(
    const AppleEvent *event,
    AppleEvent *reply,
    SRefCon handlerRefcon)
{
    Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
    KillEvent *eventPtr;

    if (interp) {
	/*
	 * Call the exit command from the event loop, since you are not
	 * supposed to call ExitToShell in an Apple Event Handler. We put this
	 * at the head of Tcl's event queue because this message usually comes
	 * when the Mac is shutting down, and we want to kill the shell as
	 * quickly as possible.
	 */

	eventPtr = (KillEvent *) ckalloc(sizeof(KillEvent));
	eventPtr->header.proc = ReallyKillMe;
	eventPtr->interp = interp;

	Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_HEAD);
    }
    return noErr;
}

/*
 *----------------------------------------------------------------------
 *
 * OappHandler --
 *
 *	This is the 'oapp' core Apple event handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSErr
OappHandler(
    const AppleEvent *event,
    AppleEvent *reply,
    SRefCon handlerRefcon)
{
    Tcl_CmdInfo dummy;
    Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;

    if (interp &&
	    Tcl_GetCommandInfo(interp, "::tk::mac::OpenApplication", &dummy)){
	int code = Tcl_EvalEx(interp, "::tk::mac::OpenApplication", -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundError(interp);
	}
    }
    return noErr;
}

/*
 *----------------------------------------------------------------------
 *
 * RappHandler --
 *
 *	This is the 'rapp' core Apple event handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSErr
RappHandler(
    const AppleEvent *event,
    AppleEvent *reply,
    SRefCon handlerRefcon)
{
    Tcl_CmdInfo dummy;
    Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
    ProcessSerialNumber thePSN = {0, kCurrentProcess};
    OSStatus err = ChkErr(SetFrontProcess, &thePSN);

    if (interp && Tcl_GetCommandInfo(interp,
	    "::tk::mac::ReopenApplication", &dummy)) {
	int code = Tcl_EvalEx(interp, "::tk::mac::ReopenApplication", -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK){
	    Tcl_BackgroundError(interp);
	}
    }
    return err;
}

/*
 *----------------------------------------------------------------------
 *
 * PrefsHandler --
 *
 *	This is the 'pref' core Apple event handler. Called when the user
 *	selects 'Preferences...' in MacOS X
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSErr
PrefsHandler(
    const AppleEvent *event,
    AppleEvent *reply,
    SRefCon handlerRefcon)
{
    Tcl_CmdInfo dummy;
    Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;

    if (interp &&
	    Tcl_GetCommandInfo(interp, "::tk::mac::ShowPreferences", &dummy)){
	int code = Tcl_EvalEx(interp, "::tk::mac::ShowPreferences", -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundError(interp);
	}
    }
    return noErr;
}

/*
 *----------------------------------------------------------------------
 *
 * OdocHandler --
 *
 *	This is the 'odoc' core Apple event handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSErr
OdocHandler(
    const AppleEvent *event,
    AppleEvent *reply,
    SRefCon handlerRefcon)
{
    Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
    AEDescList fileSpecList;
    FSRef file;
    DescType type;
    Size actual;
    long count, index;
    AEKeyword keyword;
    Tcl_DString command, pathName;
    Tcl_CmdInfo dummy;
    int code;

    /*
     * Don't bother if we don't have an interp or the open document procedure
     * doesn't exist.
     */

    if (!interp ||
	    !Tcl_GetCommandInfo(interp, "::tk::mac::OpenDocument", &dummy)) {
	return noErr;
    }

    /*
     * If we get any errors while retrieving our parameters we just return with
     * no error.
     */

    if (ChkErr(AEGetParamDesc, event, keyDirectObject, typeAEList,
	    &fileSpecList) != noErr) {
	return noErr;
    }
    if (MissedAnyParameters(event) != noErr) {
	return noErr;
    }
    if (ChkErr(AECountItems, &fileSpecList, &count) != noErr) {
	return noErr;
    }

    /*
     * Convert our parameters into a script to evaluate, skipping things that
     * we can't handle right.
     */

    Tcl_DStringInit(&command);
    Tcl_DStringAppend(&command, "::tk::mac::OpenDocument", -1);
    for (index = 1; index <= count; index++) {
	if (ChkErr(AEGetNthPtr, &fileSpecList, index, typeFSRef, &keyword,
		&type, (Ptr) &file, sizeof(FSRef), &actual) != noErr) {
	    continue;
	}

	if (ChkErr(FSRefToDString, &file, &pathName) == noErr) {
	    Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
	    Tcl_DStringFree(&pathName);
	}
    }

    /*
     * Now handle the event by evaluating a script.
     */

    code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
	    Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundError(interp);
    }
    Tcl_DStringFree(&command);
    return noErr;
}

/*
 *----------------------------------------------------------------------
 *
 * PrintHandler --
 *
 *	This is the 'pdoc' core Apple event handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSErr
PrintHandler(
    const AppleEvent * event,
    AppleEvent * reply,
    SRefCon handlerRefcon)
{
    Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
    AEDescList fileSpecList;
    FSRef file;
    DescType type;
    Size actual;
    long count, index;
    AEKeyword keyword;
    Tcl_DString command, pathName;
    Tcl_CmdInfo dummy;
    int code;

    /*
     * Don't bother if we don't have an interp or the print document procedure
     * doesn't exist.
     */

    if (!interp ||
	    !Tcl_GetCommandInfo(interp, "::tk::mac::PrintDocument", &dummy)) {
	return noErr;
    }

    /*
     * If we get any errors while retrieving our parameters we just return with
     * no error.
     */

    if (ChkErr(AEGetParamDesc, event, keyDirectObject, typeAEList,
	    &fileSpecList) != noErr) {
	return noErr;
    }
    if (ChkErr(MissedAnyParameters, event) != noErr) {
	return noErr;
    }
    if (ChkErr(AECountItems, &fileSpecList, &count) != noErr) {
	return noErr;
    }

    Tcl_DStringInit(&command);
    Tcl_DStringAppend(&command, "::tk::mac::PrintDocument", -1);
    for (index = 1; index <= count; index++) {
	if (ChkErr(AEGetNthPtr, &fileSpecList, index, typeFSRef, &keyword,
		&type, (Ptr) &file, sizeof(FSRef), &actual) != noErr) {
	    continue;
	}

	if (ChkErr(FSRefToDString, &file, &pathName) == noErr) {
	    Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
	    Tcl_DStringFree(&pathName);
	}
    }

    /*
     * Now handle the event by evaluating a script.
     */

    code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
	    Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundError(interp);
    }
    Tcl_DStringFree(&command);
    return noErr;
}

/*
 *----------------------------------------------------------------------
 *
 * ScriptHandler --
 *
 *	This handler process the script event.
 *
 * Results:
 *	Schedules the given event to be processed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSErr
ScriptHandler(
    const AppleEvent *event,
    AppleEvent *reply,
    SRefCon handlerRefcon)
{
    OSStatus theErr;
    AEDescList theDesc;
    Size size;
    int tclErr = -1;
    Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon;
    char errString[128];

    /*
     * The do script event receives one parameter that should be data or a
     * file.
     */

    theErr = AEGetParamDesc(event, keyDirectObject, typeWildCard,
	    &theDesc);
    if (theErr != noErr) {
	sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d",
		(int)theErr);
	theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString,
		strlen(errString));
    } else if (MissedAnyParameters(event)) {
	/*
	 * Return error if parameter is missing.
	 */

	sprintf(errString, "AEDoScriptHandler: extra parameters");
	AEPutParamPtr(reply, keyErrorString, typeChar, errString,
		strlen(errString));
	theErr = -1771;
    } else if (theDesc.descriptorType == (DescType) typeAlias &&
	    AEGetParamPtr(event, keyDirectObject, typeFSRef, NULL, NULL,
	    0, &size) == noErr && size == sizeof(FSRef)) {
	/*
	 * We've had a file sent to us. Source it.
	 */

	FSRef file;
	theErr = AEGetParamPtr(event, keyDirectObject, typeFSRef, NULL, &file,
		size, NULL);
	if (theErr == noErr) {
	    Tcl_DString scriptName;

	    theErr = FSRefToDString(&file, &scriptName);
	    if (theErr == noErr) {
		tclErr = Tcl_EvalFile(interp, Tcl_DStringValue(&scriptName));
		Tcl_DStringFree(&scriptName);
	    } else {
		sprintf(errString, "AEDoScriptHandler: file not found");
		AEPutParamPtr(reply, keyErrorString, typeChar, errString,
			strlen(errString));
	    }
	}
    } else if (AEGetParamPtr(event, keyDirectObject, typeUTF8Text, NULL, NULL,
	    0, &size) == noErr && size) {
	/*
	 * We've had some data sent to us. Evaluate it.
	 */

	char *data = ckalloc(size + 1);
	theErr = AEGetParamPtr(event, keyDirectObject, typeUTF8Text, NULL, data,
		size, NULL);
	if (theErr == noErr) {
	    tclErr = Tcl_EvalEx(interp, data, size, TCL_EVAL_GLOBAL);
	}
    } else {
	/*
	 * Umm, don't recognize what we've got...
	 */

	sprintf(errString, "AEDoScriptHandler: invalid script type '%-4.4s', "
		"must be 'alis' or coercable to 'utf8'",
		(char*) &theDesc.descriptorType);
	AEPutParamPtr(reply, keyErrorString, typeChar, errString,
		strlen(errString));
	theErr = -1770;
    }

    /*
     * If we actually go to run Tcl code - put the result in the reply.
     */

    if (tclErr >= 0) {
	int reslen;
	const char *result =
		Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &reslen);

	if (tclErr == TCL_OK) {
	    AEPutParamPtr(reply, keyDirectObject, typeChar, result, reslen);
	} else {
	    AEPutParamPtr(reply, keyErrorString, typeChar, result, reslen);
	    AEPutParamPtr(reply, keyErrorNumber, typeSInt32, (Ptr) &tclErr,
		    sizeof(int));
	}
    }

    AEDisposeDesc(&theDesc);
    return theErr;
}

/*
 *----------------------------------------------------------------------
 *
 * ReallyKillMe --
 *
 *	This proc tries to kill the shell by running exit, called from an
 *	event scheduled by the "Quit" AppleEvent handler.
 *
 * Results:
 *	Runs the "exit" command which might kill the shell.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ReallyKillMe(
    Tcl_Event *eventPtr,
    int flags)
{
    Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
    Tcl_CmdInfo dummy;









>






>
>

















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




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

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

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



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






<
|
>












|

|
<
<





<
|
<
|
<
|
<

|
>
|
<

|
>
|
<

|
>
|
<

|
>
|
<

|
>
|
<

<
|
>
|
<
<








|





|








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


















<







1
2
3
4
5
6
7
8
9
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
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
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
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
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
290
291
292
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
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
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
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






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
/*
 * tkMacOSXHLEvents.c --
 *
 *	Implements high level event support for the Macintosh. Currently, the
 *	only event that really does anything is the Quit event.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
 * Copyright (c) 2015 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 <sys/param.h>
#define URL_MAX_LENGTH (17 + MAXPATHLEN)

/*
 * This is a Tcl_Event structure that the Quit AppleEvent handler uses to
 * schedule the ReallyKillMe function.
 */

typedef struct KillEvent {
    Tcl_Event header;		/* Information that is standard for all
				 * events. */
    Tcl_Interp *interp;		/* Interp that was passed to the Quit
				 * AppleEvent */
} KillEvent;

/*
 * Static functions used only in this file.
 */

static void tkMacOSXProcessFiles(NSAppleEventDescriptor* event, 
				 NSAppleEventDescriptor* replyEvent,
				 Tcl_Interp *interp,
				 char* procedure);










static int  MissedAnyParameters(const AppleEvent *theEvent);
static int  ReallyKillMe(Tcl_Event *eventPtr, int flags);


#pragma mark TKApplication(TKHLEvents)

@implementation TKApplication(TKHLEvents)
- (void) terminate: (id) sender
{
    [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}

- (void) preferences: (id) sender
{
    [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
}

- (void) handleQuitApplicationEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    KillEvent *eventPtr;

    if (_eventInterp) {
	/*
	 * Call the exit command from the event loop, since you are not
	 * supposed to call ExitToShell in an Apple Event Handler. We put this
	 * at the head of Tcl's event queue because this message usually comes
	 * when the Mac is shutting down, and we want to kill the shell as
	 * quickly as possible.
	 */

	eventPtr = (KillEvent*)ckalloc(sizeof(KillEvent));
	eventPtr->header.proc = ReallyKillMe;
	eventPtr->interp = _eventInterp;

	Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_HEAD);
    }
}

- (void) handleOpenApplicationEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
   Tcl_Interp *interp = _eventInterp;

    if (interp &&
	Tcl_FindCommand(_eventInterp, "::tk::mac::OpenApplication", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::OpenApplication",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundError(_eventInterp);
	}
    }
}

- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
    ProcessSerialNumber thePSN = {0, kCurrentProcess};
    SetFrontProcess(&thePSN);
#else
    [[NSApplication sharedApplication] activateIgnoringOtherApps: YES];
#endif
    if (_eventInterp && Tcl_FindCommand(_eventInterp,
	    "::tk::mac::ReopenApplication", NULL, 0)) {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ReopenApplication",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK){
	    Tcl_BackgroundError(_eventInterp);
	}
    }
}

- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    if (_eventInterp &&
	    Tcl_FindCommand(_eventInterp, "::tk::mac::ShowPreferences", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowPreferences",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundError(_eventInterp);
	}
    }
}

- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    tkMacOSXProcessFiles(event, replyEvent, _eventInterp, "::tk::mac::OpenDocument");
}

- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    tkMacOSXProcessFiles(event, replyEvent, _eventInterp, "::tk::mac::PrintDocument");
}

- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event 
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    OSStatus err;
    const AEDesc *theDesc = nil;
    DescType type = 0, initialType = 0;
    Size actual;
    int tclErr = -1;
    char URLBuffer[1 + URL_MAX_LENGTH];
    char errString[128];
    char typeString[5];

    /*
     * The DoScript event receives one parameter that should be text data or a
     * fileURL.
     */

    theDesc = [event aeDesc];
    if (theDesc == nil) {
	return;
    }

    err = AEGetParamPtr(theDesc, keyDirectObject, typeWildCard, &initialType,
			NULL, 0, NULL);
    if (err != noErr) {
	sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)err);
	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
		      errString, strlen(errString));
	return;
    }
    
    if (MissedAnyParameters((AppleEvent*)theDesc)) {
    	sprintf(errString, "AEDoScriptHandler: extra parameters");
    	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
    		      errString, strlen(errString));
    	return;
    }

    if (initialType == typeFileURL || initialType == typeAlias) {
	/*
	 * The descriptor can be coerced to a file url.  Source the file, or
	 * pass the path as a string argument to ::tk::mac::DoScriptFile if
	 * that procedure exists.
	 */
	err = AEGetParamPtr(theDesc, keyDirectObject, typeFileURL, &type,
			    (Ptr) URLBuffer, URL_MAX_LENGTH, &actual);
	if (err == noErr && actual > 0){
	    URLBuffer[actual] = '\0';
	    NSString *urlString = [NSString stringWithUTF8String:(char*)URLBuffer];
	    NSURL *fileURL = [NSURL URLWithString:urlString];
	    Tcl_DString command;
	    Tcl_DStringInit(&command);
	    if (Tcl_FindCommand(_eventInterp, "::tk::mac::DoScriptFile", NULL, 0)){
		Tcl_DStringAppend(&command, "::tk::mac::DoScriptFile", -1);
	    } else {
		Tcl_DStringAppend(&command, "source", -1);
	    }
	    Tcl_DStringAppendElement(&command, [[fileURL path] UTF8String]);
	    tclErr = Tcl_EvalEx(_eventInterp, Tcl_DStringValue(&command),
				 Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
	}
    } else if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
			   NULL, 0, &actual)) {
	if (actual > 0) {
	    /*
	     * The descriptor can be coerced to UTF8 text.  Evaluate as Tcl, or
	     * or pass the text as a string argument to ::tk::mac::DoScriptText
	     * if that procedure exists.
	     */ 
	    char *data = ckalloc(actual + 1);
	    if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
			    data, actual, NULL)) {
		if (Tcl_FindCommand(_eventInterp, "::tk::mac::DoScriptText", NULL, 0)){
		    Tcl_DString command;
		    Tcl_DStringInit(&command);
		    Tcl_DStringAppend(&command, "::tk::mac::DoScriptText", -1);
		    Tcl_DStringAppendElement(&command, data);
		    tclErr = Tcl_EvalEx(_eventInterp, Tcl_DStringValue(&command),
				 Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
		} else {
		    tclErr = Tcl_EvalEx(_eventInterp, data, actual, TCL_EVAL_GLOBAL);
		}
	    }
	    ckfree(data);
	}
    } else {
	/*
	 * The descriptor can not be coerced to a fileURL or UTF8 text.
	 */
	for (int i = 0; i < 4; i++) {
	    typeString[i] = ((char*)&initialType)[3-i];
	}
	typeString[4] = '\0';
	sprintf(errString, "AEDoScriptHandler: invalid script type '%s', "
		"must be coercable to 'furl' or 'utf8'", typeString);
	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar, errString,
		      strlen(errString));
    }
    /*
     * If we ran some Tcl code, put the result in the reply.
     */
    if (tclErr >= 0) {
	int reslen;
	const char *result =
	    Tcl_GetStringFromObj(Tcl_GetObjResult(_eventInterp), &reslen);
	if (tclErr == TCL_OK) {
	    AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyDirectObject, typeChar,
			  result, reslen);
	} else {
	    AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString, typeChar,
			  result, reslen);
	    AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorNumber, typeSInt32,
			  (Ptr) &tclErr,sizeof(int));
	}
    }
    return;
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXProcessFiles --
 *
 *	Extract a list of fileURLs from an AppleEvent and call the specified
 *      procedure with the file paths as arguments.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The event is handled by running the procedure.
 *
 *----------------------------------------------------------------------
 */

static void
tkMacOSXProcessFiles(
    NSAppleEventDescriptor* event, 
    NSAppleEventDescriptor* replyEvent,
    Tcl_Interp *interp,
    char* procedure)
{
    Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8");
    const AEDesc *fileSpecDesc = nil;
    AEDesc contents;
    char URLString[1 + URL_MAX_LENGTH];
    NSURL *fileURL;
    DescType type;
    Size actual;
    long count, index;
    AEKeyword keyword;
    Tcl_DString command, pathName;
    int code;

    /*
     * Do nothing if we don't have an interpreter or the procedure doesn't exist.
     */

    if (!interp || !Tcl_FindCommand(interp, procedure, NULL, 0)) {
	return;
    }
    
    fileSpecDesc = [event aeDesc];
    if (fileSpecDesc == nil ) {
    	return;
    }
    
    /*
     * The AppleEvent's descriptor should either contain a value of
     * typeObjectSpecifier or typeAEList.  In the first case, the descriptor
     * can be treated as a list of size 1 containing a value which can be
     * coerced into a fileURL. In the second case we want to work with the list
     * itself.  Values in the list will be coerced into fileURL's if possible;
     * otherwise they will be ignored.
     */
    
    /* Get a copy of the AppleEvent's descriptor. */
    AEGetParamDesc(fileSpecDesc, keyDirectObject, typeWildCard, &contents);
    if (contents.descriptorType == typeAEList) {
    	fileSpecDesc = &contents;
    }
    
    if (AECountItems(fileSpecDesc, &count) != noErr) {
	AEDisposeDesc(&contents);
    	return;
    }
    
    /*    
     * Construct a Tcl command which calls the procedure, passing the
     * paths contained in the AppleEvent as arguments.
     */
    
    Tcl_DStringInit(&command);
    Tcl_DStringAppend(&command, procedure, -1);

    for (index = 1; index <= count; index++) {
	if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword,
				 &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) {
	    continue;
	}
	if (type != typeFileURL) {
	    continue;
	}
	URLString[actual] = '\0';
	fileURL = [NSURL URLWithString:[NSString stringWithUTF8String:(char*)URLString]]; 
	if (fileURL == nil) {
	    continue;
	}
	Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], -1, &pathName);
	Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
	Tcl_DStringFree(&pathName);
    }
    AEDisposeDesc(&contents);

    /*
     * Handle the event by evaluating the Tcl expression we constructed.
     */

    code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
	    Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundError(interp);
    }
    Tcl_DStringFree(&command);
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitAppleEvents --
 *

 *	Register AppleEvent handlers with the NSAppleEventManager for
 *      this NSApplication.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXInitAppleEvents(
    Tcl_Interp *interp)   /* not used */
{
    NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];


    static Boolean initialized = FALSE;

    if (!initialized) {
	initialized = TRUE;


	[aeManager setEventHandler:NSApp

	    andSelector:@selector(handleQuitApplicationEvent:withReplyEvent:)

	    forEventClass:kCoreEventClass andEventID:kAEQuitApplication];


	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleOpenApplicationEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEOpenApplication];


	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleReopenApplicationEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEReopenApplication];


	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleShowPreferencesEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEShowPreferences];


	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];


	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleOpenDocumentsEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEPrintDocuments];



	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleDoScriptEvent:withReplyEvent:)
	    forEventClass:kAEMiscStandards andEventID:kAEDoScript];


    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDoHLEvent --
 *
 *	Dispatch an AppleEvent.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Depend on the AppleEvent.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXDoHLEvent(
    void *theEvent)
{


    /* According to the NSAppleEventManager reference:















     *   "The theReply parameter always specifies a reply Apple event, never








     *   nil.  However, the handler should not fill out the reply if the








     *   descriptor type for the reply event is typeNull, indicating the sender



     *   does not want a reply."




     * The specified way to build such a non-nil descriptor is used here.  But















     * on OSX 10.11, the compiler nonetheless generates a warning.  I am








     * supressing the warning here -- maybe the warnings will stop in a future














































     * compiler release.















     */
#ifdef __clang__








#pragma clang diagnostic push









#pragma clang diagnostic ignored "-Wnonnull"















#endif























































    NSAppleEventDescriptor* theReply = [NSAppleEventDescriptor nullDescriptor];





    NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];





















































































































    return [aeManager dispatchRawAppleEvent:(const AppleEvent*)theEvent
		      withRawReply: (AppleEvent *)theReply
		      handlerRefCon: (SRefCon)0];







#ifdef __clang__




#pragma clang diagnostic pop











#endif








































































}

/*
 *----------------------------------------------------------------------
 *
 * ReallyKillMe --
 *
 *	This proc tries to kill the shell by running exit, called from an
 *	event scheduled by the "Quit" AppleEvent handler.
 *
 * Results:
 *	Runs the "exit" command which might kill the shell.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ReallyKillMe(
    Tcl_Event *eventPtr,
    int flags)
{
    Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
    Tcl_CmdInfo dummy;
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
   OSStatus err;

   err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr,
	    typeWildCard, &returnedType, NULL, 0, &actualSize);

   return (err != errAEDescNotFound);
}

/*
 *----------------------------------------------------------------------
 *
 * FSRefToDString --
 *
 *	Get a POSIX path from an FSRef.
 *
 * Results:
 *	In the parameter ds.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static OSStatus
FSRefToDString(
    const FSRef *fsref,
    Tcl_DString *ds)
{
    UInt8 fileName[PATH_MAX+1];
    OSStatus err;

    err = ChkErr(FSRefMakePath, fsref, fileName, sizeof(fileName));
    if (err == noErr) {
	Tcl_ExternalToUtfDString(NULL, (char*) fileName, -1, ds);
    }
    return err;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







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








529
530
531
532
533
534
535
536































537
538
539
540
541
542
543
544
   OSStatus err;

   err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr,
	    typeWildCard, &returnedType, NULL, 0, &actualSize);

   return (err != errAEDescNotFound);
}
































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

Changes to macosx/tkMacOSXKeyEvent.c.

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

    return theEvent;
}
@end



@implementation TKContentView(TKKeyEvent)
/* <NSTextInput> implementation (called through interpretKeyEvents:]). */

/* <NSTextInput>: called when done composing;
   NOTE: also called when we delete over working text, followed immed.
         by doCommandBySelector: deleteBackward: */
- (void)insertText: (id)aString
{







|







223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

    return theEvent;
}
@end



@implementation TKContentView
/* <NSTextInput> implementation (called through interpretKeyEvents:]). */

/* <NSTextInput>: called when done composing;
   NOTE: also called when we delete over working text, followed immed.
         by doCommandBySelector: deleteBackward: */
- (void)insertText: (id)aString
{
288
289
290
291
292
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

  processingCompose = YES;
  privateWorkingText = [str copy];

  //PENDING: insert workingText underlined
}


/* 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
}


- (BOOL)hasMarkedText
{
  return privateWorkingText != nil;
}









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







288
289
290
291
292
293
294
















295
296
297
298
299
300
301

  processingCompose = YES;
  privateWorkingText = [str copy];

  //PENDING: insert workingText underlined
}


















- (BOOL)hasMarkedText
{
  return privateWorkingText != nil;
}


413
414
415
416
417
418
419


















420
421
422
423
424
425
426
  if (NS_KEYLOG)
    NSLog (@"attributedSubstringFromRange request");
  return str;
}
/* End <NSTextInput> impl. */
@end





















/*
 *  Set up basic fields in xevent for keyboard input.
 */
static void
setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)







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







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
  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
}
@end



/*
 *  Set up basic fields in xevent for keyboard input.
 */
static void
setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)

Changes to macosx/tkMacOSXMenu.c.

788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
    inPostMenu = 1;

    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 convertScreenToBase:frame.origin] fromView:nil];

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

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







|







788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
    inPostMenu = 1;

    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];

Changes to macosx/tkMacOSXMouseEvent.c.

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
54
55
56
57
58
59
60
61
62
63
    Window window;
    Point global;
    Point local;
} MouseEventData;

static int		GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int	ButtonModifiers2State(UInt32 buttonState,
			    UInt32 keyModifiers);

#pragma mark TKApplication(TKMouseEvent)

enum {
    NSWindowWillMoveEventType = 20
};











@implementation TKApplication(TKMouseEvent)
- (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent {
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    id		    win;
    NSEventType	    type = [theEvent type];
#if 0
    NSTrackingArea  *trackingArea = nil;
    NSInteger eventNumber, clickCount, buttonNumber;
#endif

    switch (type) {
    case NSMouseEntered:









    case NSMouseExited:
    case NSCursorUpdate:
#if 0
	trackingArea = [theEvent trackingArea];
	/* fall through */
#endif
    case NSLeftMouseDown:
    case NSLeftMouseUp:
    case NSRightMouseDown:
    case NSRightMouseUp:
    case NSOtherMouseDown:
    case NSOtherMouseUp:
    case NSLeftMouseDragged:







|







>
>
>
>
>
>
>
>
>
>





|
|





|

>
>
>
>
>
>
>
>
>


<
<
<
<







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
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
    Window window;
    Point global;
    Point local;
} MouseEventData;

static int		GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int	ButtonModifiers2State(UInt32 buttonState,
					      UInt32 keyModifiers);

#pragma mark TKApplication(TKMouseEvent)

enum {
    NSWindowWillMoveEventType = 20
};

/*
 * In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
 * window attribute pointing to the active window.  As of 10.8 this behavior
 * had changed.  The new behavior was that if the mouse were ever moved outside
 * of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
 * attribute.  To work around this the TKApplication remembers the last non-Nil
 * window that it received in a mouse event. If it receives an NSEvent with a
 * Nil window attribute then the saved window is used.
 */

@implementation TKApplication(TKMouseEvent)
- (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent {
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSWindow*    eventWindow = [theEvent window];
    NSEventType	 eventType = [theEvent type];
#if 0
    NSTrackingArea  *trackingArea = nil;
    NSInteger eventNumber, clickCount, buttonNumber;
#endif

    switch (eventType) {
    case NSMouseEntered:
	/* Remember which window has the mouse. */
	if (_windowWithMouse) {
	    [_windowWithMouse release];
	}
	_windowWithMouse = [theEvent window];
	if (_windowWithMouse) {
	    [_windowWithMouse retain];
	}
	break;
    case NSMouseExited:
    case NSCursorUpdate:




    case NSLeftMouseDown:
    case NSLeftMouseUp:
    case NSRightMouseDown:
    case NSRightMouseUp:
    case NSOtherMouseDown:
    case NSOtherMouseUp:
    case NSLeftMouseDragged:
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
	    buttonNumber = [theEvent buttonNumber];
	}
#endif
    case NSTabletPoint:
    case NSTabletProximity:
    case NSScrollWheel:
        break;

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










    /* Create an Xevent to add to the Tk queue. */
    win = [theEvent window];
    NSPoint global, local = [theEvent locationInWindow];





    if (win) {

	global = [win convertBaseToScreen:local];

	local.y = [win frame].size.height - local.y;
	global.y = tkMacOSXZeroScreenHeight - global.y;
    } else {
	local.y = tkMacOSXZeroScreenHeight - local.y;
	global = local;
    }


    Window window = TkMacOSXGetXWindow(win);
    Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
	    window) : NULL;
    if (!tkwin) {
	tkwin = TkMacOSXGetCapture();
    }
    if (!tkwin) {
	return theEvent; /* Give up.  No window for this event. */







<




>
>
>
>
>
>
>
>
>

<

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







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
	    buttonNumber = [theEvent buttonNumber];
	}
#endif
    case NSTabletPoint:
    case NSTabletProximity:
    case NSScrollWheel:
        break;

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

    /* Remember the window in case we need it next time. */
    if (eventWindow && eventWindow != _windowWithMouse) {
	if (_windowWithMouse) {
	    [_windowWithMouse release];
	}
	_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;
	}
    }

    Window window = TkMacOSXGetXWindow(eventWindow);
    Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
	    window) : NULL;
    if (!tkwin) {
	tkwin = TkMacOSXGetCapture();
    }
    if (!tkwin) {
	return theEvent; /* Give up.  No window for this event. */
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    UInt32 buttons;
    OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord,
	    typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);
    if (err == noErr) {
	state |= (buttons & ((1<<5) - 1)) << 8;
    } else {
	if (button < 5) {
	    switch (type) {
	    case NSLeftMouseDown:
	    case NSRightMouseDown:
	    case NSLeftMouseDragged:
	    case NSRightMouseDragged:
	    case NSOtherMouseDown:
		state |= 1 << (button + 8);
		break;







|







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    UInt32 buttons;
    OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord,
	    typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);
    if (err == noErr) {
	state |= (buttons & ((1<<5) - 1)) << 8;
    } else {
	if (button < 5) {
	    switch (eventType) {
	    case NSLeftMouseDown:
	    case NSRightMouseDown:
	    case NSLeftMouseDragged:
	    case NSRightMouseDragged:
	    case NSOtherMouseDown:
		state |= 1 << (button + 8);
		break;
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
    if (modifiers & NSNumericPadKeyMask) {
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }

    if (type != NSScrollWheel) {
#ifdef TK_MAC_DEBUG_EVENTS
	TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d", tkwin, global.x, global.y, state);
#endif
	Tk_UpdatePointer(tkwin, global.x, global.y, state);
    } else {
	CGFloat delta;
	int coarseDelta;
	XEvent xEvent;

	xEvent.type = MouseWheelEvent;
	xEvent.xbutton.x = local.x;
	xEvent.xbutton.y = local.y;
	xEvent.xbutton.x_root = global.x;
	xEvent.xbutton.y_root = global.y;
	xEvent.xany.send_event = false;
	xEvent.xany.display = Tk_Display(tkwin);
	xEvent.xany.window = Tk_WindowId(tkwin);

	delta = [theEvent deltaY];
	if (delta != 0.0) {
	    coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta);

	    xEvent.xbutton.state = state;
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
	delta = [theEvent deltaX];
	if (delta != 0.0) {
	    coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta);

	    xEvent.xbutton.state = state | ShiftMask;
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
    }
    return theEvent;







|




|















|
>







|
>







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
    if (modifiers & NSNumericPadKeyMask) {
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }

    if (eventType != NSScrollWheel) {
#ifdef TK_MAC_DEBUG_EVENTS
	TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d", tkwin, global.x, global.y, state);
#endif
	Tk_UpdatePointer(tkwin, global.x, global.y, state);
    } else { /* handle scroll wheel event */
	CGFloat delta;
	int coarseDelta;
	XEvent xEvent;

	xEvent.type = MouseWheelEvent;
	xEvent.xbutton.x = local.x;
	xEvent.xbutton.y = local.y;
	xEvent.xbutton.x_root = global.x;
	xEvent.xbutton.y_root = global.y;
	xEvent.xany.send_event = false;
	xEvent.xany.display = Tk_Display(tkwin);
	xEvent.xany.window = Tk_WindowId(tkwin);

	delta = [theEvent deltaY];
	if (delta != 0.0) {
	    coarseDelta = (delta > -1.0 && delta < 1.0) ?
		(signbit(delta) ? -1 : 1) : lround(delta);
	    xEvent.xbutton.state = state;
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
	delta = [theEvent deltaX];
	if (delta != 0.0) {
	    coarseDelta = (delta > -1.0 && delta < 1.0) ?
		(signbit(delta) ? -1 : 1) : lround(delta);
	    xEvent.xbutton.state = state | ShiftMask;
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
    }
    return theEvent;
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *) w;
	    NSWindow *win = TkMacOSXDrawableWindow(w);

	    if (win) {
		NSPoint local;

		local = [win convertScreenToBase: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;







|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
	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;
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
    med.global.h = x;
    med.global.v = y;
    med.local = med.global;

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

	local = [win convertScreenToBase: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;







|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
    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;

Changes to macosx/tkMacOSXPrivate.h.

268
269
270
271
272
273
274

275
276
277
278
279
280
281
@interface TKApplication : NSApplication {
@private
    Tcl_Interp *_eventInterp;
    NSMenu *_servicesMenu;
    TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems;

}
@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
@end
@interface TKApplication(TKEvent)
- (NSEvent *)tkProcessEvent:(NSEvent *)theEvent;







>







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
@interface TKApplication : NSApplication {
@private
    Tcl_Interp *_eventInterp;
    NSMenu *_servicesMenu;
    TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems;
    NSWindow *_windowWithMouse;
}
@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
@end
@interface TKApplication(TKEvent)
- (NSEvent *)tkProcessEvent:(NSEvent *)theEvent;
289
290
291
292
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
@interface TKApplication(TKMenu)
- (void)tkSetMainMenu:(TKMenu *)menu;
@end
@interface TKApplication(TKClipboard)
- (void)tkProvidePasteboard:(TkDisplay *)dispPtr;
- (void)tkCheckPasteboard;
@end



















VISIBILITY_HIDDEN
@interface TKContentView : NSView <NSTextInput> {
@private
  /*Remove private API calls.*/
   #if 0
    id _savedSubviews;
    BOOL _subviewsSetAside;
    #endif
    NSString *privateWorkingText;
}
@end

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













VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
@end






#pragma mark NSMenu & NSMenuItem Utilities

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







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





|


|







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




>
>
>
>
>







290
291
292
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
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
358
@interface TKApplication(TKMenu)
- (void)tkSetMainMenu:(TKMenu *)menu;
@end
@interface TKApplication(TKClipboard)
- (void)tkProvidePasteboard:(TkDisplay *)dispPtr;
- (void)tkCheckPasteboard;
@end
@interface TKApplication(TKHLEvents)
- (void) terminate: (id) sender;
- (void) preferences: (id) sender;
- (void) handleQuitApplicationEvent:   (NSAppleEventDescriptor *)event 
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleOpenApplicationEvent:   (NSAppleEventDescriptor *)event 
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event 
		       withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
- (void) handleShowPreferencesEvent:   (NSAppleEventDescriptor *)event
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleOpenDocumentsEvent:     (NSAppleEventDescriptor *)event 
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;
- (void) handlePrintDocumentsEvent:    (NSAppleEventDescriptor *)event 
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;
- (void) handleDoScriptEvent:          (NSAppleEventDescriptor *)event 
		   withReplyEvent:     (NSAppleEventDescriptor *)replyEvent;
@end

VISIBILITY_HIDDEN
@interface TKContentView : NSView <NSTextInput> {
@private
  /*Remove private API calls.*/
#if 0
    id _savedSubviews;
    BOOL _subviewsSetAside;
#endif
    NSString *privateWorkingText;
}
@end

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

@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
- (void) generateExposeEvents: (HIShapeRef) shape;
- (void) generateExposeEvents: (HIShapeRef) shape childrenOnly: (int) childrenOnly;
- (void) viewDidEndLiveResize;
- (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;
+ (id)menuWithTitle:(NSString *)title submenus:(NSArray *)submenus;
337
338
339
340
341
342
343
344
345
346
+ (id)itemWithTitle:(NSString *)title action:(SEL)action
	keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
+ (id)itemWithTitle:(NSString *)title action:(SEL)action
	target:(id)target keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
@end


#endif /* _TKMACPRIV */








<

373
374
375
376
377
378
379
380

381
+ (id)itemWithTitle:(NSString *)title action:(SEL)action
	keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
+ (id)itemWithTitle:(NSString *)title action:(SEL)action
	target:(id)target keyEquivalent:(NSString *)keyEquivalent
	keyEquivalentModifierMask:(NSUInteger)keyEquivalentModifierMask;
@end


#endif /* _TKMACPRIV */

Changes to macosx/tkMacOSXSubwindows.c.

801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
		    CFRelease(visRgn);
		    TkpReleaseRegion(r);
		}

		/*
		 * TODO: Here we should handle out of process embedding.
		 */
	    } else if (winPtr->wmInfoPtr->attributes &
		    kWindowResizableAttribute) {
		NSWindow *w = TkMacOSXDrawableWindow(winPtr->window);
	    }
	    macWin->aboveVisRgn = HIShapeCreateCopy(rgn);

	    /*
	     * The final clip region is the aboveVis region (or visible region)
	     * minus all the children of this window. If the window is a
	     * container, we must also subtract the region of the embedded







<
<
<







801
802
803
804
805
806
807



808
809
810
811
812
813
814
		    CFRelease(visRgn);
		    TkpReleaseRegion(r);
		}

		/*
		 * TODO: Here we should handle out of process embedding.
		 */



	    }
	    macWin->aboveVisRgn = HIShapeCreateCopy(rgn);

	    /*
	     * The final clip region is the aboveVis region (or visible region)
	     * minus all the children of this window. If the window is a
	     * container, we must also subtract the region of the embedded

Changes to macosx/tkMacOSXWindowEvent.c.

743
744
745
746
747
748
749
750

751
752
753
754
755
756
757
758


759
760
761
762
763
764
765
 *
 *----------------------------------------------------------------------
 */

int
Tk_MacOSXIsAppInFront(void)
{
    OSStatus err;

    ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess};
    Boolean isFrontProcess = true;

    err = ChkErr(GetFrontProcess, &frontPsn);
    if (err == noErr) {
	ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess);
    }



    return (isFrontProcess == true);
}

#pragma mark TKContentView

#import <ApplicationServices/ApplicationServices.h>








|
>

<

|
<
|

|
>
>







743
744
745
746
747
748
749
750
751
752

753
754

755
756
757
758
759
760
761
762
763
764
765
766
 *
 *----------------------------------------------------------------------
 */

int
Tk_MacOSXIsAppInFront(void)
{
    Boolean isFrontProcess = true;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess};


    if (noErr == GetFrontProcess(&frontPsn)){

	SameProcess(&frontPsn, &ourPsn, &isFrontProcess);
    }
#else
    isFrontProcess = [NSRunningApplication currentApplication].active;
#endif
    return (isFrontProcess == true);
}

#pragma mark TKContentView

#import <ApplicationServices/ApplicationServices.h>

778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
 * Widgets it was necessary to use Apple private API calls.  In order to avoid
 * using private API calls, the NSView-based widgets have been replaced with
 * normal Tk widgets which draw themselves as native widgets by using the
 * HITheme API.
 *
 */

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

@implementation TKContentView
@end

/*Restrict event processing to Expose events.*/
static Tk_RestrictAction
ExposeRestrictProc(
    ClientData arg,
    XEvent *eventPtr)
{
    return (eventPtr->type==Expose && eventPtr->xany.serial==PTR2UINT(arg)







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







779
780
781
782
783
784
785















786
787
788
789
790
791
792
 * Widgets it was necessary to use Apple private API calls.  In order to avoid
 * using private API calls, the NSView-based widgets have been replaced with
 * normal Tk widgets which draw themselves as native widgets by using the
 * HITheme API.
 *
 */
















/*Restrict event processing to Expose events.*/
static Tk_RestrictAction
ExposeRestrictProc(
    ClientData arg,
    XEvent *eventPtr)
{
    return (eventPtr->type==Expose && eventPtr->xany.serial==PTR2UINT(arg)

Changes to macosx/tkMacOSXWm.c.

195
196
197
198
199
200
201










































202
203
204
205
206
207
208

/*
 * Hash table for Mac Window -> TkWindow mapping.
 */

static Tcl_HashTable windowTable;
static int windowHashInit = false;











































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

static NSRect		InitialWindowBounds(TkWindow *winPtr,
			    NSWindow *macWindow);







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







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
249
250

/*
 * Hash table for Mac Window -> TkWindow mapping.
 */

static Tcl_HashTable windowTable;
static int windowHashInit = false;



#pragma mark NSWindow(TKWm)

/*
 * 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];
}
@end
#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;
}
@end
#endif

#pragma mark -


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

static NSRect		InitialWindowBounds(TkWindow *winPtr,
			    NSWindow *macWindow);
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
	   NSWindow *front = [windows objectAtIndex:0];
	   if ( front && [front canBecomeKeyWindow] ) {
               [front makeKeyAndOrderFront:NSApp];
           }
       }
       [pool drain];
    }
    ckfree(wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmSetClass --







|







855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
	   NSWindow *front = [windows objectAtIndex:0];
	   if ( front && [front canBecomeKeyWindow] ) {
               [front makeKeyAndOrderFront:NSApp];
           }
       }
       [pool drain];
    }
    ckfree((char *)wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmSetClass --
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
	{ "ignoreClicks",	kWindowIgnoreClicksAttribute		     },
	{ "noConstrain",	kWindowNoConstrainAttribute		     },
	{ "doesNotHide",	tkWindowDoesNotHideAttribute		     },
	{ "canJoinAllSpaces",	tkCanJoinAllSpacesAttribute		     },
	{ "moveToActiveSpace",	tkMoveToActiveSpaceAttribute		     },
	{ "nonActivating",	tkNonactivatingPanelAttribute		     },
	{ "hud",		tkHUDWindowAttribute			     },
	{ "black",		NULL			                     },
	{ "dark",		NULL			                     },
	{ "light",		NULL			                     },
	{ "gray",		NULL			                     },
	{ "red",		NULL 			                     },
	{ "green",		NULL                			     },
	{ "blue",		NULL           			             },
	{ "cyan",		NULL			                     },
	{ "yellow",		NULL			                     },
	{ "magenta",		NULL  			                     },
	{ "orange",		NULL 			                     },
	{ "purple",		NULL			                     },
	{ "brown",		NULL			                     },
	{ "clear",		NULL			                     },
	{ "opacity",		NULL			                     },
	{ "fullscreen",         NULL                                         },
	{ NULL }
    };

    int index, i;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc == 3) {







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
	{ "ignoreClicks",	kWindowIgnoreClicksAttribute		     },
	{ "noConstrain",	kWindowNoConstrainAttribute		     },
	{ "doesNotHide",	tkWindowDoesNotHideAttribute		     },
	{ "canJoinAllSpaces",	tkCanJoinAllSpacesAttribute		     },
	{ "moveToActiveSpace",	tkMoveToActiveSpaceAttribute		     },
	{ "nonActivating",	tkNonactivatingPanelAttribute		     },
	{ "hud",		tkHUDWindowAttribute			     },
	{ "black",		0			                     },
	{ "dark",		0			                     },
	{ "light",		0			                     },
	{ "gray",		0			                     },
	{ "red",		0 			                     },
	{ "green",		0                			     },
	{ "blue",		0           			             },
	{ "cyan",		0			                     },
	{ "yellow",		0			                     },
	{ "magenta",		0  			                     },
	{ "orange",		0 			                     },
	{ "purple",		0			                     },
	{ "brown",		0			                     },
	{ "clear",		0			                     },
	{ "opacity",		0			                     },
	{ "fullscreen",         0			                     },
	{ NULL }
    };

    int index, i;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc == 3) {

Changes to macosx/tkMacOSXXStubs.c.

177
178
179
180
181
182
183




184










185
186
187
188
189
190
191
	display->proto_minor_version = [[cgVers objectAtIndex:2] integerValue];
    }
    if (!vendor[0]) {
	snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
		NSAppKitVersionNumber);
    }
    display->vendor = vendor;




    Gestalt(gestaltSystemVersion, (SInt32 *) &display->release);











    /*
     * These screen bits never change
     */
    screen->root	= ROOT_ID;
    screen->display	= display;
    screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;







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







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
	display->proto_minor_version = [[cgVers objectAtIndex:2] integerValue];
    }
    if (!vendor[0]) {
	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;
	patch = systemVersion.patchVersion;
#endif
	display->release = major << 16 | minor << 8 | patch;
    }

    /*
     * These screen bits never change
     */
    screen->root	= ROOT_ID;
    screen->display	= display;
    screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
886
887
888
889
890
891
892

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937


938
939
940
941
942
943











944
945
946
947
948
949
950
    int y,
    unsigned int width,
    unsigned int height,
    unsigned long plane_mask,
    int format)
{
    NSBitmapImageRep *bitmap_rep;

    XImage *       imagePtr = NULL;
    char *           bitmap = NULL;
    char *           image_data=NULL;
    int	        depth = 32;
    int	        offset = 0;
    int	        bitmap_pad = 0;
    int	        bytes_per_row = 4*width;
    int                size;
    TkMacOSXDbgMsg("XGetImage");
    if (format == ZPixmap) {
	if (width == 0 || height == 0) {
	    /* This happens all the time.
	    TkMacOSXDbgMsg("XGetImage: empty image requested");
	    */
	    return NULL;
	}

	bitmap_rep =  BitmapRepFromDrawableRect(d, x, y,width, height);


	if ( bitmap_rep == Nil                        ||
	     [bitmap_rep bitmapFormat] != 0    || 
	     [bitmap_rep samplesPerPixel] != 4 ||
	     [bitmap_rep isPlanar] != 0               ) {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
	    return NULL;
	}

	NSSize image_size = NSMakeSize(width, height);
	NSImage* ns_image = [[NSImage alloc]initWithSize:image_size];
	[ns_image addRepresentation:bitmap_rep];
 
	/* Assume premultiplied nonplanar data with 4 bytes per pixel and alpha last.*/
	if ( [bitmap_rep bitmapFormat] == 0 &&
	     [bitmap_rep isPlanar ] == 0 &&
	     [bitmap_rep samplesPerPixel] == 4 ) {
	    bytes_per_row = [bitmap_rep bytesPerRow];
	    size = bytes_per_row*height;
	    image_data = (char*)[bitmap_rep bitmapData];
	    if ( image_data ) {
		int row, n, m;
		bitmap = ckalloc(size);
		/*
		  Oddly enough, the bitmap has the top row at the beginning,
		  and the pixels are in BGRA format.
		*/


		for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
		    for (m=n; m<n+bytes_per_row; m+=4) {
			*(bitmap+m)     = *(image_data+m+2);
			*(bitmap+m+1) = *(image_data+m+1);
			*(bitmap+m+2) = *(image_data+m);
			*(bitmap+m+3) = *(image_data+m+3);











		    }
		}
	    }
	}
	if (bitmap) {
	    imagePtr = XCreateImage(display, NULL, depth, format, offset,
				    (char*)bitmap, width, height, bitmap_pad, bytes_per_row);







>


















>

|
|
|








|
|
<
|









|

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







900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
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
966
967
968
969
970
971
972
973
974
975
976
977
978
    int y,
    unsigned int width,
    unsigned int height,
    unsigned long plane_mask,
    int format)
{
    NSBitmapImageRep *bitmap_rep;
    NSUInteger         bitmap_fmt;
    XImage *       imagePtr = NULL;
    char *           bitmap = NULL;
    char *           image_data=NULL;
    int	        depth = 32;
    int	        offset = 0;
    int	        bitmap_pad = 0;
    int	        bytes_per_row = 4*width;
    int                size;
    TkMacOSXDbgMsg("XGetImage");
    if (format == ZPixmap) {
	if (width == 0 || height == 0) {
	    /* This happens all the time.
	    TkMacOSXDbgMsg("XGetImage: empty image requested");
	    */
	    return NULL;
	}

	bitmap_rep =  BitmapRepFromDrawableRect(d, x, y,width, height);
	bitmap_fmt = [bitmap_rep bitmapFormat];

	if ( bitmap_rep == Nil                     ||
	     (bitmap_fmt != 0 && bitmap_fmt != 1)  ||
	     [bitmap_rep samplesPerPixel] != 4     ||
	     [bitmap_rep isPlanar] != 0               ) {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
	    return NULL;
	}

	NSSize image_size = NSMakeSize(width, height);
	NSImage* ns_image = [[NSImage alloc]initWithSize:image_size];
	[ns_image addRepresentation:bitmap_rep];

	/* Assume premultiplied nonplanar data with 4 bytes per pixel.*/

	if ( [bitmap_rep isPlanar ] == 0 &&
	     [bitmap_rep samplesPerPixel] == 4 ) {
	    bytes_per_row = [bitmap_rep bytesPerRow];
	    size = bytes_per_row*height;
	    image_data = (char*)[bitmap_rep bitmapData];
	    if ( image_data ) {
		int row, n, m;
		bitmap = ckalloc(size);
		/*
		  Oddly enough, the bitmap has the top row at the beginning,
		  and the pixels are in BGRA or ABGR format.
		*/
		if (bitmap_fmt == 0) {
		    /* BGRA */
		    for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
			for (m=n; m<n+bytes_per_row; m+=4) {
			    *(bitmap+m)   = *(image_data+m+2);
			    *(bitmap+m+1) = *(image_data+m+1);
			    *(bitmap+m+2) = *(image_data+m);
			    *(bitmap+m+3) = *(image_data+m+3);
			}
		    }
		} else {
		    /* ABGR */
		    for (row=0, n=0; row<height; row++, n+=bytes_per_row) {
			for (m=n; m<n+bytes_per_row; m+=4) {
			    *(bitmap+m)   = *(image_data+m+3);
			    *(bitmap+m+1) = *(image_data+m+2);
			    *(bitmap+m+2) = *(image_data+m+1);
			    *(bitmap+m+3) = *(image_data+m);
			}
		    }
		}
	    }
	}
	if (bitmap) {
	    imagePtr = XCreateImage(display, NULL, depth, format, offset,
				    (char*)bitmap, width, height, bitmap_pad, bytes_per_row);

Changes to tests/bevel.tcl.

38
39
40
41
42
43
44

45
46
47
48
49
50
51
regions to exercise the bevel-drawing facilities of
DisplayLineBackground.  The letters have the following
significance:

r - should appear raised
u - should appear raised and also slightly offset vertically
s - should appear sunken

n - preceding relief should extend right to end of line.
* - should appear "normal"
x - extra long lines to allow horizontal scrolling.

Try scrolling the text both vertically and horizontally to
be sure that the bevels are still drawn correctly.








>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
regions to exercise the bevel-drawing facilities of
DisplayLineBackground.  The letters have the following
significance:

r - should appear raised
u - should appear raised and also slightly offset vertically
s - should appear sunken
S - should appear solid
n - preceding relief should extend right to end of line.
* - should appear "normal"
x - extra long lines to allow horizontal scrolling.

Try scrolling the text both vertically and horizontally to
be sure that the bevels are still drawn correctly.

121
122
123
124
125
126
127
128
129
130
131
132


133






134






135
136





137
138

139
    .t.t insert end rrrrr r1
}
.t.t insert end \n
.t.t insert end rrr r1
.t.t insert end *****
.t.t insert end rrr r1








































|
|
|
|
|
>
>

>
>
>
>
>
>

>
>
>
>
>
>
|

>
>
>
>
>
|

>

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
160
    .t.t insert end rrrrr r1
}
.t.t insert end \n
.t.t insert end rrr r1
.t.t insert end *****
.t.t insert end rrr r1

font configure TkFixedFont -size 20
.t.t tag configure sol100 -relief solid -borderwidth 100 \
                          -foreground red -font TkFixedFont
.t.t tag configure sol12 -relief solid -borderwidth 12 \
                          -foreground red -font TkFixedFont
.t.t tag configure big -font TkFixedFont
set ind [.t.t index end]

.t.t insert end "\n\nBorders do not leak on the neighbour chars"
.t.t insert end "\nOnly \"S\" is on dark background"
.t.t insert end {
 xxx
 x} {} S sol100 {x
 xxx}

.t.t insert end "\n\nA very thick border grows toward the inside of the tagged area only"
.t.t insert end "\nOnly \"S\" is on dark background"
.t.t insert end {
 xxxx} {} SSSSS sol100 {xxxx
 x} {} SSSSSSSSSSSSSSSSSS sol100 {x
 xxx} {} SSSSSSSSS sol100 xxxx {}
}

.t.t insert end "\n\nA thinner border is continuous"
.t.t insert end {
 xxxx} {} SSSSS sol12 {xxxx
 x} {} SSSSSSSSSSSSSSSSSS sol12 {x
 xxx} {} SSSSSSSSS sol12 xxxx {}
}

.t.t tag add big $ind end

Changes to tests/entry.test.

774
775
776
777
778
779
780








781
782
783
784
785
786
787
    lappend x [winfo reqwidth .e]
    .e configure -show ""
    lappend x [winfo reqwidth .e]
} [list \
    [expr 8+5*[font measure {helvetica 12} .]] \
    [expr 8+5*[font measure {helvetica 12} X]] \
    [expr 8+[font measure {helvetica 12} 12345]]]









catch {destroy .e}
entry .e -width 10 -font $fixed -textvariable contents -xscrollcommand scroll
pack .e
focus .e
test entry-7.1 {InsertChars procedure} {
    .e delete 0 end







>
>
>
>
>
>
>
>







774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
    lappend x [winfo reqwidth .e]
    .e configure -show ""
    lappend x [winfo reqwidth .e]
} [list \
    [expr 8+5*[font measure {helvetica 12} .]] \
    [expr 8+5*[font measure {helvetica 12} X]] \
    [expr 8+[font measure {helvetica 12} 12345]]]
test entry-6.12 {EntryComputeGeometry procedure} {fonts} {
    catch {destroy .e}
    entry .e -font $fixed -bd 2 -relief raised -width 20
    pack .e
    .e insert end "012\t456\t"
    update
    list [.e index @81] [.e index @82] [.e index @116] [.e index @117]
} {6 7 7 8}

catch {destroy .e}
entry .e -width 10 -font $fixed -textvariable contents -xscrollcommand scroll
pack .e
focus .e
test entry-7.1 {InsertChars procedure} {
    .e delete 0 end

Changes to tests/event.test.

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    set result
} {1.3 A 1.3 A}
test event-7.2(double-click) {A double click on a lone character\
	in an entry widget should select that character} {knownBug} {
    destroy .t
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    focus -force $e
    _keypress_string $e "On A letter"







|







701
702
703
704
705
706
707
708
709
710
711
712
713
714
715

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    set result
} {1.3 A 1.3 A}
test event-7.2(double-click) {A double click on a lone character\
	in an entry widget should select that character} {
    destroy .t
    set t [toplevel .t]
    set e [entry $t.e]
    pack $e
    tkwait visibility $e
    focus -force $e
    _keypress_string $e "On A letter"
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    set result
} {3 A 4 A}

# cleanup

destroy .t

unset -nocomplain keypress_lookup
rename _init_keypress_lookup {}







|







762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
    event generate $e <ButtonRelease-1> -x $right_x -y $right_y
    _pause 50

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    set result
} {4 A 4 A}

# cleanup

destroy .t

unset -nocomplain keypress_lookup
rename _init_keypress_lookup {}

Changes to tests/font.test.

825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
    set x {}
    .b.l config -text "000\t"
    lappend x [getsize]
    .b.l config -text "000\t00" -wrap [expr $ax*6]
    lappend x [getsize]
    .b.l config -wrap 0
    set x
} "{[expr $ax*3] $ay} {[expr $ax*3] [expr $ay*2]}"
test font-24.11 {Tk_ComputeTextLayout: absorb spaces at eol} {
    set x {}
    .b.l config -text "000            000" -wrap [expr $ax*5]
    lappend x [getsize]
    .b.l config -text "000            "
    lappend x [getsize]
    .b.l config -wrap 0







|







825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
    set x {}
    .b.l config -text "000\t"
    lappend x [getsize]
    .b.l config -text "000\t00" -wrap [expr $ax*6]
    lappend x [getsize]
    .b.l config -wrap 0
    set x
} "{[expr $ax*8] $ay} {[expr $ax*8] [expr $ay*2]}"
test font-24.11 {Tk_ComputeTextLayout: absorb spaces at eol} {
    set x {}
    .b.l config -text "000            000" -wrap [expr $ax*5]
    lappend x [getsize]
    .b.l config -text "000            "
    lappend x [getsize]
    .b.l config -wrap 0

Changes to tests/menu.test.

2561
2562
2563
2564
2565
2566
2567









2568
2569
2570
2571
2572
    catch {destroy .m}
    menu .m
    .m add command -label "File" -underline [expr {1<<30}]
    . configure -menu .m
    update
    tk::TraverseToMenu . "e"
} {}










# cleanup
deleteWindows
cleanupTests
return







>
>
>
>
>
>
>
>
>





2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
    catch {destroy .m}
    menu .m
    .m add command -label "File" -underline [expr {1<<30}]
    . configure -menu .m
    update
    tk::TraverseToMenu . "e"
} {}

test menu-37.1 {menubar menues cannot be posted - bug 2160206} {} {
    # On Linux the following used to panic
    # It now returns an error (on all platforms)
    catch {destroy .m}
    menu .m -type menubar
    list [catch ".m post 1 1" msg] $msg
} {1 {a menubar menu cannot be posted}}


# cleanup
deleteWindows
cleanupTests
return

Added tests/option.file3.





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
! This file is a sample option (resource) database used to test
! Tk's option-handling capabilities.

! Comment line \
  with a backslash-newline sequence embedded in it.

*x1: 	blue
	 tktest.x2		: green
*\
x3 \
  : pur\
ple
*x 4:	brówn
# More comments, this time delimited by hash-marks.
	# Comment-line with space.
*x6:	  
*x9: \ \	\\\101\n
# comment line as last line of file.

Changes to tests/option.test.

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
} {1 {wrong # args: should be "option get window name class"}}
test option-14.12 {error conditions} {
    list [catch {option get .gorp.gorp a A} msg] $msg
} {1 {bad window path name ".gorp.gorp"}}

set option1 [file join [testsDirectory] option.file1]
set option2 [file join [testsDirectory] option.file2]


test option-15.1 {database files} {
    list [catch {option read non-existent} msg] $msg
} {1 {couldn't open "non-existent": no such file or directory}}
option read $option1
test option-15.2 {database files} {option get . x1 color} blue
test option-15.3 {database files} appNameIsTktest {option get . x2 color} green
test option-15.4 {database files} {option get . x3 color} purple
test option-15.5 {database files} {option get . {x 4} color} brown
test option-15.6 {database files} {option get . x6 color} {}
test option-15.7 {database files} {option get . x9 color} " \t\\A\n"
test option-15.8 {database files} {
    list [catch {option read $option1 widget foo} msg] $msg
} {1 {wrong # args: should be "option readfile fileName ?priority?"}}
option add *x3 burgundy
catch {option read $option1 userDefault}
test option-15.9 {database files} {option get . x3 color} burgundy
test option-15.10 {database files} {
    list [catch {option read $option2} msg] $msg
} {1 {missing colon on line 2}}



test option-16.1 {ReadOptionFile} {
    set option3 [makeFile {} option.file3]
    set file [open $option3 w]
    fconfigure $file -translation crlf
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option3 userDefault
    set result [list [option get . x7 color] [option get . x8 color]]
    removeFile $option3
    set result
} {true false}

catch {destroy .op1}
catch {destroy .op2}

# cleanup
cleanupTests
return







>




















>
>


|
|



|

|









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
} {1 {wrong # args: should be "option get window name class"}}
test option-14.12 {error conditions} {
    list [catch {option get .gorp.gorp a A} msg] $msg
} {1 {bad window path name ".gorp.gorp"}}

set option1 [file join [testsDirectory] option.file1]
set option2 [file join [testsDirectory] option.file2]
set option3 [file join [testsDirectory] option.file3]

test option-15.1 {database files} {
    list [catch {option read non-existent} msg] $msg
} {1 {couldn't open "non-existent": no such file or directory}}
option read $option1
test option-15.2 {database files} {option get . x1 color} blue
test option-15.3 {database files} appNameIsTktest {option get . x2 color} green
test option-15.4 {database files} {option get . x3 color} purple
test option-15.5 {database files} {option get . {x 4} color} brown
test option-15.6 {database files} {option get . x6 color} {}
test option-15.7 {database files} {option get . x9 color} " \t\\A\n"
test option-15.8 {database files} {
    list [catch {option read $option1 widget foo} msg] $msg
} {1 {wrong # args: should be "option readfile fileName ?priority?"}}
option add *x3 burgundy
catch {option read $option1 userDefault}
test option-15.9 {database files} {option get . x3 color} burgundy
test option-15.10 {database files} {
    list [catch {option read $option2} msg] $msg
} {1 {missing colon on line 2}}
option read $option3
test option-15.11 {database files} {option get . {x 4} color} br\xf3wn

test option-16.1 {ReadOptionFile} {
    set option4 [makeFile {} option.file3]
    set file [open $option4 w]
    fconfigure $file -translation crlf
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option4 userDefault
    set result [list [option get . x7 color] [option get . x8 color]]
    removeFile $option4
    set result
} {true false}

catch {destroy .op1}
catch {destroy .op2}

# cleanup
cleanupTests
return

Changes to tests/text.test.

741
742
743
744
745
746
747




748
749
750
751
752
753
754
} -body {
    for {set i 1} {$i < 25} {incr i} {
        .t insert end "Line $i\n"
    }
    .t tag configure hidden -elide true
    .t tag add hidden 5.7 11.0
    update




    set y1 [lindex [.t yview] 1]
    .t count -displaylines 5.0 11.0
    set y2 [lindex [.t yview] 1]
    .t count -displaylines 5.0 12.0
    set y3 [lindex [.t yview] 1]
    list [expr {$y1 == $y2}] [expr {$y1 == $y3}]
} -result {1 1}







>
>
>
>







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
} -body {
    for {set i 1} {$i < 25} {incr i} {
        .t insert end "Line $i\n"
    }
    .t tag configure hidden -elide true
    .t tag add hidden 5.7 11.0
    update
    # next line to be fully sure that asynchronous line heights calculation is
    # up-to-date otherwise this test may fail (depending on the computer
    # performance), especially when the . toplevel has small height
    .t count -update -ypixels 1.0 end
    set y1 [lindex [.t yview] 1]
    .t count -displaylines 5.0 11.0
    set y2 [lindex [.t yview] 1]
    .t count -displaylines 5.0 12.0
    set y3 [lindex [.t yview] 1]
    list [expr {$y1 == $y2}] [expr {$y1 == $y3}]
} -result {1 1}

Changes to tests/textDisp.test.

4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
} {ok}
test textDisp-33.2 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 1]
    after 100 ; update
    # Nothing should have been recalculated.
    set tk_textHeightCalc
} {}
test textDisp-33.3 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1







|







4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
} {ok}
test textDisp-33.2 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 1]
    after 100 ; update idletasks
    # Nothing should have been recalculated.
    set tk_textHeightCalc
} {}
test textDisp-33.3 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
4180
4181
4182
4183
4184
4185
4186
















4187
4188
4189
4190
4191
4192
4193
4194
    lappend result [.sy get]
    after 0 {lappend result [.sy get]}
    after 1000 {lappend result [.sy get]}
    vwait result;vwait result
    return $result
} -cleanup {
    destroy .t1 .sy
















} -result {{0.0 1.0} {0.0 1.0} {0.0 1.0} {0.0 0.24}}

deleteWindows
option clear

# cleanup
cleanupTests
return







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







4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
    lappend result [.sy get]
    after 0 {lappend result [.sy get]}
    after 1000 {lappend result [.sy get]}
    vwait result;vwait result
    return $result
} -cleanup {
    destroy .t1 .sy
} -result {{0.0 0.24} {0.0 0.24} {0.0 0.24} {0.0 0.24}}

test textDisp-35.1 {Init value of charHeight - Dancing scrollbar bug 1499165} -setup {
    pack [text .t1] -fill both -expand y -side left
    .t insert end "[string repeat a\nb\nc\n 500000]THE END\n"
    set res {}
} -body {
    .t see 10000.0
    after 300 {set fr1 [.t yview] ; set done 1}
    vwait done
    after 300 {set fr2 [.t yview] ; set done 1}
    vwait done
    lappend res [expr {[lindex $fr1 0] == [lindex $fr2 0]}]
    lappend res [expr {[lindex $fr1 1] == [lindex $fr2 1]}]
} -cleanup {
    destroy .t1
} -result {1 1}

deleteWindows
option clear

# cleanup
cleanupTests
return

Changes to unix/configure.

7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096

    if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then

        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        if test "${SHLIB_SUFFIX}" = ".dll"; then

            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"

else

            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'

fi







|







7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096

    if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then

        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        if test "${SHLIB_SUFFIX}" = ".dll"; then

            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)";if test -f $(LIB_FILE).a; then $(INSTALL_DATA) $(LIB_FILE).a "$(LIB_INSTALL_DIR)"; fi;'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"

else

            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'

fi
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
/usr/local/x11r5/include
/usr/lpp/Xamples/include

/usr/openwin/include
/usr/openwin/share/include'

if test "$ac_x_includes" = no; then
  # Guess where to find include files, by looking for Intrinsic.h.
  # First, try using that file with no special directory specified.
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <X11/Intrinsic.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5







|







|







10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
/usr/local/x11r5/include
/usr/lpp/Xamples/include

/usr/openwin/include
/usr/openwin/share/include'

if test "$ac_x_includes" = no; then
  # Guess where to find include files, by looking for Xlib.h.
  # First, try using that file with no special directory specified.
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <X11/Xlib.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
  # We can compile using X headers with no special include directory.
ac_x_includes=
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

  for ac_dir in $ac_x_header_dirs; do
  if test -r "$ac_dir/X11/Intrinsic.h"; then
    ac_x_includes=$ac_dir
    break
  fi
done
fi
rm -f conftest.err conftest.$ac_ext
fi # $ac_x_includes = no

if test "$ac_x_libraries" = no; then
  # Check for the libraries.
  # See if we find them without any special options.
  # Don't add to $LIBS permanently.
  ac_save_LIBS=$LIBS
  LIBS="-lXt $LIBS"
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <X11/Intrinsic.h>
int
main ()
{
XtMalloc (0)
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>conftest.er1







|













|






|



|







10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
  # We can compile using X headers with no special include directory.
ac_x_includes=
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

  for ac_dir in $ac_x_header_dirs; do
  if test -r "$ac_dir/X11/Xlib.h"; then
    ac_x_includes=$ac_dir
    break
  fi
done
fi
rm -f conftest.err conftest.$ac_ext
fi # $ac_x_includes = no

if test "$ac_x_libraries" = no; then
  # Check for the libraries.
  # See if we find them without any special options.
  # Don't add to $LIBS permanently.
  ac_save_LIBS=$LIBS
  LIBS="-lX11 $LIBS"
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <X11/Xlib.h>
int
main ()
{
XrmInitialize ()
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>conftest.er1

Changes to unix/tcl.m4.

2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
	UNSHARED_LIB_SUFFIX='${VERSION}.a'])
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"

    AS_IF([test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""], [
        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        AS_IF([test "${SHLIB_SUFFIX}" = ".dll"], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
        ], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
        ])
    ], [
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}








|







2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
	UNSHARED_LIB_SUFFIX='${VERSION}.a'])
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"

    AS_IF([test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""], [
        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        AS_IF([test "${SHLIB_SUFFIX}" = ".dll"], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)";if test -f $(LIB_FILE).a; then $(INSTALL_DATA) $(LIB_FILE).a "$(LIB_INSTALL_DIR)"; fi;'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
        ], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
        ])
    ], [
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}

Changes to unix/tkUnixEmbed.c.

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
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    CONST char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    int id, anyError;
    Window parent;
    Tk_ErrorHandler handler;
    Container *containerPtr;
    XWindowAttributes parentAtts;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window != None) {
	Tcl_AppendResult(interp,
		"can't modify container after widget is created", NULL);
	return TCL_ERROR;
    }
    if (Tcl_GetInt(interp, string, &id) != TCL_OK) {
	return TCL_ERROR;
    }
    parent = (Window) id;

    usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, parent);
    if (usePtr != NULL) {
	if (!(usePtr->flags & TK_CONTAINER)) {
	    Tcl_AppendResult(interp, "window \"", usePtr->pathName,
                    "\" doesn't have -container option set", NULL);
	    return TCL_ERROR;







|












|


<







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
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    CONST char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    int anyError;
    Window parent;
    Tk_ErrorHandler handler;
    Container *containerPtr;
    XWindowAttributes parentAtts;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window != None) {
	Tcl_AppendResult(interp,
		"can't modify container after widget is created", NULL);
	return TCL_ERROR;
    }
    if (TkpScanWindowId(interp, string, &parent) != TCL_OK) {
	return TCL_ERROR;
    }


    usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, parent);
    if (usePtr != NULL) {
	if (!(usePtr->flags & TK_CONTAINER)) {
	    Tcl_AppendResult(interp, "window \"", usePtr->pathName,
                    "\" doesn't have -container option set", NULL);
	    return TCL_ERROR;

Changes to unix/tkUnixXId.c.

582
583
584
585
586
587
588
589

590




591

592


593
594


595
596
597
598
599
600
601
602

int
TkpScanWindowId(
    Tcl_Interp *interp,
    CONST char *string,
    Window *idPtr)
{
    int value;






    if (Tcl_GetInt(interp, string, &value) != TCL_OK) {

	return TCL_ERROR;


    }
    *idPtr = (Window) value;


    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78







|
>

>
>
>
>
|
>
|
>
>

|
>
>
|







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

int
TkpScanWindowId(
    Tcl_Interp *interp,
    CONST char *string,
    Window *idPtr)
{
    int code;
    Tcl_Obj obj;

    obj.refCount = 1;
    obj.bytes = (char *) string;	/* DANGER?! */
    obj.length = strlen(string);
    obj.typePtr = NULL;

    code = Tcl_GetLongFromObj(interp, &obj, (long *)idPtr);

    if (obj.refCount > 1) {
	Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
    }
    if (obj.typePtr && obj.typePtr->freeIntRepProc) {
	obj.typePtr->freeIntRepProc(&obj);
    }
    return code;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78

Changes to win/nmakehlp.c.

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
	/*
	 * Build a list of substutitions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
		char *ks, *ke, *vs, *ve;
		ks = szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, ks, vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifdef _DEBUG
	{







|
|








|







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
	/*
	 * Build a list of substutitions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
		unsigned char *ks, *ke, *vs, *ve;
		ks = (unsigned char*)szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, (char*)ks, (char*)vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifdef _DEBUG
	{

Changes to win/tkWinEmbed.c.

252
253
254
255
256
257
258




259
260
261
262
263
264
265
266
267
268
269
    if (strcmp(string, "") == 0) {
	if (winPtr->flags & TK_EMBEDDED) {
	    Tk_DetachEmbeddedWindow(winPtr, TRUE);
	}
	return TCL_OK;
    }





    if (Tcl_GetInt(interp, string, &id) != TCL_OK) {
	return TCL_ERROR;
    }
    hwnd = (HWND) INT2PTR(id);
    if ((HWND)winPtr->privatePtr == hwnd) {
	return TCL_OK;
    }

    /*
     * Check if the window is a valid handle. If it is invalid, return
     * TCL_ERROR and potentially leave an error message in the interp's







>
>
>
>
|


<







252
253
254
255
256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
    if (strcmp(string, "") == 0) {
	if (winPtr->flags & TK_EMBEDDED) {
	    Tk_DetachEmbeddedWindow(winPtr, TRUE);
	}
	return TCL_OK;
    }

    if (
#ifdef _WIN64
	    (sscanf(string, "0x%p", &hwnd) != 1) &&
#endif
	    Tcl_GetInt(interp, string, (int *) &hwnd) != TCL_OK) {
	return TCL_ERROR;
    }

    if ((HWND)winPtr->privatePtr == hwnd) {
	return TCL_OK;
    }

    /*
     * Check if the window is a valid handle. If it is invalid, return
     * TCL_ERROR and potentially leave an error message in the interp's

Changes to win/ttkWinXPTheme.c.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) { return TCL_OK; }
#else

#define WINVER 0x0501	/* Requires Windows XP APIs */

#include <windows.h>
#include <uxtheme.h>
#ifdef HAVE_VSSYM32_H
#   include <vssym32.h>
#else
#   include <tmschema.h>
#endif

#include <tkWinInt.h>








|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) { return TCL_OK; }
#else

#define WINVER 0x0501	/* Requires Windows XP APIs */

#include <windows.h>
#include <uxtheme.h>
#if defined(HAVE_VSSYM32_H) || _MSC_VER > 1500
#   include <vssym32.h>
#else
#   include <tmschema.h>
#endif

#include <tkWinInt.h>