Tk Source Code

Changes On Branch bug-502e74e9ad
Login

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

Changes In Branch bug-502e74e9ad Excluding Merge-Ins

This is equivalent to a diff from 745b4344 to 5cc6bb16

2018-02-11
12:01
Fix [502e74e9ad]: crash for untrusted X connections (for ssh: ForwardX11Trusted no). Patches from Christian Werner. check-in: 3b83c2a9 user: fvogel tags: core-8-6-branch
2018-02-03
15:07
Fix [9d27218f76]: ttk::spinbox doc page mentions current, but it is not a valid command check-in: 35639ec2 user: fvogel tags: core-8-6-branch
2018-01-31
17:48
Implementation of TIP #496 - Display hints in ::ttk::entry (by RenĂ© Zaumseil) check-in: 7fc7849e user: fvogel tags: tip-496
07:28
Remove superfluous blank line Closed-Leaf check-in: 5cc6bb16 user: fvogel tags: bug-502e74e9ad
07:25
Patch refinement from Christian Werner. It is now possible to 'make test' with an untrusted X connection without being stopped by X errors (and of course with more failures due to the untrusted connection). check-in: fc243f37 user: fvogel tags: bug-502e74e9ad
2018-01-29
21:32
Fix [502e74e9ad]: crash for untrusted X connections (for ssh: ForwardX11Trusted no). Patch from Christian Werner. check-in: 3c7f220c user: fvogel tags: bug-502e74e9ad
07:16
Fix [71b1319acc]: Regression in tkUnixRFont.c. Patch from Christian Werner. check-in: a16ed2d0 user: fvogel tags: bug-71b1319acc
2018-01-28
22:00
merge core-8-6-branch ([e20d5ca7cd] - textTag-18.1 fails on OS X - was already fixed in trunk) check-in: db04f1ae user: fvogel tags: trunk
21:57
Fix [e20d5ca7cd]: textTag-18.1 fails on OS X check-in: 745b4344 user: fvogel tags: core-8-6-branch
21:20
Fix indentation that was lost in [f057be0817] check-in: 776de100 user: fvogel tags: core-8-6-branch

Changes to generic/tkCmds.c.

97
98
99
100
101
102
103

104
105
106
107
108
109
110
{
    static const char *const bellOptions[] = {
	"-displayof", "-nice", NULL
    };
    enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE };
    Tk_Window tkwin = clientData;
    int i, index, nice = 0;


    if (objc > 4) {
    wrongArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?-nice?");
	return TCL_ERROR;
    }








>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
{
    static const char *const bellOptions[] = {
	"-displayof", "-nice", NULL
    };
    enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE };
    Tk_Window tkwin = clientData;
    int i, index, nice = 0;
    Tk_ErrorHandler handler;

    if (objc > 4) {
    wrongArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?-nice?");
	return TCL_ERROR;
    }

124
125
126
127
128
129
130

131
132
133
134
135

136
137
138
139
140
141
142
	    }
	    break;
	case TK_BELL_NICE:
	    nice = 1;
	    break;
	}
    }

    XBell(Tk_Display(tkwin), 0);
    if (!nice) {
	XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset);
    }
    XFlush(Tk_Display(tkwin));

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







>





>







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
	    }
	    break;
	case TK_BELL_NICE:
	    nice = 1;
	    break;
	}
    }
    handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, NULL, NULL);
    XBell(Tk_Display(tkwin), 0);
    if (!nice) {
	XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset);
    }
    XFlush(Tk_Display(tkwin));
    Tk_DeleteErrorHandler(handler);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_BindObjCmd --

Changes to unix/tkUnixSend.c.

257
258
259
260
261
262
263

264
265
266
267


