@@ -179,6 +179,13 @@ extern "C" {
179179//
180180#if (defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(__HAIKU__)
181181#define LINUX_LIKE_SYSTEM 1
182+ #include < libevdev-1.0/libevdev/libevdev.h>
183+ #include < libevdev-1.0/libevdev/libevdev.h>
184+ #include < fcntl.h>
185+ // #include <unistd.h> || alraedy included
186+ #include < glob.h>
187+ // #include <ctime> || already included
188+
182189#endif
183190
184191#if WASM
@@ -2003,6 +2010,86 @@ const vector<string> X_display_values_initialize() {
20032010 return display_values;
20042011}
20052012
2013+ // call example:
2014+ // long linuxIdleTimeInSeconds = linuxGetIdleTimeInSeconds(&linuxLastSeen);
2015+ time_t linuxLastSeen = time(nullptr );
2016+ long linuxGetIdleTimeInSeconds (time_t *lastSeen)
2017+ {
2018+ long idleTime = 0 ;
2019+ // Use glob to enumerate input devices in /dev/input/
2020+ glob_t globbuf;
2021+ if (glob (" /dev/input/event*" , GLOB_NOSORT, nullptr , &globbuf) != 0 )
2022+ {
2023+ std::cerr << " Failed to enumerate input devices. " << std::endl;
2024+
2025+ return 0 ;
2026+ }
2027+
2028+ // Create libevdev structures for each device
2029+ libevdev *devices[globbuf.gl_pathc ];
2030+
2031+ // Open and initialize each device
2032+ for (size_t i = 0 ; i < globbuf.gl_pathc ; ++i)
2033+ {
2034+ const char *devicePath = globbuf.gl_pathv [i];
2035+ int fd = open (devicePath, O_RDONLY | O_NONBLOCK);
2036+ if (fd < 0 )
2037+ {
2038+ std::cerr << " Failed to open device (Permission denied?): " << devicePath << std::endl;
2039+ return 0 ;
2040+ }
2041+
2042+ if (libevdev_new_from_fd (fd, &devices[i]) < 0 )
2043+ {
2044+ std::cerr << " Failed to initialize libevdev for device: " << devicePath << std::endl;
2045+ return 0 ;
2046+ }
2047+ }
2048+ bool systemInUse = false ;
2049+ // Read events from all devices
2050+ for (size_t i = 0 ; i < globbuf.gl_pathc ; ++i)
2051+ {
2052+ struct input_event ev;
2053+ int rc;
2054+
2055+ while ((rc = libevdev_next_event (devices[i], LIBEVDEV_READ_FLAG_NORMAL, &ev)) == 1 )
2056+ {
2057+ // Handle input events as needed
2058+ // For this example, we simply print event information
2059+ std::cout << " Event type: " << ev.type << " , code: " << ev.code << " , value: " << ev.value << std::endl;
2060+
2061+ // Set systemInUse to true if an event is detected
2062+ systemInUse = true ;
2063+ }
2064+
2065+ if (rc < 0 && rc != -EAGAIN)
2066+ {
2067+ std::cerr << " Error reading from device: " << globbuf.gl_pathv [i] << std::endl;
2068+ return 0 ;
2069+ }
2070+ }
2071+ if (systemInUse)
2072+ {
2073+ std::cout << " System is being used." << std::endl;
2074+ *lastSeen = time (nullptr );
2075+ idleTime = 0 ;
2076+ }
2077+ else
2078+ {
2079+ std::cout << " System is not being used." << std::endl;
2080+ idleTime = time (nullptr ) - *lastSeen;
2081+ }
2082+ // You can add a sleep here to reduce CPU usage
2083+ printf (" Idle time: %ld\n " , idleTime);
2084+ for (size_t i = 0 ; i < globbuf.gl_pathc ; ++i)
2085+ {
2086+ libevdev_free (devices[i]);
2087+ }
2088+ globfree (&globbuf);
2089+
2090+ return idleTime;
2091+ }
2092+
20062093// Ask the X server for user idle time (using XScreenSaver API)
20072094// Return min of idle times.
20082095// This function assumes that the boinc user has been
0 commit comments