Commit | Line | Data |
---|---|---|
ef79bbde P |
1 | /* |
2 | * Copyright (c) 2010, Wei Mingzhi <whistler@openoffice.org>. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * Based on: Cdrom for Psemu Pro like Emulators | |
6 | * By: linuzappz <linuzappz@hotmail.com> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, see <http://www.gnu.org/licenses>. | |
20 | */ | |
21 | ||
22 | #include "../cfg.c" | |
23 | ||
24 | #include <gtk/gtk.h> | |
25 | #include <glade/glade.h> | |
26 | ||
27 | GtkWidget *MainWindow; | |
28 | ||
29 | // function to check if the device is a cdrom | |
30 | int is_cdrom(const char *device) { | |
31 | struct stat st; | |
32 | int fd = -1; | |
33 | ||
34 | // check if the file exist | |
35 | if (stat(device, &st) < 0) return 0; | |
36 | ||
37 | // check if is a block or char device | |
38 | if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) return 0; | |
39 | ||
40 | // try to open the device file descriptor | |
41 | if ((fd = open(device, O_RDONLY | O_NONBLOCK)) < 0) return 0; | |
42 | ||
43 | #ifdef __linux__ | |
44 | // I need a method to check is a device is really a CD-ROM. | |
45 | // some problems/ideas are: | |
46 | // - different protocls (ide, scsi, old proprietary...) | |
47 | // - maybe we can use major number (see linux/major.h) to do some check. | |
48 | // major number can be retrieved with (st.st_rdev>>8) | |
49 | // scsi has SCSI_CDROM_MAJOR but does this cover all scsi drives? | |
50 | // beside IDE major is the same for hard disks and cdroms... | |
51 | // and DVDs? | |
52 | // - another idea is to parse /proc, but again IDE, scsi etc have | |
53 | // different files... I've not found a way to query "which CD drives | |
54 | // are available?" | |
55 | // | |
56 | // Now I use this ioctl which works also if the drive is empty, | |
57 | // I hope that is implemented for all the drives... here works | |
58 | // fine: at least doesn't let me to select my HD as CDs ;) | |
59 | ||
60 | // try a ioctl to see if it's a CD-ROM device | |
61 | if (ioctl(fd, CDROM_GET_CAPABILITY, NULL) < 0) { | |
62 | close(fd); | |
63 | return 0; | |
64 | } | |
65 | #endif | |
66 | ||
67 | close(fd); | |
68 | ||
69 | // yes, it seems a CD drive! | |
70 | return 1; | |
71 | } | |
72 | ||
73 | // fill_drives_list: retrieves available cd drives. At the moment it use a quite | |
74 | // ugly "brute force" method: we check for the most common location for cdrom | |
75 | // in /dev and chech if they are cdrom devices. | |
76 | // If your cdrom path is not listed here you'll have to type it in the dialog | |
77 | // entry yourself (or add it here and recompile). | |
78 | // Are there any other common entry to add to the list? (especially scsi, I | |
79 | // deliberately ignored old non standard cdroms... ) | |
80 | // If you come up with a better method let me know!! | |
81 | void fill_drives_list(GtkWidget *widget) { | |
82 | int i; | |
83 | GtkListStore *store; | |
84 | GtkTreeIter iter; | |
85 | ||
86 | #if defined (__linux__) | |
87 | static const char *cdrom_devices[] = { | |
88 | "/dev/cdrom", | |
89 | "/dev/cdrom0", | |
90 | "/dev/cdrom1", | |
91 | "/dev/cdrom2", | |
92 | "/dev/cdrom3", | |
93 | "/dev/cdroms/cdrom0", | |
94 | "/dev/cdroms/cdrom1", | |
95 | "/dev/cdroms/cdrom2", | |
96 | "/dev/cdroms/cdrom3", | |
97 | "/dev/hda", | |
98 | "/dev/hdb", | |
99 | "/dev/hdc", | |
100 | "/dev/hdd", | |
101 | "/dev/sda", | |
102 | "/dev/sdb", | |
103 | "/dev/sdc", | |
104 | "/dev/sdd", | |
105 | "/dev/scd0", | |
106 | "/dev/scd1", | |
107 | "/dev/scd2", | |
108 | "/dev/scd3", | |
109 | "/dev/optcd", | |
110 | ""}; | |
111 | #elif defined (__FreeBSD__) | |
112 | static const char *cdrom_devices[] = { | |
113 | "/dev/cd0", | |
114 | "/dev/cd1", | |
115 | "/dev/cd2", | |
116 | "/dev/cd3", | |
117 | ""}; | |
118 | #elif defined (__sun) | |
119 | char cdrom_devices[256][256]; | |
120 | FILE *fp; | |
121 | char buf[256], *devname, *nick; | |
122 | ||
123 | memset(cdrom_devices, 0, sizeof(cdrom_devices)); | |
124 | ||
125 | i = 0; | |
126 | ||
127 | fp = popen("eject -l", "r"); | |
128 | ||
129 | if (fp != NULL) { | |
130 | while (!feof(fp) && i < 256) { | |
131 | fgets(buf, 256, fp); | |
132 | ||
133 | devname = strtok(buf, " "); | |
134 | nick = strtok(NULL, " "); | |
135 | ||
136 | if (devname == NULL || nick == NULL) continue; | |
137 | ||
138 | if (strstr(nick, "cdrom") != NULL) { | |
139 | strcpy(cdrom_devices[i++], devname); | |
140 | } | |
141 | } | |
142 | ||
143 | pclose(fp); | |
144 | } | |
145 | #else | |
146 | static const char *cdrom_devices[] = { "" }; | |
147 | #endif | |
148 | ||
149 | store = gtk_list_store_new(1, G_TYPE_STRING); | |
150 | ||
151 | // first we put our current drive | |
152 | if (CdromDev[0] != '\0') { | |
153 | gtk_list_store_append(store, &iter); | |
154 | gtk_list_store_set(store, &iter, 0, CdromDev, -1); | |
155 | } | |
156 | ||
157 | i = 0; | |
158 | ||
159 | // scan cdrom_devices for real cdrom and add them to list | |
160 | while (cdrom_devices[i][0] != '\0') { | |
161 | // check that is not our current dev (already in list) | |
162 | if (strcmp(cdrom_devices[i], CdromDev) != 0) { | |
163 | // check that is a cdrom device | |
164 | if (is_cdrom(cdrom_devices[i])) { | |
165 | gtk_list_store_append(store, &iter); | |
166 | gtk_list_store_set(store, &iter, 0, cdrom_devices[i], -1); | |
167 | } | |
168 | } | |
169 | ++i; | |
170 | } | |
171 | ||
172 | gtk_combo_box_set_model(GTK_COMBO_BOX(widget), GTK_TREE_MODEL(store)); | |
173 | gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(widget), 0); | |
174 | } | |
175 | ||
176 | static void OnConfigExit(GtkWidget *widget, gpointer user_data) { | |
177 | GladeXML *xml; | |
178 | ||
179 | xml = glade_get_widget_tree(MainWindow); | |
180 | ||
181 | widget = glade_xml_get_widget(xml, "cddev_comboboxentry"); | |
182 | strncpy(CdromDev, gtk_entry_get_text(GTK_ENTRY(GTK_BIN(widget)->child)), 255); | |
183 | CdromDev[255] = '\0'; | |
184 | ||
185 | widget = glade_xml_get_widget(xml, "readmode_combobox"); | |
186 | ReadMode = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); | |
187 | ||
188 | widget = glade_xml_get_widget(xml, "subQ_button"); | |
189 | UseSubQ = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
190 | ||
191 | widget = glade_xml_get_widget(xml, "spinCacheSize"); | |
192 | CacheSize = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); | |
193 | ||
194 | widget = glade_xml_get_widget(xml, "spinCdrSpeed"); | |
195 | CdrSpeed = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); | |
196 | ||
197 | widget = glade_xml_get_widget(xml, "comboSpinDown"); | |
198 | SpinDown = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); | |
199 | ||
200 | SaveConf(); | |
201 | ||
202 | gtk_widget_destroy(widget); | |
203 | gtk_exit(0); | |
204 | } | |
205 | ||
206 | long CDRconfigure() { | |
207 | GladeXML *xml; | |
208 | GtkWidget *widget; | |
209 | ||
210 | LoadConf(); | |
211 | ||
212 | xml = glade_xml_new(DATADIR "dfcdrom.glade2", "CfgWnd", NULL); | |
213 | if (xml == NULL) { | |
214 | g_warning("We could not load the interface!"); | |
215 | return -1; | |
216 | } | |
217 | ||
218 | MainWindow = glade_xml_get_widget(xml, "CfgWnd"); | |
219 | gtk_window_set_title(GTK_WINDOW(MainWindow), _("CDR configuration")); | |
220 | ||
221 | widget = glade_xml_get_widget(xml, "CfgWnd"); | |
222 | g_signal_connect_data(GTK_OBJECT(widget), "delete_event", | |
223 | GTK_SIGNAL_FUNC(OnConfigExit), NULL, NULL, G_CONNECT_AFTER); | |
224 | ||
225 | widget = glade_xml_get_widget(xml, "cfg_closebutton"); | |
226 | g_signal_connect_data(GTK_OBJECT(widget), "clicked", | |
227 | GTK_SIGNAL_FUNC(OnConfigExit), NULL, NULL, G_CONNECT_AFTER); | |
228 | ||
229 | widget = glade_xml_get_widget(xml, "cddev_comboboxentry"); | |
230 | fill_drives_list(widget); | |
231 | gtk_entry_set_text(GTK_ENTRY(GTK_BIN(widget)->child), CdromDev); | |
232 | ||
233 | widget = glade_xml_get_widget(xml, "readmode_combobox"); | |
234 | gtk_combo_box_set_active(GTK_COMBO_BOX(widget), ReadMode); | |
235 | ||
236 | widget = glade_xml_get_widget(xml, "subQ_button"); | |
237 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), UseSubQ); | |
238 | ||
239 | widget = glade_xml_get_widget(xml, "spinCacheSize"); | |
240 | gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), (float)CacheSize); | |
241 | ||
242 | widget = glade_xml_get_widget(xml, "spinCdrSpeed"); | |
243 | gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), (float)CdrSpeed); | |
244 | ||
245 | widget = glade_xml_get_widget(xml, "comboSpinDown"); | |
246 | gtk_combo_box_set_active(GTK_COMBO_BOX(widget), SpinDown); | |
247 | ||
248 | gtk_widget_show(MainWindow); | |
249 | gtk_main(); | |
250 | ||
251 | return 0; | |
252 | } | |
253 | ||
254 | void CDRabout() { | |
255 | GtkWidget *widget; | |
256 | const char *authors[]= {"linuzappz <linuzappz@hotmail.com>", | |
257 | "xobro <_xobro_@tin.it>", | |
258 | "Wei Mingzhi <whistler_wmz@users.sf.net>", NULL}; | |
259 | ||
260 | widget = gtk_about_dialog_new(); | |
261 | gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(widget), "CD-ROM Device Reader"); | |
262 | gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), "1.0"); | |
263 | gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(widget), authors); | |
264 | gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget), "http://pcsxr.codeplex.com/"); | |
265 | ||
266 | gtk_dialog_run(GTK_DIALOG(widget)); | |
267 | gtk_widget_destroy(widget); | |
268 | } | |
269 | ||
270 | int main(int argc, char *argv[]) { | |
271 | #ifdef ENABLE_NLS | |
272 | setlocale(LC_ALL, ""); | |
273 | bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR); | |
274 | bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); | |
275 | textdomain(GETTEXT_PACKAGE); | |
276 | #endif | |
277 | ||
278 | gtk_set_locale(); | |
279 | gtk_init(&argc, &argv); | |
280 | ||
281 | if (argc != 2) return 0; | |
282 | ||
283 | if (strcmp(argv[1], "configure") == 0) { | |
284 | CDRconfigure(); | |
285 | } else { | |
286 | CDRabout(); | |
287 | } | |
288 | ||
289 | return 0; | |
290 | } |