268
269
270
271
272
273
274
				 * use the registry until we close it. */
{
    NameRegistry *regPtr;
    int result, actualFormat;
    unsigned long bytesAfter;
    Atom actualType;
    char **propertyPtr;


    if (dispPtr->commTkwin == NULL) {
	SendInit(interp, dispPtr);
    }



    regPtr = ckalloc(sizeof(NameRegistry));
    regPtr->dispPtr = dispPtr;
    regPtr->locked = 0;
    regPtr->modified = 0;
    regPtr->allocedByX = 1;
    propertyPtr = &regPtr->property;







>




>
>







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
				 * use the registry until we close it. */
{
    NameRegistry *regPtr;
    int result, actualFormat;
    unsigned long bytesAfter;
    Atom actualType;
    char **propertyPtr;
    Tk_ErrorHandler handler;

    if (dispPtr->commTkwin == NULL) {
	SendInit(interp, dispPtr);
    }

    handler = Tk_CreateErrorHandler(dispPtr->display, -1, -1, -1, NULL, NULL);

    regPtr = ckalloc(sizeof(NameRegistry));
    regPtr->dispPtr = dispPtr;
    regPtr->locked = 0;
    regPtr->modified = 0;
    regPtr->allocedByX = 1;
    propertyPtr = &regPtr->property;
302
303
304
305
306
307
308

309


310
311
312
313
314
315
316
	    XFree(regPtr->property);
	    regPtr->propLength = 0;
	    regPtr->property = NULL;
	}
	XDeleteProperty(dispPtr->display,
		RootWindow(dispPtr->display, 0),
		dispPtr->registryProperty);

    }



    /*
     * Xlib placed an extra null byte after the end of the property, just to
     * make sure that it is always NULL-terminated. Be sure to include this
     * byte in our count if it's needed to ensure null termination (note: as
     * of 8/95 I'm no longer sure why this code is needed; seems like it
     * shouldn't be).







>

>
>







305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
	    XFree(regPtr->property);
	    regPtr->propLength = 0;
	    regPtr->property = NULL;
	}
	XDeleteProperty(dispPtr->display,
		RootWindow(dispPtr->display, 0),
		dispPtr->registryProperty);
        XSync(dispPtr->display, False);
    }

    Tk_DeleteErrorHandler(handler);

    /*
     * Xlib placed an extra null byte after the end of the property, just to
     * make sure that it is always NULL-terminated. Be sure to include this
     * byte in our count if it's needed to ensure null termination (note: as
     * of 8/95 I'm no longer sure why this code is needed; seems like it
     * shouldn't be).
510
511
512
513
514
515
516





517
518
519
520
521
522
523
 */

