Attachment "inactive.patch" to
ticket [1185731f]
added by
rmax
2005-04-27 18:51:36.
Index: generic/tk.decls
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tk.decls,v
retrieving revision 1.26
diff -u -r1.26 tk.decls
--- generic/tk.decls 17 Mar 2004 18:15:42 -0000 1.26
+++ generic/tk.decls 27 Apr 2005 11:43:14 -0000
@@ -1262,6 +1262,13 @@
int Tk_PhotoSetSize(Tcl_Interp *interp, Tk_PhotoHandle handle,
int width, int height)
}
+# TIP#245
+declare 269 generic {
+ long Tk_GetUserInactiveTime(Display *dpy)
+}
+declare 270 generic {
+ void Tk_ResetUserInactiveTime(Display *dpy)
+}
# Define the platform specific public Tk interface. These functions are
# only available on the designated platform.
Index: generic/tkCmds.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkCmds.c,v
retrieving revision 1.35
diff -u -r1.35 tkCmds.c
--- generic/tkCmds.c 12 Nov 2004 23:53:12 -0000 1.35
+++ generic/tkCmds.c 27 Apr 2005 11:43:14 -0000
@@ -619,11 +619,11 @@
Tk_Window tkwin;
static CONST char *optionStrings[] = {
"appname", "caret", "scaling", "useinputmethods",
- "windowingsystem", NULL
+ "windowingsystem", "inactive", NULL
};
enum options {
TK_APPNAME, TK_CARET, TK_SCALING, TK_USE_IM,
- TK_WINDOWINGSYSTEM
+ TK_WINDOWINGSYSTEM, TK_INACTIVE
};
tkwin = (Tk_Window) clientData;
@@ -846,6 +846,47 @@
Tcl_SetStringObj(Tcl_GetObjResult(interp), windowingsystem, -1);
break;
}
+ case TK_INACTIVE: {
+ int skip;
+
+ skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
+ }
+ if (objc - skip == 2) {
+ long inactive;
+
+ inactive = (Tcl_IsSafe(interp) ? -1 :
+ Tk_GetUserInactiveTime(Tk_Display(tkwin)));
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(inactive));
+
+ } else if (objc - skip == 3) {
+ char *string;
+
+ string = Tcl_GetStringFromObj(objv[objc-1], NULL);
+ if (strcmp(string, "reset") != 0) {
+ Tcl_Obj *msg = Tcl_NewStringObj("bad option \"", -1);
+ Tcl_AppendStringsToObj(msg, string,
+ "\": must be reset", NULL);
+ Tcl_SetObjResult(interp, msg);
+ return TCL_ERROR;
+ }
+ if (Tcl_IsSafe(interp)) {
+ Tcl_SetResult(interp,
+ "resetting the user inactivity timer "
+ "is not allowed in a safe interpreter",
+ TCL_STATIC);
+ return TCL_ERROR;
+ }
+ Tk_ResetUserInactiveTime(Tk_Display(tkwin));
+ Tcl_ResetResult(interp);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-displayof window? ?reset?");
+ return TCL_ERROR;
+ }
+ break;
+ }
}
return TCL_OK;
}
Index: macosx/tkMacOSXXStubs.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/macosx/tkMacOSXXStubs.c,v
retrieving revision 1.7
diff -u -r1.7 tkMacOSXXStubs.c
--- macosx/tkMacOSXXStubs.c 13 Nov 2004 03:41:47 -0000 1.7
+++ macosx/tkMacOSXXStubs.c 27 Apr 2005 11:43:14 -0000
@@ -30,6 +30,8 @@
#include "tkPort.h"
#include "tkMacOSXEvent.h"
+#include <IOKit/IOKitLib.h>
+
/*
* Because this file is still under major development Debugger statements are
* used through out this file. The define TCL_DEBUG will decide whether
@@ -963,3 +965,98 @@
#endif
return macScreenName;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetUserInactiveTime --
+ *
+ * Return the number of milliseconds the user was inactive.
+ *
+ * Results:
+ * The number of milliseconds the user has been inactive,
+ * or -1 if querying the inactive time is not supported.
+ *
+ * Side effects:
+ * None.
+ *----------------------------------------------------------------------
+ */
+
+long
+Tk_GetUserInactiveTime(Display *dpy)
+{
+ io_registry_entry_t regEntry;
+ CFMutableDictionaryRef props = NULL;
+ CFTypeRef timeObj;
+ long ret = -1l;
+ uint64_t time;
+
+ regEntry = IOServiceGetMatchingService(kIOMasterPortDefault,
+ IOServiceMatching("IOHIDSystem"));
+
+ if (regEntry == NULL) {
+ return -1l;
+ }
+
+ IOReturn result = IORegistryEntryCreateCFProperties(regEntry, &props,
+ kCFAllocatorDefault, 0);
+ IOObjectRelease(regEntry);
+
+ if (result != KERN_SUCCESS || props == NULL) {
+ return -1l;
+ }
+
+ timeObj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime"));
+
+ if (timeObj) {
+ CFRetain(timeObj);
+ CFTypeID type = CFGetTypeID(timeObj);
+
+ if (type == CFDataGetTypeID()) { /* Jaguar */
+ CFDataGetBytes((CFDataRef) timeObj,
+ CFRangeMake(0, sizeof(time)),
+ (UInt8 *) &time);
+ /* Convert nanoseconds to milliseconds. */
+ //ret /= kMillisecondScale;
+ ret = (long)(time/kMillisecondScale);
+ } else if (type == CFNumberGetTypeID()) { /* Panther+ */
+ CFNumberGetValue((CFNumberRef)timeObj,
+ kCFNumberSInt64Type,
+ &time);
+ /* Convert nanoseconds to milliseconds. */
+ //ret /= kMillisecondScale;
+ ret = (long)(time/kMillisecondScale);
+ } else {
+ ret = -1l;
+ }
+
+ CFRelease(timeObj);
+ }
+ /* Cleanup */
+ CFRelease(props);
+
+ return ret;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_ResetUserInactiveTime --
+ *
+ * Reset the user inactivity timer
+ *
+ * Results:
+ * none
+ *
+ * Side effects:
+ * The user inactivity timer of the underlaying windowing system
+ * is reset to zero.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_ResetUserInactiveTime(Display *dpy)
+{
+ UpdateSystemActivity(0);
+}
Index: macosx/Wish.pbproj/project.pbxproj
===================================================================
RCS file: /cvsroot/tktoolkit/tk/macosx/Wish.pbproj/project.pbxproj,v
retrieving revision 1.38
diff -u -r1.38 project.pbxproj
--- macosx/Wish.pbproj/project.pbxproj 9 Apr 2005 11:19:00 -0000 1.38
+++ macosx/Wish.pbproj/project.pbxproj 27 Apr 2005 11:43:15 -0000
@@ -101,6 +101,36 @@
//4C2
//4C3
//4C4
+//950
+//951
+//952
+//953
+//954
+ 95911CC7081532D8006F6BCB = {
+ isa = PBXFileReference;
+ lastKnownFileType = wrapper.framework;
+ name = IOKit.framework;
+ path = /System/Library/Frameworks/IOKit.framework;
+ refType = 0;
+ sourceTree = "<absolute>";
+ };
+ 95911CC8081532D8006F6BCB = {
+ fileRef = 95911CC7081532D8006F6BCB;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 95911CC9081532D8006F6BCB = {
+ fileRef = 95911CC7081532D8006F6BCB;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+//950
+//951
+//952
+//953
+//954
//F50
//F51
//F52
@@ -2175,6 +2205,7 @@
F51D903E0181474301DC9062,
F537567E016C3ADB01DC9062,
F50D96130196176E01DC9062,
+ 95911CC9081532D8006F6BCB,
);
isa = PBXFrameworksBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -3083,6 +3114,7 @@
};
F537567C016C3ADB01DC9062 = {
children = (
+ 95911CC7081532D8006F6BCB,
F50D96120196176E01DC9062,
F5875C7B016FEF1D01DC9062,
F537567D016C3ADB01DC9062,
@@ -3435,6 +3467,7 @@
F53756A7016C4DD401DC9062,
F50D96140196176E01DC9062,
F5877FB9031F9F49016F146B,
+ 95911CC8081532D8006F6BCB,
);
isa = PBXFrameworksBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
Index: unix/configure.in
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/configure.in,v
retrieving revision 1.99
diff -u -r1.99 configure.in
--- unix/configure.in 10 Jan 2005 18:57:41 -0000 1.99
+++ unix/configure.in 27 Apr 2005 11:43:15 -0000
@@ -283,6 +283,29 @@
fi
#--------------------------------------------------------------------
+# Check whether the header and library for the XScreenSaver
+# extension are available, and set HAVE_XSS if so.
+# XScreenSaver is needed for Tk_GetUserInactiveTime().
+#--------------------------------------------------------------------
+AC_MSG_CHECKING([for XScreenSaver support])
+tk_oldCFlags=$CFLAGS
+CFLAGS="$CFLAGS $XINCLUDES"
+tk_oldLibs=$LIBS
+LIBS="$LIBS $XLIBSW -lXss -lXext"
+AC_TRY_LINK([
+#include <X11/Xlib.h>
+#include <X11/extensions/scrnsaver.h>
+] , [
+XScreenSaverAllocInfo();
+], [
+AC_MSG_RESULT(yes)
+XLIBSW="$XLIBSW -lXss -lXext"
+AC_DEFINE([HAVE_XSS])
+], AC_MSG_RESULT(no))
+CFLAGS=$tk_oldCFlags
+LIBS=$tk_oldLibs
+
+#--------------------------------------------------------------------
# Check for freetype / fontconfig / Xft support.
#--------------------------------------------------------------------
Index: unix/tkUnix.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/tkUnix.c,v
retrieving revision 1.6
diff -u -r1.6 tkUnix.c
--- unix/tkUnix.c 26 Oct 2004 13:15:09 -0000 1.6
+++ unix/tkUnix.c 27 Apr 2005 11:43:15 -0000
@@ -14,6 +14,9 @@
*/
#include <tkInt.h>
+#ifdef HAVE_XSS
+#include <X11/extensions/scrnsaver.h>
+#endif
/*
*----------------------------------------------------------------------
@@ -165,3 +168,65 @@
dataPtr += lineStride;
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetUserInactiveTime --
+ *
+ * Return the number of milliseconds the user was inactive.
+ *
+ * Results:
+ * The number of milliseconds since the user's latest interaction
+ * with the system on the given display, or -1 if the
+ * XScreenSaver extension is not supported by the client
+ * libraries or the X server implementation.
+ *
+ * Side effects:
+ * None.
+ *----------------------------------------------------------------------
+ */
+
+long
+Tk_GetUserInactiveTime(dpy)
+ Display *dpy; /* The display for which to query the inactive time */
+{
+ long inactivetime = -1;
+#ifdef HAVE_XSS
+ int event_base;
+ int error_base;
+
+ if (XScreenSaverQueryExtension(dpy, &event_base, &error_base)) {
+ XScreenSaverInfo *info;
+ info = XScreenSaverAllocInfo();
+ XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), info);
+ inactivetime = info->idle;
+ XFree(info);
+ }
+#endif /* HAVE_XSS */
+ return inactivetime;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_ResetUserInactiveTime --
+ *
+ * Reset the user inactivity timer
+ *
+ * Results:
+ * none
+ *
+ * Side effects:
+ * The user inactivity timer of the underlaying windowing system
+ * is reset to zero.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_ResetUserInactiveTime(dpy)
+ Display *dpy;
+{
+ XResetScreenSaver(dpy);
+}
Index: win/tkWinX.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinX.c,v
retrieving revision 1.45
diff -u -r1.45 tkWinX.c
--- win/tkWinX.c 4 Mar 2005 01:13:03 -0000 1.45
+++ win/tkWinX.c 27 Apr 2005 11:43:15 -0000
@@ -13,6 +13,14 @@
* RCS: @(#) $Id: tkWinX.c,v 1.45 2005/03/04 01:13:03 hobbs Exp $
*/
+/*
+ * Make sure the SendInput API is available:
+ */
+#if (_WIN32_WINNT <= 0x0400)
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0401
+#endif
+
#include "tkWinInt.h"
/*
@@ -1837,3 +1845,84 @@
}
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetUserInactiveTime --
+ *
+ * Return the number of milliseconds the user was inactive.
+ *
+ * Results:
+ * Milliseconds of user inactive time or -1 if the user32.dll doesn't
+ * have the symbol GetLastInputInfo or GetLastInputInfo returns an
+ * error.
+ *
+ * Side effects:
+ * None.
+ *----------------------------------------------------------------------
+ */
+
+long
+Tk_GetUserInactiveTime(dpy)
+ Display *dpy; /* Ignored on Windows */
+{
+ struct tagLASTINPUTINFO {
+ UINT cbSize;
+ DWORD dwTime;
+ } li;
+ static FARPROC pfnGetLastInputInfo = NULL;
+ static int initinfo = 0;
+
+ if (!initinfo) {
+ HMODULE hMod = GetModuleHandleA("USER32.DLL");
+ initinfo = 1;
+ if (hMod){
+ pfnGetLastInputInfo =
+ GetProcAddress(hMod, "GetLastInputInfo");
+ }
+ }
+ if (pfnGetLastInputInfo == NULL) {
+ return -1;
+ }
+ li.cbSize = sizeof(li);
+ if ( !(BOOL)(pfnGetLastInputInfo)(&li) ) {
+ return -1;
+ }
+ /* last input info is in milliseconds, since restart time. */
+ return (GetTickCount()-li.dwTime);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_ResetUserInactiveTime --
+ *
+ * Reset the user inactivity timer
+ *
+ * Results:
+ * none
+ *
+ * Side effects:
+ * The user inactivity timer of the underlaying windowing system
+ * is reset to zero.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_ResetUserInactiveTime(dpy)
+ Display *dpy;
+{
+ INPUT inp;
+
+ inp.type=INPUT_MOUSE;
+ inp.mi.dx=0;
+ inp.mi.dy=0;
+ inp.mi.mouseData=0;
+ inp.mi.dwFlags=MOUSEEVENTF_MOVE;
+ inp.mi.time=0;
+ inp.mi.dwExtraInfo=NULL;
+
+ SendInput(1, &inp, sizeof(inp));
+}