1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2008 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
25 #include <vlc_common.h>
26 #include <vlc_plugin.h>
27 #include <vlc_inhibit.h>
31 static int Open (vlc_object_t *);
32 static void Close (vlc_object_t *);
35 set_shortname (N_("XDG-screensaver") )
36 set_description (N_("XDG screen saver inhibition") )
37 set_capability ("inhibit", 10 )
38 set_callbacks (Open, Close)
39 set_category (CAT_ADVANCED)
40 set_subcategory (SUBCAT_ADVANCED_MISC)
43 struct vlc_inhibit_sys
51 static void Inhibit (vlc_inhibit_t *ih, bool suspend);
52 static void *Thread (void *);
54 static int Open (vlc_object_t *obj)
56 vlc_inhibit_t *ih = (vlc_inhibit_t *)obj;
57 vlc_inhibit_sys_t *p_sys = malloc (sizeof (*p_sys));
62 ih->inhibit = Inhibit;
64 vlc_mutex_init (&p_sys->lock);
65 vlc_cond_init (&p_sys->wait);
66 p_sys->suspend = false;
68 if (vlc_clone (&p_sys->thread, Thread, ih, VLC_THREAD_PRIORITY_LOW))
70 vlc_cond_destroy (&p_sys->wait);
71 vlc_mutex_destroy (&p_sys->lock);
78 static void Close (vlc_object_t *obj)
80 vlc_inhibit_t *ih = (vlc_inhibit_t *)obj;
81 vlc_inhibit_sys_t *p_sys = ih->p_sys;
83 vlc_cancel (p_sys->thread);
84 vlc_join (p_sys->thread, NULL);
85 vlc_cond_destroy (&p_sys->wait);
86 vlc_mutex_destroy (&p_sys->lock);
90 static void Inhibit (vlc_inhibit_t *ih, bool suspend)
92 vlc_inhibit_sys_t *p_sys = ih->p_sys;
94 /* xdg-screensaver can take quite a while to start up (e.g. 1 second).
95 * So we avoid _waiting_ for it unless we really need to (clean up). */
96 vlc_mutex_lock (&p_sys->lock);
97 p_sys->suspend = suspend;
98 vlc_cond_signal (&p_sys->wait);
99 vlc_mutex_unlock (&p_sys->lock);
102 extern char **environ;
104 static void *Thread (void *data)
106 vlc_inhibit_t *ih = data;
107 vlc_inhibit_sys_t *p_sys = ih->p_sys;
110 snprintf (id, sizeof (id), "0x%08"PRIx32, ih->window_id);
112 for (bool suspended = false;;)
113 { /* TODO: detach the thread, so we don't need one at all time */
114 vlc_mutex_lock (&p_sys->lock);
115 mutex_cleanup_push (&p_sys->lock);
116 while (suspended == p_sys->suspend)
117 vlc_cond_wait (&p_sys->wait, &p_sys->lock);
121 (char *)"xdg-screensaver",
122 (char *)(suspended ? "resume" : "suspend"),
127 int canc = vlc_savecancel ();
129 if (!posix_spawnp (&pid, "xdg-screensaver", NULL, NULL, argv, environ))
133 msg_Dbg (ih, "started xdg-screensaver (PID = %d)", (int)pid);
134 /* Wait for command to complete */
135 while (waitpid (pid, &status, 0) == -1);
137 else/* We don't handle the error, but busy looping would be worse :( */
138 msg_Warn (ih, "could not start xdg-screensaver");
139 suspended = !suspended;
140 vlc_restorecancel (canc);