static void
RegClose(
    NameRegistry *regPtr)	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
{





    if (regPtr->modified) {
	if (!regPtr->locked && !localData.sendDebug) {
	    Tcl_Panic("The name registry was modified without being locked!");
	}
	XChangeProperty(regPtr->dispPtr->display,
		RootWindow(regPtr->dispPtr->display, 0),
		regPtr->dispPtr->registryProperty, XA_STRING, 8,







>
>
>
>
>







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
 */

static void
RegClose(
    NameRegistry *regPtr)	/* Pointer to a registry opened with a
				 * previous call to RegOpen. */
{
    Tk_ErrorHandler handler;

    handler = Tk_CreateErrorHandler(regPtr->dispPtr->display, -1, -1, -1,
            NULL, NULL);

    if (regPtr->modified) {
	if (!regPtr->locked && !localData.sendDebug) {
	    Tcl_Panic("The name registry was modified without being locked!");
	}
	XChangeProperty(regPtr->dispPtr->display,
		RootWindow(regPtr->dispPtr->display, 0),
		regPtr->dispPtr->registryProperty, XA_STRING, 8,
535
536
537
538
539
540
541


542
543
544
545
546
547
548
     * might do something else that needs to communicate with the server (such
     * as invoking a subprocess that needs to do I/O to the screen); if the
     * ungrab command is still sitting in our output buffer, we could
     * deadlock.
     */

    XFlush(regPtr->dispPtr->display);



    if (regPtr->property != NULL) {
	if (regPtr->allocedByX) {
	    XFree(regPtr->property);
	} else {
	    ckfree(regPtr->property);
	}







>
>







546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
     * might do something else that needs to communicate with the server (such
     * as invoking a subprocess that needs to do I/O to the screen); if the
     * ungrab command is still sitting in our output buffer, we could
     * deadlock.
     */

    XFlush(regPtr->dispPtr->display);

    Tk_DeleteErrorHandler(handler);

    if (regPtr->property != NULL) {
	if (regPtr->allocedByX) {
	    XFree(regPtr->property);
	} else {
	    ckfree(regPtr->property);
	}
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
    }
    Tcl_DStringAppend(&request, "\0-s ", 4);
    Tcl_DStringAppend(&request, Tcl_GetString(objv[firstArg]), -1);
    for (i = firstArg+1; i < objc; i++) {
	Tcl_DStringAppend(&request, " ", 1);
	Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), -1);
    }

























    (void) AppendPropCarefully(dispPtr->display, commWindow,
	    dispPtr->commProperty, Tcl_DStringValue(&request),
	    Tcl_DStringLength(&request) + 1, (async ? NULL : &pending));
    Tcl_DStringFree(&request);
    if (async) {
	/*
	 * This is an asynchronous send: return immediately without waiting
	 * for a response.
	 */

	return TCL_OK;
    }

    /*
     * Register the fact that we're waiting for a command to complete (this is
     * needed by SendEventProc and by AppendErrorProc to pass back the
     * command's results). Set up a timeout handler so that we can check
     * during long sends to make sure that the destination application is
     * still alive.
     */

    pending.serial = localData.sendSerial;
    pending.dispPtr = dispPtr;
    pending.target = destName;
    pending.commWindow = commWindow;
    pending.interp = interp;
    pending.result = NULL;
    pending.errorInfo = NULL;
    pending.errorCode = NULL;
    pending.gotResponse = 0;
    pending.nextPtr = tsdPtr->pendingCommands;
    tsdPtr->pendingCommands = &pending;

    /*
     * Enter a loop processing X events until the result comes in or the
     * target is declared to be dead. While waiting for a result, look only at
     * send-related events so that the send is synchronous with respect to
     * other events in the application.
     */








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













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







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
    }
    Tcl_DStringAppend(&request, "\0-s ", 4);
    Tcl_DStringAppend(&request, Tcl_GetString(objv[firstArg]), -1);
    for (i = firstArg+1; i < objc; i++) {
	Tcl_DStringAppend(&request, " ", 1);
	Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), -1);
    }

    if (!async) {
	/*
	 * Register the fact that we're waiting for a command to complete
	 * (this is needed by SendEventProc and by AppendErrorProc to pass
	 * back the command's results). Set up a timeout handler so that
	 * we can check during long sends to make sure that the destination
	 * application is still alive.
	 *
	 * We prepare the pending struct here in order to catch potential
	 * early X errors from AppendPropCarefully() due to XSync().
	 */

	pending.serial = localData.sendSerial;
	pending.dispPtr = dispPtr;
	pending.target = destName;
	pending.commWindow = commWindow;
	pending.interp = interp;
	pending.result = NULL;
	pending.errorInfo = NULL;
	pending.errorCode = NULL;
	pending.gotResponse = 0;
	pending.nextPtr = tsdPtr->pendingCommands;
	tsdPtr->pendingCommands = &pending;
    }
    (void) AppendPropCarefully(dispPtr->display, commWindow,
	    dispPtr->commProperty, Tcl_DStringValue(&request),
	    Tcl_DStringLength(&request) + 1, (async ? NULL : &pending));
    Tcl_DStringFree(&request);
    if (async) {
	/*
	 * This is an asynchronous send: return immediately without waiting
	 * for a response.
	 */

	return TCL_OK;
    }





















    /*
     * Enter a loop processing X events until the result comes in or the
     * target is declared to be dead. While waiting for a result, look only at
     * send-related events so that the send is synchronous with respect to
     * other events in the application.
     */

1947
1948
1949
1950
1951
1952
1953

1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966


1967
1968
1969
1970
1971

1972
1973
1974
1975
1976
1977
1978
    enum {
	TESTSEND_BOGUS, TESTSEND_PROP, TESTSEND_SERIAL
    };
    static const char *const testsendOptions[] = {
	"bogus",   "prop",   "serial",  NULL
    };
    TkWindow *winPtr = clientData;

    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"option ?arg ...?");
	return TCL_ERROR;
    }

	if (Tcl_GetIndexFromObjStruct(interp, objv[1], testsendOptions,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == TESTSEND_BOGUS) {


	XChangeProperty(winPtr->dispPtr->display,
		RootWindow(winPtr->dispPtr->display, 0),
		winPtr->dispPtr->registryProperty, XA_INTEGER, 32,
		PropModeReplace,
		(unsigned char *) "This is bogus information", 6);

    } else if (index == TESTSEND_PROP) {
	int result, actualFormat;
	unsigned long length, bytesAfter;
	Atom actualType, propName;
	char *property, **propertyPtr = &property, *p, *end;
	Window w;








>








|

|
|
|
>
>





>







1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
    enum {
	TESTSEND_BOGUS, TESTSEND_PROP, TESTSEND_SERIAL
    };
    static const char *const testsendOptions[] = {
	"bogus",   "prop",   "serial",  NULL
    };
    TkWindow *winPtr = clientData;
    Tk_ErrorHandler handler;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], testsendOptions,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == TESTSEND_BOGUS) {
        handler = Tk_CreateErrorHandler(winPtr->dispPtr->display, -1, -1, -1,
                NULL, NULL);
	XChangeProperty(winPtr->dispPtr->display,
		RootWindow(winPtr->dispPtr->display, 0),
		winPtr->dispPtr->registryProperty, XA_INTEGER, 32,
		PropModeReplace,
		(unsigned char *) "This is bogus information", 6);
        Tk_DeleteErrorHandler(handler);
    } else if (index == TESTSEND_PROP) {
	int result, actualFormat;
	unsigned long length, bytesAfter;
	Atom actualType, propName;
	char *property, **propertyPtr = &property, *p, *end;
	Window w;

2003
2004
2005
2006
2007
2008
2009


2010

2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021

2022
2023
2024

2025
2026
2027
2028
2029
2030
2031
		}
		Tcl_SetObjResult(interp, Tcl_NewStringObj(property, -1));
	    }
	    if (property != NULL) {
		XFree(property);
	    }
	} else if (Tcl_GetString(objv[4])[0] == 0) {


	    XDeleteProperty(winPtr->dispPtr->display, w, propName);

	} else {
	    Tcl_DString tmp;

	    Tcl_DStringInit(&tmp);
	    for (p = Tcl_DStringAppend(&tmp, Tcl_GetString(objv[4]),
		    (int) strlen(Tcl_GetString(objv[4]))); *p != 0; p++) {
		if (*p == '\n') {
		    *p = 0;
		}
	    }


	    XChangeProperty(winPtr->dispPtr->display, w, propName, XA_STRING,
		    8, PropModeReplace, (unsigned char*)Tcl_DStringValue(&tmp),
		    p-Tcl_DStringValue(&tmp));

	    Tcl_DStringFree(&tmp);
	}
    } else if (index == TESTSEND_SERIAL) {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(localData.sendSerial+1));
    }
    return TCL_OK;
}







