[George Peter Staplin]: This is a nice example for those of you that have an existing Xt program and want to add Tk. This could also be a solution for those of you that have existing custom Xt widgets, and want to use Tk widgets as well. I place the code below in the public domain. Use it however you want: ---- #include #include #include #include #include #include #include #include #include #include #include Tcl_Interp *interp; Display *dis; int screen; #define winIdLength 20 void PressMe () { fprintf (stderr, "You pressed me.\n"); } void Action () { fprintf (stderr, "Now I'm going to exit.\n"); exit (0); } void addTkToplevelToXtBox (char *winName, Widget parent) { char *tCmd; tCmd = (char *) malloc (sizeof ("toplevel ") + sizeof (*winName) + sizeof (" -use ") + (sizeof (char) * winIdLength) + (sizeof (char) * 2)); sprintf (tCmd, "%s%s%s%d", "toplevel ", winName, " -use ", XtWindow (parent)); if (Tcl_Eval (interp, tCmd) != TCL_OK) { fprintf (stderr, "Error evaluating tCmd within addTkToplevelToXtBoxCmd() %s", Tcl_GetStringResult (interp)); } free (tCmd); } Widget addXtBox (char *wClass, Widget wParent) { return (XtVaCreateManagedWidget ( wClass, boxWidgetClass, wParent, NULL, 0)); } void makeXtBoxFitToplevel (Widget wid, char *winName) { Tk_Window twin = Tk_NameToWindow (interp, winName, Tk_MainWindow (interp)); Tcl_Eval (interp, "update idletasks"); XtResizeWidget (wid, Tk_Width (twin), Tk_Height (twin), 1); XFlush (dis); } int main (int argc, char *argv[]) { Widget win, button; Widget testButton; Widget buttonShell; Widget xtBox2; Widget entry; int i = 1; XEvent event; XtAppContext appContext; char entryBuffer; Tcl_FindExecutable (argv[0]); interp = Tcl_CreateInterp (); if (Tcl_Init (interp) != TCL_OK) { fprintf (stderr, "Tcl_Init error"); exit (1); } if (Tk_Init (interp) != TCL_OK) { fprintf (stderr, "Tk_Init error"); exit (1); } win = XtVaAppInitialize( &appContext, "mainWindow", NULL, 0, &argc, argv, NULL, 0); dis = XtDisplay (win); screen = DefaultScreen (dis); buttonShell = addXtBox ("mainPanel", win); testButton = XtVaCreateManagedWidget ( "Press Me", commandWidgetClass, buttonShell, NULL, 0); button = XtVaCreateManagedWidget ( "Exit", commandWidgetClass, buttonShell, NULL, 0); xtBox2 = addXtBox ("xtBox2", buttonShell); entry = XtVaCreateManagedWidget ( "entry", asciiTextWidgetClass, buttonShell, XtNtype, XawAsciiString, XtNlength, sizeof (entryBuffer), XtNeditType, XawtextEdit, NULL, 0) ; XtRealizeWidget (win); XtAddCallback (button, XtNcallback, Action, 0); XtAddCallback (testButton, XtNcallback, PressMe, 0); XtResizeWidget (win, 400, 400, 1); /*This MUST be here:*/ XFlush (dis); addTkToplevelToXtBox (".t", xtBox2); if (Tcl_EvalFile (interp, "test_script") != TCL_OK) { fprintf (stderr, "Tcl_EvalFile error %s", Tcl_GetStringResult (interp)); } makeXtBoxFitToplevel (xtBox2, ".t"); { fd_set readfds; struct timeval timeout; int nfds; int tkFd = ConnectionNumber (Tk_Display (Tk_MainWindow (interp))); int xtFd = ConnectionNumber (XtDisplay (win)); for (;;) { FD_ZERO (&readfds); FD_SET (tkFd, &readfds); FD_SET (xtFd, &readfds); timeout.tv_sec = 0; timeout.tv_usec = 900000; select (nfds, &readfds, NULL, NULL, &timeout); while (XtAppPending (appContext) > 0) { XtAppNextEvent (appContext, &event); XtDispatchEvent (&event); } while (Tk_DoOneEvent (TCL_DONT_WAIT)) ; } } return (0); } ---- The source code above invokes Tcl_EvalFile on test_script, which in this case looks like the code below: ---- wm withdraw . pack [button .t.b -text Hello -command {puts Hello}] pack [listbox .t.l] pack [button .t.b2 -text {Can you see me?} -command {.t.l insert end Yes}] -fill x .t.l insert end {John Doe} {Jane Doe} ---- Download a working example here (Linux users add -ldl to the Makefile): http://www.xmission.com/~georgeps/TclTk_With_Xt4.tgz Note: You may need to change -ltcl83 and -ltk83 using a scheme like -ltcl8.3, depending on the name of your libtcl and libtk libraries. It looks like this: [http://www.xmission.com/~georgeps/TclTk_With_Xt.png] ----