Index: tclTimer.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclTimer.c,v
retrieving revision 1.33
diff -b -u -r1.33 tclTimer.c
--- tclTimer.c	13 Jun 2008 05:45:14 -0000	1.33
+++ tclTimer.c	3 Jul 2008 09:18:34 -0000
@@ -787,9 +787,9 @@
     int index;
     char buf[16 + TCL_INTEGER_SPACE];
     static CONST char *afterSubCmds[] = {
-	"cancel", "idle", "info", NULL
+	"cancel", "idle", "info", "next", "xinfo", NULL
     };
-    enum afterSubCmds {AFTER_CANCEL, AFTER_IDLE, AFTER_INFO};
+    enum afterSubCmds {AFTER_CANCEL, AFTER_IDLE, AFTER_INFO, AFTER_NEXT, AFTER_XINFO};
     ThreadSpecificData *tsdPtr = InitTimer();
 
     if (objc < 2) {
@@ -826,7 +826,7 @@
 	if (Tcl_GetWideIntFromObj(NULL, objv[1], &ms) != TCL_OK) {
 	    Tcl_AppendResult(interp, "bad argument \"",
 			     Tcl_GetString(objv[1]),
-			     "\": must be cancel, idle, info, or an integer",
+			     "\": must be cancel, idle, info, next, xinfo, or an integer",
 			     NULL);
 	    return TCL_ERROR;
 	}
@@ -972,6 +972,57 @@
 	Tcl_SetObjResult(interp, resultListPtr);
 	break;
     }
+    case AFTER_NEXT: {
+	TimerHandler *timerHandlerPtr;
+	Tcl_Time now;
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "");
+	    return TCL_ERROR;
+	}
+	timerHandlerPtr = tsdPtr->firstTimerHandlerPtr;
+	if (!timerHandlerPtr) {
+	    ms=-1;
+	} else {
+	    Tcl_GetTime(&now);
+	    ms = TCL_TIME_DIFF_MS(timerHandlerPtr->time,now);
+#ifndef TCL_WIDE_INT_IS_LONG
+	    if (ms > LONG_MAX) {
+		ms = LONG_MAX;
+	    }
+#endif
+	}
+	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(ms));
+	break;
+    }
+    case AFTER_XINFO: {
+	Tcl_Obj *resultListPtr;
+	TimerHandler *timerHandlerPtr;
+	Tcl_Time now;
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "");
+	    return TCL_ERROR;
+	}
+	Tcl_GetTime(&now);
+	resultListPtr = Tcl_NewObj();
+	for(timerHandlerPtr = tsdPtr->firstTimerHandlerPtr;timerHandlerPtr;timerHandlerPtr=timerHandlerPtr->nextPtr)    {
+		/* hide fileevent-originated [after 0] */
+		if (timerHandlerPtr->proc==AfterProc) {
+
+			ms = TCL_TIME_DIFF_MS(timerHandlerPtr->time,now);
+#ifndef TCL_WIDE_INT_IS_LONG
+			if (ms > LONG_MAX) {
+				ms = LONG_MAX;
+			}
+#endif
+			afterPtr=(AfterInfo *)timerHandlerPtr->clientData;
+			Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_ObjPrintf("after#%d", afterPtr->id));
+			Tcl_ListObjAppendElement(interp, resultListPtr, afterPtr->commandPtr);
+			Tcl_ListObjAppendElement(interp, resultListPtr,  Tcl_NewWideIntObj(ms));
+		}
+	}
+	Tcl_SetObjResult(interp, resultListPtr);
+	break;
+    }
     default:
 	Tcl_Panic("Tcl_AfterObjCmd: bad subcommand index to afterSubCmds");
     }