>
>

>










|
>



>







2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
		}
		Tcl_SetObjResult(interp, Tcl_NewStringObj(property, -1));
	    }
	    if (property != NULL) {
		XFree(property);
	    }
	} else if (Tcl_GetString(objv[4])[0] == 0) {
            handler = Tk_CreateErrorHandler(winPtr->dispPtr->display,
                    -1, -1, -1, NULL, NULL);
	    XDeleteProperty(winPtr->dispPtr->display, w, propName);
            Tk_DeleteErrorHandler(handler);
	} else {
	    Tcl_DString tmp;

	    Tcl_DStringInit(&tmp);
	    for (p = Tcl_DStringAppend(&tmp, Tcl_GetString(objv[4]),
		    (int) strlen(Tcl_GetString(objv[4]))); *p != 0; p++) {
		if (*p == '\n') {
		    *p = 0;
		}
	    }
            handler = Tk_CreateErrorHandler(winPtr->dispPtr->display,
                    -1, -1, -1, NULL, NULL);
	    XChangeProperty(winPtr->dispPtr->display, w, propName, XA_STRING,
		    8, PropModeReplace, (unsigned char*)Tcl_DStringValue(&tmp),
		    p-Tcl_DStringValue(&tmp));
            Tk_DeleteErrorHandler(handler);
	    Tcl_DStringFree(&tmp);
	}
    } else if (index == TESTSEND_SERIAL) {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(localData.sendSerial+1));
    }
    return TCL_OK;
}