diff -Nru shotwell-0.3.1/debian/changelog shotwell-0.3.2/debian/changelog --- shotwell-0.3.1/debian/changelog 2009-11-09 23:31:59.000000000 +0000 +++ shotwell-0.3.2/debian/changelog 2009-11-11 23:16:36.000000000 +0000 @@ -1,3 +1,12 @@ +shotwell (0.3.2-1~jaunty1) jaunty; urgency=low + + * Loosened photo pipeline assertion that checked for pixbuf scaling. + * Better error handling for situation where the HAL daemon (hald) is not + running or ready. + + -- Jim Nelson Wed, 11 Nov 2009 15:16:34 -0800 + + shotwell (0.3.1-1~jaunty1) jaunty; urgency=low * Makefile changes to facilitate packaging. diff -Nru /tmp/2IVIWXJK49/shotwell-0.3.1/Makefile /tmp/OODUNB4zm8/shotwell-0.3.2/Makefile --- shotwell-0.3.1/Makefile 2009-11-10 00:46:55.000000000 +0000 +++ shotwell-0.3.2/Makefile 2009-11-11 23:19:10.000000000 +0000 @@ -1,5 +1,5 @@ PROGRAM = shotwell -VERSION = 0.3.1 +VERSION = 0.3.2 GETTEXT_PACKAGE = $(PROGRAM) BUILD_ROOT = 1 diff -Nru /tmp/2IVIWXJK49/shotwell-0.3.1/NEWS /tmp/OODUNB4zm8/shotwell-0.3.2/NEWS --- shotwell-0.3.1/NEWS 2009-11-10 00:46:55.000000000 +0000 +++ shotwell-0.3.2/NEWS 2009-11-11 23:19:10.000000000 +0000 @@ -1,3 +1,10 @@ +Shotwell 0.3.2 - 11 November 2009 + + * Loosened photo pipeline assertion that checked for pixbuf scaling. + * Better error handling for situation where the HAL daemon (hald) is not + running or ready. + + Shotwell 0.3.1 - 9 November 2009 -------------------------------- diff -Nru /tmp/2IVIWXJK49/shotwell-0.3.1/src/Box.vala /tmp/OODUNB4zm8/shotwell-0.3.2/src/Box.vala --- shotwell-0.3.1/src/Box.vala 2009-11-10 00:46:55.000000000 +0000 +++ shotwell-0.3.2/src/Box.vala 2009-11-11 23:19:10.000000000 +0000 @@ -92,7 +92,7 @@ public Box get_scaled(Dimensions scaled) { double x_scale, y_scale; - get_dimensions().get_scale_factors(scaled, out x_scale, out y_scale); + get_dimensions().get_scale_ratios(scaled, out x_scale, out y_scale); int l = (int) Math.round((double) left * x_scale); int t = (int) Math.round((double) top * y_scale); @@ -109,7 +109,7 @@ public Box get_scaled_similar(Dimensions original, Dimensions scaled) { double x_scale, y_scale; - original.get_scale_factors(scaled, out x_scale, out y_scale); + original.get_scale_ratios(scaled, out x_scale, out y_scale); int l = (int) Math.round((double) left * x_scale); int t = (int) Math.round((double) top * y_scale); diff -Nru /tmp/2IVIWXJK49/shotwell-0.3.1/src/CameraTable.vala /tmp/OODUNB4zm8/shotwell-0.3.2/src/CameraTable.vala --- shotwell-0.3.1/src/CameraTable.vala 2009-11-10 00:46:55.000000000 +0000 +++ shotwell-0.3.2/src/CameraTable.vala 2009-11-11 23:19:10.000000000 +0000 @@ -35,29 +35,60 @@ public signal void camera_removed(DiscoveredCamera camera); private CameraTable() { + string? errmsg = init_hal(); + if (errmsg != null) { + critical(errmsg); + AppWindow.error_message( + _("Shotwell could not initialize a connection to the HAL daemon (hald). This usually means it is not running or not ready. Rebooting may solve this problem.\n\nShotwell cannot detect cameras without the HAL daemon.")); + } + + // because loading the camera abilities list takes a bit of time and slows down app + // startup, delay loading it (and notifying any observers) for a small period of time, + // after the dust has settled + Timeout.add(500, delayed_init); + } + + private string? init_hal() { // set up HAL connection to monitor for device insertion/removal, to look for cameras try { hal_conn = DBus.Bus.get(DBus.BusType.SYSTEM); } catch (DBus.Error err) { - error("Unable to get DBus system connection: %s", err.message); + hal_context = null; + + return "Unable to get DBus system connection (%s)".printf(err.message); } - if (!hal_context.set_dbus_connection(hal_conn.get_connection())) - error("Unable to set DBus connection for HAL"); + // don't unref hal_conn from hereafter because DBus complains about it is not closed and + // there is no binding for Hal.Connection.close(). Note that the connection is a shared + // connection, and the docs also say not to close shared connections. We'll just hold on + // to the connection, even if HAL initialization fails. + + if (!hal_context.set_dbus_connection(hal_conn.get_connection())) { + hal_context = null; + + return "Unable to set DBus connection for HAL"; + } DBus.RawError raw = DBus.RawError(); - if (!hal_context.init(ref raw)) - error("Unable to initialize context: %s", raw.message); - - if (!hal_context.set_device_added(on_device_added)) - error("Unable to register device-added callback"); - if (!hal_context.set_device_removed(on_device_removed)) - error("Unable to register device-removed callback"); + if (!hal_context.init(ref raw)) { + hal_context = null; + + return "Unable to initialize context (%s)".printf(raw.message); + } - // because loading the camera abilities list takes a bit of time and slows down app - // startup, delay loading it (and notifying any observers) for a small period of time, - // after the dust has settled - Timeout.add(500, delayed_init); + if (!hal_context.set_device_added(on_device_added)) { + hal_context = null; + + return "Unable to register device-added callback"; + } + + if (!hal_context.set_device_removed(on_device_removed)) { + hal_context = null; + + return "Unable to register device-removed callback"; + } + + return null; } private bool delayed_init() { @@ -112,6 +143,12 @@ // sanity assert(camera_count > 0); + if (hal_context == null) { + debug("ESP: HAL context not established"); + + return null; + } + debug("ESP: camera_count=%d port=%s", camera_count, port); DBus.RawError raw = DBus.RawError(); diff -Nru /tmp/2IVIWXJK49/shotwell-0.3.1/src/Dimensions.vala /tmp/OODUNB4zm8/shotwell-0.3.2/src/Dimensions.vala --- shotwell-0.3.1/src/Dimensions.vala 2009-11-10 00:46:55.000000000 +0000 +++ shotwell-0.3.2/src/Dimensions.vala 2009-11-11 23:19:10.000000000 +0000 @@ -91,24 +91,25 @@ return get_scaled_by_height(scale); } - public void get_scale_factors(Dimensions scaled, out double x_scale, out double y_scale) { - x_scale = (double) scaled.width / (double) width; - y_scale = (double) scaled.height / (double) height; + public void get_scale_ratios(Dimensions scaled, out double width_ratio, out double height_ratio) { + width_ratio = (double) scaled.width / (double) width; + height_ratio = (double) scaled.height / (double) height; } public Dimensions get_scaled_proportional(Dimensions viewport) { - Dimensions scaled = Dimensions(); - - // TODO: Surely this can be done by examining dimensions to avoid double calculations. - scaled.width = viewport.width; - double ratio = (double) viewport.width / (double) width; - scaled.height = (int) Math.round((double) height * ratio); - if (scaled.height > viewport.height) { - scaled.height = viewport.height; - ratio = (double) viewport.height / (double) height; - scaled.width = (int) Math.round((double) width * ratio); + double width_ratio, height_ratio; + get_scale_ratios(viewport, out width_ratio, out height_ratio); + + double scaled_width, scaled_height; + if (width_ratio < height_ratio) { + scaled_width = viewport.width; + scaled_height = (double) height * width_ratio; + } else { + scaled_width = (double) width * height_ratio; + scaled_height = viewport.height; } - + + Dimensions scaled = Dimensions((int) Math.round(scaled_width), (int) Math.round(scaled_height)); assert(scaled.height <= viewport.height); assert(scaled.width <= viewport.width); @@ -117,7 +118,7 @@ public Gdk.Rectangle get_scaled_rectangle(Dimensions scaled, Gdk.Rectangle rect) { double x_scale, y_scale; - get_scale_factors(scaled, out x_scale, out y_scale); + get_scale_ratios(scaled, out x_scale, out y_scale); Gdk.Rectangle scaled_rect = Gdk.Rectangle(); scaled_rect.x = (int) Math.round((double) rect.x * x_scale); @@ -131,7 +132,7 @@ // Returns the current dimensions scaled in a similar proportion as the two suppled dimensions public Dimensions get_scaled_similar(Dimensions original, Dimensions scaled) { double x_scale, y_scale; - original.get_scale_factors(scaled, out x_scale, out y_scale); + original.get_scale_ratios(scaled, out x_scale, out y_scale); double scale = double.min(x_scale, y_scale); diff -Nru /tmp/2IVIWXJK49/shotwell-0.3.1/src/image_util.vala /tmp/OODUNB4zm8/shotwell-0.3.2/src/image_util.vala --- shotwell-0.3.1/src/image_util.vala 2009-11-10 00:46:55.000000000 +0000 +++ shotwell-0.3.2/src/image_util.vala 2009-11-11 23:19:10.000000000 +0000 @@ -132,7 +132,7 @@ Gdk.Point coord_scaled_in_space(int x, int y, Dimensions original, Dimensions scaled) { double x_scale, y_scale; - original.get_scale_factors(scaled, out x_scale, out y_scale); + original.get_scale_ratios(scaled, out x_scale, out y_scale); Gdk.Point point = Gdk.Point(); point.x = (int) Math.round(x * x_scale); @@ -152,7 +152,7 @@ // precision are considered here. int radius_scaled_in_space(int radius, Dimensions original, Dimensions scaled) { double x_scale, y_scale; - original.get_scale_factors(scaled, out x_scale, out y_scale); + original.get_scale_ratios(scaled, out x_scale, out y_scale); x_scale = Math.floor(x_scale * 100.0) / 100.0; y_scale = Math.floor(y_scale * 100.0) / 100.0; diff -Nru /tmp/2IVIWXJK49/shotwell-0.3.1/src/Photo.vala /tmp/OODUNB4zm8/shotwell-0.3.2/src/Photo.vala --- shotwell-0.3.1/src/Photo.vala 2009-11-10 00:46:55.000000000 +0000 +++ shotwell-0.3.2/src/Photo.vala 2009-11-11 23:19:10.000000000 +0000 @@ -74,6 +74,12 @@ "jpe" }; + // There are assertions in the photo pipeline to verify that the generated (or loaded) pixbuf + // is scaled properly. We have to allow for some wobble here because of rounding errors and + // precision limitations of various subsystems. Pixel-accuracy would be best, but barring that, + // need to just make sure the pixbuf is in the ballpark. + private const int SCALING_FUDGE = 8; + public enum Exception { NONE = 0, ORIENTATION = 1 << 0, @@ -1002,7 +1008,7 @@ // no scaling, load and get out if (scaling.is_unscaled()) { #if MEASURE_PIPELINE - debug("LOAD_RAW_PIXBUF UNSCALED: requested"); + debug("LOAD_RAW_PIXBUF UNSCALED %s: requested", path); #endif return new Gdk.Pixbuf.from_file(path); @@ -1014,7 +1020,7 @@ out scaled_to_viewport); if (!is_scaled) { #if MEASURE_PIPELINE - debug("LOAD_RAW_PIXBUF UNSCALED: scaling unavailable"); + debug("LOAD_RAW_PIXBUF UNSCALED %s: scaling unavailable", path); #endif return new Gdk.Pixbuf.from_file(path); @@ -1024,12 +1030,12 @@ scaled_image.height); #if MEASURE_PIPELINE - debug("LOAD_RAW_PIXBUF %s: %s -> %s (actual: %s)", scaling.to_string(), + debug("LOAD_RAW_PIXBUF %s %s: %s -> %s (actual: %s)", scaling.to_string(), path, get_raw_dimensions().to_string(), scaled_image.to_string(), Dimensions.for_pixbuf(pixbuf).to_string()); #endif - assert(scaled_image.approx_equals(Dimensions.for_pixbuf(pixbuf))); + assert(scaled_image.approx_equals(Dimensions.for_pixbuf(pixbuf), SCALING_FUDGE)); return pixbuf; } @@ -1285,7 +1291,7 @@ // orientation are the only transformations that change the dimensions of the pixbuf, and // must be accounted for the test to be valid if (is_scaled) - assert(scaled_to_viewport.approx_equals(Dimensions.for_pixbuf(pixbuf))); + assert(scaled_to_viewport.approx_equals(Dimensions.for_pixbuf(pixbuf), SCALING_FUDGE)); #if MEASURE_PIPELINE debug("PIPELINE %s (%s): redeye=%lf crop=%lf adjustment=%lf orientation=%lf total=%lf",