/mugshot-client/tags/MUGSHOT_CLIENT_1_1_94/linux/src/hippo-idle.c

https://gitlab.com/manoj-makkuboy/magnetism · C · 144 lines · 113 code · 19 blank · 12 comment · 13 complexity · 5a594d3d50c5773b0afc54f6a4b4584a MD5 · raw file

  1. /* -*- mode; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
  2. #include <config.h>
  3. #include <string.h>
  4. #include <X11/Xlib.h>
  5. #include <X11/Xatom.h>
  6. #ifndef WITH_MAEMO
  7. #include <X11/extensions/scrnsaver.h>
  8. #endif
  9. #include <gdk/gdkx.h>
  10. #include "hippo-idle.h"
  11. struct HippoIdleMonitor {
  12. #ifndef WITH_MAEMO
  13. XScreenSaverInfo *info;
  14. #endif
  15. GdkDisplay *display;
  16. GTime activity_time;
  17. unsigned long last_idle;
  18. guint poll_id;
  19. gboolean currently_idle;
  20. HippoIdleChangedFunc func;
  21. void *data;
  22. };
  23. static GTime
  24. get_time (void)
  25. {
  26. GTimeVal tv;
  27. g_get_current_time(&tv);
  28. return tv.tv_sec;
  29. }
  30. static gboolean
  31. poll_for_idleness (void *data)
  32. {
  33. HippoIdleMonitor *monitor = data;
  34. int i;
  35. int n_screens;
  36. unsigned long idle_time;
  37. gboolean was_idle;
  38. idle_time = G_MAXINT;
  39. n_screens = gdk_display_get_n_screens(monitor->display);
  40. for (i = 0; i < n_screens; ++i) {
  41. int result = 0;
  42. GdkScreen *screen;
  43. screen = gdk_display_get_screen(monitor->display, i);
  44. #ifndef WITH_MAEMO
  45. result = XScreenSaverQueryInfo(GDK_DISPLAY_XDISPLAY(monitor->display),
  46. GDK_SCREEN_XSCREEN(screen)->root,
  47. monitor->info);
  48. #endif
  49. if (result == 0) {
  50. g_warning("Failed to get idle time from screensaver extension");
  51. break;
  52. }
  53. /* monitor->info->idle is time in milliseconds since last user interaction event */
  54. #ifndef WITH_MAEMO
  55. idle_time = MIN(monitor->info->idle, idle_time);
  56. #endif
  57. }
  58. was_idle = monitor->currently_idle;
  59. /* If the idle time has gone down, there must have been activity since we last checked */
  60. if (idle_time < monitor->last_idle) {
  61. monitor->activity_time = get_time();
  62. monitor->currently_idle = FALSE;
  63. } else {
  64. /* If no activity, see how long ago it was and count ourselves idle
  65. * if it's been a short while. We keep this idle really short, since it
  66. * simply results in keeping bubbles up; we want to do this if people
  67. * just look away for a minute, really. It can be "more aggressive"
  68. * about idle detection than a screensaver would be.
  69. */
  70. GTime now = get_time();
  71. if (now < monitor->activity_time) {
  72. /* clock went backward... just "catch up"
  73. * then wait until the idle timeout expires again
  74. */
  75. monitor->activity_time = now;
  76. } else if ((now - monitor->activity_time) > 120) { /* 120 = 2 minutes */
  77. monitor->currently_idle = TRUE;
  78. }
  79. }
  80. monitor->last_idle = idle_time;
  81. if (was_idle != monitor->currently_idle) {
  82. (* monitor->func) (monitor->currently_idle, monitor->data);
  83. }
  84. return TRUE;
  85. }
  86. HippoIdleMonitor*
  87. hippo_idle_add (GdkDisplay *display,
  88. HippoIdleChangedFunc func,
  89. void *data)
  90. {
  91. int event_base, error_base;
  92. Display *xdisplay;
  93. HippoIdleMonitor *monitor;
  94. xdisplay = GDK_DISPLAY_XDISPLAY(display);
  95. #ifndef WITH_MAEMO
  96. if (!XScreenSaverQueryExtension(xdisplay, &event_base, &error_base)) {
  97. g_warning("Screensaver extension not found on X display, can't detect user idleness");
  98. return NULL;
  99. }
  100. #endif
  101. monitor = g_new0(HippoIdleMonitor, 1);
  102. monitor->display = g_object_ref(display);
  103. #ifndef WITH_MAEMO
  104. monitor->info = XScreenSaverAllocInfo();
  105. #endif
  106. monitor->activity_time = get_time();
  107. monitor->last_idle = 0;
  108. monitor->currently_idle = FALSE;
  109. monitor->func = func;
  110. monitor->data = data;
  111. monitor->poll_id = g_timeout_add(5000, poll_for_idleness, monitor);
  112. return monitor;
  113. }
  114. void
  115. hippo_idle_free (HippoIdleMonitor *monitor)
  116. {
  117. if (monitor == NULL)
  118. return; /* means no screensaver extension */
  119. #ifndef WITH_MAEMO
  120. XFree(monitor->info);
  121. #endif
  122. g_source_remove(monitor->poll_id);
  123. g_object_unref(monitor->display);
  124. g_free(monitor);
  125. }