+/*----- Progress utilities ------------------------------------------------*/
+
+struct progress_state progress = PROGRESS_STATE_INIT;
+static struct banner_progress_item banner_progress;
+
+static void render_banner_progress(struct progress_item *item,
+ struct progress_render_state *render)
+{
+ struct banner_progress_item *bi = (struct banner_progress_item *)item;
+
+ progress_putleft(render, " %s", bi->msg);
+ progress_shownotice(render, 4, 7);
+}
+
+void show_banner(const char *msg)
+{
+ banner_progress._base.render = render_banner_progress;
+ progress_additem(&progress, &banner_progress._base);
+ banner_progress.msg = msg;
+ progress_update(&progress);
+}
+
+void hide_banner(void)
+{
+ if (!progress_removeitem(&progress, &banner_progress._base))
+ progress_update(&progress);
+}
+
+/*----- DVD utilities -----------------------------------------------------*/
+
+#ifdef notdef
+static void logfn(void *p, dvd_logger_level_t lev,
+ const char *fmt, va_list ap)
+{
+ switch (lev) {
+ case DVD_LOGGER_LEVEL_ERROR:
+ fprintf("%s (libdvdread error): ", prog);
+ break;
+ case DVD_LOGGER_LEVEL_WARN:
+ fprintf("%s (libdvdread warning): ", prog);
+ break;
+ default:
+ return;
+ }
+ vfprintf(stderr, fmt, ap);
+ fputc('\n', stderr);
+}
+static const dvd_logger_cb logger = { logfn };
+#endif
+
+void open_dvd(const char *device, int mode,
+ int *fd_out, dvd_reader_t **dvd_out)
+{
+ int fd;
+ dvd_reader_t *dvd;
+ int bannerp = 0;
+
+ for (;;) {
+ fd = open(device, mode);
+ if (fd >= 0 || errno != ENOMEDIUM) break;
+ if (!bannerp) {
+ show_banner("Waiting for disc to be inserted...");
+ bannerp = 1;
+ }
+ sit(0.2);
+ }
+ if (bannerp) hide_banner();
+ if (fd < 0) bail_syserr(errno, "failed to open device `%s'", device);
+ if (dvd_out) {
+#ifdef notdef
+ dvd = DVDOpen2(0, &logger, device);
+#else
+ dvd = DVDOpen(device);
+#endif
+ if (!dvd) bail("failed to open DVD on `%s'", device);
+ *dvd_out = dvd;
+ }
+ if (fd_out) *fd_out = fd;
+ else close(fd);
+}
+