Commit | Line | Data |
---|---|---|
dc53ebfa MW |
1 | #include "lib.h" |
2 | ||
3 | const char *prog = "<unset>"; | |
4 | ||
5 | void set_prog(const char *p) | |
6 | { const char *q = strrchr(p, '/'); prog = q ? q + 1 : p; } | |
7 | ||
8 | void vmoan(const char *fmt, va_list ap) | |
9 | { fprintf(stderr, "%s: ", prog); vfprintf(stderr, fmt, ap); } | |
10 | ||
11 | __attribute__((format(printf, 1, 2))) | |
12 | void moan(const char *fmt, ...) | |
13 | { | |
14 | va_list ap; | |
15 | ||
16 | va_start(ap, fmt); vmoan(fmt, ap); va_end(ap); | |
17 | fputc('\n', stderr); | |
18 | } | |
19 | ||
20 | __attribute__((noreturn, format(printf, 1, 2))) | |
21 | void bail(const char *fmt, ...) | |
22 | { | |
23 | va_list ap; | |
24 | ||
25 | va_start(ap, fmt); vmoan(fmt, ap); va_end(ap); | |
26 | fputc('\n', stderr); | |
27 | exit(2); | |
28 | } | |
29 | ||
30 | __attribute__((noreturn, format(printf, 2, 3))) | |
31 | void bail_syserr(int err, const char *fmt, ...) | |
32 | { | |
33 | va_list ap; | |
34 | ||
35 | va_start(ap, fmt); vmoan(fmt, ap); va_end(ap); | |
36 | if (err) fprintf(stderr, ": %s", strerror(errno)); | |
37 | fputc('\n', stderr); | |
38 | exit(2); | |
39 | } | |
40 | ||
41 | void sit(double t) | |
42 | { | |
43 | struct timeval tv; | |
44 | double whole = floor(t); | |
45 | ||
46 | if (t) { | |
47 | tv.tv_sec = whole; tv.tv_usec = floor((t - whole)*1.0e6) + 1; | |
48 | if (select(0, 0, 0, 0, &tv) < 0) bail_syserr(errno, "failed to sleep"); | |
49 | } | |
50 | } | |
51 | ||
52 | void store_filename(char *buf, ident id) | |
53 | { | |
54 | switch (id_kind(id)) { | |
55 | case RAW: | |
56 | sprintf(buf, "#<raw device>"); | |
57 | break; | |
58 | case IFO: | |
59 | if (!id_title(id)) sprintf(buf, "/VIDEO_TS/VIDEO_TS.IFO"); | |
60 | else sprintf(buf, "/VIDEO_TS/VTS_%02u_0.IFO", id_title(id)); | |
61 | break; | |
62 | case BUP: | |
63 | if (!id_title(id)) sprintf(buf, "/VIDEO_TS/VIDEO_TS.BUP"); | |
64 | else sprintf(buf, "/VIDEO_TS/VTS_%02u_0.BUP", id_title(id)); | |
65 | break; | |
66 | case VOB: | |
67 | if (!id_title(id)) sprintf(buf, "/VIDEO_TS/VIDEO_TS.VOB"); | |
68 | else | |
69 | sprintf(buf, "/VIDEO_TS/VTS_%02u_%u.VOB", id_title(id), id_part(id)); | |
70 | break; | |
71 | default: | |
72 | abort(); | |
73 | } | |
74 | } | |
75 | ||
76 | struct progress_state progress = PROGRESS_STATE_INIT; | |
77 | static struct banner_progress_item banner_progress; | |
78 | ||
79 | static void render_banner_progress(struct progress_item *item, | |
80 | struct progress_render_state *render) | |
81 | { | |
82 | struct banner_progress_item *bi = (struct banner_progress_item *)item; | |
83 | ||
84 | progress_putleft(render, " %s", bi->msg); | |
85 | progress_shownotice(render, 4, 7); | |
86 | } | |
87 | ||
88 | void show_banner(const char *msg) | |
89 | { | |
90 | banner_progress._base.render = render_banner_progress; | |
91 | progress_additem(&progress, &banner_progress._base); | |
92 | banner_progress.msg = msg; | |
93 | progress_update(&progress); | |
94 | } | |
95 | ||
96 | void hide_banner(void) | |
97 | { | |
98 | if (!progress_removeitem(&progress, &banner_progress._base)) | |
99 | progress_update(&progress); | |
100 | } | |
101 | ||
102 | #ifdef notdef | |
103 | static void logfn(void *p, dvd_logger_level_t lev, | |
104 | const char *fmt, va_list ap) | |
105 | { | |
106 | switch (lev) { | |
107 | case DVD_LOGGER_LEVEL_ERROR: | |
108 | fprintf("%s (libdvdread error): ", prog); | |
109 | break; | |
110 | case DVD_LOGGER_LEVEL_WARN: | |
111 | fprintf("%s (libdvdread warning): ", prog); | |
112 | break; | |
113 | default: | |
114 | return; | |
115 | } | |
116 | vfprintf(stderr, fmt, ap); | |
117 | fputc('\n', stderr); | |
118 | } | |
119 | static const dvd_logger_cb logger = { logfn }; | |
120 | #endif | |
121 | ||
122 | void open_dvd(const char *device, int *fd_out, dvd_reader_t **dvd_out) | |
123 | { | |
124 | int fd; | |
125 | dvd_reader_t *dvd; | |
126 | int bannerp = 0; | |
127 | ||
128 | for (;;) { | |
129 | fd = open(device, O_RDONLY); | |
130 | if (fd >= 0 || errno != ENOMEDIUM) break; | |
131 | if (!bannerp) { | |
132 | show_banner("Waiting for disc to be inserted..."); | |
133 | bannerp = 1; | |
134 | } | |
135 | sit(0.2); | |
136 | } | |
137 | if (bannerp) hide_banner(); | |
138 | if (fd < 0) bail_syserr(errno, "failed to open device `%s'", device); | |
139 | if (dvd_out) { | |
140 | #ifdef notdef | |
141 | dvd = DVDOpen2(0, &logger, device); | |
142 | #else | |
143 | dvd = DVDOpen(device); | |
144 | #endif | |
145 | if (!dvd) bail("failed to open DVD on `%s'", device); | |
146 | *dvd_out = dvd; | |
147 | } | |
148 | if (fd_out) *fd_out = fd; | |
149 | else close(fd); | |
150 | } |