pcsxr-1.9.92
[pcsx_rearmed.git] / gui / MemcardDlg.c
... / ...
CommitLineData
1/* Pcsx - Pc Psx Emulator
2 * Copyright (C) 1999-2002 Pcsx Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <string.h>
23#include <gdk/gdkkeysyms.h>
24#include <gtk/gtk.h>
25#include <glade/glade.h>
26#include <signal.h>
27#include <sys/time.h>
28
29#include "Linux.h"
30#include "../libpcsxcore/sio.h"
31
32#define MAX_MEMCARD_BLOCKS 15
33
34static gboolean quit;
35static unsigned int currentIcon;
36
37McdBlock Blocks[2][MAX_MEMCARD_BLOCKS]; // Assuming 2 cards, 15 blocks?
38int IconC[2][MAX_MEMCARD_BLOCKS];
39enum {
40 CL_ICON,
41 CL_TITLE,
42 CL_STAT,
43 CL_ID,
44 CL_NAME,
45 NUM_CL
46};
47
48GtkWidget *GtkCList_McdList1, *GtkCList_McdList2;
49
50static void AddColumns(GtkTreeView *treeview) {
51 GtkCellRenderer *renderer;
52 GtkTreeViewColumn *column;
53
54 // column for icon
55 renderer = gtk_cell_renderer_pixbuf_new ();
56 column = gtk_tree_view_column_new_with_attributes(_("Icon"),
57 renderer, "pixbuf", CL_ICON, NULL);
58 gtk_tree_view_append_column(treeview, column);
59
60 // column for title
61 renderer = gtk_cell_renderer_text_new();
62 column = gtk_tree_view_column_new_with_attributes(_("Title"),
63 renderer, "text", CL_TITLE, NULL);
64 gtk_tree_view_append_column(treeview, column);
65
66 // column for status
67 renderer = gtk_cell_renderer_text_new();
68 column = gtk_tree_view_column_new_with_attributes(_("Status"),
69 renderer, "text", CL_STAT, NULL);
70 gtk_tree_view_append_column(treeview, column);
71
72 // column for id
73 renderer = gtk_cell_renderer_text_new();
74 column = gtk_tree_view_column_new_with_attributes(_("ID"),
75 renderer, "text", CL_ID, NULL);
76 gtk_tree_view_append_column(treeview, column);
77
78 // column for Name
79 renderer = gtk_cell_renderer_text_new();
80 column = gtk_tree_view_column_new_with_attributes(_("Name"),
81 renderer, "text", CL_NAME, NULL);
82 gtk_tree_view_append_column(treeview, column);
83}
84
85static GdkPixbuf *SetIcon(GtkWidget *dialog, short *icon, int i) {
86 GdkPixmap *pixmap;
87 GdkImage *image;
88 GdkVisual *visual;
89 GdkPixbuf *pixbuf;
90 GdkGC *gc;
91 int x, y, c;
92
93 visual = gdk_window_get_visual(dialog->window);
94
95 if (visual->depth == 8) return NULL;
96
97 image = gdk_image_new(GDK_IMAGE_NORMAL, visual, 32, 32);
98
99 for (y = 0; y < 32; y++) {
100 for (x = 0; x < 32; x++) {
101 c = icon[(y>>1) * 16 + (x>>1)];
102 c = ((c & 0x001f) << 10) | ((c & 0x7c00) >> 10) | (c & 0x03e0);
103 if (visual->depth == 16)
104 c = (c & 0x001f) | ((c & 0x7c00) << 1) | ((c & 0x03e0) << 1);
105 else if (visual->depth == 24 || visual->depth == 32)
106 c = ((c & 0x001f) << 3) | ((c & 0x03e0) << 6) | ((c & 0x7c00) << 9);
107
108 gdk_image_put_pixel(image, x, y, c);
109 }
110 }
111
112 pixmap = gdk_pixmap_new(dialog->window, 32, 32, visual->depth);
113
114 gc = gdk_gc_new(pixmap);
115 gdk_draw_image(pixmap, gc, image, 0, 0, 0, 0, 32, 32);
116 gdk_gc_destroy(gc);
117 gdk_image_destroy(image);
118
119 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_PIXMAP (pixmap), NULL,
120 0, 0, 0, 0, -1, -1);
121 g_object_unref(pixmap);
122
123 return pixbuf;
124}
125
126static void LoadListItems(int mcd, GtkWidget *widget) {
127 int i;
128 GladeXML *xml;
129 GtkWidget *List;
130 GtkWidget *dialog;
131 GtkListStore *store;
132 GtkTreeIter iter;
133 GdkPixbuf *pixbuf;
134 gchar *title;
135
136 store = gtk_list_store_new(NUM_CL, GDK_TYPE_PIXBUF, G_TYPE_STRING,
137 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
138
139 xml = glade_get_widget_tree(widget);
140 dialog = glade_xml_get_widget(xml, "McdsDlg");
141
142 if (mcd == 1) List = glade_xml_get_widget(xml, "GtkCList_McdList1");
143 else List = glade_xml_get_widget(xml, "GtkCList_McdList2");
144
145 for (i = 0; i < MAX_MEMCARD_BLOCKS; i++) {
146 McdBlock *Info;
147 gchar *state;
148
149 Info = &Blocks[mcd - 1][i];
150 IconC[mcd - 1][i] = 0;
151
152 if ((Info->Flags & 0xF0) == 0xA0) {
153 if ((Info->Flags & 0xF) >= 1 &&
154 (Info->Flags & 0xF) <= 3) {
155 state = _("Deleted");
156 } else
157 state = _("Free");
158 } else if ((Info->Flags & 0xF0) == 0x50)
159 state = _("Used");
160 else
161 state = _("Free");
162
163 pixbuf = SetIcon(dialog, Info->Icon, i + 1);
164
165 gtk_list_store_append(store, &iter);
166
167 title = g_convert(Info->sTitle, strlen(Info->sTitle), "UTF-8",
168 "Shift-JIS", NULL, NULL, NULL);
169
170 gtk_list_store_set(store, &iter,
171 CL_ICON, pixbuf,
172 CL_TITLE, title,
173 CL_STAT, state,
174 CL_NAME, Info->Name,
175 CL_ID, Info->ID,
176 -1);
177
178 g_free(title);
179
180 g_object_unref(pixbuf);
181 }
182
183 gtk_tree_view_set_model(GTK_TREE_VIEW(List), GTK_TREE_MODEL(store));
184 g_object_unref(G_OBJECT(store));
185 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(List), TRUE);
186 gtk_widget_show(List);
187}
188
189static void UpdateFilenameButtons(GtkWidget *widget) {
190 int i;
191 GladeXML *xml;
192 GtkWidget *dialog;
193 const char *filename;
194 gchar *p;
195
196 xml = glade_get_widget_tree(widget);
197 dialog = glade_xml_get_widget(xml, "McdsDlg");
198
199 for (i = 0; i < 2; i++) {
200 if (i == 0) {
201 widget = glade_xml_get_widget(xml, "Mcd1Label");
202 filename = Config.Mcd1;
203 } else {
204 widget = glade_xml_get_widget(xml, "Mcd2Label");
205 filename = Config.Mcd2;
206 }
207
208 p = g_path_get_basename(filename);
209 gtk_label_set_text(GTK_LABEL(widget), p);
210 g_free(p);
211 }
212}
213
214static void LoadMcdDlg(GtkWidget *widget) {
215 int i;
216
217 for (i = 0; i < MAX_MEMCARD_BLOCKS; i++) {
218 GetMcdBlockInfo(1, i + 1, &Blocks[0][i]);
219 GetMcdBlockInfo(2, i + 1, &Blocks[1][i]);
220 }
221
222 LoadListItems(1, widget);
223 LoadListItems(2, widget);
224
225 UpdateFilenameButtons(widget);
226}
227
228static void OnTreeSelectionChanged(GtkTreeSelection *selection, gpointer user_data);
229
230static void UpdateListItems(int mcd, GtkWidget *widget) {
231 GladeXML *xml;
232 GtkWidget *List;
233 GtkWidget *dialog;
234 GtkListStore *store;
235 GtkTreeIter iter;
236 GdkPixbuf *pixbuf;
237 short *pIcon;
238 int i;
239 gchar *title;
240
241 xml = glade_get_widget_tree(widget);
242 dialog = glade_xml_get_widget(xml, "McdsDlg");
243
244 if (mcd == 1) List = glade_xml_get_widget(xml, "GtkCList_McdList1");
245 else List = glade_xml_get_widget(xml, "GtkCList_McdList2");
246
247 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(List)));
248 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
249
250 for (i = 0; i < MAX_MEMCARD_BLOCKS; i++) {
251 McdBlock *Info;
252 gchar *state;
253
254 Info = &Blocks[mcd - 1][i];
255 IconC[mcd - 1][i] = 0;
256
257 if ((Info->Flags & 0xF0) == 0xA0) {
258 if ((Info->Flags & 0xF) >= 1 &&
259 (Info->Flags & 0xF) <= 3) {
260 state = _("Deleted");
261 } else
262 state = _("Free");
263 } else if ((Info->Flags & 0xF0) == 0x50)
264 state = _("Used");
265 else
266 state = _("Free");
267
268 if (Info->IconCount > 0) {
269 pIcon = &Info->Icon[(currentIcon % Info->IconCount) * 16 * 16];
270 } else {
271 pIcon = Info->Icon;
272 }
273
274 pixbuf = SetIcon(dialog, pIcon, i + 1);
275 title = g_convert(Info->sTitle, strlen(Info->sTitle), "UTF-8",
276 "Shift-JIS", NULL, NULL, NULL);
277
278 gtk_list_store_set(store, &iter,
279 CL_ICON, pixbuf,
280 CL_TITLE, title,
281 CL_STAT, state,
282 CL_NAME, Info->Name,
283 CL_ID, Info->ID,
284 -1);
285
286 g_free(title);
287
288 g_object_unref(pixbuf);
289 gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
290 }
291
292 gtk_widget_show(List);
293
294 OnTreeSelectionChanged(gtk_tree_view_get_selection(GTK_TREE_VIEW(List)), (gpointer)mcd);
295}
296
297static void UpdateMcdDlg(GtkWidget *widget) {
298 int i;
299
300 for (i = 0; i < MAX_MEMCARD_BLOCKS; i++) {
301 GetMcdBlockInfo(1, i + 1, &Blocks[0][i]);
302 GetMcdBlockInfo(2, i + 1, &Blocks[1][i]);
303 }
304
305 UpdateListItems(1, widget);
306 UpdateListItems(2, widget);
307
308 UpdateFilenameButtons(widget);
309}
310
311static void OnMcd_Close(GtkDialog *dialog, gint arg1, gpointer user_data) {
312 quit = TRUE;
313 SaveConfig();
314 gtk_widget_destroy(GTK_WIDGET(dialog));
315}
316
317static void OnMcd_FileChange(GtkWidget *widget, gpointer user_data) {
318 gint memcard = (int)user_data;
319 gchar *filename;
320 GtkWidget *chooser;
321
322 // Ask for name of memory card
323 chooser = gtk_file_chooser_dialog_new(_("Select A File"),
324 NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
325 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
326 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
327 NULL);
328
329 if (memcard == 1)
330 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(chooser), Config.Mcd1);
331 else
332 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(chooser), Config.Mcd2);
333
334 if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_OK) {
335 gtk_widget_hide(chooser);
336
337 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
338
339 if (filename != NULL) {
340 if (memcard == 1) strncpy(Config.Mcd1, filename, MAXPATHLEN);
341 else strncpy(Config.Mcd2, filename, MAXPATHLEN);
342
343 LoadMcd(memcard, filename);
344 LoadMcdDlg(widget);
345
346 g_free(filename);
347 }
348 }
349
350 gtk_widget_destroy(chooser);
351}
352
353// format a memory card
354static void OnMcd_Format(GtkWidget *widget, gpointer user_data) {
355 GladeXML *xml;
356 GtkWidget *message_dialog;
357 gint result;
358 char *str;
359
360 gint memcard = (int)user_data;
361
362 message_dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
363 GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
364 _("Format this Memory Card?"));
365 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(message_dialog),
366 _("If you format the memory card, the card will be empty, and any existing data overwritten."));
367 gtk_dialog_add_buttons(GTK_DIALOG(message_dialog),
368 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
369 _("Format card"), GTK_RESPONSE_YES, NULL);
370
371 result = gtk_dialog_run(GTK_DIALOG(message_dialog));
372 gtk_widget_destroy(message_dialog);
373
374 if (result == GTK_RESPONSE_YES) {
375 xml = glade_get_widget_tree(widget);
376
377 if (memcard == 1) str = Config.Mcd1;
378 else str = Config.Mcd2;
379
380 CreateMcd(str);
381 LoadMcd(memcard, str);
382
383 UpdateMcdDlg(widget);
384 }
385}
386
387// create a new, formatted memory card
388static void OnMcd_New(GtkWidget *widget, gpointer user_data) {
389 GtkWidget *chooser;
390 gchar *path;
391
392 // Ask for name of new memory card
393 chooser = gtk_file_chooser_dialog_new(_("Create a new Memory Card"),
394 NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
395 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
396 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
397 NULL);
398
399 // Card should be put into $HOME/.pcsx/memcards
400 path = g_build_filename(g_get_home_dir(), ".pcsx", "memcards", NULL);
401 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), path);
402 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(chooser), _("New Memory Card.mcd"));
403 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser), TRUE);
404
405 if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_OK) {
406 gchar *name;
407
408 gtk_widget_hide(chooser);
409 name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
410
411 CreateMcd(name);
412
413 if ((int)user_data == 1) strncpy(Config.Mcd1, name, MAXPATHLEN);
414 else strncpy(Config.Mcd2, name, MAXPATHLEN);
415
416 LoadMcd((int)user_data, name);
417 LoadMcdDlg(widget);
418
419 g_free(name);
420 }
421
422 gtk_widget_destroy(chooser);
423 g_free(path);
424}
425
426static int copy = 0, copymcd = 0;
427
428static int GetFreeMemcardSlot(int target_card) {
429 McdBlock *Info;
430 gboolean found = FALSE;
431
432 int i = 0;
433 while (i < 15 && found == FALSE) {
434 Info = &Blocks[target_card][i];
435 if (g_ascii_strcasecmp(Info->Title, "") == 0) {
436 found = TRUE;
437 } else {
438 i++;
439 }
440 }
441
442 if (found == TRUE)
443 return i;
444
445 // no free slots, try to find a deleted one
446 i = 0;
447 while (i < 15 && found == FALSE) {
448 Info = &Blocks[target_card][i];
449 if ((Info->Flags & 0xF0) != 0x50) {
450 found = TRUE;
451 } else {
452 i++;
453 }
454 }
455
456 if (found == TRUE)
457 return i;
458
459 return -1;
460}
461
462static void CopyMemcardData(char *from, char *to, gint *i, gchar *str) {
463 memcpy(to + (*i + 1) * 128, from + (copy + 1) * 128, 128);
464 SaveMcd((char *)str, to, (*i + 1) * 128, 128);
465 memcpy(to + (*i + 1) * 1024 * 8, from + (copy+1) * 1024 * 8, 1024 * 8);
466 SaveMcd((char *)str, to, (*i + 1) * 1024 * 8, 1024 * 8);
467}
468
469static void OnMcd_CopyTo(GtkWidget *widget, gpointer user_data) {
470 gint mcd = (gint)user_data;
471
472 GtkTreeIter iter;
473 GtkTreeModel *model;
474 GtkTreePath *path;
475 gint *i;
476 GladeXML *xml;
477 GtkTreeSelection *treesel;
478 gchar *str;
479 char *source, *destination;
480
481 int first_free_slot;
482
483 xml = glade_get_widget_tree(widget);
484
485 if (mcd == 1)
486 treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(GtkCList_McdList2));
487 else
488 treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(GtkCList_McdList1));
489
490 // If the item selected is not reported as a 'Free' slot
491 if (gtk_tree_selection_get_selected(treesel, &model, &iter)) {
492 path = gtk_tree_model_get_path(model, &iter);
493 i = gtk_tree_path_get_indices(path);
494 copy = *i;
495 copymcd = mcd;
496 gtk_tree_path_free(path);
497 }
498
499 // Determine the first free slot in the target memory card
500 first_free_slot = GetFreeMemcardSlot(mcd - 1);
501 if (first_free_slot == -1) {
502 // No free slots available on the destination card
503 SysErrorMessage(_("No free space on memory card"),
504 _("There are no free slots available on the target memory card. Please delete a slot first."));
505 return;
506 }
507
508 xml = glade_get_widget_tree(GtkCList_McdList1);
509
510 if (mcd == 1) {
511 str = Config.Mcd1;
512 source = Mcd2Data;
513 destination = Mcd1Data;
514 } else {
515 str = Config.Mcd2;
516 source = Mcd1Data;
517 destination = Mcd2Data;
518 }
519
520 CopyMemcardData(source, destination, &first_free_slot, str);
521 UpdateMcdDlg(widget);
522}
523
524static void OnMemcardDelete(GtkWidget *widget, gpointer user_data) {
525 McdBlock *Info;
526 int i, xor = 0, j;
527 char *data, *ptr;
528 GtkTreeIter iter;
529 GtkTreeModel *model;
530 GtkTreePath *path;
531 gchar *filename;
532 GladeXML *xml;
533 gboolean selected;
534 GtkWidget *tree;
535 GtkTreeSelection *sel;
536
537 gint memcard = (int)user_data;
538
539 xml = glade_get_widget_tree(widget);
540
541 if (memcard == 1) {
542 tree = glade_xml_get_widget(xml, "GtkCList_McdList1");
543 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW (tree));
544 selected = gtk_tree_selection_get_selected (sel, &model, &iter);
545 data = Mcd1Data;
546 filename = Config.Mcd1;
547 } else {
548 tree = glade_xml_get_widget(xml, "GtkCList_McdList2");
549 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW (tree));
550 selected = gtk_tree_selection_get_selected(sel, &model, &iter);
551 data = Mcd2Data;
552 filename = Config.Mcd2;
553 }
554
555 if (selected) {
556 path = gtk_tree_model_get_path(model, &iter);
557 i = *gtk_tree_path_get_indices(path);
558
559 i++;
560 ptr = data + i * 128;
561 Info = &Blocks[memcard - 1][i - 1];
562
563 if ((Info->Flags & 0xF0) == 0xA0) {
564 if ((Info->Flags & 0xF) >= 1 &&
565 (Info->Flags & 0xF) <= 3) { // deleted
566 *ptr = 0x50 | (Info->Flags & 0xF);
567 } else return;
568 } else if ((Info->Flags & 0xF0) == 0x50) { // used
569 *ptr = 0xA0 | (Info->Flags & 0xF);
570 } else { return; }
571
572 for (j = 0; j < 127; j++) xor ^= *ptr++;
573 *ptr = xor;
574
575 SaveMcd((char *)filename, data, i * 128, 128);
576 UpdateMcdDlg(widget);
577 }
578}
579
580static void OnTreeSelectionChanged(GtkTreeSelection *selection, gpointer user_data) {
581 GladeXML *xml;
582 GtkTreeIter iter;
583 GtkTreeModel *model;
584 GtkTreePath *path;
585
586 gboolean selected;
587 int i;
588 McdBlock b;
589
590 gint memcard = (int)user_data;
591
592 xml = glade_get_widget_tree(GtkCList_McdList1);
593 selected = gtk_tree_selection_get_selected(selection, &model, &iter);
594
595 if (selected) {
596 path = gtk_tree_model_get_path(model, &iter);
597 i = *gtk_tree_path_get_indices(path);
598 gtk_tree_path_free(path);
599
600 // If a row was selected, and the row is not blank, we can now enable
601 // some of the disabled widgets
602 if (memcard == 1) {
603 GetMcdBlockInfo(1, i + 1, &b);
604
605 if ((b.Flags >= 0xA1 && b.Flags <= 0xA3) || ((b.Flags & 0xF0) == 0x50)) {
606 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_Delete1"), TRUE);
607 } else {
608 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_Delete1"), FALSE);
609 }
610
611 if ((b.Flags & 0xF0) == 0x50) {
612 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_CopyTo2"), TRUE);
613 } else {
614 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_CopyTo2"), FALSE);
615 }
616 } else {
617 GetMcdBlockInfo(2, i + 1, &b);
618
619 if ((b.Flags >= 0xA1 && b.Flags <= 0xA3) || ((b.Flags & 0xF0) == 0x50)) {
620 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_Delete2"), TRUE);
621 } else {
622 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_Delete2"), FALSE);
623 }
624
625 if ((b.Flags & 0xF0) == 0x50) {
626 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_CopyTo1"), TRUE);
627 } else {
628 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_CopyTo1"), FALSE);
629 }
630 }
631 } else {
632 if (memcard == 1) {
633 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_CopyTo2"), FALSE);
634 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_Delete1"), FALSE);
635 } else {
636 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_CopyTo1"), FALSE);
637 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "GtkButton_Delete2"), FALSE);
638 }
639 }
640}
641
642gboolean updateFunc(gpointer data) {
643 if (quit) return FALSE;
644 currentIcon++;
645 UpdateListItems(1, GtkCList_McdList1);
646 UpdateListItems(2, GtkCList_McdList2);
647 g_timeout_add(333, updateFunc, 0);
648 return FALSE;
649}
650
651void OnConf_Mcds() {
652 GladeXML *xml;
653 GtkWidget *dialog;
654 GtkWidget *widget;
655 GtkTreeSelection *treesel1, *treesel2;
656 gchar *str;
657
658 xml = glade_xml_new(PACKAGE_DATA_DIR "pcsx.glade2", "McdsDlg", NULL);
659
660 if (!xml) {
661 g_warning("We could not load the interface!");
662 return;
663 }
664
665 dialog = glade_xml_get_widget(xml, "McdsDlg");
666
667 gtk_window_set_title(GTK_WINDOW(dialog), _("Memory Card Manager"));
668
669 // Assign default memory cards
670 if (!strlen(Config.Mcd1)) {
671 str = g_strconcat(getenv("HOME"), DEFAULT_MEM_CARD_1, NULL);
672 strcpy(Config.Mcd1, str);
673 g_free(str);
674 }
675
676 if (!strlen(Config.Mcd2)) {
677 str = g_strconcat(getenv("HOME"), DEFAULT_MEM_CARD_2, NULL);
678 strcpy(Config.Mcd2, str);
679 g_free(str);
680 }
681
682 GtkCList_McdList1 = glade_xml_get_widget(xml, "GtkCList_McdList1");
683 AddColumns(GTK_TREE_VIEW(GtkCList_McdList1));
684 GtkCList_McdList2 = glade_xml_get_widget(xml, "GtkCList_McdList2");
685 AddColumns(GTK_TREE_VIEW(GtkCList_McdList2));
686
687 treesel1 = gtk_tree_view_get_selection(GTK_TREE_VIEW (GtkCList_McdList1));
688 gtk_tree_selection_set_mode(treesel1, GTK_SELECTION_SINGLE);
689 g_signal_connect_data(G_OBJECT(treesel1), "changed",
690 G_CALLBACK(OnTreeSelectionChanged),
691 (gpointer)1, NULL, G_CONNECT_AFTER);
692
693 treesel2 = gtk_tree_view_get_selection(GTK_TREE_VIEW (GtkCList_McdList2));
694 gtk_tree_selection_set_mode(treesel2, GTK_SELECTION_SINGLE);
695 g_signal_connect_data(G_OBJECT(treesel2), "changed",
696 G_CALLBACK(OnTreeSelectionChanged),
697 (gpointer)2, NULL, G_CONNECT_AFTER);
698
699 LoadMcdDlg(dialog);
700
701 // Setup a handler for when Close or Cancel is clicked
702 g_signal_connect_data(GTK_OBJECT(dialog), "response",
703 GTK_SIGNAL_FUNC(OnMcd_Close), xml, (GClosureNotify)g_object_unref, G_CONNECT_AFTER);
704
705 widget = glade_xml_get_widget(xml, "GtkButton_Format1");
706 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
707 GTK_SIGNAL_FUNC(OnMcd_Format), (gpointer)1, NULL, G_CONNECT_AFTER);
708
709 widget = glade_xml_get_widget(xml, "GtkButton_Format2");
710 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
711 GTK_SIGNAL_FUNC(OnMcd_Format), (gpointer)2, NULL, G_CONNECT_AFTER);
712
713 widget = glade_xml_get_widget(xml, "Mcd1Button");
714 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
715 GTK_SIGNAL_FUNC(OnMcd_FileChange), (gpointer)1, NULL, G_CONNECT_AFTER);
716
717 widget = glade_xml_get_widget(xml, "Mcd2Button");
718 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
719 GTK_SIGNAL_FUNC(OnMcd_FileChange), (gpointer)2, NULL, G_CONNECT_AFTER);
720
721 widget = glade_xml_get_widget(xml, "GtkButton_New1");
722 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
723 GTK_SIGNAL_FUNC(OnMcd_New), (gpointer)1, NULL, G_CONNECT_AFTER);
724
725 widget = glade_xml_get_widget(xml, "GtkButton_New2");
726 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
727 GTK_SIGNAL_FUNC(OnMcd_New), (gpointer)2, NULL, G_CONNECT_AFTER);
728
729 widget = glade_xml_get_widget(xml, "GtkButton_CopyTo1");
730 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
731 GTK_SIGNAL_FUNC(OnMcd_CopyTo), (gpointer)1, NULL, G_CONNECT_AFTER);
732 gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE);
733
734 widget = glade_xml_get_widget(xml, "GtkButton_CopyTo2");
735 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
736 GTK_SIGNAL_FUNC(OnMcd_CopyTo), (gpointer)2, NULL, G_CONNECT_AFTER);
737 gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE);
738
739 widget = glade_xml_get_widget(xml, "GtkButton_Delete1");
740 g_signal_connect_data (GTK_OBJECT (widget), "clicked",
741 GTK_SIGNAL_FUNC(OnMemcardDelete), (gpointer)1, NULL, G_CONNECT_AFTER);
742 gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE);
743
744 widget = glade_xml_get_widget(xml, "GtkButton_Delete2");
745 g_signal_connect_data (GTK_OBJECT (widget), "clicked",
746 GTK_SIGNAL_FUNC(OnMemcardDelete), (gpointer)2, NULL, G_CONNECT_AFTER);
747 gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE);
748
749 quit = FALSE;
750 currentIcon = 0;
751
752 g_timeout_add(1, updateFunc, 0);
753
754 while (gtk_events_pending()) { gtk_main_iteration(); }
755}