Merge lp:~andrew-bugs-launchpad-net/nspluginwrapper/flashsaver into lp:nspluginwrapper

Proposed by Andrew Sayers
Status: Needs review
Proposed branch: lp:~andrew-bugs-launchpad-net/nspluginwrapper/flashsaver
Merge into: lp:nspluginwrapper
Diff against target: None lines
To merge this branch: bzr merge lp:~andrew-bugs-launchpad-net/nspluginwrapper/flashsaver

This proposal supersedes a proposal from 2009-06-13.

To post a comment you must log in.
Revision history for this message
Andrew Sayers (andrew-bugs-launchpad-net) wrote : Posted in a previous version of this proposal

Adobe Flash doesn't currently inhibit the screensaver when playing a video: http://bugs.adobe.com/jira/browse/FP-997?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel). There's no sign of activity in that bug report, and users are currently working around the bug on their own: http://ubuntuforums.org/showthread.php?t=1090393

This branch includes an "npsaver.bin" application that monitors X Window events, and inhibits the screensaver when npviewer.bin is fullscreen and on the top of the stack. This gives a very close match to Flash's behaviour in Windows.

This application is being proposed for inclusion in nspluginwrapper for mainly practical reasons: the process should run whenever a Flash window is open, and has to be written in C to avoid depending on packages not currently installed by default.

This branch directly modifies the "configure" script - I think this is normally frowned upon, but I can't find the m4 script that automatically generates "configure".

Unmerged revisions

58. By Andrew Sayers <email address hidden>

Ran flashsaver through valgrind, caught a few memory leaks

57. By Andrew Sayers <email address hidden>

s/dbus-1/libdbus-1/ in debian/control

56. By Andrew Sayers <email address hidden>

Fixed a daft build-dependency issue

55. By Andrew Sayers <email address hidden>

Flash screensaver workaround now operational

54. By Andrew Sayers <email address hidden>

