Merge lp:~jazzva/nspluginwrapper/1.3.0 into lp:nspluginwrapper

Proposed by Saša Bodiroža
Status: Needs review
Proposed branch: lp:~jazzva/nspluginwrapper/1.3.0
Merge into: lp:nspluginwrapper
Diff against target: None lines
To merge this branch: bzr merge lp:~jazzva/nspluginwrapper/1.3.0
Reviewer Review Type Date Requested Status
Alexander Sack Pending
Review via email: mp+9961@code.launchpad.net
To post a comment you must log in.
lp:~jazzva/nspluginwrapper/1.3.0 updated
54. By Saša Bodiroža

Uncommit 0ubuntu6 changes from ubuntu-dev's branch, and directly apply diff from the archive

* debian/patches/use_syslsb.patch; dont build LSB libs on our own;
  this should unbreak flash+nspluginwrapper after latest ia32-libs
  update
  + use USE_SYSTEM_LSB accordingly in debian/rules

55. By Saša Bodiroža

releasing version 1.2.2-0ubuntu6

56. By Saša Bodiroža

Merge with upstream branch r1.1.7

57. By Saša Bodiroža

Add initial changelog entry

58. By Saša Bodiroža

Update Maintainer field in debian/control, as proposed by
DebianMaintainerField spec

59. By Saša Bodiroža

* Update debian/patches/000_debian_make_symlinks.diff
  - change short option for "nosymlinks" from "n" to "s" to avoid collision
    with option "native"
  - add option "nosymlinks" to print_usage()

60. By Saša Bodiroža

* Update debian/patches/003_update_help_info.diff because of change in
  debian/patches/000_debian_make_symlinks.diff
* Refresh patches

61. By Saša Bodiroža

Update debian/patches/use_syslsb.patch because of different Makefile

62. By Saša Bodiroža

Add patch debian/patches/004_system_only_update.diff from Debian
version 1.2.2-1

63. By Saša Bodiroža

change short option for "nosymlinks" from "n" to "x" to avoid collision

64. By Saša Bodiroža

Update .bzr-builddeb/default.conf

65. By Saša Bodiroža

Add LP bug number to debian/changelog

66. By Saša Bodiroža

Add patch debian/patches/000_allow_empty_short_option.diff to allow no short
option for some parameter.

67. By Saša Bodiroža

Increment indices in the name of all previous patches.

68. By Saša Bodiroža

Refresh patches

69. By Saša Bodiroža

Attribute the patch 000_allow_empty_short_option.diff to Alexander Sack

70. By Saša Bodiroža

* Remove short option "x" for "nosymlinks" option in
  debian/patches/001_debian_make_symlinks.diff
  - Update debian/patches/004_update_help_info.diff
  - Update debian/patches/005_system_only_update.diff

71. By Saša Bodiroža

releasing version 1.3.0-0ubuntu1

Unmerged revisions

71. By Saša Bodiroža

releasing version 1.3.0-0ubuntu1

70. By Saša Bodiroža

* Remove short option "x" for "nosymlinks" option in
  debian/patches/001_debian_make_symlinks.diff
  - Update debian/patches/004_update_help_info.diff
  - Update debian/patches/005_system_only_update.diff

69. By Saša Bodiroža

Attribute the patch 000_allow_empty_short_option.diff to Alexander Sack

68. By Saša Bodiroža

Refresh patches

67. By Saša Bodiroža

Increment indices in the name of all previous patches.

66. By Saša Bodiroža

Add patch debian/patches/000_allow_empty_short_option.diff to allow no short
option for some parameter.

65. By Saša Bodiroža

Add LP bug number to debian/changelog

64. By Saša Bodiroža

Update .bzr-builddeb/default.conf

63. By Saša Bodiroža

change short option for "nosymlinks" from "n" to "x" to avoid collision

62. By Saša Bodiroža

Add patch debian/patches/004_system_only_update.diff from Debian
version 1.2.2-1

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzr-builddeb/default.conf'
2--- .bzr-builddeb/default.conf 2009-01-02 10:12:06 +0000
3+++ .bzr-builddeb/default.conf 2009-08-11 01:33:30 +0000
4@@ -1,5 +1,5 @@
5 [BUILDDEB]
6 merge=True
7 export-upstream = .
8-export-upstream-revision = revid:jazzva@gmail.com-20090102100727-yx8scdwpkmh9xace
9+export-upstream-revision = revid:jazzva@gmail.com-20090811003842-htca2u6z7nfh10w3
10
11
12=== modified file 'ChangeLog'
13--- ChangeLog 2009-01-02 10:07:27 +0000
14+++ ChangeLog 2009-08-11 00:38:42 +0000
15@@ -1,8 +1,58 @@
16-2009-01-01 07:36 Gwenole Beauchesne <gb.public@free.fr>
17-
18- * NEWS, nspluginwrapper.spec: Updates for 1.2.2.
19-
20-2009-01-01 07:34 Gwenole Beauchesne <gb.public@free.fr>
21+2009-01-02 08:50 Gwenole Beauchesne <gb.public@free.fr>
22+
23+ * NEWS, nspluginwrapper.spec: Fix spelling.
24+
25+2009-01-01 20:51 Gwenole Beauchesne <gb.public@free.fr>
26+
27+ * src/rpc.c: Factor our socket creation.
28+
29+2009-01-01 20:26 Gwenole Beauchesne <gb.public@free.fr>
30+
31+ * src/npruntime-impl.h, src/npruntime.c, src/npw-viewer.c: Make it
32+ possible to disable NPIdentifier cache with
33+ NPW_NPRUNTIME_CACHE=no too.
34+
35+2009-01-01 17:58 Gwenole Beauchesne <gb.public@free.fr>
36+
37+ * NEWS, nspluginwrapper.spec: Updates for 1.3.0.
38+
39+2009-01-01 17:56 Gwenole Beauchesne <gb.public@free.fr>
40+
41+ * configure, lsb-build/headers/glib-2.0/glib.h,
42+ lsb-build/stub_libs/libglib-2.0.c: Add g_hash_table_find() and
43+ g_hash_table_remove_all() thunks. Besides, for bi-arch builds,
44+ it's assumed that 32-/64-bit glib versions are the same and
45+ exports the same functions.
46+
47+2009-01-01 17:46 Gwenole Beauchesne <gb.public@free.fr>
48+
49+ * src/npw-viewer.c: Add NPIdentifier cache.
50+
51+2009-01-01 15:13 Gwenole Beauchesne <gb.public@free.fr>
52+
53+ * src/npruntime-impl.h, src/npruntime.c: Add NPClass::HasMethod
54+ cache so that to lower RPC round-trip.
55+
56+2009-01-01 13:54 Gwenole Beauchesne <gb.public@free.fr>
57+
58+ * src/npw-viewer.c: Forcibly destroy the Xt source on exit.
59+
60+2009-01-01 11:02 Gwenole Beauchesne <gb.public@free.fr>
61+
62+ * NEWS: Updates.
63+
64+2009-01-01 10:58 Gwenole Beauchesne <gb.public@free.fr>
65+
66+ * src/npw-viewer.c: Don't create Xt polling sources if we know the
67+ plug-in uses Gtk (XEMBED).
68+
69+2009-01-01 10:33 Gwenole Beauchesne <gb.public@free.fr>
70+
71+ * src/npw-viewer.c: Get rid of the extra 25ms timer. The Xt timers
72+ & input sources are now
73+ checked in the X events source ::prepare() function.
74+
75+2009-01-01 07:31 Gwenole Beauchesne <gb.public@free.fr>
76
77 * Makefile, NEWS, README, configure, src/cxxabi-compat.cpp,
78 src/debug.c, src/debug.h, src/libxpcom.c, src/npruntime-impl.h,
79@@ -17,85 +67,186 @@
80 utils/getdeps.sh, utils/mkruntime.sh, utils/repackage.sh: Update
81 copyright notices.
82
83-2008-12-28 11:36 Gwenole Beauchesne <gb.public@free.fr>
84-
85- * NEWS, src/npw-malloc.c, src/npw-malloc.h, src/npw-viewer.c:
86- Backport from trunk:
87-
88- Make sure NPWindow::ws_info points to a unique location for the
89- lifetime of the window. This fixes support for the VLC plugin
90- that makes a local copy of NPWindow but doesn't bother about
91- making an NPWindow::ws_info copy.
92-
93-2008-12-26 23:37 Gwenole Beauchesne <gb.public@free.fr>
94-
95- * NEWS: Updates with "hot" fixes.
96-
97-2008-12-26 23:33 Gwenole Beauchesne <gb.public@free.fr>
98-
99- * src/npw-wrapper.c: Backport from trunk:
100-
101- Fix NPN_GetStringIdentifiers() to free identifiers with
102- NPW_MemFree().
103- * src/npw-player.c: Backport from trunk:
104-
105- Fix stream_new() to return NULL if an error occurred.
106-
107-2008-12-26 13:42 Gwenole Beauchesne <gb.public@free.fr>
108-
109- * nspluginwrapper.spec: Bump release for development.
110-
111-2008-12-25 21:43 Gwenole Beauchesne <gb.public@free.fr>
112-
113- * nspluginwrapper.spec: Fix day-of-week.
114-
115-2008-12-25 21:40 Gwenole Beauchesne <gb.public@free.fr>
116-
117- * NEWS, nspluginwrapper.spec: Updates for real 1.2.0 release.
118-
119-2008-12-25 21:37 Gwenole Beauchesne <gb.public@free.fr>
120-
121- * ChangeLog, Makefile: Fix ChangeLog generation for the branch.
122-
123-2008-12-25 21:29 Gwenole Beauchesne <gb.public@free.fr>
124-
125- * ChangeLog: Generated by svn2cl.
126-
127-2008-12-25 21:29 Gwenole Beauchesne <gb.public@free.fr>
128-
129- * ChangeLog: Generated by svn2cl.
130-
131-2008-12-21 21:43 Gwenole Beauchesne <gb.public@free.fr>
132-
133- * src/debug.h: Fix npw_return_if_fail() definition in !DEBUG mode.
134-
135-2008-12-21 14:02 Gwenole Beauchesne <gb.public@free.fr>
136-
137- * src/npw-viewer.c: Destroy the plugin window in NPP_Destroy().
138- NPAPI docs mention plugin shall not use graphics operations
139- beyond that call. So, don't bother with broken plugins, we
140- already have our own bugs to bother with...
141-
142-2008-12-21 12:14 Gwenole Beauchesne <gb.public@free.fr>
143-
144- * .: Create nspluginwrapper-1.2-branch from rev 837.
145+2008-12-29 15:14 Gwenole Beauchesne <gb.public@free.fr>
146+
147+ * src/npw-config.c: Fix upgrades from previous versions.
148+
149+2008-12-29 14:53 Gwenole Beauchesne <gb.public@free.fr>
150+
151+ * Makefile, nspluginwrapper.spec: Rename loader script to
152+ npviewer.sh.
153+
154+2008-12-29 14:52 Gwenole Beauchesne <gb.public@free.fr>
155+
156+ * Makefile, configure, src/npw-config.c, src/npw-wrapper.c,
157+ src/sysdeps.h: Make it possible to use alternate viewer paths
158+ with --viewer-paths configure option. By default,
159+ pkglibdir/%ARCH%/%OS% is used. If no viewer path includes an
160+ ARCH/OS expansion, then nspluginwrapper files are installed in a
161+ "flat" hierarchy. NPW_PluginInfo format is now extended to
162+ include the viewer_path[] too.
163+
164+2008-12-29 10:48 Gwenole Beauchesne <gb.public@free.fr>
165+
166+ * src/npw-viewer.sh: Move down NPW_VIEWER_DIR, after
167+ TARGET_ARCH/TARGET_OS were normalised. Also fix uses of
168+ normalized ARCH/OS variables.
169+
170+2008-12-29 09:47 Gwenole Beauchesne <gb.public@free.fr>
171+
172+ * src/npw-viewer.sh: Normalize ARCH/OS variables here too.
173+
174+2008-12-28 18:16 Gwenole Beauchesne <gb.public@free.fr>
175+
176+ * Makefile, src/npw-viewer.sh: Factor out install paths.
177+
178+2008-12-28 17:18 Gwenole Beauchesne <gb.public@free.fr>
179+
180+ * configure: Improve biarch-build check.
181+
182+2008-12-28 17:03 Gwenole Beauchesne <gb.public@free.fr>
183+
184+ * Makefile, configure, src/rpc.c: Normalize CPU and OS values for
185+ both hosts and targets. Cleanup a few internal configure option
186+ names. Rephrase --enable-generic.
187+
188+2008-12-28 11:25 Gwenole Beauchesne <gb.public@free.fr>
189+
190+ * src/npw-viewer.c: Make sure NPWindow::ws_info points to a unique
191+ location for the lifetime of the window. This fixes support for
192+ the VLC plugin that makes a local copy of NPWindow but doesn't
193+ bother about making an NPWindow::ws_info copy.
194+
195+2008-12-28 11:21 Gwenole Beauchesne <gb.public@free.fr>
196+
197+ * src/npw-malloc.c, src/npw-malloc.h: Add NPW_MemAllocCopy() and
198+ NPW_MemClone() functions.
199+
200+2008-12-27 15:19 Gwenole Beauchesne <gb.public@free.fr>
201+
202+ * src/npw-viewer.c: Minor clean-ups.
203+
204+2008-12-27 14:56 Gwenole Beauchesne <gb.public@free.fr>
205+
206+ * configure: Enable main-thread checks by default for all builds
207+ from snapshots.
208+
209+2008-12-27 14:54 Gwenole Beauchesne <gb.public@free.fr>
210+
211+ * configure, src/npruntime.c, src/npw-viewer.c: Rework configure
212+ option. Use NPW_THREAD_CHECK=yes (or "1") at run-time.
213+
214+2008-12-27 14:45 Gwenole Beauchesne <gb.public@free.fr>
215+
216+ * configure, src/npruntime.c, src/npw-viewer.c: Convert the PID
217+ check to a main-thread check.
218+
219+2008-12-27 12:19 Gwenole Beauchesne <gb.public@free.fr>
220+
221+ * src/npw-malloc.c: Simplify memory allocation code further.
222+
223+2008-12-27 12:07 Gwenole Beauchesne <gb.public@free.fr>
224+
225+ * src/npw-malloc.c: Allow malloc-checks for the libc memory
226+ allocation hooks too. This also simplifies/clarifies the
227+ different memory allocation backends.
228+
229+2008-12-27 11:45 Gwenole Beauchesne <gb.public@free.fr>
230+
231+ * Makefile, configure, src/npw-malloc.c: Enable malloc-checks by
232+ default for all builds from snapshots.
233+
234+2008-12-27 11:16 Gwenole Beauchesne <gb.public@free.fr>
235+
236+ * configure, src/npw-malloc.c, src/npw-malloc.h: Add basic malloc
237+ check routines to detect possible buffer overflows or
238+ underflows. This is enabled at run-time with
239+ NPW_MALLOC_CHECK=yes (or "1").
240+
241+2008-12-26 23:31 Gwenole Beauchesne <gb.public@free.fr>
242+
243+ * src/npw-wrapper.c: Fix NPN_GetStringIdentifiers() to free
244+ identifiers with NPW_MemFree().
245+
246+2008-12-26 23:24 Gwenole Beauchesne <gb.public@free.fr>
247+
248+ * src/npw-player.c: Fix stream_new() to return NULL if an error
249+ occurred.
250+
251+2008-12-26 21:34 Gwenole Beauchesne <gb.public@free.fr>
252+
253+ * NEWS, nspluginwrapper.spec: Merge documentation updates from
254+ 1.2-branch.
255+
256+2008-12-26 21:26 Gwenole Beauchesne <gb.public@free.fr>
257+
258+ * src/npruntime.c: Use NPW_MemAlloc() instead of NPW_MemAlloc0()
259+ since all struct members are initialized manually.
260+
261+2008-12-26 21:24 Gwenole Beauchesne <gb.public@free.fr>
262+
263+ * src/npw-malloc.c: Report an error instead of a debug-warning for
264+ NPW_MemFree()'ing a pointer that was not allocated with
265+ NPW_MemAlloc().
266+
267+2008-12-25 21:23 Gwenole Beauchesne <gb.public@free.fr>
268+
269+ * src/debug.h: Merge from 1.2-branch:
270+
271+ Fix npw_return_if_fail() definition in !DEBUG mode.
272+
273+2008-12-25 21:22 Gwenole Beauchesne <gb.public@free.fr>
274+
275+ * src/npw-viewer.c: Merge from 1.2-branch:
276+
277+ Destroy the plugin window in NPP_Destroy(). NPAPI docs mention
278+ plugin shall not use graphics operations beyond that call. So,
279+ don't bother with broken plugins, we already have our own bugs
280+ to bother with...
281+
282+2008-12-25 21:21 Gwenole Beauchesne <gb.public@free.fr>
283+
284+ * src/npw-rpc.h, src/npw-viewer.c, src/npw-wrapper.c: Revert RPC
285+ sync and silent X errors commits. They didn't fix anything in a
286+ useful way. IOW, don't bother fixing bugs that are not
287+ nspluginwrapper related and that could actually degrade its
288+ stability.
289+
290+2008-12-21 12:19 Gwenole Beauchesne <gb.public@free.fr>
291+
292+ * nspluginwrapper.spec, src/npw-wrapper.c: Bump release for
293+ development.
294+
295+2008-12-21 09:32 Gwenole Beauchesne <gb.public@free.fr>
296+
297+ * src/npw-rpc.h, src/npw-viewer.c, src/npw-wrapper.c: Try to
298+ improve the RPC flush mechanism. Flash doesn't like "cancelled"
299+ NPN_GetURLNotify() with an NPERR_INVALID_INSTANCE_ERROR return.
300+ So, we try our best to honour that call prior to sending
301+ NPP_Destroy().
302+
303+2008-12-21 08:19 Gwenole Beauchesne <gb.public@free.fr>
304+
305+ * src/npw-wrapper.c: Purge all incoming RPC prior to calling
306+ NPP_Destroy().
307+
308+2008-12-21 08:16 Gwenole Beauchesne <gb.public@free.fr>
309+
310+ * src/npw-viewer.c: Don't kill the application on X errors. That
311+ is, we ignore all X errors that could arise between the
312+ completion of NPP_Destroy() and plugin_instance_finalize(). This
313+ is not fully correct as other plugins can be created and then
314+ destroyed in the while.
315+
316+ XXX: this is a hack to debug later because in the presence of
317+ Firefox 3.0 (i.e. neither 3.1b2 nor 2.x are affected, it seems),
318+ the toplevel window receives an "unexpected GDK_DESTROY from the
319+ outside". Native plugins often get that without nspluginwrapper
320+ too but the application is not killed either.
321
322 2008-12-20 22:24 Gwenole Beauchesne <gb.public@free.fr>
323
324- * gwenole/projects/nspluginwrapper/trunk/ChangeLog: Generated by
325- svn2cl.
326-
327-2008-12-20 22:22 Gwenole Beauchesne <gb.public@free.fr>
328-
329- * gwenole/projects/nspluginwrapper/trunk/NEWS,
330- gwenole/projects/nspluginwrapper/trunk/nspluginwrapper.spec:
331- 1.2.0.
332-
333-2008-12-20 21:32 Gwenole Beauchesne <gb.public@free.fr>
334-
335- * gwenole/projects/nspluginwrapper/trunk/src/npw-config.c:
336- Suppress error messages in non-verbose mode when exec()'ing
337- npviewer.bin (Stanislav Brabec).
338+ * ChangeLog: Generated by svn2cl.
339
340 2008-12-20 22:22 Gwenole Beauchesne <gb.public@free.fr>
341
342
343=== modified file 'Makefile'
344--- Makefile 2009-01-02 10:07:27 +0000
345+++ Makefile 2009-08-11 00:38:42 +0000
346@@ -23,10 +23,10 @@
347 ifeq ($(SNAPSHOT),)
348 SNAPSHOT := $(shell echo "$(RELEASE)" | grep "^0")
349 ifeq ($(SNAPSHOT),$(RELEASE))
350-SNAPSHOT := 1
351-endif
352-endif
353-ifeq ($(SNAPSHOT),1)
354+SNAPSHOT := 2
355+endif
356+endif
357+ifeq ($(SNAPSHOT),2)
358 VERSION_SUFFIX = -$(SVNDATE)
359 endif
360
361@@ -77,7 +77,7 @@
362 endif
363
364 ARCH_32 = $(ARCH)
365-ifeq ($(biarch), yes)
366+ifeq ($(build_biarch), yes)
367 ARCH_32 = $(TARGET_ARCH)
368 LSB_LIBS = $(LSB_OBJ_DIR)/libc.so $(LSB_OBJ_DIR)/libgcc_s_32.so
369 LSB_LIBS += $(LSB_CORE_STUBS:%=$(LSB_OBJ_DIR)/%.so)
370@@ -114,7 +114,7 @@
371 npviewer_RAWSRCS = npw-viewer.c npw-common.c npw-malloc.c npw-rpc.c rpc.c debug.c utils.c npruntime.c
372 npviewer_SOURCES = $(npviewer_RAWSRCS:%.c=$(SRC_PATH)/src/%.c)
373 npviewer_OBJECTS = $(npviewer_RAWSRCS:%.c=npviewer-%.o)
374-ifeq ($(biarch),yes)
375+ifeq ($(build_biarch),yes)
376 npviewer_CFLAGS = $(CFLAGS_32)
377 npviewer_CFLAGS += -I$(LSB_INC_DIR)
378 npviewer_CFLAGS += -I$(LSB_INC_DIR)/glib-2.0
379@@ -155,7 +155,7 @@
380 libxpcom_SOURCES = $(libxpcom_RAWSRCS:%.c=$(SRC_PATH)/src/%.c)
381 libxpcom_OBJECTS = $(libxpcom_RAWSRCS:%.c=libxpcom-%.o)
382 libxpcom_CFLAGS = $(PIC_CFLAGS)
383-ifeq ($(biarch),yes)
384+ifeq ($(build_biarch),yes)
385 libxpcom_CFLAGS += -I$(LSB_INC_DIR)
386 libxpcom_LDFLAGS = $(LDFLAGS_32) -L$(LSB_OBJ_DIR)
387 endif
388@@ -182,7 +182,7 @@
389 npconfig_LDFLAGS += $(libpthread_LDFLAGS)
390 endif
391
392-nploader_PROGRAM = npviewer
393+nploader_PROGRAM = npviewer.sh
394 nploader_RAWSRCS = npw-viewer.sh
395 nploader_SOURCES = $(nploader_RAWSRCS:%.sh=$(SRC_PATH)/src/%.sh)
396
397@@ -255,51 +255,43 @@
398
399 uninstall: uninstall.player uninstall.wrapper uninstall.viewer uninstall.libxpcom uninstall.libnoxshm uninstall.loader uninstall.config uninstall.dirs
400 uninstall.dirs:
401- rmdir $(DESTDIR)$(pkglibdir)/noarch
402- rmdir $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)
403- rmdir $(DESTDIR)$(pkglibdir)/$(ARCH)
404-ifneq ($(ARCH),$(ARCH_32))
405- rmdir $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)
406- rmdir $(DESTDIR)$(pkglibdir)/$(ARCH_32)
407-endif
408+ rmdir -p $(DESTDIR)$(nptargetdir) || :
409+ rmdir -p $(DESTDIR)$(nphostdir) || :
410+ rmdir -p $(DESTDIR)$(npcommondir) || :
411 uninstall.player:
412- rm -f $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npplayer_PROGRAM)
413+ rm -f $(DESTDIR)$(nphostdir)/$(npplayer_PROGRAM)
414 uninstall.wrapper:
415- rm -f $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npwrapper_LIBRARY)
416+ rm -f $(DESTDIR)$(nphostdir)/$(npwrapper_LIBRARY)
417 uninstall.viewer:
418- rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM)
419- rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM:%.bin=%)
420+ rm -f $(DESTDIR)$(nptargetdir)/$(npviewer_PROGRAM)
421+ rm -f $(DESTDIR)$(nptargetdir)/$(npviewer_PROGRAM:%.bin=%)
422 uninstall.libxpcom:
423- rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libxpcom_LIBRARY)
424+ rm -f $(DESTDIR)$(nptargetdir)/$(libxpcom_LIBRARY)
425 uninstall.libnoxshm:
426- rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libnoxshm_LIBRARY)
427+ rm -f $(DESTDIR)$(nptargetdir)/$(libnoxshm_LIBRARY)
428 uninstall.loader:
429- rm -f $(DESTDIR)$(pkglibdir)/noarch/$(nploader_PROGRAM)
430+ rm -f $(DESTDIR)$(npcommondir)/$(nploader_PROGRAM)
431 uninstall.config:
432 rm -f $(DESTDIR)$(bindir)/nspluginwrapper
433- rm -f $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npconfig_PROGRAM)
434+ rm -f $(DESTDIR)$(nphostdir)/$(npconfig_PROGRAM)
435 uninstall.mkruntime:
436- rm -f $(DESTDIR)$(pkglibdir)/noarch/mkruntime
437+ rm -f $(DESTDIR)$(npcommondir)/mkruntime
438
439 install: install.dirs install.player install.wrapper install.viewer install.libxpcom install.libnoxshm install.loader install.config
440 install.dirs:
441- mkdir -p $(DESTDIR)$(pkglibdir)/noarch
442- mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH)
443- mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)
444-ifneq ($(ARCH),$(ARCH_32))
445- mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH_32)
446- mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)
447-endif
448+ mkdir -p $(DESTDIR)$(npcommondir) || :
449+ mkdir -p $(DESTDIR)$(nphostdir) || :
450+ mkdir -p $(DESTDIR)$(nptargetdir) || :
451 ifeq ($(build_player),yes)
452 install.player: $(npplayer_PROGRAM)
453- $(INSTALL) -m 755 $(STRIP_OPT) $(npplayer_PROGRAM) $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npplayer_PROGRAM)
454+ $(INSTALL) -m 755 $(STRIP_OPT) $(npplayer_PROGRAM) $(DESTDIR)$(nphostdir)/$(npplayer_PROGRAM)
455 mkdir -p $(DESTDIR)$(bindir)
456- $(LN_S) $(pkglibdir)/$(ARCH)/$(OS)/$(npplayer_PROGRAM) $(DESTDIR)$(bindir)/nspluginplayer
457+ $(LN_S) $(nphostdir)/$(npplayer_PROGRAM) $(DESTDIR)$(bindir)/nspluginplayer
458 else
459 install.player:
460 endif
461 install.wrapper: $(npwrapper_LIBRARY)
462- $(INSTALL) -m 755 $(STRIP_OPT) $(npwrapper_LIBRARY) $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npwrapper_LIBRARY)
463+ $(INSTALL) -m 755 $(STRIP_OPT) $(npwrapper_LIBRARY) $(DESTDIR)$(nphostdir)/$(npwrapper_LIBRARY)
464 ifeq ($(build_viewer),yes)
465 install.viewer: install.viewer.bin install.viewer.glue
466 install.libxpcom: do.install.libxpcom
467@@ -310,26 +302,26 @@
468 install.libnoxshm:
469 endif
470 install.viewer.bin: $(npviewer_PROGRAM)
471- $(INSTALL) -m 755 $(STRIP_OPT) $(npviewer_PROGRAM) $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM)
472+ $(INSTALL) -m 755 $(STRIP_OPT) $(npviewer_PROGRAM) $(DESTDIR)$(nptargetdir)/$(npviewer_PROGRAM)
473 install.viewer.glue::
474- p=$(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM:%.bin=%); \
475+ p=$(DESTDIR)$(nptargetdir)/$(npviewer_PROGRAM:%.bin=%); \
476 echo "#!/bin/sh" > $$p; \
477 echo "TARGET_OS=$(TARGET_OS)" >> $$p; \
478 echo "TARGET_ARCH=$(TARGET_ARCH)" >> $$p; \
479- echo ". $(pkglibdir)/noarch/$(nploader_PROGRAM)" >> $$p; \
480+ echo ". $(npcommondir)/$(nploader_PROGRAM)" >> $$p; \
481 chmod 755 $$p
482 do.install.libxpcom: $(libxpcom_LIBRARY)
483- $(INSTALL) -m 755 $(STRIP_OPT) $(libxpcom_LIBRARY) $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libxpcom_LIBRARY)
484+ $(INSTALL) -m 755 $(STRIP_OPT) $(libxpcom_LIBRARY) $(DESTDIR)$(nptargetdir)/$(libxpcom_LIBRARY)
485 do.install.libnoxshm: $(libnoxshm_LIBRARY)
486- $(INSTALL) -m 755 $(STRIP_OPT) $(libnoxshm_LIBRARY) $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libnoxshm_LIBRARY)
487+ $(INSTALL) -m 755 $(STRIP_OPT) $(libnoxshm_LIBRARY) $(DESTDIR)$(nptargetdir)/$(libnoxshm_LIBRARY)
488 install.config: $(npconfig_PROGRAM)
489- $(INSTALL) -m 755 $(STRIP_OPT) $(npconfig_PROGRAM) $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npconfig_PROGRAM)
490+ $(INSTALL) -m 755 $(STRIP_OPT) $(npconfig_PROGRAM) $(DESTDIR)$(nphostdir)/$(npconfig_PROGRAM)
491 mkdir -p $(DESTDIR)$(bindir)
492- $(LN_S) $(pkglibdir)/$(ARCH)/$(OS)/$(npconfig_PROGRAM) $(DESTDIR)$(bindir)/nspluginwrapper
493+ $(LN_S) $(nphostdir)/$(npconfig_PROGRAM) $(DESTDIR)$(bindir)/nspluginwrapper
494 install.loader: $(nploader_PROGRAM)
495- $(INSTALL) -m 755 $(nploader_PROGRAM) $(DESTDIR)$(pkglibdir)/noarch/$(nploader_PROGRAM)
496+ $(INSTALL) -m 755 $(nploader_PROGRAM) $(DESTDIR)$(npcommondir)/$(nploader_PROGRAM)
497 install.mkruntime: $(SRC_PATH)/utils/mkruntime.sh
498- $(INSTALL) -m 755 $< $(DESTDIR)$(pkglibdir)/noarch/mkruntime
499+ $(INSTALL) -m 755 $< $(DESTDIR)$(npcommondir)/mkruntime
500
501 $(archivedir)::
502 [ -d $(archivedir) ] || mkdir $(archivedir) > /dev/null 2>&1
503@@ -342,7 +334,7 @@
504 BUILDDIR=`mktemp -d /tmp/buildXXXXXXXX` ; \
505 mkdir -p $$BUILDDIR/$(PACKAGE)-$(VERSION) ; \
506 (cd $(SRC_PATH) && tar c $(FILES)) | tar x -C $$BUILDDIR/$(PACKAGE)-$(VERSION) ; \
507- [ "$(SNAPSHOT)" = "1" ] && svndate_def="%" || svndate_def="#" ; \
508+ [ "$(SNAPSHOT)" = "2" ] && svndate_def="%" || svndate_def="#" ; \
509 sed -e "s/^[%#]define svndate.*/$${svndate_def}define svndate $(SVNDATE)/" \
510 < $(SRC_PATH)/nspluginwrapper.spec \
511 > $$BUILDDIR/$(PACKAGE)-$(VERSION)/nspluginwrapper.spec ; \
512@@ -367,7 +359,7 @@
513
514 changelog: ../common/authors.xml
515 svn_prefix=`svn info .|sed -n '/^URL *: .*\/svn\/\(.*\)$$/s//\1\//p'`; \
516- LC_ALL=C TZ=GMT svn2cl --strip-prefix=$$svn_prefix --authors=../common/authors.xml --accum || :
517+ LC_ALL=C TZ=GMT svn2cl --strip-prefix=$$svn_prefix --authors=../common/authors.xml || :
518 changelog.commit: changelog
519 svn commit -m "Generated by svn2cl." ChangeLog
520
521@@ -413,7 +405,7 @@
522 $(CC) -o $@ -c $< $(CPPFLAGS) $(CFLAGS)
523
524 $(nploader_PROGRAM): $(nploader_SOURCES)
525- sed -e "s|%NPW_LIBDIR%|$(pkglibdir)|" $< > $@
526+ sed -e 's|%NPW_VIEWER_DIR%|$(nptargetdir_var)|' $< > $@
527 chmod 755 $@
528
529 $(LSB_OBJ_DIR)::
530
531=== modified file 'NEWS'
532--- NEWS 2009-01-02 10:07:27 +0000
533+++ NEWS 2009-08-11 00:38:42 +0000
534@@ -1,6 +1,14 @@
535 nspluginwrapper NEWS -- history of user-visible changes. 2009-01-02
536 Copyright (C) 2005-2009 Gwenole Beauchesne
537
538+Version 1.3.0 (BETA) - 02.Jan.2009
539+* Don't poll for Xt events in Gtk (XEMBED) plug-ins
540+* Use 40 Hz timer for Xt events only when necessary (Xt input sources)
541+* Add NPIdentifier and NPClass::HasMethod caches, i.e. lower RPC traffic
542+* Add support for multiple viewer paths, see --viewer-paths=PATH-EXPR
543+* Add basic checks for malloc()'ed buffer underflow/overflow
544+* Add checks for single-threaded calls into the browser (NPN_*() functions)
545+
546 Version 1.2.2 - 02.Jan.2009
547 * Fix support for the VLC plug-in
548 * Fix memory deallocation in NPN_GetStringIdentifiers()
549@@ -12,7 +20,8 @@
550 * Add support for SunStudio compilers
551 * Add support for Flash Player 10 on OpenSolaris 2008.11
552 * Fix build on non-Linux platforms
553-* Fix NPP_Destroy() to keep NPP instances longer, but destroy window immediately
554+* Fix NPP_Destroy() to keep NPP instances longer
555+* Fix NPP_Destroy() to destroy the plugin window immediately
556
557 Version 1.1.10 (BETA) - 08.Dec.2008
558 * Fix NPPVpluginScriptableNPObject::Invalidate()
559
560=== modified file 'configure'
561--- configure 2009-01-02 10:07:27 +0000
562+++ configure 2009-08-11 00:38:42 +0000
563@@ -19,15 +19,63 @@
564 TMPE="${TMPDIR1}/npw-conf-${RANDOM}-$$-${RANDOM}"
565 TMPS="${TMPDIR1}/npw-conf-${RANDOM}-$$-${RANDOM}.S"
566
567+# find source path
568+# XXX: we assume an absolute path is given when launching configure,
569+# except in './configure' case.
570+source_path=${0%configure}
571+source_path=${source_path%/}
572+source_path_used="yes"
573+if test -z "$source_path" -o "$source_path" = "." ; then
574+ source_path=`pwd`
575+ source_path_used="no"
576+fi
577+
578+# determine versions
579+VERSION=`sed < $source_path/$PACKAGE.spec -n '/^\%define version[ ]*/s///p'`
580+RELEASE=`sed < $source_path/$PACKAGE.spec -n '/^\%define release[ ]*/s///p'`
581+SVNDATE=`sed < $source_path/$PACKAGE.spec -n '/^\%define svndate[ ]*/s///p'`
582+if test -z "$SVNDATE"; then
583+ SVNDATE=`date '+%Y%m%d'`
584+fi
585+
586+MAJOR_VERSION=`echo "$VERSION"|cut -d'.' -f1`
587+MINOR_VERSION=`echo "$VERSION"|cut -d'.' -f2`
588+MICRO_VERSION=`echo "$VERSION"|cut -d'.' -f3`
589+
590+# development snapshots are officially generated tarballs for testing
591+# ("odd" minor and micro versions)
592+is_odd() {
593+ local rem=`expr "$1" % 2`
594+ test $rem -eq 1 && return 0 || return 1
595+}
596+
597+if is_odd $MINOR_VERSION || is_odd $MICRO_VERSION; then
598+ SNAPSHOT=1
599+else
600+ SNAPSHOT=0
601+fi
602+
603+# snapshots can also be unofficially generated tarballs
604+# (Release: 0.1 in specfile)
605+if echo "$RELEASE" | grep -q ^0; then
606+ SNAPSHOT=2
607+fi
608+
609+if test $SNAPSHOT -ge 1; then
610+ yes_for_snapshots="yes"
611+else
612+ yes_for_snapshots="no"
613+fi
614+
615 # default parameters
616 prefix="/usr"
617 lib32=""
618 lib64=""
619 x_base_dirs=""
620-biarch="guess"
621 build_viewer="guess"
622 build_player="yes"
623-linux_only="guess"
624+build_generic="guess"
625+build_biarch="guess"
626 strip="no"
627 cc="gcc"
628 cxx="g++"
629@@ -37,52 +85,49 @@
630 target_cpu="i386"
631 rpc_init_timeout=5
632 malloc_hooks="glib,libc"
633-use_pid_check="no"
634-case "$host_cpu" in
635+enable_malloc_check="$yes_for_snapshots"
636+enable_thread_check="$yes_for_snapshots"
637+
638+normalize_cpu() {
639+local cpu="$1"
640+case "$cpu" in
641 arm*)
642- host_cpu="arm"
643+ cpu="arm"
644 ;;
645-i386|i486|i586|i686|i86pc|BePC)
646- host_cpu="i386"
647+i[3456]86|k[678]|i86pc|BePC)
648+ cpu="i386"
649 ;;
650 ia64)
651- host_cpu="ia64"
652+ cpu="ia64"
653 ;;
654 "Power Macintosh"|ppc)
655- host_cpu="ppc"
656+ cpu="ppc"
657 ;;
658 ppc64)
659- host_cpu="ppc64"
660+ cpu="ppc64"
661 ;;
662 sparc)
663- host_cpu="sparc"
664+ cpu="sparc"
665 ;;
666 sparc64)
667- host_cpu="sparc64"
668+ cpu="sparc64"
669 ;;
670 x86_64|amd64)
671- host_cpu="x86_64"
672- ;;
673-*)
674- host_cpu="unknown"
675+ cpu="x86_64"
676 ;;
677 esac
678-case "$host_os" in
679+echo "$cpu"
680+}
681+
682+normalize_os() {
683+local os="$1"
684+case "$os" in
685 sunos*)
686- host_os="solaris"
687+ os="solaris"
688 ;;
689 esac
690-
691-# find source path
692-# XXX: we assume an absolute path is given when launching configure,
693-# except in './configure' case.
694-source_path=${0%configure}
695-source_path=${source_path%/}
696-source_path_used="yes"
697-if test -z "$source_path" -o "$source_path" = "." ; then
698- source_path=`pwd`
699- source_path_used="no"
700-fi
701+echo "$os"
702+}
703
704 for opt do
705 case "$opt" in
706@@ -92,14 +137,20 @@
707 --pkglibdir=*)
708 pkglibdir=`echo "$opt" | cut -d '=' -f 2`
709 ;;
710+--viewer-paths=*)
711+ viewer_paths=`echo "$opt" | cut -d '=' -f 2`
712+ ;;
713 --target-os=*)
714 target_os=`echo "$opt" | cut -d '=' -f 2 | tr '[A-Z]' '[a-z]'`
715 ;;
716 --target-cpu=*)
717- target_cpu=`echo "$opt" | cut -d '=' -f 2 | sed -e 's/^i.86$/i386/'`
718+ target_cpu=`echo "$opt" | cut -d '=' -f 2`
719 ;;
720 --enable-generic)
721- linux_only="no"
722+ build_generic="yes"
723+ ;;
724+--disable-generic)
725+ build_generic="no"
726 ;;
727 --enable-strip)
728 strip="yes"
729@@ -108,10 +159,10 @@
730 strip="no"
731 ;;
732 --enable-biarch)
733- biarch="yes"
734+ build_biarch="yes"
735 ;;
736 --disable-biarch)
737- biarch="no"
738+ build_biarch="no"
739 ;;
740 --enable-viewer)
741 build_viewer="yes"
742@@ -125,11 +176,17 @@
743 --disable-player)
744 build_player="no"
745 ;;
746---enable-pid-check)
747- use_pid_check="yes"
748- ;;
749---disable-pid-check)
750- use_pid_check="no"
751+--enable-thread-check)
752+ enable_thread_check="yes"
753+ ;;
754+--disable-thread-check)
755+ enable_thread_check="no"
756+ ;;
757+--enable-malloc-check)
758+ enable_malloc_check="yes"
759+ ;;
760+--disable-malloc-check)
761+ enable_malloc_check="no"
762 ;;
763 --with-lib32=*)
764 lib32=`echo "$opt" | cut -d '=' -f 2`
765@@ -155,34 +212,45 @@
766 esac
767 done
768
769+host_cpu=`normalize_cpu "$host_cpu"`
770+host_os=`normalize_os "$host_os"`
771+target_cpu=`normalize_cpu "$target_cpu"`
772+target_os=`normalize_os "$target_os"`
773+
774 # check for linux only build
775-if test "$linux_only" = "guess"; then
776+if test "$build_generic" = "guess"; then
777 if test "$host_os" = "linux" -a "$target_os" = "linux"; then
778- linux_only="yes"
779+ build_generic="no"
780 else
781- linux_only="no"
782+ build_generic="yes"
783 fi
784 fi
785
786 # check for biarch build (Linux only)
787-if test "$biarch" = "guess"; then
788- # XXX: biarch builds require LSB headers for now
789- biarch="no"
790+# XXX: biarch builds require LSB headers for now
791+build_biarch_possible="no"
792+if test "$host_os" = "linux" -a "$target_os" = "linux"; then
793 case $host_cpu:$target_cpu in
794 x86_64:i386 | ppc64:ppc)
795- if test "$host_os" = "linux"; then
796- biarch="yes"
797- fi
798+ build_biarch_possible="yes"
799 ;;
800 esac
801 fi
802+if test "$build_biarch" = "guess"; then
803+ build_biarch="$build_biarch_possible"
804+elif test "$build_biarch" = "yes"; then
805+ if test "$build_biarch_possible" = "no"; then
806+ echo "WARNING: bi-arch build is not possible, disabling"
807+ build_biarch="no"
808+ fi
809+fi
810
811 # check for viewer build
812 if test "$build_viewer" = "guess"; then
813 build_viewer="no"
814 case $host_os in
815 linux)
816- if test "$host_cpu" = "$target_cpu" -o "$biarch" = "yes"; then
817+ if test "$host_cpu" = "$target_cpu" -o "$build_biarch" = "yes"; then
818 build_viewer="yes"
819 fi
820 ;;
821@@ -224,6 +292,12 @@
822 pkglibdir="$prefix/lib/$PACKAGE"
823 fi
824
825+# check for viewer paths
826+default_viewer_paths="$pkglibdir/%ARCH%/%OS%"
827+if test -z "$viewer_paths"; then
828+ viewer_paths="$default_viewer_paths"
829+fi
830+
831 # check for __attribute__((visibility())) support
832 cat > $TMPC << EOF
833 int foo __attribute__((visibility("hidden"))) = 1;
834@@ -280,7 +354,7 @@
835 fi
836
837 # check for __stack_chk_fail() in target GNU C library
838-if test "$biarch" = "yes"; then
839+if test "$build_biarch" = "yes"; then
840 glibc_header_dir="/usr/include"
841 libc_provides_ssp=no
842 if test -f $glibc_header_dir/features.h \
843@@ -370,7 +444,7 @@
844 CFLAGS="$CFLAGS -mtune=generic"
845 fi
846 fi
847- if test "$biarch" = "yes" -a -z "$CFLAGS_32"; then
848+ if test "$build_biarch" = "yes" -a -z "$CFLAGS_32"; then
849 CFLAGS_32="-m32 -O2 -g"
850 if check_cc_option -mtune=generic $CFLAGS_32; then
851 CFLAGS_32="$CFLAGS_32 -mtune=generic"
852@@ -596,7 +670,7 @@
853 is_ok="yes"
854 ;;
855 glib)
856- if test "x$linux_only" = "xno"; then
857+ if test "x$build_generic" = "xyes"; then
858 echo "WARNING: disabling glib memory hooks with --enable-generic"
859 elif ! $pkgconfig --atleast-version=2.10 glib-2.0; then
860 echo "WARNING: disabling glib memory hooks that require glib >= 2.10 (system is $GLIB_VERSION)"
861@@ -631,6 +705,7 @@
862 echo " --help print this message"
863 echo " --prefix=PREFIX install in PREFIX [$prefix]"
864 echo " --pkglibdir=ROOT install private files in ROOT [$pkglibdir]"
865+echo " --viewer-paths=PATH allowed viewer lookup PATH [$viewer_paths]"
866 echo " --target-os=OS build plugin support for target OS [$target_os]"
867 echo " --target-cpu=CPU build plugin support for target CPU [$target_cpu]"
868 echo " --enable-viewer build viewer [$build_viewer]"
869@@ -639,9 +714,10 @@
870 echo "Advanced options (experts only):"
871 echo " --source-path=PATH path of source code [$source_path]"
872 echo " --enable-strip strip resulting binaries and libraries [$strip]"
873-echo " --enable-generic don't use system-specific additions"
874-echo " --enable-biarch build both 32-bit and 64-bit components at once"
875-echo " --enable-pid-check enable PID check (DEBUG) [$use_pid_check]"
876+echo " --enable-generic build with generic APIs [$build_generic]"
877+echo " --enable-biarch build both 32-bit and 64-bit components at once [$build_biarch]"
878+echo " --enable-thread-check enable main thread checks (DEBUG) [$enable_thread_check]"
879+echo " --enable-malloc-check enable memory allocation checks (DEBUG) [$enable_malloc_check]"
880 echo " --with-lib32=NAME use NAME as the 32-bit library dir name [$lib32]"
881 echo " --with-lib64=NAME use NAME as the 64-bit library dir name [$lib64]"
882 echo " --with-x11-prefix=PREFIX use PREFIX as the X11 base dir [autodetect]"
883@@ -654,18 +730,19 @@
884 exit 1
885 fi
886
887+echo "Source path $source_path"
888 echo "Install prefix $prefix"
889 echo "nspluginwrapper root dir $pkglibdir"
890-echo "Strip binaries $strip"
891-echo "Bi-arch build $biarch"
892+echo "Viewer paths $viewer_paths"
893 echo "Build viewer $build_viewer"
894-echo "Build for Linux only $linux_only"
895 echo "Build standalone player $build_player"
896+echo "Build 32-/64-bit at once $build_biarch"
897+echo "Build with generic APIs $build_generic"
898 echo "32-bit library dir name $lib32"
899 echo "64-bit library dir name $lib64"
900-echo "Source path $source_path"
901 echo "C compiler $cc"
902 echo "C++ compiler $cxx"
903+echo "Strip binaries $strip"
904 echo "Host OS $host_os"
905 echo "Host CPU $host_cpu"
906 echo "Host big endian $bigendian"
907@@ -673,7 +750,8 @@
908 echo "Target CPU $target_cpu"
909 echo "RPC init timeout $rpc_init_timeout secs"
910 echo "Memory allocation hooks $malloc_hooks"
911-echo "Use PID check (DEBUG) $use_pid_check"
912+echo "Use thread checks (DEBUG) $enable_thread_check"
913+echo "Use malloc checks (DEBUG) $enable_malloc_check"
914
915 config_mak="config-host.mak"
916 echo "# Automatically generated by configure - do not modify" > $config_mak
917@@ -691,7 +769,7 @@
918 echo "GTK_LDFLAGS=$GTK_LDFLAGS" >> $config_mak
919 echo "CURL_CFLAGS=$CURL_CFLAGS" >> $config_mak
920 echo "CURL_LDFLAGS=$CURL_LDFLAGS" >> $config_mak
921-if test "$biarch" = "yes"; then
922+if test "$build_biarch" = "yes"; then
923 echo "LDFLAGS_32=-m32" >> $config_mak
924 echo "CFLAGS_32=$CFLAGS_32" >> $config_mak
925 else
926@@ -768,7 +846,7 @@
927 echo "SRC_PATH=$source_path" >> $config_mak
928 echo "build_viewer=$build_viewer" >> $config_mak
929 echo "build_player=$build_player" >> $config_mak
930-echo "biarch=$biarch" >> $config_mak
931+echo "build_biarch=$build_biarch" >> $config_mak
932 echo "lib32=$lib32" >> $config_mak
933 echo "lib64=$lib64" >> $config_mak
934 echo "prefix=$prefix" >> $config_mak
935@@ -780,21 +858,11 @@
936 echo "x11prefix=$x_base_dir" >> $config_mak
937 echo "ALLOW_STRIP=$strip" >> $config_mak
938
939-VERSION=`sed < $source_path/$PACKAGE.spec -n '/^\%define version[ ]*/s///p'`
940-RELEASE=`sed < $source_path/$PACKAGE.spec -n '/^\%define release[ ]*/s///p'`
941-SVNDATE=`sed < $source_path/$PACKAGE.spec -n '/^\%define svndate[ ]*/s///p'`
942-if test -z "$SVNDATE"; then
943- SVNDATE=`date '+%Y%m%d'`
944-fi
945-SNAPSHOT=0
946-if echo "$RELEASE" | grep -q ^0; then
947- SNAPSHOT=1
948-fi
949 echo "VERSION=$VERSION" >> $config_mak
950 echo "SVNDATE=$SVNDATE" >> $config_mak
951 echo "SNAPSHOT=$SNAPSHOT" >> $config_mak
952 echo "#define NPW_SNAPSHOT $SNAPSHOT" >> $config_h
953-if test "$SNAPSHOT" = "1"; then
954+if test $SNAPSHOT -ge 2; then
955 echo "#define NPW_VERSION \"$VERSION-Pre ($SVNDATE)\"" >> $config_h
956 else
957 echo "#define NPW_VERSION \"$VERSION\"" >> $config_h
958@@ -803,6 +871,26 @@
959 echo "pkglibdir=$pkglibdir" >> $config_mak
960 echo "#define NPW_LIBDIR \"$pkglibdir\"" >> $config_h
961
962+# check if we want to install files in ARCH/OS specific locations
963+if echo ":$viewer_paths" | $EGREP -q ":$pkglibdir/%(ARCH|OS)%"; then
964+ npw_common_libdir="$pkglibdir/noarch"
965+ npw_host_libdir="$pkglibdir/$host_cpu/$host_os"
966+ npw_target_libdir="$pkglibdir/$target_cpu/$target_os"
967+ npw_target_libdir_var="$pkglibdir/\\\$\$TARGET_ARCH/\\\$\$TARGET_OS"
968+else
969+ npw_common_libdir="$pkglibdir"
970+ npw_host_libdir="$npw_common_libdir"
971+ npw_target_libdir="$npw_common_libdir"
972+ npw_target_libdir_var="$npw_common_libdir"
973+fi
974+echo "npcommondir=$npw_common_libdir" >> $config_mak
975+echo "nphostdir=$npw_host_libdir" >> $config_mak
976+echo "nptargetdir=$npw_target_libdir" >> $config_mak
977+echo "nptargetdir_var=$npw_target_libdir_var" >> $config_mak
978+echo "#define NPW_HOST_LIBDIR \"$npw_host_libdir\"" >> $config_h
979+echo "#define NPW_TARGET_LIBDIR \"$npw_target_libdir\"" >> $config_h
980+echo "#define NPW_VIEWER_PATHS \"$viewer_paths\"" >> $config_h
981+
982 echo "#define RPC_INIT_TIMEOUT $rpc_init_timeout" >> $config_h
983
984 for mh in $malloc_hooks; do
985@@ -832,11 +920,29 @@
986 else
987 echo "#undef TARGET_LIBC_PROVIDES_SSP" >> $config_h
988 fi
989-if test "$use_pid_check" = "yes"; then
990- echo "#define USE_PID_CHECK 1" >> $config_h
991-else
992- echo "#define USE_PID_CHECK 0" >> $config_h
993-fi
994+if test "$enable_thread_check" = "yes"; then
995+ echo "#define ENABLE_THREAD_CHECK 1" >> $config_h
996+else
997+ echo "#undef ENABLE_THREAD_CHECK" >> $config_h
998+fi
999+if test "$enable_malloc_check" = "yes"; then
1000+ echo "#define ENABLE_MALLOC_CHECK 1" >> $config_h
1001+else
1002+ echo "#undef ENABLE_MALLOC_CHECK" >> $config_h
1003+fi
1004+
1005+# check for functions in <glib.h>
1006+for func in g_hash_table_remove_all g_hash_table_find; do
1007+ cat > $TMPC << EOF
1008+extern void $func(void);
1009+int main(void) { $func(); return 0; }
1010+EOF
1011+ if $cc $TMPC -o $TMPE $GLIB_CFLAGS $GLIB_LDFLAGS > /dev/null 2>&1; then
1012+ func_def=`echo "$func" | tr '[:lower:]./-' '[:upper:]___'`
1013+ echo "#define HAVE_$func_def 1" >> $config_h
1014+ fi
1015+ rm -f $TMPC $TMPE
1016+done
1017
1018 config_mak="config.mak"
1019 echo "# Automatically generated by configure - do not modify" > $config_mak
1020@@ -846,8 +952,10 @@
1021 echo "/* Automatically generated by configure - do not modify */" > $config_h
1022 echo "#include \"config-host.h\"" >> $config_h
1023
1024-if test "$linux_only" = "yes"; then
1025- echo "#define BUILD_LINUX_ONLY 1" >> $config_h
1026+if test "$build_generic" = "yes"; then
1027+ echo "#define BUILD_GENERIC 1" >> $config_h
1028+else
1029+ echo "#undef BUILD_GENERIC" >> $config_h
1030 fi
1031
1032 if test "$target_os" = "linux"; then
1033
1034=== modified file 'debian/changelog'
1035--- debian/changelog 2009-04-08 18:38:27 +0000
1036+++ debian/changelog 2009-08-11 01:50:22 +0000
1037@@ -1,3 +1,30 @@
1038+nspluginwrapper (1.3.0-0ubuntu1) karmic; urgency=low
1039+
1040+ * New upstream release 1.3.0 (LP: #411740)
1041+ * Update Maintainer field in debian/control, as proposed by
1042+ DebianMaintainerField spec
1043+ * Update debian/patches/000_debian_make_symlinks.diff
1044+ - change short option for "nosymlinks" from "n" to "x" to avoid collision
1045+ with option "native"
1046+ - add option "nosymlinks" to print_usage()
1047+ * Update debian/patches/003_update_help_info.diff because of change in
1048+ debian/patches/000_debian_make_symlinks.diff
1049+ * Update debian/patches/use_syslsb.patch because of different Makefile
1050+ * Add patch debian/patches/004_system_only_update.diff from Debian
1051+ version 1.2.2-1
1052+ * Refresh patches
1053+
1054+ -- Sasa Bodiroza <jazzva@gmail.com> Tue, 11 Aug 2009 03:49:59 +0200
1055+
1056+nspluginwrapper (1.2.2-0ubuntu6) karmic; urgency=low
1057+
1058+ * debian/patches/use_syslsb.patch; dont build LSB libs on our own;
1059+ this should unbreak flash+nspluginwrapper after latest ia32-libs
1060+ update
1061+ + use USE_SYSTEM_LSB accordingly in debian/rules
1062+
1063+ -- Alexander Sack <asac@ubuntu.com> Sun, 09 Aug 2009 14:31:49 +0200
1064+
1065 nspluginwrapper (1.2.2-0ubuntu5) jaunty; urgency=low
1066
1067 * Add iceweasel dir to debian/nspluginwrapper.postinst for removal of
1068
1069=== modified file 'debian/control'
1070--- debian/control 2008-08-27 17:19:36 +0000
1071+++ debian/control 2009-08-11 00:41:22 +0000
1072@@ -1,7 +1,7 @@
1073 Source: nspluginwrapper
1074 Section: utils
1075 Priority: optional
1076-Maintainer: Ubuntu MOTU Developers <ubuntu-motu@lists.ubuntu.com>
1077+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
1078 XSBC-Original-Maintainer: Rob Andrews <rob@choralone.org>
1079 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
1080 Standards-Version: 3.8.0
1081
1082=== modified file 'debian/patches/000_debian_make_symlinks.diff'
1083--- debian/patches/000_debian_make_symlinks.diff 2009-03-07 17:43:52 +0000
1084+++ debian/patches/000_debian_make_symlinks.diff 2009-08-11 01:31:54 +0000
1085@@ -7,10 +7,10 @@
1086
1087 -- Rob Andrews <rob@choralone.org> Fri, 29 Jun 2007 21:59:49 +0100
1088
1089-Index: ubuntu.1.2.2-0ubuntu1/src/npw-config.c
1090+Index: ubuntu/src/npw-config.c
1091 ===================================================================
1092---- ubuntu.1.2.2-0ubuntu1.orig/src/npw-config.c 2009-01-03 16:26:07.000000000 +0100
1093-+++ ubuntu.1.2.2-0ubuntu1/src/npw-config.c 2009-03-07 18:38:14.000000000 +0100
1094+--- ubuntu.orig/src/npw-config.c 2009-08-11 01:53:50.000000000 +0200
1095++++ ubuntu/src/npw-config.c 2009-08-11 01:59:54.000000000 +0200
1096 @@ -44,6 +44,16 @@
1097 static bool g_allow_native = false;
1098 static const char NPW_CONFIG[] = "nspluginwrapper";
1099@@ -28,7 +28,7 @@
1100 static void error(const char *format, ...)
1101 {
1102 va_list args;
1103-@@ -161,7 +171,7 @@
1104+@@ -226,7 +236,7 @@
1105 }
1106 else if (access("/etc/debian_version", F_OK) == 0) {
1107 static const char *debian_dirs[] = {
1108@@ -37,7 +37,7 @@
1109 };
1110 dirs = debian_dirs;
1111 }
1112-@@ -812,6 +822,49 @@
1113+@@ -941,6 +951,49 @@
1114 printf(" into %s\n", d_plugin_path);
1115
1116 free(plugin_data);
1117@@ -87,7 +87,7 @@
1118 return 0;
1119 }
1120
1121-@@ -871,6 +924,48 @@
1122+@@ -1000,6 +1053,48 @@
1123 if (unlink(plugin_path) < 0)
1124 return 1;
1125
1126@@ -136,7 +136,15 @@
1127 return 0;
1128 }
1129
1130-@@ -1033,6 +1128,12 @@
1131+@@ -1141,6 +1236,7 @@
1132+ printf(" -a --auto flag: set automatic mode for plugins discovery\n");
1133+ printf(" -n --native flag: allow native plugin(s) to be wrapped\n");
1134+ printf(" -l --list list plugins currently installed\n");
1135++ printf(" -x --nosymlinks do not create symlinks to the installed plugin\n");
1136+ printf(" -u --update update plugin(s) currently installed\n");
1137+ printf(" -i --install [FILE(S)] install plugin(s)\n");
1138+ printf(" -r --remove [FILE(S)] remove plugin(s)\n");
1139+@@ -1171,6 +1267,12 @@
1140 return 0;
1141 }
1142
1143@@ -149,11 +157,11 @@
1144 static int process_list(int argvc, char *argv[])
1145 {
1146 const char **plugin_dirs = get_mozilla_plugin_dirs();
1147-@@ -1152,6 +1253,7 @@
1148+@@ -1294,6 +1396,7 @@
1149 { 'a', "auto", process_auto, 0 },
1150 { 'n', "native", process_native, 0 },
1151 { 'l', "list", process_list, 1 },
1152-+ { 'n', "nosymlinks", process_nolink, 0 },
1153++ { 'x', "nosymlinks", process_nolink, 0 },
1154 { 'u', "update", process_update, 1 },
1155 { 'i', "install", process_install, 1 },
1156 { 'r', "remove", process_remove, 1 },
1157
1158=== modified file 'debian/patches/001_remove_bashisms.diff'
1159--- debian/patches/001_remove_bashisms.diff 2009-03-07 17:43:52 +0000
1160+++ debian/patches/001_remove_bashisms.diff 2009-08-11 01:00:52 +0000
1161@@ -3,10 +3,10 @@
1162
1163 -- Rob Andrews <rob@choralone.org> Thu, 28 Jun 2007 18:08:54 +0100
1164
1165-Index: ubuntu.1.2.2-0ubuntu1/utils/mkruntime.sh
1166+Index: nspluginwrapper/utils/mkruntime.sh
1167 ===================================================================
1168---- ubuntu.1.2.2-0ubuntu1.orig/utils/mkruntime.sh 2009-01-02 11:19:18.000000000 +0100
1169-+++ ubuntu.1.2.2-0ubuntu1/utils/mkruntime.sh 2009-03-07 18:38:19.000000000 +0100
1170+--- nspluginwrapper.orig/utils/mkruntime.sh 2009-08-11 02:41:59.000000000 +0200
1171++++ nspluginwrapper/utils/mkruntime.sh 2009-08-11 02:45:41.000000000 +0200
1172 @@ -12,15 +12,15 @@
1173 # - Check acroread5, something is missing while loading a PDF
1174 # - Enough for Flash Player & PluginSDK npsimple.so
1175
1176=== modified file 'debian/patches/002_install_to_NSPLUGINDIR.diff'
1177--- debian/patches/002_install_to_NSPLUGINDIR.diff 2009-03-19 20:47:09 +0000
1178+++ debian/patches/002_install_to_NSPLUGINDIR.diff 2009-08-11 01:00:52 +0000
1179@@ -5,11 +5,11 @@
1180
1181 -- Rob Andrews <rob@choralone.org> Sat, 14 Jul 2007 18:45:00 +0100
1182
1183-Index: ubuntu.1.2.2-0ubuntu2/src/npw-config.c
1184+Index: nspluginwrapper/src/npw-config.c
1185 ===================================================================
1186---- ubuntu.1.2.2-0ubuntu2.orig/src/npw-config.c 2009-03-19 21:33:48.000000000 +0100
1187-+++ ubuntu.1.2.2-0ubuntu2/src/npw-config.c 2009-03-19 21:34:02.000000000 +0100
1188-@@ -124,6 +124,10 @@
1189+--- nspluginwrapper.orig/src/npw-config.c 2009-08-11 02:45:38.000000000 +0200
1190++++ nspluginwrapper/src/npw-config.c 2009-08-11 02:45:50.000000000 +0200
1191+@@ -189,6 +189,10 @@
1192 static const char default_dir[] = LIBDIR "/mozilla/plugins";
1193 static const char *dir = NULL;
1194
1195@@ -20,7 +20,7 @@
1196 if (dir == NULL) {
1197 const char **dirs = NULL;
1198
1199-@@ -826,7 +830,8 @@
1200+@@ -955,7 +959,8 @@
1201 /* Install symlinks on Debian systems */
1202 if (has_system_wide_wrapper_plugin(plugin_path, true)
1203 && (access("/etc/debian_version", F_OK) == 0)
1204
1205=== modified file 'debian/patches/003_update_help_info.diff'
1206--- debian/patches/003_update_help_info.diff 2009-03-07 17:43:52 +0000
1207+++ debian/patches/003_update_help_info.diff 2009-08-11 01:31:54 +0000
1208@@ -2,14 +2,14 @@
1209
1210 -- Rob Andrews <rob@choralone.org> Sun, 02 Sep 2007 11:58:27 +0100
1211
1212-Index: ubuntu.1.2.2-0ubuntu1/src/npw-config.c
1213+Index: nspluginwrapper/src/npw-config.c
1214 ===================================================================
1215---- ubuntu.1.2.2-0ubuntu1.orig/src/npw-config.c 2009-03-07 18:38:23.000000000 +0100
1216-+++ ubuntu.1.2.2-0ubuntu1/src/npw-config.c 2009-03-07 18:38:28.000000000 +0100
1217-@@ -1102,7 +1102,7 @@
1218- printf(" -a --auto flag: set automatic mode for plugins discovery\n");
1219+--- nspluginwrapper.orig/src/npw-config.c 2009-08-11 02:46:48.000000000 +0200
1220++++ nspluginwrapper/src/npw-config.c 2009-08-11 02:47:57.000000000 +0200
1221+@@ -1242,7 +1242,7 @@
1222 printf(" -n --native flag: allow native plugin(s) to be wrapped\n");
1223 printf(" -l --list list plugins currently installed\n");
1224+ printf(" -x --nosymlinks do not create symlinks to the installed plugin\n");
1225 - printf(" -u --update update plugin(s) currently installed\n");
1226 + printf(" -u --update [FILE(S)] update plugin(s) currently installed\n");
1227 printf(" -i --install [FILE(S)] install plugin(s)\n");
1228
1229=== modified file 'debian/patches/004_fix_threading.diff'
1230--- debian/patches/004_fix_threading.diff 2009-03-07 17:43:52 +0000
1231+++ debian/patches/004_fix_threading.diff 2009-08-11 01:00:52 +0000
1232@@ -2,10 +2,10 @@
1233
1234 -- Rob Andrews <rob@choralone.org> Sat, 26 Jan 2008 03:01:31 +0000
1235
1236-Index: ubuntu.1.2.2-0ubuntu1/Makefile
1237+Index: nspluginwrapper/Makefile
1238 ===================================================================
1239---- ubuntu.1.2.2-0ubuntu1.orig/Makefile 2009-01-02 11:19:18.000000000 +0100
1240-+++ ubuntu.1.2.2-0ubuntu1/Makefile 2009-03-07 18:38:33.000000000 +0100
1241+--- nspluginwrapper.orig/Makefile 2009-08-11 02:41:59.000000000 +0200
1242++++ nspluginwrapper/Makefile 2009-08-11 02:49:12.000000000 +0200
1243 @@ -120,7 +120,7 @@
1244 npviewer_CFLAGS += -I$(LSB_INC_DIR)/glib-2.0
1245 npviewer_CFLAGS += -I$(LSB_INC_DIR)/gtk-2.0
1246
1247=== added file 'debian/patches/004_system_only_update.diff'
1248--- debian/patches/004_system_only_update.diff 1970-01-01 00:00:00 +0000
1249+++ debian/patches/004_system_only_update.diff 2009-08-11 01:31:54 +0000
1250@@ -0,0 +1,63 @@
1251+Force npconfig to only update system mozilla plugin dir if requested.
1252+
1253+ -- Rob Andrews <rob@choralone.org> Mon, 09 Mar 2009 22:59:45 +0000
1254+
1255+Index: nspluginwrapper/src/npw-config.c
1256+===================================================================
1257+--- nspluginwrapper.orig/src/npw-config.c 2009-08-11 03:22:31.000000000 +0200
1258++++ nspluginwrapper/src/npw-config.c 2009-08-11 03:22:31.000000000 +0200
1259+@@ -42,6 +42,7 @@
1260+ static bool g_auto = false;
1261+ static bool g_verbose = false;
1262+ static bool g_allow_native = false;
1263++static bool g_systemonly = false;
1264+ static const char NPW_CONFIG[] = "nspluginwrapper";
1265+
1266+ /* On Debian systems, we install/remove symlinks from these paths.
1267+@@ -1239,6 +1240,7 @@
1268+ printf(" -h --help print this message\n");
1269+ printf(" -v --verbose flag: set verbose mode\n");
1270+ printf(" -a --auto flag: set automatic mode for plugins discovery\n");
1271++ printf(" -s --systemonly when auto updating, only process the system plugin directory\n");
1272+ printf(" -n --native flag: allow native plugin(s) to be wrapped\n");
1273+ printf(" -l --list list plugins currently installed\n");
1274+ printf(" -x --nosymlinks do not create symlinks to the installed plugin\n");
1275+@@ -1298,9 +1300,16 @@
1276+ {
1277+ int i;
1278+
1279+- if (g_auto)
1280++ if (g_auto && !g_systemonly)
1281+ return auto_update_plugins();
1282+
1283++ if (g_auto && g_systemonly)
1284++ {
1285++ if (g_verbose)
1286++ printf("Auto-updating system plugin path.\n");
1287++ return process_plugin_dir(get_system_mozilla_plugin_dir(), (is_plugin_cb)is_wrapper_plugin_0, (process_plugin_cb)update_plugin);
1288++ }
1289++
1290+ if (argc < 1)
1291+ error("expected plugin(s) file name to update");
1292+
1293+@@ -1371,6 +1380,12 @@
1294+ return 0;
1295+ }
1296+
1297++static int process_system_only(int argc, char *argv[])
1298++{
1299++ g_systemonly = true;
1300++ return 0;
1301++}
1302++
1303+ int main(int argc, char *argv[])
1304+ {
1305+ char **args;
1306+@@ -1399,6 +1414,7 @@
1307+ { 'h', "help", process_help, 1 },
1308+ { 'v', "verbose", process_verbose, 0 },
1309+ { 'a', "auto", process_auto, 0 },
1310++ { 's', "systemonly", process_system_only, 0 },
1311+ { 'n', "native", process_native, 0 },
1312+ { 'l', "list", process_list, 1 },
1313+ { 'x', "nosymlinks", process_nolink, 0 },
1314
1315=== modified file 'debian/patches/005_process_env_dirs.diff'
1316--- debian/patches/005_process_env_dirs.diff 2009-04-02 14:37:55 +0000
1317+++ debian/patches/005_process_env_dirs.diff 2009-08-11 01:28:09 +0000
1318@@ -4,10 +4,10 @@
1319 Adjust npconfig_CFLAGS in Makefile to include glib during compile.
1320
1321 -- Sasa Bodiroza <jazzva@gmail.com> Wed, 01 Apr 2009 21:50:00 +0200
1322-Index: ubuntu.1.2.2-0ubuntu3/src/npw-config.c
1323+Index: nspluginwrapper/src/npw-config.c
1324 ===================================================================
1325---- ubuntu.1.2.2-0ubuntu3.orig/src/npw-config.c 2009-04-02 16:29:55.000000000 +0200
1326-+++ ubuntu.1.2.2-0ubuntu3/src/npw-config.c 2009-04-02 16:32:56.000000000 +0200
1327+--- nspluginwrapper.orig/src/npw-config.c 2009-08-11 03:22:49.000000000 +0200
1328++++ nspluginwrapper/src/npw-config.c 2009-08-11 03:22:49.000000000 +0200
1329 @@ -38,6 +38,7 @@
1330 #include <pwd.h>
1331 #include <dirent.h>
1332@@ -16,7 +16,7 @@
1333
1334 static bool g_auto = false;
1335 static bool g_verbose = false;
1336-@@ -213,6 +214,21 @@
1337+@@ -279,6 +280,21 @@
1338 return plugin_path;
1339 }
1340
1341@@ -38,7 +38,7 @@
1342 static const char **get_mozilla_plugin_dirs(void)
1343 {
1344 static const char *default_dirs[] = {
1345-@@ -257,13 +273,23 @@
1346+@@ -323,13 +339,23 @@
1347 };
1348
1349 const int n_default_dirs = (sizeof(default_dirs) / sizeof(default_dirs[0]));
1350@@ -63,10 +63,10 @@
1351 dirs[j++] = get_user_mozilla_plugin_dir();
1352 dirs[j] = NULL;
1353 return dirs;
1354-Index: ubuntu.1.2.2-0ubuntu3/Makefile
1355+Index: nspluginwrapper/Makefile
1356 ===================================================================
1357---- ubuntu.1.2.2-0ubuntu3.orig/Makefile 2009-04-02 16:29:55.000000000 +0200
1358-+++ ubuntu.1.2.2-0ubuntu3/Makefile 2009-04-02 16:29:55.000000000 +0200
1359+--- nspluginwrapper.orig/Makefile 2009-08-11 03:22:48.000000000 +0200
1360++++ nspluginwrapper/Makefile 2009-08-11 03:22:49.000000000 +0200
1361 @@ -174,7 +174,8 @@
1362 npconfig_RAWSRCS = npw-config.c
1363 npconfig_SOURCES = $(npconfig_RAWSRCS:%.c=$(SRC_PATH)/src/%.c)
1364@@ -77,7 +77,7 @@
1365 ifneq (,$(findstring $(OS),netbsd dragonfly))
1366 # We will try to dlopen() the native plugin library. If that lib is
1367 # linked against libpthread, then so must our program too.
1368-@@ -410,7 +411,7 @@
1369+@@ -402,7 +403,7 @@
1370 $(CC) -o $@ $(npconfig_OBJECTS) $(npconfig_LDFLAGS)
1371
1372 npconfig-%.o: $(SRC_PATH)/src/%.c
1373@@ -85,4 +85,4 @@
1374 + $(CC) -o $@ -c $< $(CPPFLAGS) $(CFLAGS) $(npconfig_CFLAGS)
1375
1376 $(nploader_PROGRAM): $(nploader_SOURCES)
1377- sed -e "s|%NPW_LIBDIR%|$(pkglibdir)|" $< > $@
1378+ sed -e 's|%NPW_VIEWER_DIR%|$(nptargetdir_var)|' $< > $@
1379
1380=== modified file 'debian/patches/series'
1381--- debian/patches/series 2009-04-01 20:10:03 +0000
1382+++ debian/patches/series 2009-08-11 01:28:09 +0000
1383@@ -3,4 +3,6 @@
1384 002_install_to_NSPLUGINDIR.diff
1385 003_update_help_info.diff
1386 004_fix_threading.diff
1387+004_system_only_update.diff
1388 005_process_env_dirs.diff
1389+use_syslsb.patch
1390
1391=== added file 'debian/patches/use_syslsb.patch'
1392--- debian/patches/use_syslsb.patch 1970-01-01 00:00:00 +0000
1393+++ debian/patches/use_syslsb.patch 2009-08-11 01:11:02 +0000
1394@@ -0,0 +1,126 @@
1395+---
1396+ Makefile | 36 ++++++++++++++++++++++++++++++++++++
1397+ 1 file changed, 36 insertions(+)
1398+
1399+Index: nspluginwrapper/Makefile
1400+===================================================================
1401+--- nspluginwrapper.orig/Makefile 2009-08-11 03:03:59.000000000 +0200
1402++++ nspluginwrapper/Makefile 2009-08-11 03:10:00.000000000 +0200
1403+@@ -79,11 +79,13 @@
1404+ ARCH_32 = $(ARCH)
1405+ ifeq ($(build_biarch), yes)
1406+ ARCH_32 = $(TARGET_ARCH)
1407++ifeq (,$(USE_SYSTEM_LSB))
1408+ LSB_LIBS = $(LSB_OBJ_DIR)/libc.so $(LSB_OBJ_DIR)/libgcc_s_32.so
1409+ LSB_LIBS += $(LSB_CORE_STUBS:%=$(LSB_OBJ_DIR)/%.so)
1410+ LSB_LIBS += $(LSB_CORE_STATIC_STUBS:%=$(LSB_OBJ_DIR)/%.a)
1411+ LSB_LIBS += $(LSB_DESKTOP_STUBS:%=$(LSB_OBJ_DIR)/%.so)
1412+ endif
1413++endif
1414+
1415+ LSB_TOP_DIR = $(SRC_PATH)/lsb-build
1416+ LSB_INC_DIR = $(LSB_TOP_DIR)/headers
1417+@@ -119,7 +121,11 @@
1418+ npviewer_CFLAGS += -I$(LSB_INC_DIR)
1419+ npviewer_CFLAGS += -I$(LSB_INC_DIR)/glib-2.0
1420+ npviewer_CFLAGS += -I$(LSB_INC_DIR)/gtk-2.0
1421++ifeq (,$(USE_SYSTEM_LSB))
1422+ npviewer_LDFLAGS = $(LDFLAGS_32) -L$(LSB_OBJ_DIR)
1423++else
1424++npviewer_LDFLAGS = $(LDFLAGS_32) -L/usr/lib32/
1425++endif
1426+ npviewer_LDFLAGS += -lgtk-x11-2.0 -lgdk-x11-2.0 -lgobject-2.0 -ldl -lglib-2.0 -lgthread-2.0 -lX11 -lXt
1427+ else
1428+ npviewer_CFLAGS += $(GTK_CFLAGS)
1429+@@ -157,7 +163,11 @@
1430+ libxpcom_CFLAGS = $(PIC_CFLAGS)
1431+ ifeq ($(build_biarch),yes)
1432+ libxpcom_CFLAGS += -I$(LSB_INC_DIR)
1433++ifeq (,$(USE_SYSTEM_LSB))
1434+ libxpcom_LDFLAGS = $(LDFLAGS_32) -L$(LSB_OBJ_DIR)
1435++else
1436++libxpcom_LDFLAGS = $(LDFLAGS_32) -L/usr/lib32/
1437++endif
1438+ endif
1439+
1440+ libnoxshm_LIBRARY = libnoxshm.so
1441+@@ -167,7 +177,11 @@
1442+ libnoxshm_CFLAGS = $(PIC_CFLAGS)
1443+ ifeq ($(biarch),yes)
1444+ libnoxshm_CFLAGS += -I$(LSB_INC_DIR)
1445++ifeq (,$(USE_SYSTEM_LSB))
1446+ libnoxshm_LDFLAGS = $(LDFLAGS_32) -L$(LSB_OBJ_DIR)
1447++else
1448++libxpcom_LDFLAGS = $(LDFLAGS_32) -L/usr/lib32/
1449++endif
1450+ endif
1451+
1452+ npconfig_PROGRAM = npconfig
1453+@@ -235,6 +249,7 @@
1454+ FILES += $(addprefix $(LSB_TOP_DIR)/headers/,$(shell cat $(LSB_TOP_DIR)/headers/core_filelist))
1455+ FILES += $(LSB_TOP_DIR)/headers/desktop_filelist
1456+ FILES += $(addprefix $(LSB_TOP_DIR)/headers/,$(shell cat $(LSB_TOP_DIR)/headers/desktop_filelist))
1457++ifeq (,$(USE_SYSTEM_LSB))
1458+ FILES += $(LSB_SRC_DIR)/LibNameMap.txt
1459+ FILES += $(LSB_SRC_DIR)/core_filelist
1460+ FILES += $(LSB_SRC_DIR)/core_static_filelist
1461+@@ -244,6 +259,7 @@
1462+ FILES += $(patsubst %,$(LSB_SRC_DIR)/%.c,$(LSB_CORE_STATIC_STUBS))
1463+ FILES += $(patsubst %,$(LSB_SRC_DIR)/%.c,$(LSB_DESKTOP_STUBS))
1464+ FILES += $(patsubst %,$(LSB_SRC_DIR)/%.Version,$(LSB_DESKTOP_STUBS))
1465++endif
1466+
1467+ all: $(TARGETS)
1468+
1469+@@ -370,8 +386,13 @@
1470+ npwrapper-%.os: $(SRC_PATH)/src/%.c
1471+ $(CC) -o $@ -c $< $(PIC_CFLAGS) $(CPPFLAGS) $(npwrapper_CFLAGS) -DBUILD_WRAPPER
1472+
1473++ifeq (,$(USE_SYSTEM_LSB))
1474+ $(npviewer_PROGRAM): $(npviewer_OBJECTS) $(npviewer_MAPFILE) $(LSB_OBJ_DIR) $(LSB_LIBS)
1475+ $(CC) $(LDFLAGS_32) -o $@ $(npviewer_OBJECTS) $(npviewer_LDFLAGS)
1476++else
1477++$(npviewer_PROGRAM): $(npviewer_OBJECTS) $(npviewer_MAPFILE)
1478++ $(CC) $(LDFLAGS_32) -o $@ $(npviewer_OBJECTS) $(npviewer_LDFLAGS)
1479++endif
1480+
1481+ npviewer-%.o: $(SRC_PATH)/src/%.c
1482+ $(CC) $(CFLAGS_32) -o $@ -c $< $(CPPFLAGS) $(npviewer_CFLAGS) -DBUILD_VIEWER
1483+@@ -379,22 +400,37 @@
1484+ npviewer-%.o: $(SRC_PATH)/src/%.cpp
1485+ $(CXX) $(CFLAGS_32) -o $@ -c $< $(CPPFLAGS) $(npviewer_CFLAGS) -DBUILD_VIEWER
1486+
1487++ifeq (,$(USE_SYSTEM_LSB))
1488+ $(npplayer_PROGRAM): $(npplayer_OBJECTS) $(npplayer_MAPFILE) $(LSB_OBJ_DIR) $(LSB_LIBS)
1489+ $(CC) $(LDFLAGS) -o $@ $(npplayer_OBJECTS) $(npplayer_LDFLAGS)
1490++else
1491++$(npplayer_PROGRAM): $(npplayer_OBJECTS) $(npplayer_MAPFILE)
1492++ $(CC) $(LDFLAGS) -o $@ $(npplayer_OBJECTS) $(npplayer_LDFLAGS)
1493++endif
1494+
1495+ npplayer-%.o: $(SRC_PATH)/src/%.c
1496+ $(CC) $(CFLAGS) -o $@ -c $< $(CPPFLAGS) $(npplayer_CFLAGS) -DBUILD_PLAYER
1497+ npplayer-%.o: $(SRC_PATH)/src/tidy/%.c
1498+ $(CC) $(CFLAGS) -o $@ -c $< $(CPPFLAGS) $(npplayer_CFLAGS) -DBUILD_PLAYER
1499+
1500++ifeq (,$(USE_SYSTEM_LSB))
1501+ $(libxpcom_LIBRARY): $(libxpcom_OBJECTS) $(LSB_OBJ_DIR) $(LSB_LIBS)
1502+ $(CC) $(LDFLAGS_32) $(DSO_LDFLAGS) -o $@ $(libxpcom_OBJECTS) $(libxpcom_LDFLAGS) -Wl,$(LD_soname),libxpcom.so
1503++else
1504++$(libxpcom_LIBRARY): $(libxpcom_OBJECTS)
1505++ $(CC) $(LDFLAGS_32) $(DSO_LDFLAGS) -o $@ $(libxpcom_OBJECTS) $(libxpcom_LDFLAGS) -Wl,$(LD_soname),libxpcom.so
1506++endif
1507+
1508+ libxpcom-%.o: $(SRC_PATH)/src/%.c
1509+ $(CC) $(CFLAGS_32) -o $@ -c $< $(CPPFLAGS) $(libxpcom_CFLAGS) -DBUILD_XPCOM
1510+
1511++ifeq (,$(USE_SYSTEM_LSB))
1512+ $(libnoxshm_LIBRARY): $(libnoxshm_OBJECTS) $(LSB_OBJ_DIR) $(LSB_LIBS)
1513+ $(CC) $(LDFLAGS_32) $(DSO_LDFLAGS) -o $@ $(libnoxshm_OBJECTS) $(libnoxshm_LDFLAGS) -Wl,$(LD_soname),libnoxshm.so
1514++else
1515++$(libnoxshm_LIBRARY): $(libnoxshm_OBJECTS)
1516++ $(CC) $(LDFLAGS_32) $(DSO_LDFLAGS) -o $@ $(libnoxshm_OBJECTS) $(libnoxshm_LDFLAGS) -Wl,$(LD_soname),libnoxshm.so
1517++endif
1518+
1519+ libnoxshm-%.o: $(SRC_PATH)/src/%.c
1520+ $(CC) $(CFLAGS_32) -o $@ -c $< $(CPPFLAGS) $(libnoxshm_CFLAGS)
1521
1522=== modified file 'debian/rules' (properties changed: +x to -x)
1523--- debian/rules 2008-08-27 01:07:14 +0000
1524+++ debian/rules 2009-08-11 00:37:05 +0000
1525@@ -49,7 +49,7 @@
1526 build: configure build-stamp
1527 build-stamp:
1528 dh_testdir
1529- $(MAKE)
1530+ $(MAKE) USE_SYSTEM_LSB=1
1531 touch $@
1532
1533 clean: clean-patched unpatch
1534@@ -65,7 +65,7 @@
1535 dh_testroot
1536 dh_clean -k
1537 dh_installdirs
1538- $(MAKE) DESTDIR=$(CURDIR)/debian/nspluginwrapper install
1539+ $(MAKE) USE_SYSTEM_LSB=1 DESTDIR=$(CURDIR)/debian/nspluginwrapper install
1540
1541
1542 # Build architecture-independent files here.
1543
1544=== modified file 'lsb-build/headers/glib-2.0/glib.h'
1545--- lsb-build/headers/glib-2.0/glib.h 2008-10-15 15:29:08 +0000
1546+++ lsb-build/headers/glib-2.0/glib.h 2009-08-11 00:38:42 +0000
1547@@ -2642,6 +2642,7 @@
1548 extern GHashTable *g_hash_table_new(GHashFunc, GEqualFunc);
1549 extern const gchar *g_dir_read_name(GDir *);
1550 extern gboolean g_hash_table_remove(GHashTable *, gconstpointer);
1551+ extern void g_hash_table_remove_all(GHashTable *);
1552 extern gchar *g_utf8_strdown(const gchar *, gssize);
1553 extern GIOCondition g_io_channel_get_buffer_condition(GIOChannel *);
1554 extern GSource *g_child_watch_source_new(GPid);
1555
1556=== modified file 'lsb-build/stub_libs/libglib-2.0.c'
1557--- lsb-build/stub_libs/libglib-2.0.c 2008-10-15 15:29:08 +0000
1558+++ lsb-build/stub_libs/libglib-2.0.c 2009-08-11 00:38:42 +0000
1559@@ -195,6 +195,7 @@
1560 void g_hash_table_new() {} ;
1561 void g_hash_table_new_full() {} ;
1562 void g_hash_table_remove() {} ;
1563+void g_hash_table_remove_all() {} ;
1564 void g_hash_table_replace() {} ;
1565 void g_hash_table_size() {} ;
1566 void g_hash_table_steal() {} ;
1567
1568=== modified file 'nspluginwrapper.spec'
1569--- nspluginwrapper.spec 2009-01-02 10:07:27 +0000
1570+++ nspluginwrapper.spec 2009-08-11 00:38:42 +0000
1571@@ -1,7 +1,7 @@
1572 %define name nspluginwrapper
1573-%define version 1.2.2
1574+%define version 1.3.0
1575 %define release 1
1576-#define svndate DATE
1577+#define svndate 20090102
1578
1579 # define 32-bit arch of multiarch platforms
1580 %define arch_32 %{nil}
1581@@ -159,7 +159,7 @@
1582 %{plugindir}/npwrapper.so
1583 %dir %{pkglibdir}
1584 %dir %{pkglibdir}/noarch
1585-%{pkglibdir}/noarch/npviewer
1586+%{pkglibdir}/noarch/npviewer.sh
1587 %dir %{pkglibdir}/%{_arch}
1588 %dir %{pkglibdir}/%{_arch}/%{_os}
1589 %{pkglibdir}/%{_arch}/%{_os}/npconfig
1590@@ -191,6 +191,14 @@
1591 %endif
1592
1593 %changelog
1594+* Fri Jan 02 2009 Gwenole Beauchesne <gb.public@free.fr> 1.3.0-1
1595+- don't poll for Xt events in Gtk (XEMBED) plug-ins
1596+- use 40 Hz timer for Xt events only when necessary (Xt input sources)
1597+- add NPIdentifier and NPClass::HasMethod caches, i.e. lower RPC traffic
1598+- add support for multiple viewer paths, see --viewer-paths=PATH-EXPR
1599+- add basic checks for malloc()'ed buffer underflow/overflow
1600+- add checks for single-threaded calls into the browser (NPN_*() functions)
1601+
1602 * Fri Jan 02 2009 Gwenole Beauchesne <gb.public@free.fr> 1.2.2-1
1603 - fix support for the VLC plug-in
1604 - fix memory deallocation in NPN_GetStringIdentifiers()
1605
1606=== modified file 'src/npruntime-impl.h'
1607--- src/npruntime-impl.h 2009-01-02 10:07:27 +0000
1608+++ src/npruntime-impl.h 2009-08-11 00:38:42 +0000
1609@@ -27,6 +27,7 @@
1610 uint32_t npobj_id;
1611 bool is_valid;
1612 void *plugin;
1613+ void *hasMethod_cache;
1614 } NPObjectInfo;
1615
1616 extern NPObjectInfo *npobject_info_new(NPObject *npobj) attribute_hidden;
1617@@ -59,6 +60,10 @@
1618 extern void print_npvariant_args(const struct _NPVariant *args, uint32_t nargs) attribute_hidden;
1619
1620 // Deactivate all NPObject instances
1621-extern void npruntime_deactivate(void);
1622+extern void npruntime_deactivate(void) attribute_hidden;
1623+
1624+// Check whether to use NPRuntime data caching
1625+// (on by default, disabled with NPW_NPRUNTIME_CACHE=0|no)
1626+extern bool npruntime_use_cache(void) attribute_hidden;
1627
1628 #endif /* NPRUNTIME_IMPL_H */
1629
1630=== modified file 'src/npruntime.c'
1631--- src/npruntime.c 2009-01-02 10:07:27 +0000
1632+++ src/npruntime.c 2009-08-11 00:38:42 +0000
1633@@ -30,15 +30,55 @@
1634 #include "debug.h"
1635
1636
1637+// Define to enable NPClass::HasMethod cache
1638+#define USE_NPCLASS_HAS_METHOD_CACHE 1
1639+
1640+// Define to enable NPClass::HasProperty cache (derived from ::HasMethod cache)
1641+#define USE_NPCLASS_HAS_PROPERTY_CACHE 1
1642+
1643 // Defined in npw-{wrapper,viewer}.c
1644 extern rpc_connection_t *g_rpc_connection attribute_hidden;
1645
1646 // Defined in npw-viewer.c
1647-#if USE_PID_CHECK && NPW_IS_PLUGIN
1648-extern bool pid_check(void);
1649-#else
1650-#define pid_check() true
1651-#endif
1652+#if defined(ENABLE_THREAD_CHECK) && NPW_IS_PLUGIN
1653+extern bool thread_check(void);
1654+#else
1655+#define thread_check() true
1656+#endif
1657+
1658+
1659+/* ====================================================================== */
1660+/* === Helpers === */
1661+/* ====================================================================== */
1662+
1663+static inline bool get_use_npruntime_cache_env(void)
1664+{
1665+ const gchar *env = getenv("NPW_NPRUNTIME_CACHE");
1666+ return env == NULL || (strcmp(env, "no") != 0 && strcmp(env, "0") != 0);
1667+}
1668+
1669+bool npruntime_use_cache(void)
1670+{
1671+ static int use_cache = -1;
1672+ if (G_UNLIKELY(use_cache < 0))
1673+ use_cache = get_use_npruntime_cache_env();
1674+ return use_cache;
1675+}
1676+
1677+static inline bool use_npclass_has_method_cache(void)
1678+{
1679+#if USE_NPCLASS_HAS_METHOD_CACHE
1680+ return npruntime_use_cache();
1681+#else
1682+ return false;
1683+#endif
1684+}
1685+
1686+static inline bool use_npclass_has_property_cache(void)
1687+{
1688+ /* this depends on the NPClass::HasMethod cache */
1689+ return use_npclass_has_method_cache();
1690+}
1691
1692
1693 /* ====================================================================== */
1694@@ -131,8 +171,8 @@
1695 if (!is_valid_npobject_class(npobj))
1696 return;
1697
1698- if (!pid_check()) {
1699- npw_printf("WARNING: NPClass::Invalidate called from the wrong process\n");
1700+ if (!thread_check()) {
1701+ npw_printf("WARNING: NPClass::Invalidate not called from the main thread\n");
1702 return;
1703 }
1704
1705@@ -196,18 +236,34 @@
1706 return ret;
1707 }
1708
1709+static bool npclass_cached_HasMethod(NPObject *npobj, NPIdentifier name)
1710+{
1711+ NPObjectInfo *npobj_info = npobject_info_lookup(npobj);
1712+ if (use_npclass_has_method_cache() && npobj_info) {
1713+ if (G_UNLIKELY(npobj_info->hasMethod_cache == NULL))
1714+ npobj_info->hasMethod_cache = g_hash_table_new(NULL, NULL);
1715+ gpointer hasMethod = NULL;
1716+ if (g_hash_table_lookup_extended(npobj_info->hasMethod_cache, name, NULL, &hasMethod))
1717+ return GPOINTER_TO_UINT(hasMethod);
1718+ }
1719+ bool hasMethod = npclass_invoke_HasMethod(npobj, name);
1720+ if (use_npclass_has_method_cache() && npobj_info)
1721+ g_hash_table_insert(npobj_info->hasMethod_cache, name, GUINT_TO_POINTER(hasMethod));
1722+ return hasMethod;
1723+}
1724+
1725 bool g_NPClass_HasMethod(NPObject *npobj, NPIdentifier name)
1726 {
1727 if (!is_valid_npobject_class(npobj))
1728 return false;
1729
1730- if (!pid_check()) {
1731- npw_printf("WARNING: NPClass::HasMethod called from the wrong process\n");
1732+ if (!thread_check()) {
1733+ npw_printf("WARNING: NPClass::HasMethod not called from the main thread\n");
1734 return false;
1735 }
1736
1737 D(bugiI("NPClass::HasMethod(npobj %p, name id %p)\n", npobj, name));
1738- bool ret = npclass_invoke_HasMethod(npobj, name);
1739+ bool ret = npclass_cached_HasMethod(npobj, name);
1740 D(bugiD("NPClass::HasMethod return: %d\n", ret));
1741 return ret;
1742 }
1743@@ -300,8 +356,8 @@
1744 if (!is_valid_npobject_class(npobj))
1745 return false;
1746
1747- if (!pid_check()) {
1748- npw_printf("WARNING: NPClass::Invoke called from the wrong process\n");
1749+ if (!thread_check()) {
1750+ npw_printf("WARNING: NPClass::Invoke not called from the main thread\n");
1751 return false;
1752 }
1753
1754@@ -399,8 +455,8 @@
1755 if (!is_valid_npobject_class(npobj))
1756 return false;
1757
1758- if (!pid_check()) {
1759- npw_printf("WARNING: NPClass::InvokeDefault called from the wrong process\n");
1760+ if (!thread_check()) {
1761+ npw_printf("WARNING: NPClass::InvokeDefault not called from the main thread\n");
1762 return false;
1763 }
1764
1765@@ -468,18 +524,29 @@
1766 return ret;
1767 }
1768
1769+static bool npclass_cached_HasProperty(NPObject *npobj, NPIdentifier name)
1770+{
1771+ NPObjectInfo *npobj_info = npobject_info_lookup(npobj);
1772+ if (use_npclass_has_property_cache() && npobj_info && npobj_info->hasMethod_cache) {
1773+ /* If the NPIdentifier references a method, it can't be a property */
1774+ if (g_hash_table_lookup_extended(npobj_info->hasMethod_cache, name, NULL, NULL))
1775+ return false;
1776+ }
1777+ return npclass_invoke_HasProperty(npobj, name);
1778+}
1779+
1780 bool g_NPClass_HasProperty(NPObject *npobj, NPIdentifier name)
1781 {
1782 if (!is_valid_npobject_class(npobj))
1783 return false;
1784
1785- if (!pid_check()) {
1786- npw_printf("WARNING: NPClass::HasProperty called from the wrong process\n");
1787+ if (!thread_check()) {
1788+ npw_printf("WARNING: NPClass::HasProperty not called from the main thread\n");
1789 return false;
1790 }
1791
1792 D(bugiI("NPClass::HasProperty(npobj %p, name id %p)\n", npobj, name));
1793- bool ret = npclass_invoke_HasProperty(npobj, name);
1794+ bool ret = npclass_cached_HasProperty(npobj, name);
1795 D(bugiD("NPClass::HasProperty return: %d\n", ret));
1796 return ret;
1797 }
1798@@ -559,8 +626,8 @@
1799 if (!is_valid_npobject_class(npobj))
1800 return false;
1801
1802- if (!pid_check()) {
1803- npw_printf("WARNING: NPClass::GetProperty called from the wrong process\n");
1804+ if (!thread_check()) {
1805+ npw_printf("WARNING: NPClass::GetProperty not called from the main thread\n");
1806 return false;
1807 }
1808
1809@@ -645,8 +712,8 @@
1810 if (!is_valid_npobject_class(npobj))
1811 return false;
1812
1813- if (!pid_check()) {
1814- npw_printf("WARNING: NPClass::SetProperty called from the wrong process\n");
1815+ if (!thread_check()) {
1816+ npw_printf("WARNING: NPClass::SetProperty not called from the main thread\n");
1817 return false;
1818 }
1819
1820@@ -716,8 +783,8 @@
1821 if (!is_valid_npobject_class(npobj))
1822 return false;
1823
1824- if (!pid_check()) {
1825- npw_printf("WARNING: NPClass::RemoveProperty called from the wrong process\n");
1826+ if (!thread_check()) {
1827+ npw_printf("WARNING: NPClass::RemoveProperty not called from the main thread\n");
1828 return false;
1829 }
1830
1831@@ -734,22 +801,31 @@
1832
1833 NPObjectInfo *npobject_info_new(NPObject *npobj)
1834 {
1835- NPObjectInfo *npobj_info = NPW_MemNew0(NPObjectInfo, 1);
1836+ NPObjectInfo *npobj_info = NPW_MemNew(NPObjectInfo, 1);
1837 if (npobj_info) {
1838 static uint32_t id;
1839 npobj_info->npobj = npobj;
1840 npobj_info->npobj_id = ++id;
1841 npobj_info->is_valid = true;
1842+ npobj_info->plugin = NULL;
1843+ npobj_info->hasMethod_cache = NULL;
1844 }
1845 return npobj_info;
1846 }
1847
1848 void npobject_info_destroy(NPObjectInfo *npobj_info)
1849 {
1850- if (npobj_info) {
1851- npw_plugin_instance_unref(npobj_info->plugin);
1852- NPW_MemFree(npobj_info);
1853+ if (npobj_info == NULL)
1854+ return;
1855+
1856+ npw_plugin_instance_unref(npobj_info->plugin);
1857+
1858+ if (npobj_info->hasMethod_cache) {
1859+ g_hash_table_destroy(npobj_info->hasMethod_cache);
1860+ npobj_info->hasMethod_cache = NULL;
1861 }
1862+
1863+ NPW_MemFree(npobj_info);
1864 }
1865
1866
1867
1868=== modified file 'src/npw-config.c'
1869--- src/npw-config.c 2009-01-02 10:12:06 +0000
1870+++ src/npw-config.c 2009-08-11 00:40:05 +0000
1871@@ -71,6 +71,71 @@
1872 return 1;
1873 }
1874
1875+static const char *strnstr(const char *str, int len, const char *substr)
1876+{
1877+ const char *match = strstr(str, substr);
1878+ if (len > 0 && (match + strlen(substr) > str + len))
1879+ match = NULL;
1880+ return match;
1881+}
1882+
1883+typedef struct {
1884+ const char *name;
1885+ const char *value;
1886+} Var;
1887+
1888+static int strexpand(char *dst, int dstlen, const char *src, int srclen, const Var *vars)
1889+{
1890+ if (dst == NULL || dstlen < 1 || src == NULL)
1891+ return -1;
1892+
1893+ if (srclen <= 0)
1894+ srclen = strlen(src);
1895+
1896+ int n = 0;
1897+ for (int i = 0; i < srclen; i++) {
1898+ char ch = src[i];
1899+ if (ch != '%') {
1900+ dst[n++] = ch;
1901+ if (n >= dstlen - 1)
1902+ return -1;
1903+ }
1904+ else {
1905+ char var[16];
1906+ const char *str = &src[i + 1];
1907+ const char *end = strchr(str, '%');
1908+ if (end == NULL)
1909+ error("unterminated var '%s'", str);
1910+
1911+ int len = end - str;
1912+ if (len >= sizeof(var) - 1) {
1913+ len = sizeof(var) - 1;
1914+ memcpy(var, str, len);
1915+ var[len] = '\0';
1916+ error("unsupported var '%s...'", var);
1917+ }
1918+ memcpy(var, str, len);
1919+ var[len] = '\0';
1920+
1921+ str = NULL;
1922+ for (int j = 0; vars[j].name != NULL; j++) {
1923+ if (strcmp(vars[j].name, var) == 0) {
1924+ str = vars[j].value;
1925+ break;
1926+ }
1927+ }
1928+ if (str == NULL)
1929+ error("could not expand var '%s'", var);
1930+ i += len + 1;
1931+ len = strlen(str);
1932+ memcpy(&dst[n], str, len);
1933+ n += len;
1934+ }
1935+ }
1936+ dst[n] = '\0';
1937+ return 0;
1938+}
1939+
1940 /* Implement mkdir -p with default permissions (derived from busybox code) */
1941 static int mkdir_p(const char *path)
1942 {
1943@@ -489,6 +554,30 @@
1944 EXIT_VIEWER_NATIVE = 20
1945 };
1946
1947+static bool is_plugin_viewer_ok(const char *viewer_path, const char *filename)
1948+{
1949+ int pid = fork();
1950+ if (pid < 0)
1951+ return false;
1952+ if (pid == 0) {
1953+ if (!g_verbose) {
1954+ // don't spit out errors in non-verbose mode, we only need
1955+ // to know whether there is a valid viewer or not
1956+ freopen("/dev/null", "w", stderr);
1957+ }
1958+ execl(viewer_path, NPW_VIEWER, "--test", "--plugin", filename, NULL);
1959+ exit(1);
1960+ }
1961+ else {
1962+ int status;
1963+ while (waitpid(pid, &status, 0) != pid)
1964+ ;
1965+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
1966+ return true;
1967+ }
1968+ return false;
1969+}
1970+
1971 static int detect_plugin_viewer(const char *filename, NPW_PluginInfo *out_plugin_info)
1972 {
1973 static const char *target_arch_table[] = {
1974@@ -522,52 +611,60 @@
1975 && out_plugin_info->target_os && strcmp(out_plugin_info->target_os, HOST_OS) == 0)
1976 return EXIT_VIEWER_NATIVE;
1977
1978- for (int i = 0; i < target_arch_table_size; i++) {
1979- const char *target_arch = target_arch_table[i];
1980- if (target_arch == NULL)
1981- continue;
1982- char viewer_arch_path[PATH_MAX];
1983- sprintf(viewer_arch_path, "%s/%s", NPW_LIBDIR, target_arch);
1984- if (access(viewer_arch_path, F_OK) != 0) {
1985- target_arch_table[i] = NULL; // this target ARCH is not available, skip it for good
1986- continue;
1987- }
1988- for (int j = 0; j < target_os_table_size; j++) {
1989- const char *target_os = target_os_table[j];
1990- if (target_os == NULL)
1991- continue;
1992- char viewer_path[PATH_MAX];
1993- sprintf(viewer_path, "%s/%s/%s", viewer_arch_path, target_os, NPW_VIEWER);
1994- if (access(viewer_path, F_OK) != 0)
1995- continue;
1996- int pid = fork();
1997- if (pid < 0)
1998- continue;
1999- else if (pid == 0) {
2000- if (!g_verbose) {
2001- // don't spit out errors in non-verbose mode, we only need
2002- // to know whether there is a valid viewer or not
2003- freopen("/dev/null", "w", stderr);
2004- }
2005- execl(viewer_path, NPW_VIEWER, "--test", "--plugin", filename, NULL);
2006- exit(1);
2007- }
2008- else {
2009- int status;
2010- while (waitpid(pid, &status, 0) != pid)
2011- ;
2012- if (WIFEXITED(status)) {
2013- status = WEXITSTATUS(status);
2014- if (status == EXIT_VIEWER_OK && out_plugin_info) {
2015- strcpy(out_plugin_info->target_arch, target_arch);
2016- strcpy(out_plugin_info->target_os, target_os);
2017- }
2018- return status;
2019- }
2020- return EXIT_VIEWER_ERROR;
2021- }
2022- }
2023- }
2024+ enum { VAR_ARCH, VAR_OS, VAR_COUNT };
2025+ Var vars[VAR_COUNT+1];
2026+ vars[VAR_ARCH].name = "ARCH";
2027+ vars[VAR_OS].name = "OS";
2028+ vars[VAR_COUNT].name = NULL;
2029+ vars[VAR_COUNT].value = NULL;
2030+
2031+ char viewer_path[sizeof(out_plugin_info->viewer_path)];
2032+ const int viewer_path_len = sizeof(viewer_path) - strlen(NPW_VIEWER) - 1;
2033+ const char viewer_paths[] = NPW_VIEWER_PATHS;
2034+ const char *viewer_path_spec_end, *viewer_path_spec = viewer_paths;
2035+ do {
2036+ int len;
2037+ if ((viewer_path_spec_end = strchr(viewer_path_spec, ':')) != NULL)
2038+ len = viewer_path_spec_end - viewer_path_spec;
2039+ else
2040+ len = strchr(viewer_path_spec, '\0') - viewer_path_spec;
2041+
2042+ for (int i = 0; i < target_arch_table_size; i++) {
2043+ const char *target_arch = target_arch_table[i];
2044+ if (target_arch == NULL)
2045+ continue;
2046+ vars[VAR_ARCH].value = target_arch;
2047+
2048+ for (int j = 0; j < target_os_table_size; j++) {
2049+ const char *target_os = target_os_table[j];
2050+ if (target_os == NULL)
2051+ continue;
2052+ vars[VAR_OS].value = target_os;
2053+
2054+ if (strexpand(viewer_path, viewer_path_len, viewer_path_spec, len, vars) < 0)
2055+ continue;
2056+ strcat(viewer_path, "/" NPW_VIEWER);
2057+ if (access(viewer_path, F_OK) != 0)
2058+ continue;
2059+
2060+ if (is_plugin_viewer_ok(viewer_path, filename)) {
2061+ strcpy(out_plugin_info->target_arch, target_arch);
2062+ strcpy(out_plugin_info->target_os, target_os);
2063+ strcpy(out_plugin_info->viewer_path, viewer_path);
2064+ return EXIT_VIEWER_OK;
2065+ }
2066+
2067+ if (strnstr(viewer_path_spec, len, "%OS%") == NULL)
2068+ break; // don't iterate over OS table if there is no "%OS%" pattern
2069+ }
2070+
2071+ if (strnstr(viewer_path_spec, len, "%ARCH%") == NULL)
2072+ break; // don't iterate over ARCH table if there is no "%ARCH%" pattern
2073+ }
2074+
2075+ viewer_path_spec += len + 1;
2076+ } while (viewer_path_spec_end != NULL);
2077+
2078 return EXIT_VIEWER_NOT_FOUND;
2079 }
2080
2081@@ -604,15 +701,27 @@
2082 if ((pi = (NPW_PluginInfo *)dlsym(handle, "NPW_Plugin")) == NULL)
2083 return false;
2084 if (out_plugin_info) {
2085+ int plugin_info_version = 0;
2086+ if (strncmp(pi->ident, "NPW:0.9.90", 10) != 0)
2087+ plugin_info_version = 1;
2088+ if (strncmp(pi->ident, "NPW:X:", 6) == 0)
2089+ plugin_info_version = pi->struct_version;
2090+ out_plugin_info->struct_version = plugin_info_version;
2091 strcpy(out_plugin_info->ident, pi->ident);
2092 strcpy(out_plugin_info->path, pi->path);
2093 out_plugin_info->mtime = pi->mtime;
2094- out_plugin_info->target_arch[0] = '\0';
2095- out_plugin_info->target_os[0] = '\0';
2096- if (strncmp(pi->ident, "NPW:0.9.90", 10) != 0) { // additional members in 0.9.91+
2097+ if (plugin_info_version >= 1) { // additional members in 0.9.91+
2098 strcpy(out_plugin_info->target_arch, pi->target_arch);
2099 strcpy(out_plugin_info->target_os, pi->target_os);
2100 }
2101+ else {
2102+ out_plugin_info->target_arch[0] = '\0';
2103+ out_plugin_info->target_os[0] = '\0';
2104+ }
2105+ if (plugin_info_version >= 2) // additional members in 1.3.0+
2106+ strcpy(out_plugin_info->viewer_path, pi->viewer_path);
2107+ else
2108+ out_plugin_info->viewer_path[0] = '\0';
2109 }
2110 return true;
2111 }
2112@@ -628,12 +737,26 @@
2113 return ret;
2114 }
2115
2116+static bool is_master_wrapper_plugin(const char *plugin_path)
2117+{
2118+ static const char *master_plugin_paths[] = {
2119+ NPW_LIBDIR "/" HOST_ARCH "/" NPW_WRAPPER,
2120+ NPW_LIBDIR "/" HOST_ARCH "/" HOST_OS "/" NPW_WRAPPER,
2121+ NPW_DEFAULT_PLUGIN_PATH,
2122+ NULL
2123+ };
2124+ for (int i = 0; master_plugin_paths[i] != NULL; i++) {
2125+ if (strcmp(master_plugin_paths[i], plugin_path) == 0)
2126+ return true;
2127+ }
2128+ return false;
2129+}
2130+
2131 static bool is_wrapper_plugin_0(const char *plugin_path)
2132 {
2133 NPW_PluginInfo plugin_info;
2134 return is_wrapper_plugin(plugin_path, &plugin_info)
2135- && strcmp(plugin_info.path, NPW_DEFAULT_PLUGIN_PATH) != 0 // exclude OS/ARCH npwrapper.so
2136- && strcmp(plugin_info.path, NPW_OLD_DEFAULT_PLUGIN_PATH) != 0; // exclude ARCH npwrapper.so
2137+ && !is_master_wrapper_plugin(plugin_path);
2138 }
2139
2140 static bool has_system_wide_wrapper_plugin(const char *plugin_path, bool check_ident)
2141@@ -789,11 +912,17 @@
2142 if (!is_plugin_viewer_available(plugin_path, plugin_info))
2143 return 15;
2144 }
2145+ if (plugin_info->viewer_path[0] == '\0') {
2146+ if (!is_plugin_viewer_available(plugin_path, plugin_info))
2147+ return 16;
2148+ }
2149
2150 NPW_PluginInfo *pi = (NPW_PluginInfo *)(plugin_data + ofs - NPW_PLUGIN_IDENT_SIZE);
2151 pi->mtime = st.st_mtime;
2152 strcpy(pi->target_arch, plugin_info->target_arch);
2153 strcpy(pi->target_os, plugin_info->target_os);
2154+ pi->struct_version = w_plugin_info.struct_version;
2155+ strcpy(pi->viewer_path, plugin_info->viewer_path);
2156
2157 int mode = 0700;
2158 if (!is_user_home_path(d_plugin_path) &&
2159@@ -902,6 +1031,7 @@
2160
2161 int ret = 0;
2162 NPW_PluginInfo plugin_info;
2163+ memset(&plugin_info, 0, sizeof(plugin_info));
2164 is_wrapper_plugin(plugin_path, &plugin_info);
2165
2166 struct stat st;
2167@@ -968,13 +1098,21 @@
2168 static int list_plugin(const char *plugin_path)
2169 {
2170 NPW_PluginInfo plugin_info;
2171+ memset(&plugin_info, 0, sizeof(plugin_info));
2172 is_wrapper_plugin(plugin_path, &plugin_info);
2173
2174 printf("%s\n", plugin_path);
2175 printf(" Original plugin: %s\n", plugin_info.path);
2176+ if (plugin_info.struct_version >= 2 && plugin_info.viewer_path[0] != '\0')
2177+ printf(" Plugin viewer: %s\n", plugin_info.viewer_path);
2178 char *str = strtok(plugin_info.ident, ":");
2179 if (str && strcmp(str, "NPW") == 0) {
2180 str = strtok(NULL, ":");
2181+ if (plugin_info.struct_version >= 2) { /* skip 'X' */
2182+ if (str[0] != 'X')
2183+ error("invalid NPW_PluginInfo format");
2184+ str = strtok(NULL, ":");
2185+ }
2186 if (str) {
2187 printf(" Wrapper version string: %s", str);
2188 str = strtok(NULL, ":");
2189@@ -1083,15 +1221,19 @@
2190
2191 for (i = 0; i < argc; i++) {
2192 NPW_PluginInfo plugin_info;
2193+ memset(&plugin_info, 0, sizeof(plugin_info));
2194+
2195 const char *plugin_path = argv[i];
2196 if (!is_plugin(plugin_path, &plugin_info))
2197 error("%s is not a valid NPAPI plugin", plugin_path);
2198+
2199 ret = detect_plugin_viewer(plugin_path, &plugin_info);
2200 if (ret != EXIT_VIEWER_OK) {
2201 if (ret == EXIT_VIEWER_NATIVE)
2202 return 0; /* silently ignore exit status */
2203 error("no appropriate viewer found for %s", plugin_path);
2204 }
2205+
2206 ret = install_plugin(plugin_path, &plugin_info);
2207 if (ret != 0)
2208 return ret;
2209
2210=== modified file 'src/npw-malloc.c'
2211--- src/npw-malloc.c 2009-01-02 10:07:27 +0000
2212+++ src/npw-malloc.c 2009-08-11 00:38:42 +0000
2213@@ -23,17 +23,33 @@
2214 #define DEBUG 1
2215 #include "debug.h"
2216
2217-typedef void *(*NPW_MemAllocProcPtr) (uint32_t);
2218-typedef void *(*NPW_MemAlloc0ProcPtr) (uint32_t);
2219-typedef void (*NPW_MemFreeProcPtr) (void *);
2220+typedef void *(*NPW_MemAllocProcPtr) (uint32_t);
2221+typedef void (*NPW_MemFreeProcPtr) (void *, uint32_t);
2222
2223 typedef struct _NPW_MallocHooks NPW_MallocHooks;
2224 struct _NPW_MallocHooks
2225 {
2226- NPW_MemAllocProcPtr memalloc;
2227- NPW_MemAlloc0ProcPtr memalloc0;
2228- NPW_MemFreeProcPtr memfree;
2229-};
2230+ NPW_MemAllocProcPtr memalloc;
2231+ NPW_MemAllocProcPtr memalloc0;
2232+ NPW_MemFreeProcPtr memfree;
2233+};
2234+
2235+#define NPW_MALLOC_MAGIC 0x4e50574d /* 'NPWM' */
2236+
2237+typedef struct _NPW_MemBlock NPW_MemBlock;
2238+struct _NPW_MemBlock
2239+{
2240+ uint32_t magic;
2241+ uint32_t real_size;
2242+ uint32_t alloc_size;
2243+ uint32_t alloc_lineno;
2244+ const char *alloc_file;
2245+};
2246+
2247+static void *npw_mem_alloc (uint32_t size, const char *file, int lineno);
2248+static void *npw_mem_alloc0 (uint32_t size, const char *file, int lineno);
2249+static void *npw_mem_alloc_copy (uint32_t size, const void *ptr, const char *file, int lineno);
2250+static void npw_mem_free (void *ptr, const char *file, int lineno);
2251
2252 /* ====================================================================== */
2253 /* === Standard C library === */
2254@@ -59,7 +75,7 @@
2255 }
2256
2257 static void
2258-NPW_Libc_MemFree (void *ptr)
2259+NPW_Libc_MemFree (void *ptr, uint32_t size)
2260 {
2261 free (ptr);
2262 }
2263@@ -82,57 +98,22 @@
2264 #if USE_MALLOC_GLIB
2265 #include <glib.h>
2266
2267-#define NPW_GLIB_MALLOC_MAGIC 0x476c6962 /* 'Glib' */
2268-
2269-typedef struct _NPW_Glib_MemBlock NPW_Glib_MemBlock;
2270-struct _NPW_Glib_MemBlock
2271-{
2272- uint32_t magic;
2273- uint32_t real_size;
2274- char data[];
2275-};
2276-
2277 static void *
2278 NPW_Glib_MemAlloc (uint32_t size)
2279 {
2280- uint32_t real_size;
2281- NPW_Glib_MemBlock *mem;
2282-
2283- real_size = sizeof (*mem) + size;
2284- if ((mem = g_slice_alloc (real_size)) == NULL)
2285- return NULL;
2286- mem->magic = NPW_GLIB_MALLOC_MAGIC;
2287- mem->real_size = real_size;
2288- return &mem->data[0];
2289+ return g_slice_alloc (size);
2290 }
2291
2292 static void *
2293 NPW_Glib_MemAlloc0 (uint32_t size)
2294 {
2295- uint32_t real_size;
2296- NPW_Glib_MemBlock *mem;
2297-
2298- real_size = sizeof (*mem) + size;
2299- if ((mem = g_slice_alloc0 (real_size)) == NULL)
2300- return NULL;
2301- mem->magic = NPW_GLIB_MALLOC_MAGIC;
2302- mem->real_size = real_size;
2303- return &mem->data[0];
2304+ return g_slice_alloc0 (size);
2305 }
2306
2307 static void
2308-NPW_Glib_MemFree (void *ptr)
2309+NPW_Glib_MemFree (void *ptr, uint32_t size)
2310 {
2311- if (ptr == NULL)
2312- return;
2313- NPW_Glib_MemBlock *mem = (NPW_Glib_MemBlock *)((char *)ptr - sizeof (*mem));
2314- if (mem->magic == NPW_GLIB_MALLOC_MAGIC)
2315- g_slice_free1 (mem->real_size, mem);
2316- else
2317- {
2318- D(bug("WARNING: block %p was not allocated with NPN_MemAlloc(), reverting to libc free()\n", ptr));
2319- free (ptr);
2320- }
2321+ g_slice_free1 (size, ptr);
2322 }
2323
2324 static const NPW_MallocHooks g_glib_hooks = {
2325@@ -190,26 +171,200 @@
2326 void *
2327 NPW_MemAlloc (uint32_t size)
2328 {
2329- return get_malloc_hooks ()->memalloc (size);
2330+ return npw_mem_alloc (size, NULL, 0);
2331 }
2332
2333 void *
2334 NPW_MemAlloc0 (uint32_t size)
2335 {
2336- return get_malloc_hooks ()->memalloc0 (size);
2337-}
2338-
2339-void *
2340-NPW_MemAllocCopy (uint32_t size, const void *src)
2341-{
2342- void *ptr = NPW_MemAlloc (size);
2343+ return npw_mem_alloc0 (size, NULL, 0);
2344+}
2345+
2346+void *
2347+NPW_MemAllocCopy (uint32_t size, const void *ptr)
2348+{
2349+ return npw_mem_alloc_copy (size, ptr, NULL, 0);
2350+}
2351+
2352+void
2353+NPW_MemFree (void *ptr)
2354+{
2355+ npw_mem_free (ptr, NULL, 0);
2356+}
2357+
2358+void *
2359+NPW_Debug_MemAlloc (uint32_t size, const char *file, int lineno)
2360+{
2361+ return npw_mem_alloc (size, file, lineno);
2362+}
2363+
2364+void *
2365+NPW_Debug_MemAlloc0 (uint32_t size, const char *file, int lineno)
2366+{
2367+ return npw_mem_alloc0 (size, file, lineno);
2368+}
2369+
2370+void *
2371+NPW_Debug_MemAllocCopy (uint32_t size, const void *ptr, const char *file, int lineno)
2372+{
2373+ return npw_mem_alloc_copy (size, ptr, file, lineno);
2374+}
2375+
2376+void
2377+NPW_Debug_MemFree (void *ptr, const char *file, int lineno)
2378+{
2379+ npw_mem_free (ptr, file, lineno);
2380+}
2381+
2382+/* ====================================================================== */
2383+/* === Implementation allowing basic underflow/overflow checks === */
2384+/* ====================================================================== */
2385+
2386+#ifdef ENABLE_MALLOC_CHECK
2387+static bool
2388+is_malloc_check_enabled_1 (void)
2389+{
2390+ const char *malloc_check_str;
2391+ if ((malloc_check_str = getenv ("NPW_MALLOC_CHECK")) != NULL)
2392+ return ((strcmp (malloc_check_str, "yes") == 0) ||
2393+ (strcmp (malloc_check_str, "1") == 0));
2394+
2395+ /* enable malloc-checks by default for all builds from snapshots */
2396+ return NPW_SNAPSHOT > 0;
2397+}
2398+#endif
2399+
2400+#define MALLOC_CHECK_GUARD_MARK 'E'
2401+#define MALLOC_CHECK_GUARD_SIZE malloc_check_guards_size ()
2402+
2403+static inline bool
2404+is_malloc_check_enabled (void)
2405+{
2406+#ifdef ENABLE_MALLOC_CHECK
2407+ static int malloc_check = -1;
2408+ if (malloc_check < 0)
2409+ malloc_check = is_malloc_check_enabled_1 ();
2410+ return malloc_check;
2411+#else
2412+ return false;
2413+#endif
2414+}
2415+
2416+static inline uint32_t
2417+malloc_check_guards_size (void)
2418+{
2419+ return is_malloc_check_enabled () ? 16 : 0;
2420+}
2421+
2422+static void
2423+malloc_check_guards_init (uint8_t *ptr, uint32_t size)
2424+{
2425+ if (!is_malloc_check_enabled ())
2426+ return;
2427+
2428+ memset (ptr - MALLOC_CHECK_GUARD_SIZE,
2429+ MALLOC_CHECK_GUARD_MARK,
2430+ MALLOC_CHECK_GUARD_SIZE);
2431+ memset (ptr + size,
2432+ MALLOC_CHECK_GUARD_MARK,
2433+ MALLOC_CHECK_GUARD_SIZE);
2434+}
2435+
2436+static bool
2437+malloc_check_guards_ok (uint8_t *ptr, uint32_t size, int *punderflow, int *poverflow)
2438+{
2439+ if (!is_malloc_check_enabled ())
2440+ return true;
2441+
2442+ int i, underflow = 0, overflow = 0;
2443+ for (i = 0; i < MALLOC_CHECK_GUARD_SIZE; i++)
2444+ {
2445+ if (ptr[-(1 + i)] != MALLOC_CHECK_GUARD_MARK)
2446+ ++underflow;
2447+ if (ptr[size + i] != MALLOC_CHECK_GUARD_MARK)
2448+ ++overflow;
2449+ }
2450+ if (punderflow)
2451+ *punderflow = underflow;
2452+ if (poverflow)
2453+ *poverflow = overflow;
2454+ return !underflow && !overflow;
2455+}
2456+
2457+static inline void *
2458+npw_do_mem_alloc (NPW_MemAllocProcPtr mem_alloc_func, uint32_t size, const char *file, int lineno)
2459+{
2460+ uint32_t real_size;
2461+ NPW_MemBlock *mem;
2462+
2463+ real_size = sizeof (*mem) + size + 2 * MALLOC_CHECK_GUARD_SIZE;
2464+ if ((mem = mem_alloc_func (real_size)) == NULL)
2465+ return NULL;
2466+
2467+ mem->magic = NPW_MALLOC_MAGIC;
2468+ mem->real_size = real_size;
2469+ mem->alloc_size = size;
2470+ mem->alloc_file = file;
2471+ mem->alloc_lineno = lineno;
2472+
2473+ uint8_t *ptr = (uint8_t *)mem + sizeof (*mem) + MALLOC_CHECK_GUARD_SIZE;
2474+ malloc_check_guards_init (ptr, size);
2475+ return ptr;
2476+}
2477+
2478+static void *
2479+npw_mem_alloc (uint32_t size, const char *file, int lineno)
2480+{
2481+ return npw_do_mem_alloc (get_malloc_hooks ()->memalloc, size, file, lineno);
2482+}
2483+
2484+static void *
2485+npw_mem_alloc0 (uint32_t size, const char *file, int lineno)
2486+{
2487+ return npw_do_mem_alloc (get_malloc_hooks ()->memalloc0, size, file, lineno);
2488+}
2489+
2490+static void *
2491+npw_mem_alloc_copy (uint32_t size, const void *src, const char *file, int lineno)
2492+{
2493+ void *ptr = npw_mem_alloc (size, file, lineno);
2494 if (ptr)
2495 memcpy (ptr, src, size);
2496 return ptr;
2497 }
2498
2499-void
2500-NPW_MemFree (void *ptr)
2501+static void
2502+npw_mem_free (void *ptr, const char *file, int lineno)
2503 {
2504- get_malloc_hooks ()->memfree (ptr);
2505+ if (ptr == NULL)
2506+ return;
2507+
2508+ NPW_MemBlock *mem = (NPW_MemBlock *)((char *)ptr - (sizeof (*mem) + MALLOC_CHECK_GUARD_SIZE));
2509+ if (mem->magic == NPW_MALLOC_MAGIC)
2510+ {
2511+ int underflow, overflow;
2512+ if (!malloc_check_guards_ok (ptr, mem->alloc_size, &underflow, &overflow))
2513+ {
2514+ if (underflow)
2515+ npw_printf ("ERROR: detected underflow of %d bytes\n"
2516+ " for block allocated at %s:%d\n"
2517+ " and released at %s:%d\n",
2518+ underflow,
2519+ mem->alloc_file, mem->alloc_lineno,
2520+ file, lineno);
2521+ if (overflow)
2522+ npw_printf ("ERROR: detected overflow of %d bytes\n"
2523+ " for block allocated at %s:%d\n"
2524+ " and released at %s:%d\n",
2525+ overflow,
2526+ mem->alloc_file, mem->alloc_lineno,
2527+ file, lineno);
2528+ }
2529+ get_malloc_hooks ()->memfree (mem, mem->real_size);
2530+ }
2531+ else
2532+ {
2533+ npw_printf("ERROR: block %p was not allocated with NPW_MemAlloc(), reverting to libc free()\n", ptr);
2534+ free (ptr);
2535+ }
2536 }
2537
2538=== modified file 'src/npw-malloc.h'
2539--- src/npw-malloc.h 2009-01-02 10:07:27 +0000
2540+++ src/npw-malloc.h 2009-08-11 00:38:42 +0000
2541@@ -33,6 +33,18 @@
2542 void
2543 NPW_MemFree (void *ptr);
2544
2545+void *
2546+NPW_Debug_MemAlloc (uint32_t size, const char *file, int lineno);
2547+
2548+void *
2549+NPW_Debug_MemAlloc0 (uint32_t size, const char *file, int lineno);
2550+
2551+void *
2552+NPW_Debug_MemAllocCopy (uint32_t size, const void *ptr, const char *file, int lineno);
2553+
2554+void
2555+NPW_Debug_MemFree (void *ptr, const char *file, int lineno);
2556+
2557 #define NPW_MemNew(type, n) \
2558 ((type *) NPW_MemAlloc ((n) * sizeof (type)))
2559
2560@@ -42,4 +54,11 @@
2561 #define NPW_MemClone(type, ptr) \
2562 ((type *) NPW_MemAllocCopy (sizeof (type), ptr))
2563
2564+#ifdef ENABLE_MALLOC_CHECK
2565+# define NPW_MemAlloc(SIZE) NPW_Debug_MemAlloc(SIZE, __FILE__, __LINE__)
2566+# define NPW_MemAlloc0(SIZE) NPW_Debug_MemAlloc0(SIZE, __FILE__, __LINE__)
2567+# define NPW_MemAllocCopy(SIZE, PTR) NPW_Debug_MemAllocCopy(SIZE, PTR, __FILE__, __LINE__)
2568+# define NPW_MemFree(PTR) NPW_Debug_MemFree(PTR, __FILE__, __LINE__)
2569+#endif
2570+
2571 #endif /* NPW_MALLOC_H */
2572
2573=== modified file 'src/npw-viewer.c'
2574--- src/npw-viewer.c 2009-01-02 10:07:27 +0000
2575+++ src/npw-viewer.c 2009-08-11 00:38:42 +0000
2576@@ -28,6 +28,8 @@
2577 #include <dlfcn.h>
2578 #include <unistd.h>
2579 #include <errno.h>
2580+#include <pthread.h>
2581+#include <fcntl.h>
2582
2583 #include <X11/X.h>
2584 #include <X11/Xlib.h>
2585@@ -58,11 +60,15 @@
2586 // Define to allow windowless plugins
2587 #define ALLOW_WINDOWLESS_PLUGINS 1
2588
2589+// Define to use NPIdentifier cache
2590+#define USE_NPIDENTIFIER_CACHE 1
2591+#define NPIDENTIFIER_CACHE_SIZE 256
2592+
2593 // RPC global connections
2594 rpc_connection_t *g_rpc_connection attribute_hidden = NULL;
2595
2596-// Viewer orignal pid - check against incorrect plugins
2597-static pid_t g_viewer_pid = 0;
2598+// Viewer main thread - make sure we call into the browser from the main thread
2599+static pthread_t g_main_thread = 0;
2600
2601 // Instance state information about the plugin
2602 typedef struct _PluginInstance {
2603@@ -101,6 +107,8 @@
2604
2605 // Prototypes
2606 static void destroy_window(PluginInstance *plugin);
2607+static int xt_source_create(void);
2608+static void xt_source_destroy(void);
2609
2610
2611 /* ====================================================================== */
2612@@ -162,16 +170,38 @@
2613 }
2614 }
2615
2616-// Pid support routines
2617-static void pid_init(void)
2618-{
2619- g_viewer_pid = getpid();
2620-}
2621-
2622-bool pid_check(void)
2623-{
2624-#if USE_PID_CHECK
2625- return (g_viewer_pid == getpid());
2626+// Thread support routines
2627+static void thread_check_init(void)
2628+{
2629+ g_main_thread = pthread_self();
2630+}
2631+
2632+#ifdef ENABLE_THREAD_CHECK
2633+static bool is_thread_check_enabled_1(void)
2634+{
2635+ const char *thread_check_str;
2636+ if ((thread_check_str = getenv("NPW_THREAD_CHECK")) != NULL)
2637+ return ((strcmp(thread_check_str, "yes") == 0) ||
2638+ (strcmp(thread_check_str, "1") == 0));
2639+
2640+ /* enable main-thread checks by default for all builds from snapshots */
2641+ return NPW_SNAPSHOT > 0;
2642+}
2643+
2644+static inline bool is_thread_check_enabled(void)
2645+{
2646+ static int thread_check = -1;
2647+ if (thread_check < 0)
2648+ thread_check = is_thread_check_enabled_1();
2649+ return thread_check;
2650+}
2651+#endif
2652+
2653+bool thread_check(void)
2654+{
2655+#ifdef ENABLE_THREAD_CHECK
2656+ if (is_thread_check_enabled())
2657+ return (g_main_thread == pthread_self());
2658 #endif
2659 return true;
2660 }
2661@@ -180,8 +210,7 @@
2662 // XXX: use a pipe, this should be faster (avoids GSource creation and
2663 // explicit memory allocation)
2664 enum {
2665- RPC_DELAYED_NPN_RELEASE_OBJECT = 1,
2666- RPC_DELAYED_NPN_INVALIDATE_RECT,
2667+ RPC_DELAYED_NPN_RELEASE_OBJECT = 1
2668 };
2669
2670 typedef struct _DelayedCall {
2671@@ -251,6 +280,200 @@
2672 return delayed_calls_process(NULL, FALSE);
2673 }
2674
2675+// NPIdentifier cache
2676+static inline bool use_npidentifier_cache(void)
2677+{
2678+ return USE_NPIDENTIFIER_CACHE && npruntime_use_cache();
2679+}
2680+
2681+#if USE_NPIDENTIFIER_CACHE
2682+/* XXX: NPIdentifierInfo could become the NPIdentifier, thus avoiding
2683+ the global hash table, if there is a garbage collector. Otherwise,
2684+ we will be leaking memory since there is no function that kills an
2685+ NPIdentifier. */
2686+typedef struct _NPIdentifierInfo {
2687+ guint string_len; /* >0 implies 1+strlen(string), =0 implies an integer */
2688+ union {
2689+ gchar *string;
2690+ int32_t value;
2691+ } u;
2692+} NPIdentifierInfo;
2693+
2694+static GHashTable *g_npidentifier_cache = NULL;
2695+
2696+
2697+static inline NPIdentifierInfo *npidentifier_info_new(void)
2698+{
2699+ return NPW_MemNew(NPIdentifierInfo, 1);
2700+}
2701+
2702+static inline void npidentifier_info_destroy(NPIdentifierInfo *npi)
2703+{
2704+ if (G_UNLIKELY(npi == NULL))
2705+ return;
2706+ if (npi->string_len > 0) {
2707+ NPW_MemFree(npi->u.string);
2708+ npi->u.string = NULL;
2709+ }
2710+ NPW_MemFree(npi);
2711+}
2712+
2713+static inline void npidentifier_cache_create(void)
2714+{
2715+ g_npidentifier_cache =
2716+ g_hash_table_new_full(NULL, NULL, NULL,
2717+ (GDestroyNotify)npidentifier_info_destroy);
2718+}
2719+
2720+static inline void npidentifier_cache_destroy(void)
2721+{
2722+ if (g_npidentifier_cache) {
2723+ g_hash_table_destroy(g_npidentifier_cache);
2724+ g_npidentifier_cache = NULL;
2725+ }
2726+}
2727+
2728+static void npidentifier_cache_invalidate(void)
2729+{
2730+#if defined(HAVE_G_HASH_TABLE_REMOVE_ALL) && !defined(BUILD_GENERIC)
2731+ if (g_npidentifier_cache)
2732+ g_hash_table_remove_all(g_npidentifier_cache);
2733+#else
2734+ npidentifier_cache_destroy();
2735+ npidentifier_cache_create();
2736+#endif
2737+}
2738+
2739+static void npidentifier_cache_reserve(int n_entries)
2740+{
2741+ if (G_UNLIKELY(g_npidentifier_cache == NULL))
2742+ npidentifier_cache_create();
2743+ if (g_hash_table_size(g_npidentifier_cache) + n_entries > NPIDENTIFIER_CACHE_SIZE)
2744+ npidentifier_cache_invalidate();
2745+}
2746+
2747+static inline NPIdentifierInfo *npidentifier_cache_lookup(NPIdentifier ident)
2748+{
2749+ if (G_UNLIKELY(g_npidentifier_cache == NULL))
2750+ return NULL;
2751+ return g_hash_table_lookup(g_npidentifier_cache, ident);
2752+}
2753+
2754+static void npidentifier_cache_add_int(NPIdentifier ident, int32_t value)
2755+{
2756+ if (G_UNLIKELY(g_npidentifier_cache == NULL))
2757+ return;
2758+ NPIdentifierInfo *npi = npidentifier_info_new();
2759+ if (G_UNLIKELY(npi == NULL))
2760+ return;
2761+ npi->string_len = 0;
2762+ npi->u.value = value;
2763+ g_hash_table_insert(g_npidentifier_cache, ident, npi);
2764+}
2765+
2766+typedef struct _NPIdentifierFindArgs {
2767+ NPIdentifierInfo info; /* in */
2768+ NPIdentifier ident; /* out */
2769+} NPIdentifierFindArgs;
2770+
2771+static gboolean npidentifier_cache_find_info(gpointer key, gpointer value, gpointer user_data)
2772+{
2773+ NPIdentifier *ident = (NPIdentifier)key;
2774+ NPIdentifierInfo *npi = (NPIdentifierInfo *)value;
2775+ NPIdentifierFindArgs *args = (NPIdentifierFindArgs *)user_data;
2776+#if !defined(HAVE_G_HASH_TABLE_FIND) || defined(BUILD_GENERIC)
2777+ if (args->ident)
2778+ return FALSE;
2779+#endif
2780+ if (npi->string_len != args->info.string_len)
2781+ return FALSE;
2782+ if (args->info.string_len > 0) { /* a string */
2783+ if (memcmp(args->info.u.string, npi->u.string, args->info.string_len) == 0) {
2784+ args->ident = ident;
2785+ return TRUE;
2786+ }
2787+ }
2788+ else { /* an integer */
2789+ if (args->info.u.value == npi->u.value) {
2790+ args->ident = ident;
2791+ return TRUE;
2792+ }
2793+ }
2794+ return FALSE;
2795+}
2796+
2797+static inline bool npidentifier_cache_find(NPIdentifierFindArgs *args, NPIdentifier *pident)
2798+{
2799+ args->ident = NULL;
2800+#if defined(HAVE_G_HASH_TABLE_FIND) && !defined(BUILD_GENERIC)
2801+ if (!g_hash_table_find(g_npidentifier_cache, npidentifier_cache_find_info, args))
2802+ return false;
2803+#else
2804+ g_hash_table_foreach(g_npidentifier_cache, (GHFunc)npidentifier_cache_find_info, args);
2805+ if (args->ident == NULL)
2806+ return false;
2807+#endif
2808+
2809+ if (pident)
2810+ *pident = args->ident;
2811+ return true;
2812+}
2813+
2814+static inline bool npidentifier_cache_has_int(int32_t value, NPIdentifier *pident)
2815+{
2816+ if (G_UNLIKELY(g_npidentifier_cache == NULL))
2817+ return false;
2818+
2819+ NPIdentifierFindArgs args;
2820+ args.info.string_len = 0;
2821+ args.info.u.value = value;
2822+ return npidentifier_cache_find(&args, pident);
2823+}
2824+
2825+static inline int32_t npidentifier_cache_get_int(NPIdentifier ident)
2826+{
2827+ NPIdentifierInfo *npi = npidentifier_cache_lookup(ident);
2828+ if (G_UNLIKELY(npi == NULL || npi->string_len > 0))
2829+ return 0;
2830+ return npi->u.value;
2831+}
2832+
2833+static void npidentifier_cache_add_string(NPIdentifier ident, const gchar *str)
2834+{
2835+ if (G_UNLIKELY(g_npidentifier_cache == NULL))
2836+ return;
2837+ NPIdentifierInfo *npi = npidentifier_info_new();
2838+ if (G_UNLIKELY(npi == NULL))
2839+ return;
2840+ npi->string_len = strlen(str) + 1;
2841+ if ((npi->u.string = NPW_MemAlloc(npi->string_len)) == NULL) {
2842+ npidentifier_info_destroy(npi);
2843+ return;
2844+ }
2845+ memcpy(npi->u.string, str, npi->string_len);
2846+ g_hash_table_insert(g_npidentifier_cache, ident, npi);
2847+}
2848+
2849+static inline bool npidentifier_cache_has_string(const gchar *str, NPIdentifier *pident)
2850+{
2851+ if (G_UNLIKELY(g_npidentifier_cache == NULL))
2852+ return false;
2853+
2854+ NPIdentifierFindArgs args;
2855+ args.info.string_len = strlen(str) + 1;
2856+ args.info.u.string = (gchar *)str;
2857+ return npidentifier_cache_find(&args, pident);
2858+}
2859+
2860+static inline NPUTF8 *npidentifier_cache_get_string_copy(NPIdentifier ident)
2861+{
2862+ NPIdentifierInfo *npi = npidentifier_cache_lookup(ident);
2863+ if (G_UNLIKELY(npi == NULL || npi->string_len == 0))
2864+ return NULL;
2865+ return NPW_MemAllocCopy(npi->string_len, npi->u.string);
2866+}
2867+#endif
2868+
2869
2870 /* ====================================================================== */
2871 /* === X Toolkit glue === */
2872@@ -302,6 +525,57 @@
2873 CorePart core;
2874 } WidgetRec, CoreRec;
2875
2876+typedef struct _TimerEventRec {
2877+ struct timeval te_timer_value;
2878+ struct _TimerEventRec *te_next;
2879+ XtTimerCallbackProc te_proc;
2880+ XtAppContext app;
2881+ XtPointer te_closure;
2882+} TimerEventRec;
2883+
2884+typedef struct _InputEvent {
2885+ XtInputCallbackProc ie_proc;
2886+ XtPointer ie_closure;
2887+ struct _InputEvent *ie_next;
2888+ struct _InputEvent *ie_oq;
2889+ XtAppContext app;
2890+ int ie_source;
2891+ XtInputMask ie_condition;
2892+} InputEvent;
2893+
2894+typedef struct _SignalEventRec {
2895+ XtSignalCallbackProc se_proc;
2896+ XtPointer se_closure;
2897+ struct _SignalEventRec *se_next;
2898+ XtAppContext app;
2899+ Boolean se_notice;
2900+} SignalEventRec;
2901+
2902+struct _XtAppStruct {
2903+ XtAppContext next; /* link to next app in process context */
2904+ void *process; /* back pointer to our process context */
2905+ void *destroy_callbacks;
2906+ Display **list;
2907+ TimerEventRec *timerQueue;
2908+ void *workQueue;
2909+ InputEvent **input_list;
2910+ InputEvent *outstandingQueue;
2911+ SignalEventRec *signalQueue;
2912+ XrmDatabase errorDB;
2913+ XtErrorMsgHandler errorMsgHandler, warningMsgHandler;
2914+ XtErrorHandler errorHandler, warningHandler;
2915+ struct _ActionListRec *action_table;
2916+ void *converterTable;
2917+ unsigned long selectionTimeout;
2918+ char __maxed__nfds[3*sizeof(fd_set)+4];
2919+ short __maybe__count; /* num of assigned entries in list */
2920+ short __maybe__max; /* allocate size of list */
2921+ short __maybe__last;
2922+ short __maybe__input_count;
2923+ short __maybe__input_max; /* elts input_list init'd with */
2924+ /* ... don't care about other members */
2925+};
2926+
2927 extern void XtResizeWidget(
2928 Widget /* widget */,
2929 _XtDimension /* width */,
2930@@ -780,8 +1054,8 @@
2931 static NPError
2932 g_NPN_GetURL(NPP instance, const char *url, const char *target)
2933 {
2934- if (!pid_check()) {
2935- npw_printf("WARNING: NPN_GetURL called from the wrong process\n");
2936+ if (!thread_check()) {
2937+ npw_printf("WARNING: NPN_GetURL not called from the main thread\n");
2938 return NPERR_INVALID_INSTANCE_ERROR;
2939 }
2940
2941@@ -834,8 +1108,8 @@
2942 static NPError
2943 g_NPN_GetURLNotify(NPP instance, const char *url, const char *target, void *notifyData)
2944 {
2945- if (!pid_check()) {
2946- npw_printf("WARNING: NPN_GetURLNotify called from the wrong process\n");
2947+ if (!thread_check()) {
2948+ npw_printf("WARNING: NPN_GetURLNotify not called from the main thread\n");
2949 return NPERR_INVALID_INSTANCE_ERROR;
2950 }
2951
2952@@ -933,8 +1207,8 @@
2953 {
2954 D(bug("NPN_GetValue instance=%p, variable=%d [%s]\n", instance, variable, string_of_NPNVariable(variable)));
2955
2956- if (!pid_check()) {
2957- npw_printf("WARNING: NPN_GetValue called from the wrong process\n");
2958+ if (!thread_check()) {
2959+ npw_printf("WARNING: NPN_GetValue not called from the main thread\n");
2960 return NPERR_INVALID_INSTANCE_ERROR;
2961 }
2962
2963@@ -1038,8 +1312,8 @@
2964 static void
2965 g_NPN_InvalidateRect(NPP instance, NPRect *invalidRect)
2966 {
2967- if (!pid_check()) {
2968- npw_printf("WARNING: NPN_InvalidateRect called from the wrong process\n");
2969+ if (!thread_check()) {
2970+ npw_printf("WARNING: NPN_InvalidateRect not called from the main thread\n");
2971 return;
2972 }
2973
2974@@ -1132,8 +1406,8 @@
2975 static NPError
2976 g_NPN_PostURL(NPP instance, const char *url, const char *target, uint32 len, const char *buf, NPBool file)
2977 {
2978- if (!pid_check()) {
2979- npw_printf("WARNING: NPN_PostURL called from the wrong process\n");
2980+ if (!thread_check()) {
2981+ npw_printf("WARNING: NPN_PostURL not called from the main thread\n");
2982 return NPERR_INVALID_INSTANCE_ERROR;
2983 }
2984
2985@@ -1188,8 +1462,8 @@
2986 static NPError
2987 g_NPN_PostURLNotify(NPP instance, const char *url, const char *target, uint32 len, const char *buf, NPBool file, void *notifyData)
2988 {
2989- if (!pid_check()) {
2990- npw_printf("WARNING: NPN_PostURLNotify called from the wrong process\n");
2991+ if (!thread_check()) {
2992+ npw_printf("WARNING: NPN_PostURLNotify not called from the main thread\n");
2993 return NPERR_INVALID_INSTANCE_ERROR;
2994 }
2995
2996@@ -1267,8 +1541,8 @@
2997 static NPError
2998 g_NPN_RequestRead(NPStream *stream, NPByteRange *rangeList)
2999 {
3000- if (!pid_check()) {
3001- npw_printf("WARNING: NPN_RequestRead called from the wrong process\n");
3002+ if (!thread_check()) {
3003+ npw_printf("WARNING: NPN_RequestRead not called from the main thread\n");
3004 return NPERR_INVALID_INSTANCE_ERROR;
3005 }
3006
3007@@ -1320,8 +1594,8 @@
3008 static NPError
3009 g_NPN_SetValue(NPP instance, NPPVariable variable, void *value)
3010 {
3011- if (!pid_check()) {
3012- npw_printf("WARNING: NPN_SetValue called from the wrong process\n");
3013+ if (!thread_check()) {
3014+ npw_printf("WARNING: NPN_SetValue not called from the main thread\n");
3015 return NPERR_INVALID_INSTANCE_ERROR;
3016 }
3017
3018@@ -1368,8 +1642,8 @@
3019 static void
3020 g_NPN_Status(NPP instance, const char *message)
3021 {
3022- if (!pid_check()) {
3023- npw_printf("WARNING: NPN_Status called from the wrong process\n");
3024+ if (!thread_check()) {
3025+ npw_printf("WARNING: NPN_Status not called from the main thread\n");
3026 return;
3027 }
3028
3029@@ -1415,8 +1689,8 @@
3030 static const char *
3031 g_NPN_UserAgent(NPP instance)
3032 {
3033- if (!pid_check()) {
3034- npw_printf("WARNING: NPN_UserAgent called from the wrong process\n");
3035+ if (!thread_check()) {
3036+ npw_printf("WARNING: NPN_UserAgent not called from the main thread\n");
3037 return NULL;
3038 }
3039
3040@@ -1505,8 +1779,8 @@
3041 static NPError
3042 g_NPN_NewStream(NPP instance, NPMIMEType type, const char *target, NPStream **stream)
3043 {
3044- if (!pid_check()) {
3045- npw_printf("WARNING: NPN_NewStream called from the wrong process\n");
3046+ if (!thread_check()) {
3047+ npw_printf("WARNING: NPN_NewStream not called from the main thread\n");
3048 return NPERR_INVALID_INSTANCE_ERROR;
3049 }
3050
3051@@ -1564,8 +1838,8 @@
3052 static NPError
3053 g_NPN_DestroyStream(NPP instance, NPStream *stream, NPError reason)
3054 {
3055- if (!pid_check()) {
3056- npw_printf("WARNING: NPN_DestroyStream called from the wrong process\n");
3057+ if (!thread_check()) {
3058+ npw_printf("WARNING: NPN_DestroyStream not called from the main thread\n");
3059 return NPERR_INVALID_INSTANCE_ERROR;
3060 }
3061
3062@@ -1634,8 +1908,8 @@
3063 static int32
3064 g_NPN_Write(NPP instance, NPStream *stream, int32 len, void *buf)
3065 {
3066- if (!pid_check()) {
3067- npw_printf("WARNING: NPN_Write called from the wrong process\n");
3068+ if (!thread_check()) {
3069+ npw_printf("WARNING: NPN_Write not called from the main thread\n");
3070 return -1;
3071 }
3072
3073@@ -1683,8 +1957,8 @@
3074 static void
3075 g_NPN_PushPopupsEnabledState(NPP instance, NPBool enabled)
3076 {
3077- if (!pid_check()) {
3078- npw_printf("WARNING: NPN_PushPopupsEnabledState called from the wrong process\n");
3079+ if (!thread_check()) {
3080+ npw_printf("WARNING: NPN_PushPopupsEnabledState not called from the main thread\n");
3081 return;
3082 }
3083
3084@@ -1727,8 +2001,8 @@
3085 static void
3086 g_NPN_PopPopupsEnabledState(NPP instance)
3087 {
3088- if (!pid_check()) {
3089- npw_printf("WARNING: NPN_PophPopupsEnabledState called from the wrong process\n");
3090+ if (!thread_check()) {
3091+ npw_printf("WARNING: NPN_PophPopupsEnabledState not called from the main thread\n");
3092 return;
3093 }
3094
3095@@ -1783,8 +2057,8 @@
3096 static NPObject *
3097 g_NPN_CreateObject(NPP instance, NPClass *class)
3098 {
3099- if (!pid_check()) {
3100- npw_printf("WARNING: NPN_CreateObject called from the wrong process\n");
3101+ if (!thread_check()) {
3102+ npw_printf("WARNING: NPN_CreateObject not called from the main thread\n");
3103 return NULL;
3104 }
3105
3106@@ -1839,8 +2113,8 @@
3107 static NPObject *
3108 g_NPN_RetainObject(NPObject *npobj)
3109 {
3110- if (!pid_check()) {
3111- npw_printf("WARNING: NPN_RetainObject called from the wrong process\n");
3112+ if (!thread_check()) {
3113+ npw_printf("WARNING: NPN_RetainObject not called from the main thread\n");
3114 return NULL;
3115 }
3116
3117@@ -1902,8 +2176,8 @@
3118 static void
3119 g_NPN_ReleaseObject(NPObject *npobj)
3120 {
3121- if (!pid_check()) {
3122- npw_printf("WARNING: NPN_ReleaseObject called from the wrong process\n");
3123+ if (!thread_check()) {
3124+ npw_printf("WARNING: NPN_ReleaseObject not called from the main thread\n");
3125 return;
3126 }
3127
3128@@ -1958,8 +2232,8 @@
3129 g_NPN_Invoke(NPP instance, NPObject *npobj, NPIdentifier methodName,
3130 const NPVariant *args, uint32_t argCount, NPVariant *result)
3131 {
3132- if (!pid_check()) {
3133- npw_printf("WARNING: NPN_Invoke called from the wrong process\n");
3134+ if (!thread_check()) {
3135+ npw_printf("WARNING: NPN_Invoke not called from the main thread\n");
3136 return false;
3137 }
3138
3139@@ -2021,8 +2295,8 @@
3140 g_NPN_InvokeDefault(NPP instance, NPObject *npobj,
3141 const NPVariant *args, uint32_t argCount, NPVariant *result)
3142 {
3143- if (!pid_check()) {
3144- npw_printf("WARNING: NPN_InvokeDefault called from the wrong process\n");
3145+ if (!thread_check()) {
3146+ npw_printf("WARNING: NPN_InvokeDefault not called from the main thread\n");
3147 return false;
3148 }
3149
3150@@ -2082,8 +2356,8 @@
3151 static bool
3152 g_NPN_Evaluate(NPP instance, NPObject *npobj, NPString *script, NPVariant *result)
3153 {
3154- if (!pid_check()) {
3155- npw_printf("WARNING: NPN_Evaluate called from the wrong process\n");
3156+ if (!thread_check()) {
3157+ npw_printf("WARNING: NPN_Evaluate not called from the main thread\n");
3158 return false;
3159 }
3160
3161@@ -2147,8 +2421,8 @@
3162 g_NPN_GetProperty(NPP instance, NPObject *npobj, NPIdentifier propertyName,
3163 NPVariant *result)
3164 {
3165- if (!pid_check()) {
3166- npw_printf("WARNING: NPN_GetProperty called from the wrong process\n");
3167+ if (!thread_check()) {
3168+ npw_printf("WARNING: NPN_GetProperty not called from the main thread\n");
3169 return false;
3170 }
3171
3172@@ -2209,8 +2483,8 @@
3173 g_NPN_SetProperty(NPP instance, NPObject *npobj, NPIdentifier propertyName,
3174 const NPVariant *value)
3175 {
3176- if (!pid_check()) {
3177- npw_printf("WARNING: NPN_SetProperty called from the wrong process\n");
3178+ if (!thread_check()) {
3179+ npw_printf("WARNING: NPN_SetProperty not called from the main thread\n");
3180 return false;
3181 }
3182
3183@@ -2266,8 +2540,8 @@
3184 static bool
3185 g_NPN_RemoveProperty(NPP instance, NPObject *npobj, NPIdentifier propertyName)
3186 {
3187- if (!pid_check()) {
3188- npw_printf("WARNING: NPN_RemoveProperty called from the wrong process\n");
3189+ if (!thread_check()) {
3190+ npw_printf("WARNING: NPN_RemoveProperty not called from the main thread\n");
3191 return false;
3192 }
3193
3194@@ -2323,8 +2597,8 @@
3195 static bool
3196 g_NPN_HasProperty(NPP instance, NPObject *npobj, NPIdentifier propertyName)
3197 {
3198- if (!pid_check()) {
3199- npw_printf("WARNING: NPN_HasProperty called from the wrong process\n");
3200+ if (!thread_check()) {
3201+ npw_printf("WARNING: NPN_HasProperty not called from the main thread\n");
3202 return false;
3203 }
3204
3205@@ -2380,8 +2654,8 @@
3206 static bool
3207 g_NPN_HasMethod(NPP instance, NPObject *npobj, NPIdentifier methodName)
3208 {
3209- if (!pid_check()) {
3210- npw_printf("WARNING: NPN_HasMethod called from the wrong process\n");
3211+ if (!thread_check()) {
3212+ npw_printf("WARNING: NPN_HasMethod not called from the main thread\n");
3213 return false;
3214 }
3215
3216@@ -2431,8 +2705,8 @@
3217 static void
3218 g_NPN_SetException(NPObject *npobj, const NPUTF8 *message)
3219 {
3220- if (!pid_check()) {
3221- npw_printf("WARNING: NPN_SetException called from the wrong process\n");
3222+ if (!thread_check()) {
3223+ npw_printf("WARNING: NPN_SetException not called from the main thread\n");
3224 return;
3225 }
3226
3227@@ -2480,10 +2754,26 @@
3228 }
3229
3230 static NPIdentifier
3231+cached_NPN_GetStringIdentifier(const NPUTF8 *name)
3232+{
3233+ NPIdentifier ident;
3234+ if (!use_npidentifier_cache())
3235+ ident = invoke_NPN_GetStringIdentifier(name);
3236+#if USE_NPIDENTIFIER_CACHE
3237+ else if (!npidentifier_cache_has_string(name, &ident)) {
3238+ ident = invoke_NPN_GetStringIdentifier(name);
3239+ npidentifier_cache_reserve(1);
3240+ npidentifier_cache_add_string(ident, name);
3241+ }
3242+#endif
3243+ return ident;
3244+}
3245+
3246+static NPIdentifier
3247 g_NPN_GetStringIdentifier(const NPUTF8 *name)
3248 {
3249- if (!pid_check()) {
3250- npw_printf("WARNING: NPN_GetStringIdentifier called from the wrong process\n");
3251+ if (!thread_check()) {
3252+ npw_printf("WARNING: NPN_GetStringIdentifier not called from the main thread\n");
3253 return NULL;
3254 }
3255
3256@@ -2491,7 +2781,7 @@
3257 return NULL;
3258
3259 D(bugiI("NPN_GetStringIdentifier name='%s'\n", name));
3260- NPIdentifier ret = invoke_NPN_GetStringIdentifier(name);
3261+ NPIdentifier ret = cached_NPN_GetStringIdentifier(name);
3262 D(bugiD("NPN_GetStringIdentifier return: %p\n", ret));
3263 return ret;
3264 }
3265@@ -2536,10 +2826,29 @@
3266 }
3267
3268 static void
3269+cached_NPN_GetStringIdentifiers(const NPUTF8 **names, uint32_t nameCount, NPIdentifier *identifiers)
3270+{
3271+ /* XXX: could be optimized further */
3272+ invoke_NPN_GetStringIdentifiers(names, nameCount, identifiers);
3273+
3274+#if USE_NPIDENTIFIER_CACHE
3275+ if (use_npidentifier_cache()) {
3276+ for (int i = 0; i < nameCount; i++) {
3277+ NPIdentifier ident = identifiers[i];
3278+ if (npidentifier_cache_lookup(ident) == NULL) {
3279+ npidentifier_cache_reserve(1);
3280+ npidentifier_cache_add_string(ident, names[i]);
3281+ }
3282+ }
3283+ }
3284+#endif
3285+}
3286+
3287+static void
3288 g_NPN_GetStringIdentifiers(const NPUTF8 **names, uint32_t nameCount, NPIdentifier *identifiers)
3289 {
3290- if (!pid_check()) {
3291- npw_printf("WARNING: NPN_GetStringIdentifiers called from the wrong process\n");
3292+ if (!thread_check()) {
3293+ npw_printf("WARNING: NPN_GetStringIdentifiers not called from the main thread\n");
3294 return;
3295 }
3296
3297@@ -2550,7 +2859,7 @@
3298 return;
3299
3300 D(bugiI("NPN_GetStringIdentifiers names=%p\n", names));
3301- invoke_NPN_GetStringIdentifiers(names, nameCount, identifiers);
3302+ cached_NPN_GetStringIdentifiers(names, nameCount, identifiers);
3303 D(bugiD("NPN_GetStringIdentifiers done\n"));
3304 }
3305
3306@@ -2584,15 +2893,31 @@
3307 }
3308
3309 static NPIdentifier
3310+cached_NPN_GetIntIdentifier(int32_t intid)
3311+{
3312+ NPIdentifier ident;
3313+ if (!use_npidentifier_cache())
3314+ ident = invoke_NPN_GetIntIdentifier(intid);
3315+#if USE_NPIDENTIFIER_CACHE
3316+ else if (!npidentifier_cache_has_int(intid, &ident)) {
3317+ ident = invoke_NPN_GetIntIdentifier(intid);
3318+ npidentifier_cache_reserve(1);
3319+ npidentifier_cache_add_int(ident, intid);
3320+ }
3321+#endif
3322+ return ident;
3323+}
3324+
3325+static NPIdentifier
3326 g_NPN_GetIntIdentifier(int32_t intid)
3327 {
3328- if (!pid_check()) {
3329- npw_printf("WARNING: NPN_GetIntIdentifier called from the wrong process\n");
3330+ if (!thread_check()) {
3331+ npw_printf("WARNING: NPN_GetIntIdentifier not called from the main thread\n");
3332 return NULL;
3333 }
3334
3335 D(bugiI("NPN_GetIntIdentifier intid=%d\n", intid));
3336- NPIdentifier ret = invoke_NPN_GetIntIdentifier(intid);
3337+ NPIdentifier ret = cached_NPN_GetIntIdentifier(intid);
3338 D(bugiD("NPN_GetIntIdentifier return: %p\n", ret));
3339 return ret;
3340 }
3341@@ -2627,10 +2952,25 @@
3342 }
3343
3344 static bool
3345+cached_NPN_IdentifierIsString(NPIdentifier ident)
3346+{
3347+#if USE_NPIDENTIFIER_CACHE
3348+ if (use_npidentifier_cache()) {
3349+ NPIdentifierInfo *npi = npidentifier_cache_lookup(ident);
3350+ if (npi)
3351+ return npi->string_len > 0;
3352+ }
3353+#endif
3354+ /* cache update is postponed to actual NPN_UTF8FromIdentifier() or
3355+ NPN_IntFromIdentifier() */
3356+ return invoke_NPN_IdentifierIsString(ident);
3357+}
3358+
3359+static bool
3360 g_NPN_IdentifierIsString(NPIdentifier identifier)
3361 {
3362- if (!pid_check()) {
3363- npw_printf("WARNING: NPN_IdentifierIsString called from the wrong process\n");
3364+ if (!thread_check()) {
3365+ npw_printf("WARNING: NPN_IdentifierIsString not called from the main thread\n");
3366 return false;
3367 }
3368
3369@@ -2670,15 +3010,34 @@
3370 }
3371
3372 static NPUTF8 *
3373+cached_NPN_UTF8FromIdentifier(NPIdentifier identifier)
3374+{
3375+ NPUTF8 *str;
3376+ if (!use_npidentifier_cache())
3377+ str = invoke_NPN_UTF8FromIdentifier(identifier);
3378+ else {
3379+#if USE_NPIDENTIFIER_CACHE
3380+ str = npidentifier_cache_get_string_copy(identifier);
3381+ if (str == NULL) {
3382+ str = invoke_NPN_UTF8FromIdentifier(identifier);
3383+ npidentifier_cache_reserve(1);
3384+ npidentifier_cache_add_string(identifier, str);
3385+ }
3386+#endif
3387+ }
3388+ return str;
3389+}
3390+
3391+static NPUTF8 *
3392 g_NPN_UTF8FromIdentifier(NPIdentifier identifier)
3393 {
3394- if (!pid_check()) {
3395- npw_printf("WARNING: NPN_UTF8FromIdentifier called from the wrong process\n");
3396+ if (!thread_check()) {
3397+ npw_printf("WARNING: NPN_UTF8FromIdentifier not called from the main thread\n");
3398 return NULL;
3399 }
3400
3401 D(bugiI("NPN_UTF8FromIdentifier identifier=%p\n", identifier));
3402- NPUTF8 *ret = invoke_NPN_UTF8FromIdentifier(identifier);
3403+ NPUTF8 *ret = cached_NPN_UTF8FromIdentifier(identifier);
3404 D(bugiD("NPN_UTF8FromIdentifier return: '%s'\n", ret));
3405 return ret;
3406 }
3407@@ -2714,15 +3073,38 @@
3408 }
3409
3410 static int32_t
3411+cached_NPN_IntFromIdentifier(NPIdentifier identifier)
3412+{
3413+ int32_t value;
3414+ if (!use_npidentifier_cache())
3415+ value = invoke_NPN_IntFromIdentifier(identifier);
3416+ else {
3417+#if USE_NPIDENTIFIER_CACHE
3418+ NPIdentifierInfo *npi = npidentifier_cache_lookup(identifier);
3419+ if (npi) {
3420+ assert(npi->string_len == 0);
3421+ value = npi->u.value;
3422+ }
3423+ else {
3424+ value = invoke_NPN_IntFromIdentifier(identifier);
3425+ npidentifier_cache_reserve(1);
3426+ npidentifier_cache_add_int(identifier, value);
3427+ }
3428+#endif
3429+ }
3430+ return value;
3431+}
3432+
3433+static int32_t
3434 g_NPN_IntFromIdentifier(NPIdentifier identifier)
3435 {
3436- if (!pid_check()) {
3437- npw_printf("WARNING: NPN_IntFromIdentifier called from the wrong process\n");
3438+ if (!thread_check()) {
3439+ npw_printf("WARNING: NPN_IntFromIdentifier not called from the main thread\n");
3440 return 0;
3441 }
3442
3443 D(bugiI("NPN_IntFromIdentifier identifier=%p\n", identifier));
3444- int32_t ret = invoke_NPN_IntFromIdentifier(identifier);
3445+ int32_t ret = cached_NPN_IntFromIdentifier(identifier);
3446 D(bugiD("NPN_IntFromIdentifier return: %d\n", ret));
3447 return ret;
3448 }
3449@@ -3006,6 +3388,13 @@
3450 plugin->use_xembed = supports_XEmbed && needs_XEmbed;
3451 }
3452 }
3453+
3454+ // assume Gtk plugin (no Xt event loop) if XEMBED is used
3455+ if (!plugin->use_xembed) {
3456+ if (xt_source_create() < 0)
3457+ return NPERR_GENERIC_ERROR;
3458+ }
3459+
3460 return ret;
3461 }
3462
3463@@ -3075,6 +3464,9 @@
3464 NPError ret = plugin_funcs.destroy(instance, sdata);
3465 D(bugiD("NPP_Destroy return: %d [%s]\n", ret, string_of_NPError(ret)));
3466
3467+ if (!plugin->use_xembed)
3468+ xt_source_destroy();
3469+
3470 npw_plugin_instance_invalidate(plugin);
3471 npw_plugin_instance_unref(plugin);
3472 return ret;
3473@@ -3723,19 +4115,205 @@
3474 typedef void (*GSourceFinalizeFunc)(GSource *);
3475
3476 // Xt events
3477+static GSource *xt_source = NULL;
3478+static int xt_source_count = 0;
3479 static GPollFD xt_event_poll_fd;
3480+static const int XT_DEFAULT_TIMEOUT = 25;
3481+static const int XT_MAX_DISPATCH_EVENTS = 10;
3482+
3483+static void xt_dummy_timeout_cb(XtPointer closure, XtIntervalId *id)
3484+{
3485+ /* dummy function, never called */
3486+ npw_printf("ERROR: xt_dummy_timeout_cb() should never be called\n");
3487+}
3488+
3489+static int xt_has_compatible_appcontext_timerQueue(void)
3490+{
3491+ int is_compatible;
3492+ XtIntervalId id;
3493+ TimerEventRec *tq, *tq_probe;
3494+
3495+ /* Try to determine where is the pointer to the next allocated
3496+ TimerEventRec.
3497+
3498+ Besides, XtAppAddTimeOut() shall not have been called already
3499+ because we want to be sure any (libXt internal) "free"
3500+ TimerEventRec pointer cache is empty. */
3501+ tq = XtNew(TimerEventRec);
3502+ XtFree((char *)tq);
3503+ tq_probe = XtNew(TimerEventRec);
3504+ XtFree((char *)tq_probe);
3505+ if (tq != tq_probe)
3506+ return 0;
3507+
3508+ id = XtAppAddTimeOut(x_app_context, 0,
3509+ xt_dummy_timeout_cb,
3510+ GUINT_TO_POINTER(0xdeadbeef));
3511+
3512+ tq = x_app_context->timerQueue;
3513+ is_compatible = tq == tq_probe
3514+ && tq->app == x_app_context
3515+ && tq->te_proc == xt_dummy_timeout_cb
3516+ && tq->te_closure == GUINT_TO_POINTER(0xdeadbeef)
3517+ ;
3518+
3519+ XtRemoveTimeOut(id);
3520+ return is_compatible;
3521+}
3522+
3523+static void xt_dummy_input_cb(XtPointer closure, int *source, XtInputId *id)
3524+{
3525+ /* dummy function, never called */
3526+ npw_printf("ERROR: xt_dummy_input_cb() should never be called\n");
3527+}
3528+
3529+static inline int get_appcontext_input_count_at(int offset)
3530+{
3531+ return *((short *)((char *)x_app_context + offset));
3532+}
3533+
3534+static inline int add_appcontext_input(int fd, int n)
3535+{
3536+ return XtAppAddInput(x_app_context,
3537+ fd,
3538+ GUINT_TO_POINTER(XtInputWriteMask),
3539+ xt_dummy_input_cb,
3540+ GUINT_TO_POINTER(0xdead0000));
3541+}
3542+
3543+static int get_appcontext_input_count_offset(void)
3544+{
3545+#define low_offset offsetof(struct _XtAppStruct, __maxed__nfds)
3546+#define high_offset offsetof(struct _XtAppStruct, __maybe__input_max)
3547+#define n_offsets_max (high_offset - low_offset)/2
3548+ int i, ofs, n_offsets = 0;
3549+ int offsets[n_offsets_max] = { 0, };
3550+
3551+#define n_inputs_max 4 /* number of refinements/input sources */
3552+ int fd, id, n_inputs = 0;
3553+ struct { int fd, id; } inputs[n_inputs_max] = { 0, };
3554+
3555+ if ((fd = open("/dev/null", O_WRONLY)) < 0)
3556+ return 0;
3557+ if ((id = add_appcontext_input(fd, 0)) < 0) {
3558+ close(fd);
3559+ return 0;
3560+ }
3561+ inputs[n_inputs].fd = fd;
3562+ inputs[n_inputs].id = id;
3563+ n_inputs++;
3564+
3565+ for (ofs = low_offset; ofs < high_offset; ofs += 2) {
3566+ if (get_appcontext_input_count_at(ofs) == 1)
3567+ offsets[n_offsets++] = ofs;
3568+ }
3569+
3570+ while (n_inputs < n_inputs_max) {
3571+ if ((fd = open("/dev/null", O_WRONLY)) < 0)
3572+ break;
3573+ if ((id = add_appcontext_input(fd, n_inputs)) < 0) {
3574+ close(fd);
3575+ break;
3576+ }
3577+ inputs[n_inputs].fd = fd;
3578+ inputs[n_inputs].id = id;
3579+ n_inputs++;
3580+
3581+ int n = 0;
3582+ for (i = 0; i < n_offsets; i++) {
3583+ if (get_appcontext_input_count_at(offsets[i]) == n_inputs)
3584+ offsets[n++] = offsets[i];
3585+ }
3586+ for (i = n; i < n_offsets; i++)
3587+ offsets[i] = 0;
3588+ n_offsets = n;
3589+ }
3590+
3591+ for (i = 0; i < n_inputs; i++) {
3592+ XtRemoveInput(inputs[i].id);
3593+ close(inputs[i].fd);
3594+ }
3595+
3596+ if (n_offsets == 1)
3597+ return offsets[0];
3598+
3599+#undef n_fds_max
3600+#undef n_offsets_max
3601+#undef high_offset
3602+#undef low_offset
3603+ return 0;
3604+}
3605+
3606+static int get_appcontext_input_count(void)
3607+{
3608+ static int input_count_offset = -1;
3609+ if (input_count_offset < 0)
3610+ input_count_offset = get_appcontext_input_count_offset();
3611+ if (input_count_offset == 0)
3612+ return 1; /* fake we have input to trigger timeout */
3613+ return get_appcontext_input_count_at(input_count_offset);
3614+}
3615+
3616+static int xt_has_compatible_appcontext(void)
3617+{
3618+ return xt_has_compatible_appcontext_timerQueue();
3619+}
3620+
3621+static int xt_get_next_timeout(GSource *source)
3622+{
3623+ static int has_compatible_appcontext = -1;
3624+ if (has_compatible_appcontext < 0) {
3625+ if ((has_compatible_appcontext = xt_has_compatible_appcontext()) == 0)
3626+ npw_printf("WARNING: xt_get_next_timeout() is not optimizable\n");
3627+ }
3628+ int timeout = XT_DEFAULT_TIMEOUT;
3629+ if (has_compatible_appcontext) {
3630+ int input_timeout, timer_timeout;
3631+ /* Check there is any input source to process */
3632+ if (get_appcontext_input_count() > 0)
3633+ input_timeout = XT_DEFAULT_TIMEOUT;
3634+ else
3635+ input_timeout = -1;
3636+ /* Check there is any timer to process */
3637+ if (x_app_context->timerQueue == NULL)
3638+ timer_timeout = -1;
3639+ else {
3640+ /* Determine delay to next timeout. Zero means timeout already expired */
3641+ struct timeval *next = &x_app_context->timerQueue->te_timer_value;
3642+ GTimeVal now;
3643+ int64_t diff;
3644+ g_source_get_current_time(source, &now);
3645+ if ((diff = (int64_t)next->tv_sec - (int64_t)now.tv_sec) < 0)
3646+ timer_timeout = 0;
3647+ else if ((diff = diff*1000 + ((int64_t)next->tv_usec - (int64_t)now.tv_usec)/1000) <= 0)
3648+ timer_timeout = 0;
3649+ else
3650+ timer_timeout = diff;
3651+ }
3652+ if (input_timeout < 0)
3653+ timeout = timer_timeout;
3654+ else if (timer_timeout < 0)
3655+ timeout = input_timeout;
3656+ else
3657+ timeout = MIN(input_timeout, timer_timeout);
3658+ }
3659+ return timeout;
3660+}
3661
3662 static gboolean xt_event_prepare(GSource *source, gint *timeout)
3663 {
3664 int mask = XtAppPending(x_app_context);
3665- return mask & XtIMXEvent;
3666+ if (mask)
3667+ return TRUE;
3668+ /* XXX: create new GPollFD for input sources? */
3669+ return (*timeout = xt_get_next_timeout(source)) == 0;
3670 }
3671
3672 static gboolean xt_event_check(GSource *source)
3673 {
3674 if (xt_event_poll_fd.revents & G_IO_IN) {
3675 int mask = XtAppPending(x_app_context);
3676- if (mask & XtIMXEvent)
3677+ if (mask)
3678 return TRUE;
3679 }
3680 return FALSE;
3681@@ -3744,11 +4322,11 @@
3682 static gboolean xt_event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
3683 {
3684 int i;
3685- for (i = 0; i < 5; i++) {
3686+ for (i = 0; i < XT_MAX_DISPATCH_EVENTS; i++) {
3687 int mask = XtAppPending(x_app_context);
3688- if ((mask & XtIMXEvent) == 0)
3689+ if (mask == 0)
3690 break;
3691- XtAppProcessEvent(x_app_context, XtIMXEvent);
3692+ XtAppProcessEvent(x_app_context, XtIMAll);
3693 }
3694 return TRUE;
3695 }
3696@@ -3762,15 +4340,31 @@
3697 (GSourceDummyMarshal)NULL
3698 };
3699
3700-static gboolean xt_event_polling_timer_callback(gpointer user_data)
3701-{
3702- int i;
3703- for (i = 0; i < 5; i++) {
3704- if ((XtAppPending(x_app_context) & (XtIMAll & ~XtIMXEvent)) == 0)
3705- break;
3706- XtAppProcessEvent(x_app_context, XtIMAll & ~XtIMXEvent);
3707- }
3708- return TRUE;
3709+static int xt_source_create(void)
3710+{
3711+ if (++xt_source_count > 1 && xt_source != NULL)
3712+ return 0;
3713+
3714+ if ((xt_source = g_source_new(&xt_event_funcs, sizeof(GSource))) == NULL) {
3715+ npw_printf("ERROR: failed to initialize Xt events listener\n");
3716+ return -1;
3717+ }
3718+ g_source_set_priority(xt_source, GDK_PRIORITY_EVENTS);
3719+ g_source_set_can_recurse(xt_source, TRUE);
3720+ g_source_attach(xt_source, NULL);
3721+ xt_event_poll_fd.fd = ConnectionNumber(x_display);
3722+ xt_event_poll_fd.events = G_IO_IN;
3723+ xt_event_poll_fd.revents = 0;
3724+ g_source_add_poll(xt_source, &xt_event_poll_fd);
3725+ return 0;
3726+}
3727+
3728+static void xt_source_destroy(void)
3729+{
3730+ if (--xt_source_count < 1 && xt_source) {
3731+ g_source_destroy(xt_source);
3732+ xt_source = NULL;
3733+ }
3734 }
3735
3736 // RPC events
3737@@ -3825,10 +4419,11 @@
3738 return 1;
3739 }
3740 D(bug(" Plugin connection: %s\n", connection_path));
3741-
3742- pid_init();
3743- D(bug(" Plugin viewer pid: %d\n", g_viewer_pid));
3744-
3745+ D(bug(" Plugin viewer pid: %d\n", getpid()));
3746+
3747+ thread_check_init();
3748+ D(bug(" Plugin main thread: %p\n", g_main_thread));
3749+
3750 // Cleanup environment, the program may fork/exec a native shell
3751 // script and having 32-bit libraries in LD_PRELOAD is not right,
3752 // though not a fatal error
3753@@ -3886,24 +4481,6 @@
3754
3755 id_init();
3756
3757- // Initialize Xt events listener (integrate X events into GTK events loop)
3758- GSource *xt_source = g_source_new(&xt_event_funcs, sizeof(GSource));
3759- if (xt_source == NULL) {
3760- npw_printf("ERROR: failed to initialize Xt events listener\n");
3761- return 1;
3762- }
3763- g_source_set_priority(xt_source, GDK_PRIORITY_EVENTS);
3764- g_source_set_can_recurse(xt_source, TRUE);
3765- g_source_attach(xt_source, NULL);
3766- xt_event_poll_fd.fd = ConnectionNumber(x_display);
3767- xt_event_poll_fd.events = G_IO_IN;
3768- xt_event_poll_fd.revents = 0;
3769- g_source_add_poll(xt_source, &xt_event_poll_fd);
3770-
3771- gint xt_polling_timer_id = g_timeout_add(25,
3772- xt_event_polling_timer_callback,
3773- NULL);
3774-
3775 // Initialize RPC events listener
3776 GSource *rpc_source = g_source_new(&rpc_event_funcs, sizeof(GSource));
3777 if (rpc_source == NULL) {
3778@@ -3924,9 +4501,13 @@
3779 gtk_main();
3780 D(bug("--- EXIT ---\n"));
3781
3782- g_source_remove(xt_polling_timer_id);
3783+#if USE_NPIDENTIFIER_CACHE
3784+ npidentifier_cache_destroy();
3785+#endif
3786+
3787 g_source_destroy(rpc_source);
3788- g_source_destroy(xt_source);
3789+ if (xt_source)
3790+ g_source_destroy(xt_source);
3791
3792 if (g_user_agent)
3793 free(g_user_agent);
3794
3795=== modified file 'src/npw-viewer.sh'
3796--- src/npw-viewer.sh 2008-12-27 02:10:20 +0000
3797+++ src/npw-viewer.sh 2009-08-11 00:38:42 +0000
3798@@ -2,9 +2,8 @@
3799 #
3800 # nsplugin viewer wrapper script (C) 2005-2006 Gwenole Beauchesne
3801 #
3802-OS="`uname -s`"
3803+OS="`uname -s | tr '[A-Z]' '[a-z]'`"
3804 ARCH="`uname -m`"
3805-NPW_LIBDIR="%NPW_LIBDIR%"
3806
3807 if test -z "$TARGET_OS"; then
3808 echo "*** NSPlugin Viewer *** error, TARGET_OS not initialized"
3809@@ -16,7 +15,54 @@
3810 exit 1
3811 fi
3812
3813-NPW_VIEWER_DIR=$NPW_LIBDIR/$TARGET_ARCH/$TARGET_OS
3814+normalize_cpu() {
3815+local cpu="$1"
3816+case "$cpu" in
3817+arm*)
3818+ cpu="arm"
3819+ ;;
3820+i[3456]86|k[678]|i86pc|BePC)
3821+ cpu="i386"
3822+ ;;
3823+ia64)
3824+ cpu="ia64"
3825+ ;;
3826+"Power Macintosh"|ppc)
3827+ cpu="ppc"
3828+ ;;
3829+ppc64)
3830+ cpu="ppc64"
3831+ ;;
3832+sparc)
3833+ cpu="sparc"
3834+ ;;
3835+sparc64)
3836+ cpu="sparc64"
3837+ ;;
3838+x86_64|amd64)
3839+ cpu="x86_64"
3840+ ;;
3841+esac
3842+echo "$cpu"
3843+}
3844+
3845+normalize_os() {
3846+local os="$1"
3847+case "$os" in
3848+sunos*)
3849+ os="solaris"
3850+ ;;
3851+esac
3852+echo "$os"
3853+}
3854+
3855+ARCH=`normalize_cpu "$ARCH"`
3856+OS=`normalize_os "$OS"`
3857+TARGET_ARCH=`normalize_cpu "$TARGET_ARCH"`
3858+TARGET_OS=`normalize_os "$TARGET_OS"`
3859+
3860+# Define where npviewer.bin is located
3861+NPW_VIEWER_DIR="%NPW_VIEWER_DIR%"
3862
3863 # Set a new LD_LIBRARY_PATH that is TARGET specific
3864 export LD_LIBRARY_PATH=$NPW_VIEWER_DIR
3865@@ -31,24 +77,15 @@
3866 NPW_USE_VALGRIND=${NPW_USE_VALGRIND:-no}
3867 can_use_valgrind="no"
3868
3869-case $ARCH in
3870-i?86|i86pc)
3871- ARCH=i386
3872- ;;
3873-amd64)
3874- ARCH=x86_64
3875- ;;
3876-esac
3877-
3878 if test "$ARCH" != "$TARGET_ARCH"; then
3879 case $TARGET_ARCH in
3880 i386)
3881 if test "$ARCH" = "x86_64"; then
3882 case "$OS" in
3883- Linux)
3884+ linux)
3885 LOADER=`which linux32`
3886 ;;
3887- FreeBSD | NetBSD)
3888+ freebsd | netbsd)
3889 # XXX check that COMPAT_LINUX is enabled or fail otherwise
3890 LOADER="none"
3891 ;;
3892@@ -66,7 +103,7 @@
3893 ppc)
3894 if test "$ARCH" = "ppc64"; then
3895 case "$OS" in
3896- Linux)
3897+ linux)
3898 LOADER=`which linux32`
3899 ;;
3900 esac
3901@@ -98,7 +135,7 @@
3902 fi
3903
3904 # Expand PATH for RealPlayer package on NetBSD (realplay)
3905-if test "$OS" = "NetBSD"; then
3906+if test "$OS" = "netbsd"; then
3907 REALPLAYER_HOME="/usr/pkg/lib/RealPlayer"
3908 if test -x "$REALPLAYER_HOME/realplay"; then
3909 export PATH=$PATH:$REALPLAYER_HOME
3910@@ -114,7 +151,7 @@
3911 # XXX: detect QEMU target soundwrapper differently
3912 case "$LOADER" in
3913 *linux32)
3914- if test "$OS" = "Linux"; then
3915+ if test "$OS" = "linux"; then
3916 soundwrapper=`which soundwrapper 2>/dev/null`
3917 if test -x "$soundwrapper"; then
3918 LOADER="$LOADER $soundwrapper"
3919
3920=== modified file 'src/npw-wrapper.c'
3921--- src/npw-wrapper.c 2009-01-02 10:07:27 +0000
3922+++ src/npw-wrapper.c 2009-08-11 00:38:42 +0000
3923@@ -21,7 +21,6 @@
3924 #define _GNU_SOURCE 1 /* RTLD_DEFAULT */
3925 #include "sysdeps.h"
3926
3927-#include <assert.h>
3928 #include <stdio.h>
3929 #include <stdlib.h>
3930 #include <string.h>
3931@@ -61,12 +60,17 @@
3932 NPW_DEFAULT_PLUGIN_PATH,
3933 0,
3934 HOST_OS,
3935- HOST_ARCH
3936+ HOST_ARCH,
3937+ NPW_PLUGIN_INFO_VERSION,
3938+ ""
3939 };
3940
3941 // Path to plugin to use
3942 static const char *plugin_path = NPW_Plugin.path;
3943
3944+// Path to associated plugin viewer
3945+static const char *plugin_viewer_path = NPW_Plugin.viewer_path;
3946+
3947 // Netscape exported functions
3948 static NPNetscapeFuncs mozilla_funcs;
3949
3950@@ -2607,7 +2611,7 @@
3951 str =
3952 "<a href=\"http://gwenole.beauchesne.info/projects/nspluginwrapper/\">nspluginwrapper</a> "
3953 " is a cross-platform NPAPI plugin viewer, in particular for linux/i386 plugins.<br>"
3954- "This software is available under the terms of the GNU General Public License.<br>"
3955+ "This <b>beta</b> software is available under the terms of the GNU General Public License.<br>"
3956 ;
3957 ret = NPERR_NO_ERROR;
3958 }
3959@@ -3348,15 +3352,13 @@
3960
3961 static int init_count = 0;
3962 ++init_count;
3963- char viewer_path[PATH_MAX];
3964- sprintf(viewer_path, "%s/%s/%s/%s", NPW_LIBDIR, NPW_Plugin.target_arch, NPW_Plugin.target_os, NPW_VIEWER);
3965 char connection_path[128];
3966 sprintf(connection_path, "%s/%s/%d-%d", NPW_CONNECTION_PATH, plugin_file_name, getpid(), init_count);
3967
3968 // Cache MIME info and plugin name/description
3969 if (g_plugin.name == NULL && g_plugin.description == NULL && g_plugin.formats == NULL) {
3970 char command[1024];
3971- if (snprintf(command, sizeof(command), "%s --info --plugin %s", viewer_path, plugin_path) >= sizeof(command))
3972+ if (snprintf(command, sizeof(command), "%s --info --plugin %s", plugin_viewer_path, plugin_path) >= sizeof(command))
3973 return;
3974 FILE *viewer_fp = popen(command, "r");
3975 if (viewer_fp == NULL)
3976@@ -3416,7 +3418,7 @@
3977
3978 npw_close_all_open_files();
3979
3980- execv(viewer_path, argv);
3981+ execv(plugin_viewer_path, argv);
3982 npw_printf("ERROR: failed to execute NSPlugin viewer\n");
3983 _Exit(255);
3984 }
3985
3986=== modified file 'src/rpc.c'
3987--- src/rpc.c 2009-01-02 10:07:27 +0000
3988+++ src/rpc.c 2009-08-11 00:38:42 +0000
3989@@ -60,9 +60,11 @@
3990 // build of the viewer can interoperate with non-Linux wrappers. Linux
3991 // distributions can use this code though.
3992 // XXX better clean-up dead sockets properly on failure...
3993-#ifdef BUILD_LINUX_ONLY
3994+#ifndef BUILD_GENERIC
3995+#if defined(__linux__)
3996 #define USE_ANONYMOUS_SOCKETS 1
3997 #endif
3998+#endif
3999
4000 // Define the maximum amount of time (in seconds) to wait for a message
4001 #ifndef RPC_MESSAGE_TIMEOUT
4002@@ -459,6 +461,8 @@
4003 int status;
4004 int socket;
4005 char *socket_path;
4006+ struct sockaddr_un socket_addr;
4007+ socklen_t socket_addr_len;
4008 int server_socket;
4009 int server_thread_active;
4010 pthread_t server_thread;
4011@@ -663,59 +667,131 @@
4012 return n;
4013 }
4014
4015+// Create a new RPC connection (initialize common structure members)
4016+static rpc_connection_t *rpc_connection_new(int type, const char *ident)
4017+{
4018+ rpc_connection_t *connection;
4019+
4020+ if (ident == NULL)
4021+ return NULL;
4022+
4023+ if ((connection = (rpc_connection_t *)calloc(1, sizeof(*connection))) == NULL)
4024+ return NULL;
4025+
4026+ connection->type = type;
4027+ connection->refcnt = 1;
4028+ connection->status = RPC_STATUS_CLOSED;
4029+ connection->socket = -1;
4030+ connection->server_socket = -1;
4031+ connection->server_thread_active = 0;
4032+ connection->error_callback = NULL;
4033+ connection->error_callback_data = NULL;
4034+ connection->dispatch_depth = 0;
4035+ connection->invoke_depth = 0;
4036+ connection->handle_depth = 0;
4037+ connection->sync_depth = 0;
4038+ connection->pending_sync_depth = 0;
4039+
4040+ if ((connection->types = rpc_map_new_full((free))) == NULL) {
4041+ rpc_exit(connection);
4042+ return NULL;
4043+ }
4044+
4045+ if ((connection->methods = rpc_map_new()) == NULL) {
4046+ rpc_exit(connection);
4047+ return NULL;
4048+ }
4049+
4050+ int fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
4051+ if (fd < 0) {
4052+ perror("socket");
4053+ rpc_exit(connection);
4054+ return NULL;
4055+ }
4056+
4057+ if (type == RPC_CONNECTION_SERVER)
4058+ connection->server_socket = fd;
4059+ else {
4060+ connection->socket = fd;
4061+
4062+ if (rpc_set_non_blocking_io(fd) < 0) {
4063+ perror("socket set non-blocking");
4064+ rpc_exit(connection);
4065+ return NULL;
4066+ }
4067+ }
4068+
4069+ memset(&connection->socket_addr, 0, sizeof(connection->socket_addr));
4070+ connection->socket_addr.sun_family = AF_UNIX;
4071+ connection->socket_path = NULL;
4072+ connection->socket_addr_len = _rpc_socket_path(&connection->socket_path, ident);
4073+ memcpy(&connection->socket_addr.sun_path[0], connection->socket_path, connection->socket_addr_len);
4074+ connection->socket_addr_len += offsetof(struct sockaddr_un, sun_path); /* though POSIX says size of the actual sockaddr structure */
4075+#ifdef HAVE_SOCKADDR_UN_SUN_LEN
4076+ connection->socket_addr.sun_len = connection->socket_addr_len;
4077+#endif
4078+
4079+ return connection;
4080+}
4081+
4082+// Destroy an RPC connection
4083+static void rpc_connection_destroy(rpc_connection_t *connection)
4084+{
4085+ if (connection == NULL)
4086+ return;
4087+
4088+ if (connection->socket_path) {
4089+ if (connection->socket_path[0])
4090+ unlink(connection->socket_path);
4091+ free(connection->socket_path);
4092+ connection->socket_path = NULL;
4093+ }
4094+
4095+ if (connection->type == RPC_CONNECTION_SERVER) {
4096+ if (connection->server_thread_active) {
4097+ pthread_cancel(connection->server_thread);
4098+ pthread_join(connection->server_thread, NULL);
4099+ connection->server_thread = 0;
4100+ }
4101+ if (connection->socket != -1) {
4102+ close(connection->socket);
4103+ connection->socket = -1;
4104+ }
4105+ if (connection->server_socket != -1) {
4106+ close(connection->server_socket);
4107+ connection->server_socket = -1;
4108+ }
4109+ }
4110+ else {
4111+ if (connection->socket != -1) {
4112+ close(connection->socket);
4113+ connection->socket = -1;
4114+ }
4115+ }
4116+
4117+ if (connection->types) {
4118+ rpc_map_destroy(connection->types);
4119+ connection->types = NULL;
4120+ }
4121+ if (connection->methods) {
4122+ rpc_map_destroy(connection->methods);
4123+ connection->methods = NULL;
4124+ }
4125+
4126+ free(connection);
4127+}
4128+
4129 // Initialize server-side RPC system
4130 rpc_connection_t *rpc_init_server(const char *ident)
4131 {
4132 D(bug("rpc_init_server ident='%s'\n", ident));
4133
4134 rpc_connection_t *connection;
4135- struct sockaddr_un addr;
4136- socklen_t addr_len;
4137-
4138- if (ident == NULL)
4139- return NULL;
4140-
4141- connection = (rpc_connection_t *)calloc(1, sizeof(*connection));
4142- if (connection == NULL)
4143- return NULL;
4144- connection->type = RPC_CONNECTION_SERVER;
4145- connection->refcnt = 1;
4146- connection->status = RPC_STATUS_CLOSED;
4147- connection->socket = -1;
4148- connection->server_thread_active = 0;
4149- connection->error_callback = NULL;
4150- connection->error_callback_data = NULL;
4151- connection->dispatch_depth = 0;
4152- connection->invoke_depth = 0;
4153- connection->handle_depth = 0;
4154- connection->sync_depth = 0;
4155- connection->pending_sync_depth = 0;
4156- if ((connection->types = rpc_map_new_full((free))) == NULL) {
4157- rpc_exit(connection);
4158- return NULL;
4159- }
4160- if ((connection->methods = rpc_map_new()) == NULL) {
4161- rpc_exit(connection);
4162- return NULL;
4163- }
4164-
4165- if ((connection->server_socket = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0)) < 0) {
4166- perror("server socket");
4167- rpc_exit(connection);
4168- return NULL;
4169- }
4170-
4171- memset(&addr, 0, sizeof(addr));
4172- addr.sun_family = AF_UNIX;
4173- connection->socket_path = NULL;
4174- addr_len = _rpc_socket_path(&connection->socket_path, ident);
4175- memcpy(&addr.sun_path[0], connection->socket_path, addr_len);
4176- addr_len += offsetof(struct sockaddr_un, sun_path); /* though POSIX says size of the actual sockaddr structure */
4177-#ifdef HAVE_SOCKADDR_UN_SUN_LEN
4178- addr.sun_len = addr_len;
4179-#endif
4180-
4181- if (bind(connection->server_socket, (struct sockaddr *)&addr, addr_len) < 0) {
4182+
4183+ if ((connection = rpc_connection_new(RPC_CONNECTION_SERVER, ident)) == NULL)
4184+ return NULL;
4185+
4186+ if (bind(connection->server_socket, (struct sockaddr *)&connection->socket_addr, connection->socket_addr_len) < 0) {
4187 perror("server bind");
4188 rpc_exit(connection);
4189 return NULL;
4190@@ -737,56 +813,9 @@
4191 D(bug("rpc_init_client ident='%s'\n", ident));
4192
4193 rpc_connection_t *connection;
4194- struct sockaddr_un addr;
4195- socklen_t addr_len;
4196-
4197- if (ident == NULL)
4198- return NULL;
4199-
4200- connection = (rpc_connection_t *)calloc(1, sizeof(*connection));
4201- if (connection == NULL)
4202- return NULL;
4203- connection->type = RPC_CONNECTION_CLIENT;
4204- connection->refcnt = 1;
4205- connection->status = RPC_STATUS_CLOSED;
4206- connection->server_socket = -1;
4207- connection->error_callback = NULL;
4208- connection->error_callback_data = NULL;
4209- connection->dispatch_depth = 0;
4210- connection->invoke_depth = 0;
4211- connection->handle_depth = 0;
4212- connection->sync_depth = 0;
4213- connection->pending_sync_depth = 0;
4214- if ((connection->types = rpc_map_new_full((free))) == NULL) {
4215- rpc_exit(connection);
4216- return NULL;
4217- }
4218- if ((connection->methods = rpc_map_new()) == NULL) {
4219- rpc_exit(connection);
4220- return NULL;
4221- }
4222-
4223- if ((connection->socket = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0)) < 0) {
4224- perror("client socket");
4225- rpc_exit(connection);
4226- return NULL;
4227- }
4228-
4229- if (rpc_set_non_blocking_io(connection->socket) < 0) {
4230- perror("client socket set non-blocking");
4231- rpc_exit(connection);
4232- return NULL;
4233- }
4234-
4235- memset(&addr, 0, sizeof(addr));
4236- addr.sun_family = AF_UNIX;
4237- connection->socket_path = NULL;
4238- addr_len = _rpc_socket_path(&connection->socket_path, ident);
4239- memcpy(&addr.sun_path[0], connection->socket_path, addr_len);
4240- addr_len += offsetof(struct sockaddr_un, sun_path); /* though POSIX says size of the actual sockaddr structure */
4241-#ifdef HAVE_SOCKADDR_UN_SUN_LEN
4242- addr.sun_len = addr_len;
4243-#endif
4244+
4245+ if ((connection = rpc_connection_new(RPC_CONNECTION_CLIENT, ident)) == NULL)
4246+ return NULL;
4247
4248 // Wait at most RPC_INIT_TIMEOUT seconds for server to initialize
4249 const int N_CONNECT_WAIT_DELAY = 10;
4250@@ -794,7 +823,7 @@
4251 if (n_connect_attempts == 0)
4252 n_connect_attempts = 1;
4253 while (n_connect_attempts > 0) {
4254- if (connect(connection->socket, (struct sockaddr *)&addr, addr_len) == 0)
4255+ if (connect(connection->socket, (struct sockaddr *)&connection->socket_addr, connection->socket_addr_len) == 0)
4256 break;
4257 if (n_connect_attempts > 1 && errno != ECONNREFUSED && errno != ENOENT) {
4258 perror("client_connect");
4259@@ -821,45 +850,7 @@
4260 if (connection == NULL)
4261 return RPC_ERROR_CONNECTION_NULL;
4262
4263- if (connection->socket_path) {
4264- if (connection->socket_path[0])
4265- unlink(connection->socket_path);
4266- free(connection->socket_path);
4267- connection->socket_path = NULL;
4268- }
4269-
4270- if (connection->type == RPC_CONNECTION_SERVER) {
4271- if (connection->server_thread_active) {
4272- pthread_cancel(connection->server_thread);
4273- pthread_join(connection->server_thread, NULL);
4274- connection->server_thread = 0;
4275- }
4276- if (connection->socket != -1) {
4277- close(connection->socket);
4278- connection->socket = -1;
4279- }
4280- if (connection->server_socket != -1) {
4281- close(connection->server_socket);
4282- connection->server_socket = -1;
4283- }
4284- }
4285- else {
4286- if (connection->socket != -1) {
4287- close(connection->socket);
4288- connection->socket = -1;
4289- }
4290- }
4291-
4292- if (connection->types) {
4293- rpc_map_destroy(connection->types);
4294- connection->types = NULL;
4295- }
4296- if (connection->methods) {
4297- rpc_map_destroy(connection->methods);
4298- connection->methods = NULL;
4299- }
4300-
4301- free(connection);
4302+ rpc_connection_destroy(connection);
4303 return RPC_ERROR_NO_ERROR;
4304 }
4305
4306
4307=== modified file 'src/sysdeps.h'
4308--- src/sysdeps.h 2009-01-02 10:07:27 +0000
4309+++ src/sysdeps.h 2009-08-11 00:38:42 +0000
4310@@ -45,9 +45,9 @@
4311 #define NPW_VIEWER NPW_VIEWER_BASE
4312 #define NPW_WRAPPER_BASE "npwrapper"
4313 #define NPW_WRAPPER NPW_WRAPPER_BASE ".so"
4314-#define NPW_OLD_DEFAULT_PLUGIN_PATH NPW_LIBDIR "/" HOST_ARCH "/" NPW_WRAPPER
4315-#define NPW_DEFAULT_PLUGIN_PATH NPW_LIBDIR "/" HOST_ARCH "/" HOST_OS "/" NPW_WRAPPER
4316-#define NPW_PLUGIN_IDENT "NPW:" NPW_VERSION
4317+#define NPW_DEFAULT_PLUGIN_PATH NPW_HOST_LIBDIR "/" NPW_WRAPPER
4318+#define NPW_PLUGIN_INFO_VERSION 2
4319+#define NPW_PLUGIN_IDENT "NPW:X:" NPW_VERSION
4320 #define NPW_PLUGIN_IDENT_SIZE 32
4321 typedef struct __attribute__((packed)) {
4322 char ident[NPW_PLUGIN_IDENT_SIZE];
4323@@ -55,6 +55,8 @@
4324 time_t mtime;
4325 char target_arch[65];
4326 char target_os[65];
4327+ char struct_version; /* extended format "NPW:X:VERSION" */
4328+ char viewer_path[PATH_MAX];
4329 } NPW_PluginInfo;
4330
4331 #if defined(BUILD_XPCOM)

Subscribers

People subscribed via source and target branches

to all changes: