Friday, February 24, 2012

CGI, Spreadsheet::XLSX and Archive::Zip on Windows 7

I wanted to use Spreadsheet::XLSX to open a spreadsheet uploaded to a web server / CGI program running on Windows 7. On the face of it, it's easy - the CGI module returns a file handle to the uploaded file and Spreadsheet::XLSX accepts a file handle to the file to be opened. But all I got back were errors.

After quick investigation, I discovered that Archive::Zip was rejecting the file handles as not seekable. So, I tried providing different file handles. I tried converting the lightweight file handle from CGI to one compatible with IO::Handle (per the docs). I tried slurping the file into a scalar and creating a file handle from the scalar, using IO::Handle, File::Handle and open. Nothing worked.

So I had another look at Archive::Zip and, in particular the _isSeekable subroutine. No doubt the sub is the way it is for good reasons, but I couldn't understand why it was the way it was and there was not much explanation, beyond notes of some cases that claim to work but don't (or, perhaps, didn't).

One of my programming principles is to simply do what is to be done and deal with errors if and as they occur, rather than running tests to determine whether what is to be done will succeed and not try if success seems unlikely. The test might suggest failure when the operation would succeed (the case I am dealing with here) or they might suggest success when the operation will fail. Because of the latter case, it is necessary to detect and handle errors despite the test and if errors are detected and handled appropriately when they happen there is realitvely little value and some cost in running an unreliable (more or less) test first. The only justification for using an unreliable test up-front is if the actual failed operation is significantly expensive (time, CPU, memory or whatever the relevant resource might be) and the test is not. Very often this is not the case and the up front test is almost purly a disadvantage.

In this case, the tests being done concluded that a seekable file handle was not seekable, so Archive::Zip refused to open the archive. I knew the file handles I was passing were seekable: I tried seeking and it worked.

Rather than rewrite Archive::Zip to skip the test for seekability, which would have required a more thorough review and who knows how much rewrite, I rewrote the test. To me, it's simple: If you want to know if a file handle can seek, try seeking. If it works: it works!! If it fails, then seek doesn't work.

There are many ways to test whether seek is working. One is to simply trust its return status, but comments in the existing code suggest that some implementations are broken so badly that they return success when they have failed. A more robust test would require knowing the contents of the file in advance, seeking to specific locations, reading (I don't care about writing or alternating between reading and writing in this case) and getting expected data. But I didn't know the contents of the file. I could have tried seeking to a location then seeking back to that same location, re-reading and confirming that the same data was read. This would make the test more robust.

I simply called tell and seek on the file handle and checked that no errors were indicated and that reasonable results were returned. More thorough testing could be done, like checking that the same data is read whenever tell reports the same file position, but I haven't bothered.

I don't suggest at all that what I have written is a good, general solution to the problem for Archive::Zip. I have no idea what experience, no doubt time consuming and difficult, lead to the batter of tests and heuristics in _isSeekable. Nor do I care - what I have done works for my case.

If I were worried about (or experienced) more serious errors (die'ing) when trying to tell or seek, I would have wrapped the test in an eval block, but quick and dirty worked fine in this case.

In case this may be of some use to you, here is the diff:

psh.bat% diff -u Zip.pm /inetpub/xenwof/lib/Archive/Zip.pm
--- aZip.pm      Tue Jun 30 06:51:10 2009
+++ bZip.pm   Sat Feb 25 08:04:36 2012
@@ -379,28 +379,64 @@
 sub _isSeekable {
     my $fh = shift;
     return 0 unless ref $fh;
-    if ( _ISA($fh, 'IO::Scalar') ) {
-        # IO::Scalar objects are brokenly-seekable
-        return 0;
+#    IG 21 Feb 2012
+#    Try to make a better test for whether the filehandle is seekable
+#    as the current test (below) seems to give false negatives for
+#    file handles that are seekable.
+#
+#    if ( _ISA($fh, 'IO::Scalar') ) {
+#        # IO::Scalar objects are brokenly-seekable
+#        return 0;
+#    }
+#    if ( _ISA($fh, 'IO::String') ) {
+#        return 1;
+#    }
+#    if ( _ISA($fh, 'IO::Seekable') ) {
+#        # Unfortunately, some things like FileHandle objects
+#        # return true for Seekable, but AREN'T!!!!!
+#        if ( _ISA($fh, 'FileHandle') ) {
+#            return 0;
+#        } else {
+#            return 1;
+#        }
+#    }
+#    if ( _CAN($fh, 'stat') ) {
+#        return -f $fh;
+#    }
+#    return (
+#        _CAN($fh, 'seek') and _CAN($fh, 'tell')
+#        ) ? 1 : 0;
+#
+#        IG 21 Feb 2012
+#        What we want to be able to do is seek and tell on the
+#        file handle. Let's start with tell.
+#
+    my $pos = tell($fh);
+    return 0 if($pos == -1);
+
+    # OK - tell works
+    # try seek
+    unless(seek($fh, $pos + 10, 0)) {
+        return 0;   # seek failed
     }
-    if ( _ISA($fh, 'IO::String') ) {
-        return 1;
+
+    my $pos2 = tell($fh);
+
+    unless($pos2 == $pos + 10) {
+        return 0;   # No failure indication but wrong position
     }
-    if ( _ISA($fh, 'IO::Seekable') ) {
-        # Unfortunately, some things like FileHandle objects
-        # return true for Seekable, but AREN'T!!!!!
-        if ( _ISA($fh, 'FileHandle') ) {
-            return 0;
-        } else {
-            return 1;
-        }
+
+    unless(seek($fh, $pos, 0)) {
+        return 0;   # it seems we can seek forward but not back
     }
-    if ( _CAN($fh, 'stat') ) {
-        return -f $fh;
+
+    my $pos3 = tell($fh);
+
+    unless($pos3 == $pos) {
+        return 0;   # no failure indication but wrong position
     }
-    return (
-        _CAN($fh, 'seek') and _CAN($fh, 'tell')
-        ) ? 1 : 0;
+
+    return 1;       # it works well enough for me
 }

 # Print to the filehandle, while making sure the pesky Perl special global




Thursday, February 23, 2012

Recycling

An interesting blog post on recycling

I'll have to read more of this blog when I have time...

Another day, another mood

Peter Garland has 36 videos on YouTube. I listened to many and enjoyed every one. Most have fewer than 50 views. So much talent goes unnoticed, while complete dross gets attention.

Wednesday, February 22, 2012

Inspiring guitar playing

I listened to these over and over again - beautiful and inspiring.

Baby Please Don't Go

I'm Taking Chances A Blues in E

Both by Kenny Wilson.

If my wildest dreams come true, I'll play like this some day.

Wednesday, February 15, 2012

IIS7 FastCgiModule configuration

I won't be using FastCgiModule on IIS7. I had hoped to use it to run Perl scripts and, perhpas, avoid faults I have experienced with the CgiModule on IIS7 on Windows 7, but after several days searching and trying, I did not have any significant progress towards a working solution and had found no documentation from Microsoft that described how the module works or how to do anything with it other than run PHP, so I decided to cut my losses and stop the effort.

Instead, I will use Apache HTTP Server.

There are many examples of configuring IIS7 for FastCGI/PHP, but I am interested in Perl and, in particular, Strawberry Perl.

Enabling FastCGI in IIS7 is easy, just select the CGI feature.

I haven't found thorough documentation of the configuration of FastCGI from Microsoft. Maybe my searching or persistence are insufficient, but all I have seen from them is marketing, how to enable it and examples of configuration for PHP.

Many people have posted examples and instructions for configuration for specific purposes, but these generally present what to do without explaining why or how it works or what the alternatives are. Most of these I have found are for PHP or ActiveState Perl and mostly for older versions of the module and IIS.

One clue that at least got my toe in the water (i.e. enabled me to run perl with arguments) was this post on Catalyst. It showed the unusual (in my experience) feature of separating the executable from its arguments with a vertical bar rather than a space, as is done almost everywhere else. As usual with such examples, there was no explanation.

So, in the Executable field of the Edit Module Mapping window of IIS Manager for the FastCgiModule module, one can put:

'|'

Mysteriously, none of "%s%", %s% or %s get expanded in this context, as they do in the same field for the CgiModule. Obviously, the syntax and semantics of the Executable field are module specific.

So, I wonder what all the possibilities are and how they relate to the specific query being processed.

I wonder where Microsoft has documentation of their FastCGI feature, beyond how to enable it.

The Adding Handlers (add) page really should say more about how the text in the scriptProcessor attribute is parsed, what substitutions are done and how it is processed. If this is, as I suspect it is, module specific, then this should be stated and the documentation of the individual modules should provide details of what the module does with the attribute value.

The instructions at CosmicScripts.com refer to C:\windows\system32\inetsrv\fcgiext.ini but there is no such file on my Windows7 system, even though I have the FastCgiModule module installed and configured and executing Perl script. Although this page lists IIS7, the configuration page says "coming soon" for IIS7. I note also that the FCGI::IIS module documentaiton says IIS7 is supported, and refers to the CosmicScripts site for configuration instructions.

The environment of the script I have running has a variable named _FCGI_X_PIPE. This is the only variable that appears to be relevant to FCGI. Searching Microsoft for references to this variable name, there are two Japanese article found and KB980363, which provides a brief description. There are only 17 hits searching MSDN, and they almost all give the same information. None of them describe how the interface works.

this post mentions where IIS7 keeps configuration of the FastCgiModule module: in applicationHost.config, along with other IIS configuration. That file exists on my Windows7 system with IIS7, and it does have some of my configuration for the FastCgiModule module, though it is hard to be sure it is all there.

After many hours of searching, I have found so little other than examples of how to configure for PHP that I am not inclined to pursue using IIS/FastCgiModule with Perl.

Saturday, February 11, 2012

gmusicbrowser on Windows7

This is a long ramble describing how I installed Perl modules Glib and Gtk2 on Strawberry Perl (This is perl 5, version 12, subversion 3 (v5.12.3) built for MSWin32-x86-multi-thread) on Windows 7 Professional 64bit. I like gmusicbrowser and lately must use Windows on my laptop, but there is no binary distribution for Windows and it needs Glib and Gtk2 modules, which I didn't have installed, so...

There were many false starts and errors along the way. There seems to be some confusion about getting Glib and Gtk2 running on Windows. After all, what is required is not very complicated (or, I should say that others have done all the hard work and, while a simple 'cpan install Glib' and 'cpan install Gtk2' don't work, there isn't much that needs to be done in order to get it goind. I have edited out most of my failed attempts leaving, I hope, a fairely simple procedure including a few particularly relevant errors that might help others searching for solutions.

I already had Strawberry Perl installed.

Gmusicbrowser uses Glib and Gtk2 modules. These are not bundled with Strawberry Perl.

Various people suggest "ppm install Bundle::Gnome2" as an easy way to install Gtk2 on Windows. I tried that. It installed the Bundle::Gnome2.pm module, but none of the modules it referenced. Maybe it works OK on ActiveState Perl but, despite various suggestions it works with Strawberry, it did nothing for me.

So I downloaded the "all-in-one" bundle of Gtk version 2.22 from www.gtk.org and unzipped it to C:\GTK. Then edited Windows environment variables, adding C:\GTK\bin to PATH and setting LIB to 'C:\GTK\lib'.

Eventually, following a suggestion of Khen1950fx on PerlMonks, I began having some success installing Perl modules. I installed them in the order he recommended:

"Test::Harness",
"Test::More",
"Test::Number::Delta",
"File::Spec",
"Pod::Man",
"Pod::Simple",
"Text::Wrap",
"Pod::Escapes",
"ExtUtils::MakeMaker",
"ExtUtils::PkgConfig",
"ExtUtils::Depends",
"Cairo",
"Glib",
"Pango",
"Gtk2"
I installed each module with 'cpan install Module::Name' in a command prompt window, except where there were problems. A few of them were already installed, but most were new to my system.

All went well until the Cairo module. With this I had trouble because I had initially installed the 64bit version of the Gtk all-in-one bundle (I have 64bit Windows). The linker failed to link against the 64bit library, reporting many undefined symbols. I removed the 64bit bundle and installed the 32bit bundle, after which the Cairo module built without problems. Thanks to Mithaldu and TonyC over at #win32 at mibbit.com for helping me solve this problem.

Glib had a test failure - only one on a new feature, so I did a force install.

Pango wasn't linking against the Cairo library, reporting several unresolved symbols:

Running Mkbootstrap for Pango ()
C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e chmod -- 644 Pango.bs
C:\strawberry\perl\bin\perl.exe -MExtUtils::Mksymlists \
     -e "Mksymlists('NAME'=>\"Pango\", 'DLBASE' => 'Pango', 'DL_FUNCS' => { Pang
o=>[] }, 'FUNCLIST' => [q[newSVPangoRectangle], q[SvPangoRectangle], q[gtk2perl_
pango_attribute_get_type], q[gtk2perl_pango_attribute_register_custom_type], q[g
tk2perl_pango_attr_iterator_get_type], q[gtk2perl_pango_layout_iter_get_type], q
[gtk2perl_pango_layout_line_get_type], q[gtk2perl_pango_script_iter_get_type]],
'IMPORTS' => {  }, 'DL_VARS' => []);"
dlltool --def Pango.def --output-exp dll.exp
[ LD blib\arch\auto\Pango\Pango.dll ]
xs/PangoCairo.o:PangoCairo.c:(.text+0xaa6): undefined reference to `cairo_refere
nce'
xs/PangoCairo.o:PangoCairo.c:(.text+0xf7d): undefined reference to `cairo_font_o
ptions_copy'
xs/PangoCairo.o:PangoCairo.c:(.text+0x2042): undefined reference to `cairo_scale
d_font_reference'
collect2: ld returned 1 exit status
dmake.EXE:  Error code 129, while making 'blib\arch\auto\Pango\Pango.dll'
  XAOC/Pango-1.223.tar.gz
  C:\strawberry\c\bin\dmake.EXE -- NOT OK
Failed during this command:
 XAOC/Pango-1.223.tar.gz                      : make NO

I had to hack the Makefile for this one. I ran cpan interactively and did a 'make Pango', then 'look Pango' to drop into the build directory. I edited the Makefile, adding 'C:\GTK\lib\libcairo.dll.a' to the start of the list of libraries assigned to the EXTRALIBS and LDLOADLIBS variables, then ran 'dmake' and 'dmake test'. Note: 'dmake' not 'make'. I don't know what the difference is other than 'dmake' works and 'make' doesn't. Finally, with all tests run successfully, I installed with 'dmake install', then exited the sub-shell and cpan - all done with Pango.

Then the Perl Gtk2 module install failed:

dlltool --def Gtk2.def --output-exp dll.exp
[ LD blib\arch\auto\Gtk2\Gtk2.dll ]
xs/GtkPrintContext.o:GtkPrintContext.c:(.text+0x1542): undefined reference to `c
airo_reference'
xs/GdkCairo.o:GdkCairo.c:(.text+0x6f2): undefined reference to `cairo_pattern_re
ference'
xs/GdkCairo.o:GdkCairo.c:(.text+0x8e3): undefined reference to `cairo_surface_re
ference'
xs/GdkCairo.o:GdkCairo.c:(.text+0x11ba): undefined reference to `cairo_rectangle
'
collect2: ld returned 1 exit status
dmake.EXE:  Error code 129, while making 'blib\arch\auto\Gtk2\Gtk2.dll'
  XAOC/Gtk2-1.242.tar.gz
  C:\strawberry\c\bin\dmake.EXE -- NOT OK
Failed during this command:
 XAOC/Gtk2-1.242.tar.gz                       : make NO

This looks familiar. Again, interactive cpan, make then look and edit the Makefile to add C:\GTK\lib\libcairo.dll.a to EXTRALIBS and LDLOADLIBS, after which dmake ran to successful completion, but dmake test gave errors:

C:\strawberry\cpan\build\Gtk2-1.242-wKFYdS>dmake test
C:\strawberry\perl\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_harness(0,
'blib\lib', 'blib\arch')" t/*.t
t/00.Gtk2.t ........................ 1/44 # Testing Gtk2 1.242
#    Running against gtk+ 2.24.10
#   Compiled against gtk+ 2.24.10
#               and pango 1.29.4
t/00.Gtk2.t ........................ ok
t/01.GtkWindow.t ................... ok
t/02.GtkContainer.t ................ ok
t/Gdk.t ............................ 1/17 Gdk-WARNING **: gdk_set_sm_client_id b
lub at t/Gdk.t line 62.
Gdk-WARNING **: gdk_set_sm_client_id NULL at t/Gdk.t line 63.
t/Gdk.t ............................ ok
t/GdkCairo.t ....................... ok
t/GdkColor.t ....................... 1/18 Gdk-WARNING **: gdkcolor-win32.c:110:
DeleteObject failed: The operation completed successfully..
t/GdkColor.t ....................... ok
t/GdkCursor.t ...................... ok
t/GdkDisplay.t ..................... 1/24 Gdk-WARNING **: gdk_display_get_defaul
t_group not yet implemented at t/GdkDisplay.t line 67.

#   Failed test at t/GdkDisplay.t line 77.
#          got: ''
#     expected: '1'
# Looks like you failed 1 test of 24.
t/GdkDisplay.t ..................... Dubious, test returned 1 (wstat 256, 0x100)

Failed 1/24 subtests
        (less 3 skipped subtests: 20 okay)
t/GdkDisplayManager.t .............. ok
t/GdkDnd.t ......................... ok
t/GdkDrawable.t .................... ok
t/GdkEvent.t ....................... ok
t/GdkGC.t .......................... ok
t/GdkImage.t .......................
t/GdkImage.t ....................... 1/23 #   Failed test 'get_image_type()'
#   at t/GdkImage.t line 10.
#          got: 'shared'
#     expected: 'normal'
Gdk-WARNING **: gdkcolor-win32.c:110: DeleteObject failed: The operation complet
ed successfully. at t/GdkImage.t line 56.
# Looks like you failed 1 test of 23.
t/GdkImage.t ....................... Dubious, test returned 1 (wstat 256, 0x100)

Failed 1/23 subtests
t/GdkInput.t ....................... ok
t/GdkKeys.t ........................ ok
t/GdkPango.t ....................... ok
t/GdkPixbuf.t ...................... ok
t/GdkPixbufLoader.t ................ ok
t/GdkPixbufSimpleAnim.t ............ ok
t/GdkPixmap.t ...................... ok
t/GdkProperty.t .................... 1/49 Gdk-CRITICAL **: gdk_property_change:
assertion `type != GDK_TARGET_STRING' failed at t/GdkProperty.t line 38.
Gdk-CRITICAL **: gdk_property_change: assertion `type != GDK_TARGET_STRING' fail
ed at t/GdkProperty.t line 40.
Gdk-WARNING **: gdk_property_change: General case not implemented at t/GdkProper
ty.t line 42.
Gdk-WARNING **: gdk_property_change: General case not implemented at t/GdkProper
ty.t line 44.
t/GdkProperty.t .................... ok
t/GdkRegion.t ...................... ok
t/GdkRgb.t ......................... ok
t/GdkScreen.t ...................... ok
t/GdkSelection.t ................... ok
t/GdkVisual.t ...................... ok
t/GdkWindow.t ...................... 1/58 Gdk-WARNING **: gdk_window_set_group n
ot implemented at t/GdkWindow.t line 277.
Gdk-CRITICAL **: gdk_window_set_opacity: assertion `WINDOW_IS_TOPLEVEL (window)'
 failed at t/GdkWindow.t line 316.
t/GdkWindow.t ...................... ok
t/GdkX11.t ......................... ok
t/GtkAboutDialog.t ................. ok
t/GtkAccelGroup.t .................. ok
t/GtkAccelLabel.t .................. ok
t/GtkAccelMap.t .................... ok
t/GtkAction.t ...................... ok
t/GtkActionGroup.t ................. ok
t/GtkActivatable.t ................. ok
t/GtkAdjustment.t .................. ok
t/GtkAlignment.t ................... ok
t/GtkArrow.t ....................... ok
t/GtkAspectFrame.t ................. ok
t/GtkAssistant.t ................... ok
t/GtkBin.t ......................... ok
t/GtkBindings.t .................... ok
t/GtkBox.t ......................... ok
t/GtkBuildable.t ................... ok
t/GtkBuildableIface.t .............. ok
t/GtkBuilder.t ..................... ok
t/GtkButton.t ...................... ok
t/GtkButtonBox.t ................... ok
t/GtkCalendar.t .................... ok
t/GtkCellEditable.t ................ GLib-GObject-CRITICAL **: Object class Edit
ableTest doesn't implement property 'editing-canceled' from interface 'GtkCellEd
itable' at C:/strawberry/perl/site/lib/Glib/Object/Subclass.pm line 233.
t/GtkCellEditable.t ................ ok
t/GtkCellLayout.t .................. ok
t/GtkCellLayoutIface.t ............. ok
t/GtkCellRenderer.t ................ ok
t/GtkCellRendererAccel.t ........... ok
t/GtkCellRendererCombo.t ........... ok
t/GtkCellRendererIface-Chaining.t .. ok
t/GtkCellRendererPixbuf.t .......... ok
t/GtkCellRendererProgress.t ........ ok
t/GtkCellRendererSpin.t ............ ok
t/GtkCellRendererSpinner.t ......... ok
t/GtkCellRendererText.t ............ ok
t/GtkCellRendererToggle.t .......... ok
t/GtkCellView.t .................... ok
t/GtkCheckButton.t ................. ok
t/GtkCheckMenuItem.t ............... ok
t/GtkClipboard.t ................... ok
t/GtkColorButton.t ................. ok
t/GtkColorSelection.t .............. ok
t/GtkColorSelectionDialog.t ........ ok
t/GtkCombo.t ....................... ok
t/GtkComboBox.t .................... ok
t/GtkComboBoxEntry.t ............... ok
t/GtkCurve.t ....................... ok
t/GtkDialog.t ...................... 1/33 Gtk-CRITICAL **: gtk_box_reorder_child
: assertion `GTK_IS_WIDGET (child)' failed at t/GtkDialog.t line 91.
Gtk-CRITICAL **: gtk_box_reorder_child: assertion `GTK_IS_WIDGET (child)' failed
 at t/GtkDialog.t line 91.
Gtk-CRITICAL **: gtk_box_reorder_child: assertion `GTK_IS_WIDGET (child)' failed
 at t/GtkDialog.t line 92.
Gtk-CRITICAL **: gtk_box_reorder_child: assertion `GTK_IS_WIDGET (child)' failed
 at t/GtkDialog.t line 92.
Gtk-CRITICAL **: gtk_box_reorder_child: assertion `GTK_IS_WIDGET (child)' failed
 at t/GtkDialog.t line 92.
Gtk-CRITICAL **: gtk_box_reorder_child: assertion `GTK_IS_WIDGET (child)' failed
 at t/GtkDialog.t line 92.
t/GtkDialog.t ...................... ok
t/GtkDnd.t ......................... 1/6 Gdk-CRITICAL **: gdk_window_get_screen:
 assertion `GDK_IS_WINDOW (window)' failed at t/GtkDnd.t line 55.
Gtk-CRITICAL **: gtk_drag_set_icon_pixmap: assertion `!mask || gdk_window_get_sc
reen (mask) == screen' failed at t/GtkDnd.t line 55.
Gtk-WARNING **: Could not find the icon 'gtk-add'. The 'hicolor' theme
was not found either, perhaps you need to install it.
You can get a copy from:
        http://icon-theme.freedesktop.org/releases at t/GtkDnd.t line 65.
Gtk-WARNING **: Cannot load drag icon from icon name gtk-add at t/GtkDnd.t line
65.
t/GtkDnd.t ......................... ok
t/GtkDrawingArea.t ................. ok
t/GtkEditable.t .................... ok
t/GtkEntry.t ....................... ok
t/GtkEntryBuffer.t ................. ok
t/GtkEntryCompletion.t ............. ok
t/GtkEventBox.t .................... ok
t/GtkExpander.t .................... ok
t/GtkFileChooser.t ................. skipped: this test is unreliable
t/GtkFileChooserButton.t ........... ok
t/GtkFileChooserDialog.t ........... ok
t/GtkFileChooserWidget.t ........... ok
t/GtkFileFilter.t .................. ok
t/GtkFileSelection.t ............... ok
t/GtkFixed.t ....................... ok
t/GtkFontButton.t .................. ok
t/GtkFontSelection.t ............... ok
t/GtkFrame.t ....................... ok
t/GtkGammaCurve.t .................. ok
t/GtkGC.t .......................... ok
t/GtkHandleBox.t ................... ok
t/GtkHBox.t ........................ ok
t/GtkHButtonBox.t .................. ok
t/GtkHPaned.t ...................... ok
t/GtkHRuler.t ...................... ok
t/GtkHScale.t ...................... ok
t/GtkHScrollbar.t .................. ok
t/GtkHSeparator.t .................. ok
t/GtkHSV.t ......................... ok
t/GtkIconFactory.t ................. ok
t/GtkIconTheme.t ................... 1/17 Gtk-WARNING **: Could not find the ico
n 'stock_edit'. The 'hicolor' theme
was not found either, perhaps you need to install it.
You can get a copy from:
        http://icon-theme.freedesktop.org/releases at t/GtkIconTheme.t line 26.
t/GtkIconTheme.t ................... ok
t/GtkIconView.t .................... ok
t/GtkImage.t ....................... ok
t/GtkImageMenuItem.t ............... ok
t/GtkIMContext.t ................... ok
t/GtkInfoBar.t ..................... ok
t/GtkInputDialog.t ................. ok
t/GtkInvisible.t ................... ok
t/GtkItemFactory.t ................. ok
t/GtkLabel.t ....................... ok
t/GtkLayout.t ...................... ok
t/GtkLinkButton.t .................. ok
t/GtkListStore.t ................... ok
t/GtkMenu.t ........................ ok
t/GtkMenuBar.t ..................... ok
t/GtkMenuItem.t .................... ok
t/GtkMenuShell.t ................... ok
t/GtkMenuToolButton.t .............. ok
t/GtkMessageDialog.t ............... ok
t/GtkMisc.t ........................ ok
t/GtkNotebook.t .................... ok
t/GtkObject.t ...................... ok
t/GtkOffscreenWindow.t ............. ok
t/GtkOptionMenu.t .................. ok
t/GtkOrientable.t .................. ok
t/GtkPageSetup.t ................... ok
t/GtkPaned.t ....................... ok
t/GtkPaperSize.t ................... ok
t/GtkPrintContext.t ................ ok
t/GtkPrintOperation.t .............. ok
t/GtkPrintOperationPreview.t ....... ok
t/GtkPrintSettings.t ............... ok
t/GtkProgressBar.t ................. ok
t/GtkRadioAction.t ................. ok
t/GtkRadioButton.t ................. ok
t/GtkRadioMenuItem.t ............... ok
t/GtkRadioToolButton.t ............. ok
t/GtkRange.t ....................... ok
t/GtkRc.t .......................... ok
t/GtkRecentAction.t ................ ok
t/GtkRecentChooser.t ............... ok
t/GtkRecentChooserDialog.t ......... ok
t/GtkRecentChooserMenu.t ........... ok
t/GtkRecentChooserWidget.t ......... ok
t/GtkRecentFilter.t ................ ok
t/GtkRecentManager.t ............... 1/36 Gtk-WARNING **: Could not find the ico
n 'stock_edit'. The 'hicolor' theme
was not found either, perhaps you need to install it.
You can get a copy from:
        http://icon-theme.freedesktop.org/releases at t/GtkRecentManager.t line
45.
t/GtkRecentManager.t ............... ok
t/GtkRuler.t ....................... ok
t/GtkScale.t ....................... ok
t/GtkScaleButton.t ................. ok
t/GtkScrolledWindow.t .............. ok
t/GtkSelection.t ................... ok
t/GtkSeparatorMenuItem.t ........... ok
t/GtkSeparatorToolItem.t ........... ok
t/GtkShow.t ........................ skipped: can only test interactively
t/GtkSimpleList.t .................. ok
t/GtkSimpleMenu.t .................. ok
t/GtkSizeGroup.t ................... ok
t/GtkSocket-GtkPlug.t .............. skipped: not appliciable on win32
t/GtkSpinButton.t .................. ok
t/GtkSpinner.t ..................... ok
t/GtkStatusbar.t ................... ok
t/GtkStatusIcon.t .................. 1/37 Gtk-WARNING **: Could not find the ico
n 'stock_edit'. The 'hicolor' theme
was not found either, perhaps you need to install it.
You can get a copy from:
        http://icon-theme.freedesktop.org/releases at t/GtkStatusIcon.t line 60.

t/GtkStatusIcon.t .................. ok
t/GtkStock.t ....................... ok
t/GtkStyle.t ....................... 1/125 Gdk-WARNING **: gdkdrawable-win32.c:6
41: SelectObject failed: The operation completed successfully. at t/GtkStyle.t l
ine 77.
Gdk-WARNING **: gdkdrawable-win32.c:644: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 77.
Gdk-WARNING **: gdkdrawable-win32.c:711: MaskBlt failed: The operation completed
 successfully. at t/GtkStyle.t line 77.
Gdk-WARNING **: gdkdrawable-win32.c:714: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 77.
Gdk-WARNING **: gdkdrawable-win32.c:715: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 77.
Gdk-WARNING **: gdkdrawable-win32.c:641: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 78.
Gdk-WARNING **: gdkdrawable-win32.c:644: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 78.
Gdk-WARNING **: gdkdrawable-win32.c:711: MaskBlt failed: The operation completed
 successfully. at t/GtkStyle.t line 78.
Gdk-WARNING **: gdkdrawable-win32.c:714: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 78.
Gdk-WARNING **: gdkdrawable-win32.c:715: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 78.
Gdk-WARNING **: gdkdrawable-win32.c:641: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 81.
Gdk-WARNING **: gdkdrawable-win32.c:644: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 81.
Gdk-WARNING **: gdkdrawable-win32.c:711: MaskBlt failed: The operation completed
 successfully. at t/GtkStyle.t line 81.
Gdk-WARNING **: gdkdrawable-win32.c:714: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 81.
Gdk-WARNING **: gdkdrawable-win32.c:715: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 81.
Gdk-WARNING **: gdkdrawable-win32.c:641: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 82.
Gdk-WARNING **: gdkdrawable-win32.c:644: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 82.
Gdk-WARNING **: gdkdrawable-win32.c:711: MaskBlt failed: The operation completed
 successfully. at t/GtkStyle.t line 82.
Gdk-WARNING **: gdkdrawable-win32.c:714: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 82.
Gdk-WARNING **: gdkdrawable-win32.c:715: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 82.
Gdk-WARNING **: gdkdrawable-win32.c:641: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 84.
Gdk-WARNING **: gdkdrawable-win32.c:644: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 84.
Gdk-WARNING **: gdkdrawable-win32.c:711: MaskBlt failed: The operation completed
 successfully. at t/GtkStyle.t line 84.
Gdk-WARNING **: gdkdrawable-win32.c:714: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 84.
Gdk-WARNING **: gdkdrawable-win32.c:715: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 84.
Gdk-WARNING **: gdkdrawable-win32.c:641: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 90.
Gdk-WARNING **: gdkdrawable-win32.c:644: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 90.
Gdk-WARNING **: gdkdrawable-win32.c:711: MaskBlt failed: The operation completed
 successfully. at t/GtkStyle.t line 90.
Gdk-WARNING **: gdkdrawable-win32.c:714: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 90.
Gdk-WARNING **: gdkdrawable-win32.c:715: SelectObject failed: The operation comp
leted successfully. at t/GtkStyle.t line 90.
t/GtkStyle.t ....................... ok
t/GtkTable.t ....................... ok
t/GtkTearoffMenuItem.t ............. ok
t/GtkTextBuffer.t .................. ok
t/GtkTextBufferRichText.t .......... ok
t/GtkTextChildAnchor.t ............. ok
t/GtkTextIter.t .................... ok
t/GtkTextMark.t .................... ok
t/GtkTextTag.t ..................... ok
t/GtkTextTagTable.t ................ ok
t/GtkTextView.t .................... ok
t/GtkToggleAction.t ................ ok
t/GtkToggleButton.t ................ ok
t/GtkToggleToolButton.t ............ ok
t/GtkToolbar.t ..................... ok
t/GtkToolButton.t .................. ok
t/GtkToolItem.t .................... ok
t/GtkToolItemGroup.t ............... ok
t/GtkToolPalette.t ................. ok
t/GtkToolShell.t ................... ok
t/GtkTooltip.t ..................... ok
t/GtkTooltips.t .................... ok
t/GtkTreeDnd.t ..................... ok
t/GtkTreeModel.t ................... ok
t/GtkTreeModelFilter.t ............. ok
t/GtkTreeModelIface.t .............. ok
t/GtkTreeModelSort.t ............... ok
t/GtkTreeSelection.t ............... ok
t/GtkTreeSortable.t ................ ok
t/GtkTreeStore.t ................... ok
t/GtkTreeView-Dnd.t ................ skipped: this test is interactive
t/GtkTreeView.t .................... ok
t/GtkUIManager.t ................... ok
t/GtkVBox.t ........................ ok
t/GtkVButtonBox.t .................. ok
t/GtkViewport.t .................... ok
t/GtkVolumeButton.t ................ ok
t/GtkVPaned.t ...................... ok
t/GtkVRuler.t ...................... ok
t/GtkVScale.t ...................... ok
t/GtkVScrollbar.t .................. ok
t/GtkVSeparator.t .................. ok
t/GtkWidget.t ...................... ok
t/pango-compat.t ................... ok
t/PangoAttributes.t ................ ok
t/PangoCairo.t ..................... ok
t/PangoContext.t ................... ok
t/PangoFont.t ...................... ok
t/PangoFontMap.t ................... ok
t/PangoFontset.t ................... ok
t/PangoGravity.t ................... ok
t/PangoLayout.t .................... ok
t/PangoMatrix.t .................... ok
t/PangoRenderer.t .................. ok
t/PangoScript.t .................... ok
t/PangoTabs.t ...................... ok
t/PangoTypes.t ..................... ok
t/set-scroll-adjustments-signal.t .. ok
t/signal-chaining.t ................ ok
t/tied-objects.t ................... ok
t/version-checks.t ................. ok

Test Summary Report
-------------------
t/GdkDisplay.t                   (Wstat: 256 Tests: 24 Failed: 1)
  Failed test:  20
  Non-zero exit status: 1
t/GdkImage.t                     (Wstat: 256 Tests: 23 Failed: 1)
  Failed test:  1
  Non-zero exit status: 1
Files=229, Tests=5068, 43 wallclock secs ( 2.86 usr +  0.72 sys =  3.57 CPU)
Result: FAIL
Failed 2/229 test programs. 2/5068 subtests failed.
dmake:  Error code 255, while making 'test_dynamic'
There were only two failures reported (but several suspicous messages along the way). I don't know how to solve them and found nothing in a brief perusal of Google search results, so I installed anyway and hope for the best.

After all this, I ran gmusicbrowser.pl and the GUI came up!! Now all I have to do is get it to make some noise!!

I loaded up my music library with no obvious problem, but when I tried to play a track nothing happened (or maybe there was an error, I foget exactly what happened). The problem was that there was no audio configured or, more correctly, icecast server was configured and nothing else available.

I installed mpg123. There is a windows binary available. I got the 32bit binary and put it in C:\Program Files (x86)\mpg123, then added this folder to the path environment variable. I was then able to play mp3 files with mpg123, so expect gmusicbrowser can too. I started it up and checked the audio settings but mpg123/ogg123/flac123 was still greyed out. Then I noticed that it is mpg321 NOT mpg123. I didn't find an mpg321 binary for windows, so I had a look at how to get gmusicbrowser to run mpg123.

gmusicbrowser_123.pm seems to be the relevant file. I added 'mpg123' as a command for mp3 files in %cmdname. Tried again and no luck. Then I changed the path separator in the init sub from ':' to ';' (only a quick and dirty to test - need a better solution than this), and tried again. The mpg321/ogg123/flac123 was now available.

So, I selected the mpg321/ogg123/flac123 audio device and tried to play a track, but it reported that it couldn't. So, down in sub Play I added a branch for mpg123, and finally was able to play a track.

But, while the track played the gmusicbrowser GUI was not responding. And when the track finished perl crashed (so says Windows). So, there are more puzzles to solve...

Labels