Initial Flash screensaver workaround

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2009-01-02 10:07:27 +0000
3+++ Makefile 2009-06-13 09:20:20 +0000
4@@ -143,6 +143,15 @@
5 npviewer_LDFLAGS += $(libsocket_LDFLAGS)
6 endif
7
8+npsaver_PROGRAM = npsaver.bin
9+npsaver_RAWSRCS = npw-screensaver.c inhibit-screensaver.c
10+npsaver_SOURCES = $(npsaver_RAWSRCS:%.c=$(SRC_PATH)/src/%.c)
11+npsaver_OBJECTS = $(npsaver_RAWSRCS:%.c=npsaver-%.o)
12+npsaver_CFLAGS = $(DBUS_CFLAGS) -DNDEBUG
13+npsaver_LDFLAGS = $(DBUS_LDFLAGS)
14+npsaver_LDFLAGS += $(X_LDFLAGS)
15+npsaver_LDFLAGS += $(libdl_LDFLAGS) $(libpthread_LDFLAGS) -lgthread-2.0
16+
17 npplayer_PROGRAM = npplayer
18 npplayer_SOURCES = npw-player.c debug.c rpc.c utils.c glibcurl.c gtk2xtbin.c $(tidy_SOURCES)
19 npplayer_OBJECTS = $(npplayer_SOURCES:%.c=npplayer-%.o)
20@@ -208,6 +217,7 @@
21 TARGETS += $(npwrapper_LIBRARY)
22 ifeq ($(build_viewer),yes)
23 TARGETS += $(npviewer_PROGRAM)
24+TARGETS += $(npsaver_PROGRAM)
25 TARGETS += $(libxpcom_LIBRARY)
26 TARGETS += $(libnoxshm_LIBRARY)
27 endif
28@@ -253,7 +263,7 @@
29 distclean: clean
30 rm -f config-host.* config.*
31
32-uninstall: uninstall.player uninstall.wrapper uninstall.viewer uninstall.libxpcom uninstall.libnoxshm uninstall.loader uninstall.config uninstall.dirs
33+uninstall: uninstall.player uninstall.wrapper uninstall.viewer uninstall.saver uninstall.libxpcom uninstall.libnoxshm uninstall.loader uninstall.config uninstall.dirs
34 uninstall.dirs:
35 rmdir $(DESTDIR)$(pkglibdir)/noarch
36 rmdir $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)
37@@ -269,6 +279,9 @@
38 uninstall.viewer:
39 rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM)
40 rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM:%.bin=%)
41+uninstall.saver:
42+ rm -f $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npsaver_PROGRAM)
43+ rm -f $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npsaver_PROGRAM:%.bin=%)
44 uninstall.libxpcom:
45 rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libxpcom_LIBRARY)
46 uninstall.libnoxshm:
47@@ -281,7 +294,7 @@
48 uninstall.mkruntime:
49 rm -f $(DESTDIR)$(pkglibdir)/noarch/mkruntime
50
51-install: install.dirs install.player install.wrapper install.viewer install.libxpcom install.libnoxshm install.loader install.config
52+install: install.dirs install.player install.wrapper install.viewer install.saver install.libxpcom install.libnoxshm install.loader install.config
53 install.dirs:
54 mkdir -p $(DESTDIR)$(pkglibdir)/noarch
55 mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH)
56@@ -302,6 +315,8 @@
57 $(INSTALL) -m 755 $(STRIP_OPT) $(npwrapper_LIBRARY) $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npwrapper_LIBRARY)
58 ifeq ($(build_viewer),yes)
59 install.viewer: install.viewer.bin install.viewer.glue
60+install.saver: $(npsaver_PROGRAM)
61+ $(INSTALL) -m 755 $(STRIP_OPT) $(npsaver_PROGRAM) $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npsaver_PROGRAM)
62 install.libxpcom: do.install.libxpcom
63 install.libnoxshm: do.install.libnoxshm
64 else
65@@ -386,6 +401,15 @@
66 npviewer-%.o: $(SRC_PATH)/src/%.cpp
67 $(CXX) $(CFLAGS_32) -o $@ -c $< $(CPPFLAGS) $(npviewer_CFLAGS) -DBUILD_VIEWER
68
69+$(npsaver_PROGRAM): $(npsaver_OBJECTS) $(LSB_OBJ_DIR) $(LSB_LIBS)
70+ $(CC) $(LDFLAGS) -o $@ $(npsaver_OBJECTS) $(npsaver_LDFLAGS)
71+
72+npsaver-%.o: $(SRC_PATH)/src/%.c
73+ $(CC) $(CFLAGS) -o $@ -c $< $(CPPFLAGS) $(npsaver_CFLAGS) -DBUILD_VIEWER
74+
75+npsaver-%.o: $(SRC_PATH)/src/%.cpp
76+ $(CXX) $(CFLAGS) -o $@ -c $< $(CPPFLAGS) $(npsaver_CFLAGS) -DBUILD_VIEWER
77+
78 $(npplayer_PROGRAM): $(npplayer_OBJECTS) $(npplayer_MAPFILE) $(LSB_OBJ_DIR) $(LSB_LIBS)
79 $(CC) $(LDFLAGS) -o $@ $(npplayer_OBJECTS) $(npplayer_LDFLAGS)
80
81
82=== modified file 'configure'
83--- configure 2009-01-02 10:07:27 +0000
84+++ configure 2009-06-13 09:20:20 +0000
85@@ -436,6 +436,32 @@
86 rm -f $TMPC $TMPE
87 fi
88
89+# check for DBUS-1 compile CFLAGS
90+if test "$build_viewer" = "yes" -o "$build_player" = "yes"; then
91+ if $pkgconfig --exists dbus-1; then
92+ DBUS_CFLAGS=`$pkgconfig --cflags dbus-1`
93+ DBUS_LDFLAGS=`$pkgconfig --libs dbus-1`
94+ DBUS_VERSION=`$pkgconfig --modversion dbus-1`
95+ else
96+ echo "DBUS not found"
97+ exit 1
98+ fi
99+ cat > $TMPC << EOF
100+#include <dbus/dbus.h>
101+int main(void) {
102+ DBusError err;
103+ dbus_error_init(&err);
104+ return 0;
105+}
106+EOF
107+ if ! $cc $CFLAGS $DBUS_CFLAGS $DBUS_LDFLAGS $TMPC -o $TMPE > /dev/null 2>&1; then
108+ echo "DBUS not usable"
109+ rm -f $TMPC
110+ exit 1
111+ fi
112+ rm -f $TMPC $TMPE
113+fi
114+
115 # check for cURL compile CFLAGS
116 if test "$build_player" = "yes"; then
117 if $pkgconfig --exists libcurl; then
118@@ -689,6 +715,8 @@
119 echo "GLIB_LDFLAGS=$GLIB_LDFLAGS" >> $config_mak
120 echo "GTK_CFLAGS=$GTK_CFLAGS" >> $config_mak
121 echo "GTK_LDFLAGS=$GTK_LDFLAGS" >> $config_mak
122+echo "DBUS_CFLAGS=$DBUS_CFLAGS" >> $config_mak
123+echo "DBUS_LDFLAGS=$DBUS_LDFLAGS" >> $config_mak
124 echo "CURL_CFLAGS=$CURL_CFLAGS" >> $config_mak
125 echo "CURL_LDFLAGS=$CURL_LDFLAGS" >> $config_mak
126 if test "$biarch" = "yes"; then
127
128=== modified file 'debian/control'
129--- debian/control 2008-08-27 17:19:36 +0000
130+++ debian/control 2009-06-13 16:56:18 +0000
131@@ -3,7 +3,7 @@
132 Priority: optional
133 Maintainer: Ubuntu MOTU Developers <ubuntu-motu@lists.ubuntu.com>
134 XSBC-Original-Maintainer: Rob Andrews <rob@choralone.org>
135-Build-Depends: debhelper (>= 5), quilt, autotools-dev, libc6-dev-i386 [ amd64 ], libxt-dev, x11proto-core-dev, x11proto-xext-dev, libx11-dev, libatk1.0-dev, libfontconfig1-dev, libgtk2.0-dev, libglib2.0-dev, libpango1.0-dev, ia32-libs [ amd64 ], gcc-multilib [ amd64 ], g++-multilib [ amd64 ], libcurl4-gnutls-dev
136+Build-Depends: debhelper (>= 5), quilt, autotools-dev, libc6-dev-i386 [ amd64 ], libxt-dev, x11proto-core-dev, x11proto-xext-dev, libx11-dev, libatk1.0-dev, libfontconfig1-dev, libgtk2.0-dev, libglib2.0-dev, libpango1.0-dev, ia32-libs [ amd64 ], gcc-multilib [ amd64 ], g++-multilib [ amd64 ], libcurl4-gnutls-dev, libdbus-1-dev
137 Standards-Version: 3.8.0
138 Xs-Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-dev/nspluginwrapper/ubuntu
139
140
141=== added file 'src/inhibit-screensaver.c'
142--- src/inhibit-screensaver.c 1970-01-01 00:00:00 +0000
143+++ src/inhibit-screensaver.c 2009-06-23 12:32:38 +0000
144@@ -0,0 +1,195 @@
145+/*
146+ * inhibit-screensaver.c - screensaver (dis)inhibition functions
147+ *
148+ * nspluginwrapper (C) 2005-2009 Gwenole Beauchesne
149+ *
150+ * This program is free software; you can redistribute it and/or modify
151+ * it under the terms of the GNU General Public License as published by
152+ * the Free Software Foundation; either version 2 of the License, or
153+ * (at your option) any later version.
154+ *
155+ * This program is distributed in the hope that it will be useful,
156+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
157+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
158+ * GNU General Public License for more details.
159+ *
160+ * You should have received a copy of the GNU General Public License along
161+ * with this program; if not, write to the Free Software Foundation, Inc.,
162+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
163+ */
164+
165+#include <dbus/dbus.h>
166+#include <stdio.h>
167+#include <stdlib.h>
168+
169+#define DBUS_MESSAGE(O, M) dbus_message_new_method_call("org."O".ScreenSaver", "/org/"O"/ScreenSaver", "org."O".ScreenSaver", M)
170+
171+// GNOME and KDE use the compatible interfaces with different names
172+static DBusMessage *freedesktop_inhibit;
173+static DBusMessage *gnome_inhibit;
174+
175+static DBusConnection *connection;
176+
177+static char const*const name = "npviewer.bin";
178+static char const*const reason = "Fullscreen Flash application running";
179+
180+static enum { UNINITIALISED, UNINHIBITED, INHIBITED } state = UNINITIALISED;
181+
182+static unsigned int freedesktop_cookie;
183+static unsigned int gnome_cookie;
184+
185+void screensaver_terminate() {
186+#ifndef NDEBUG
187+ printf("Freeing screensaver data\n");
188+#endif
189+ if (freedesktop_inhibit)
190+ dbus_message_unref(freedesktop_inhibit);
191+ freedesktop_inhibit = 0;
192+ if (gnome_inhibit)
193+ dbus_message_unref(gnome_inhibit);
194+ gnome_inhibit = 0;
195+ if (connection)
196+ dbus_connection_unref(connection);
197+ connection = 0;
198+};
199+
200+void initialise() {
201+
202+ if (UNINITIALISED != state) return;
203+
204+ DBusError err;
205+
206+ dbus_error_init(&err);
207+
208+ connection = dbus_bus_get(DBUS_BUS_SESSION, &err);
209+ if (dbus_error_is_set(&err)) {
210+ fprintf(stderr, "Connection Error (%s)\n", err.message);
211+ dbus_error_free(&err);
212+ }
213+ if (NULL == connection) {
214+ exit(1);
215+ }
216+
217+ freedesktop_inhibit = DBUS_MESSAGE("freedesktop", "Inhibit");
218+ gnome_inhibit = DBUS_MESSAGE("gnome" , "Inhibit");
219+
220+ dbus_message_append_args(freedesktop_inhibit,
221+ DBUS_TYPE_STRING, &name,
222+ DBUS_TYPE_STRING, &reason,
223+ DBUS_TYPE_INVALID);
224+
225+ dbus_message_append_args(gnome_inhibit,
226+ DBUS_TYPE_STRING, &name,
227+ DBUS_TYPE_STRING, &reason,
228+ DBUS_TYPE_INVALID);
229+
230+ state = UNINHIBITED;
231+
232+ atexit(screensaver_terminate);
233+
234+}
235+
236+// Send either gnome_inhibit or freedesktop_inhibit, and get the reply
237+int inhibit_one(DBusMessage* inhibit) {
238+ DBusPendingCall* pending;
239+ DBusMessageIter args;
240+ dbus_uint32_t ret;
241+
242+ if (!dbus_connection_send_with_reply(connection, inhibit, &pending, -1)) {
243+ fprintf(stderr, "Out Of Memory!\n");
244+ exit(1);
245+ }
246+ if (NULL == pending) {
247+ fprintf(stderr, "Pending Call Null\n");
248+ exit(1);
249+ }
250+
251+ dbus_connection_flush(connection);
252+
253+ dbus_pending_call_block(pending);
254+
255+ // get the reply message
256+ DBusMessage* msg = dbus_pending_call_steal_reply(pending);
257+ if (NULL == msg) {
258+ fprintf(stderr, "Reply Null\n");
259+ exit(1);
260+ }
261+ // free the pending message handle
262+ dbus_pending_call_unref(pending);
263+
264+ // read the parameters
265+ if (!dbus_message_iter_init(msg, &args))
266+ fprintf(stderr, "Message has no arguments!\n");
267+ else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
268+ ret = 0; // Failed
269+ else
270+ dbus_message_iter_get_basic(&args, &ret);
271+
272+ // free reply and close connection
273+ dbus_message_unref(msg);
274+
275+ return ret;
276+}
277+
278+void screensaver_inhibit() {
279+ initialise();
280+ if (UNINHIBITED != state) return;
281+
282+#ifndef NDEBUG
283+ printf("Inhibiting screensaver\n");
284+#endif
285+
286+ freedesktop_cookie = inhibit_one(freedesktop_inhibit);
287+ gnome_cookie = inhibit_one(gnome_inhibit);
288+
289+ state = INHIBITED;
290+}
291+
292+void screensaver_uninhibit() {
293+ if (INHIBITED != state) return;
294+
295+#ifndef NDEBUG
296+ printf("Uninhibiting screensaver\n");
297+#endif
298+
299+ if (freedesktop_cookie) {
300+ DBusMessage *uninhibit = DBUS_MESSAGE("freedesktop", "UnInhibit");
301+ dbus_message_append_args(uninhibit,
302+ DBUS_TYPE_UINT32, &freedesktop_cookie,
303+ DBUS_TYPE_INVALID);
304+
305+ if (!dbus_connection_send(connection, uninhibit, NULL)) {
306+ fprintf(stderr, "Out Of Memory!\n");
307+ exit(1);
308+ };
309+
310+ // free reply and close connection
311+ dbus_message_unref(uninhibit);
312+ };
313+
314+
315+ if ( gnome_cookie) {
316+ DBusMessage *uninhibit = DBUS_MESSAGE("gnome", "UnInhibit");
317+ dbus_message_append_args(uninhibit,
318+ DBUS_TYPE_UINT32, & gnome_cookie,
319+ DBUS_TYPE_INVALID);
320+
321+ if (!dbus_connection_send(connection, uninhibit, NULL)) {
322+ fprintf(stderr, "Out Of Memory!\n");
323+ exit(1);
324+ };
325+
326+ // free reply and close connection
327+ dbus_message_unref(uninhibit);
328+ };
329+
330+ state = UNINHIBITED;
331+
332+}
333+
334+void screensaver_flip() {
335+ if (INHIBITED==state)
336+ screensaver_uninhibit();
337+ else
338+ screensaver_inhibit();
339+}
340
341=== added file 'src/inhibit-screensaver.h'
342--- src/inhibit-screensaver.h 1970-01-01 00:00:00 +0000
343+++ src/inhibit-screensaver.h 2009-06-23 12:32:38 +0000
344@@ -0,0 +1,13 @@
345+// These functions can be safely called at the wrong time (e.g. calling inhibit() several times in a row). The extra calls will do nothing.
346+
347+// Inhibit the screensaver
348+void screensaver_inhibit();
349+
350+// Uninhibit the screensaver
351+void screensaver_uninhibit();
352+
353+// If the screensaver is inhibited, uninhibit the screensaver. Else inhibit the screensaver
354+void screensaver_flip();
355+
356+// Free data when the program terminates (automatically called during normal process termination)
357+void screensaver_terminate();
358
359=== added file 'src/npw-screensaver.c'
360--- src/npw-screensaver.c 1970-01-01 00:00:00 +0000
361+++ src/npw-screensaver.c 2009-06-23 12:32:38 +0000
362@@ -0,0 +1,211 @@
363+/*
364+ * npw-screensaver.c - control the screensaver based on Flash
365+ *
366+ * nspluginwrapper (C) 2005-2009 Gwenole Beauchesne
367+ *
368+ * This program is free software; you can redistribute it and/or modify
369+ * it under the terms of the GNU General Public License as published by
370+ * the Free Software Foundation; either version 2 of the License, or
371+ * (at your option) any later version.
372+ *
373+ * This program is distributed in the hope that it will be useful,
374+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
375+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
376+ * GNU General Public License for more details.
377+ *
378+ * You should have received a copy of the GNU General Public License along
379+ * with this program; if not, write to the Free Software Foundation, Inc.,
380+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
381+ */
382+
383+#include <time.h>
384+#include <X11/Xlib.h>
385+#include <X11/Xatom.h>
386+#include <stdlib.h>
387+#include "inhibit-screensaver.h"
388+#include <string.h>
389+#ifndef NDEBUG
390+#include <stdio.h>
391+#endif
392+#include <unistd.h>
393+
394+// Run for at least VALGRIND seconds, with no waiting. Useful for testing with valgrind
395+//#define VALGRIND 10
396+
397+// Minimum number of seconds between (dis)inhibiting the screensaver
398+#define MIN_TIME 30
399+
400+// WM_NAME
401+Atom name;
402+// _NET_WM_STATE
403+Atom state;
404+// _NET_WM_STATE_FULLSCREEN
405+Atom fullscreen;
406+// _NET_CLIENT_LIST_STACKING
407+Atom stacking;
408+
409+// Temporary variables used in many places
410+
411+Atom type;
412+int format;
413+unsigned long nItems;
414+unsigned long bytesAfter;
415+unsigned char *property;
416+
417+// Current display
418+Display *display;
419+// Root window of the current display
420+Atom root_window;
421+
422+// Is this window a fullscreen npviewer window?
423+int is_fullscreen_flash(Window* w)
424+{
425+ if (property)
426+ XFree(property);
427+ property = 0;
428+
429+ // Is this window called npviewer.bin?
430+ if (Success != XGetWindowProperty(display, *w, name, 0, 3, False, XA_STRING,
431+ &type, &format, &nItems, &bytesAfter, &property)
432+ || !property
433+ || strcmp((char*)property, "npviewer.bin")) {
434+ if (property)
435+ XFree(property);
436+ property = 0;
437+ return 0;
438+ };
439+ if (property)
440+ XFree(property);
441+ property = 0;
442+
443+ // Get the number of state atoms for this window
444+ if (Success != XGetWindowProperty(display, *w, state, 0, 0, False, XA_ATOM,
445+ &type, &format, &nItems, &bytesAfter, &property)
446+ || !property
447+ || !bytesAfter) {
448+ if (property)
449+ XFree(property);
450+ property = 0;
451+ return 0;
452+ };
453+ if (property)
454+ XFree(property);
455+ property = 0;
456+
457+ // Get the state atoms for this window
458+ property = 0;
459+ if (Success != XGetWindowProperty(display, *w, state, 0, (bytesAfter / 4), False, XA_ATOM,
460+ &type, &format, &nItems, &bytesAfter, &property)
461+ || !property) {
462+ if (property)
463+ XFree(property);
464+ property = 0;
465+ return 0;
466+ };
467+
468+ // Check whether any of the state atoms are _NET_WM_STATE_FULLSCREEN
469+ if (property) {
470+ Atom* states = (Atom*)property;
471+ while (nItems--) {
472+ if (*states++ == fullscreen) {
473+ XFree(property);
474+ property = 0;
475+ return 1;
476+ };
477+ };
478+
479+ XFree(property);
480+ property = 0;
481+ };
482+
483+ // Fail
484+ return 0;
485+}
486+
487+// Inhibit or uninhibit the screensaver, depending on the current state of npviewer
488+void inhibit(Atom* old_window)
489+{
490+ if(Success == XGetWindowProperty(display, root_window, stacking, 0, 0, False, XA_WINDOW,
491+ &type, &format, &nItems, &bytesAfter, &property)) {
492+
493+ if (property)
494+ XFree(property);
495+ property = 0;
496+
497+ if(Success == XGetWindowProperty(display, root_window, stacking, (bytesAfter / 4) - 1, sizeof(Atom), False, XA_WINDOW,
498+ &type, &format, &nItems, &bytesAfter, &property)
499+ && property && *old_window != *((Atom*)property)) {
500+ *old_window = *((Atom*)property);
501+
502+ if (is_fullscreen_flash(old_window)) {
503+ screensaver_inhibit();
504+ } else {
505+ screensaver_uninhibit();
506+ };
507+ }
508+
509+ if (property) {
510+ XFree(property);
511+ };
512+ property = 0;
513+ }
514+}
515+
516+// Get the value for an atom
517+void get_atom(char const*const name, Atom* a)
518+{
519+ *a = XInternAtom(display, name, True);
520+ if(*a == None) {
521+#ifndef NDEBUG
522+ printf("No such atom: %s\n", name);
523+#endif
524+ exit(1);
525+ }
526+}
527+
528+int main()
529+{
530+ // Start with the root window.
531+ display = XOpenDisplay(0);
532+
533+ get_atom("WM_NAME", &name);
534+ get_atom("_NET_WM_STATE", &state);
535+ get_atom("_NET_WM_STATE_FULLSCREEN", &fullscreen);
536+ get_atom("_NET_CLIENT_LIST_STACKING", &stacking);
537+
538+ root_window = XDefaultRootWindow(display);
539+
540+ Atom old_window = root_window;
541+
542+ XSelectInput(display, root_window, PropertyChangeMask);
543+
544+ XEvent event;
545+
546+ time_t prev_time = 0;
547+
548+#ifdef VALGRIND
549+ time_t start_time = time(0);
550+ while (time(0) - start_time < VALGRIND) {
551+#else
552+ for (;;) {
553+#endif
554+ XNextEvent(display, &event);
555+ if (event.xproperty.atom != stacking) continue; // Window stacking has changed
556+
557+#ifndef VALGRIND
558+ time_t time_elapsed = time(0) - prev_time;
559+ if (time_elapsed < MIN_TIME) // Update at most once every 30 seconds
560+ sleep(MIN_TIME - time_elapsed);
561+#endif
562+
563+ inhibit(&old_window);
564+ prev_time = time(0);
565+ };
566+
567+#ifndef NDEBUG
568+ printf("Freeing global variables\n");
569+#endif
570+ XCloseDisplay(display);
571+ if (property)
572+ XFree(property);
573+}
574
575=== modified file 'src/npw-viewer.sh'
576--- src/npw-viewer.sh 2008-12-27 02:10:20 +0000
577+++ src/npw-viewer.sh 2009-06-13 09:20:20 +0000
578@@ -3,6 +3,7 @@
579 # nsplugin viewer wrapper script (C) 2005-2006 Gwenole Beauchesne
580 #
581 OS="`uname -s`"
582+OS_LOWER="`uname -s | tr '[A-Z]' '[a-z]'`"
583 ARCH="`uname -m`"
584 NPW_LIBDIR="%NPW_LIBDIR%"
585
586@@ -143,4 +144,9 @@
587 fi
588 fi
589
590-exec $LOADER $NPW_VIEWER_DIR/npviewer.bin ${1+"$@"}
591+$NPW_LIBDIR/$ARCH/$OS_LOWER/npsaver.bin &
592+NPSAVER=$!
593+
594+$LOADER $NPW_VIEWER_DIR/npviewer.bin ${1+"$@"}
595+
596+kill $NPSAVER

Subscribers

People subscribed via source and target branches

to all changes: