00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <gtk/gtk.h>
00033 #include <string.h>
00034
00035
00036 #include <libergtk/ergtk.h>
00037 #include <liberipc/eripc.h>
00038 #include <liberutils/display_utils.h>
00039
00040
00041 #include "log.h"
00042 #include "dialog.h"
00043 #include "i18n.h"
00044 #include "ipc.h"
00045 #include "popup.h"
00046 #include "statusbar.h"
00047
00048
00049
00050
00051
00052
00053
00054 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00055 static const int TEXT_TOP_PADDING = 40 + 5;
00056 static const int TEXT_BOTTOM_PADDING = 830 + 5;
00057 static const int TEXT_LEFT_PADDING = 150 + 5;
00058 static const int TEXT_RIGHT_PADDING = 100 + 5;
00059
00060 static const int TITLE_TOP_PADDING = 0;
00061 static const int TITLE_BOTTOM_PADDING = 0;
00062 static const int TITLE_LEFT_PADDING = 0;
00063 static const int TITLE_RIGHT_PADDING = 0;
00064
00065 static const int MESSAGE_TOP_PADDING = 0;
00066 static const int MESSAGE_BOTTOM_PADDING = 0;
00067 static const int MESSAGE_LEFT_PADDING = 0;
00068 static const int MESSAGE_RIGHT_PADDING = 0;
00069 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00070 static const int TITLE_TOP_PADDING = 0;
00071 static const int TITLE_BOTTOM_PADDING = 25;
00072 static const int TITLE_LEFT_PADDING = 25;
00073 static const int TITLE_RIGHT_PADDING = 25;
00074
00075 static const int MESSAGE_TOP_PADDING = 0;
00076 static const int MESSAGE_BOTTOM_PADDING = 80;
00077 static const int MESSAGE_LEFT_PADDING = 0;
00078 static const int MESSAGE_RIGHT_PADDING = 0;
00079 #else
00080 #error "Unhandled machine type"
00081 #endif
00082
00083
00084
00085
00086
00087 static GtkWidget *dialog_wait = NULL;
00088 static GtkWidget *splash_window = NULL;
00089 static GtkWidget *splash_title = NULL;
00090 static GtkWidget *splash_message = NULL;
00091 static GdkPixbuf *splash_pixbuf = NULL;
00092 static gboolean g_got_control = FALSE;
00093
00094 typedef struct
00095 {
00096 GtkWidget *widget;
00097 eripc_context_t *context;
00098 gchar *message_id;
00099 } dialog_t;
00100
00101 static dialog_t *dialog_response = NULL;
00102 static dialog_t *dialog_info = NULL;
00103 static gboolean g_is_rotated = FALSE;
00104 static gboolean g_temp_rotation = FALSE;
00105 static gboolean g_expect_expose = FALSE;
00106 static gboolean g_ignore_next_expose = FALSE;
00107
00108
00109
00110
00111
00112
00113 static void create_splash(void);
00114 static void show_splash(const char *background, const char *title, const char *message);
00115 static void redraw_splash(void);
00116
00117 static void on_dialog_response(GtkDialog *dialog, gint rc, gpointer data);
00118 static void on_dialog_close (GtkDialog *dialog, gint rc, gpointer data);
00119
00120 static void dialog_message_confirm_destroy(void);
00121 static void dialog_message_info_destroy(void);
00122
00123
00124
00125
00126
00127
00128 void dialog_create(void)
00129 {
00130 LOGPRINTF("entry");
00131
00132 gchar *orient = ipc_get_orientation();
00133 if (orient && (strcmp(orient, "portrait") !=0))
00134 {
00135 g_is_rotated = TRUE;
00136 }
00137 g_free(orient);
00138
00139 create_splash();
00140 }
00141
00142
00143 gboolean dialog_splash_remove()
00144 {
00145 LOGPRINTF("entry");
00146
00147 if (g_temp_rotation)
00148 {
00149
00150 ipc_set_orientation("landscape");
00151 g_ignore_next_expose = TRUE;
00152 return FALSE;
00153 }
00154
00155 gtk_widget_hide(splash_window);
00156 ipc_send_request_popup("unblock");
00157
00158 if (g_got_control) {
00159 display_splash_unlock();
00160 display_return_control();
00161 g_got_control = FALSE;
00162 }
00163
00164 return TRUE;
00165 }
00166
00167
00168 gboolean dialog_splash_show(const char *type)
00169 {
00170 LOGPRINTF("entry");
00171 gboolean retval = TRUE;
00172
00173 g_return_val_if_fail(type != NULL, FALSE);
00174
00175 if (strcmp(type,"usbconnect") == 0)
00176 {
00177 show_splash("usbconnect",
00178 _("Connected"),
00179 _("Tip: Eject the device from your computer to resume use while charging."));
00180 }
00181 else if (strcmp(type,"restart") == 0)
00182 {
00183 show_splash("softwareupdate",
00184 _("Installing Firmware"),
00185 _("In a few seconds, the device will restart "
00186 "to install the new firmware."));
00187 }
00188 else if (strcmp(type,"shutdown") == 0)
00189 {
00190 show_splash("shutdown",
00191 _("Goodbye"),
00192 _("In a few seconds, the device will turn off."));
00193 }
00194 else if (strcmp(type, "indexing") == 0)
00195 {
00196 show_splash("indexing",
00197 _("Indexing Files"),
00198 _("Please wait while indexing files..."));
00199 }
00200 else if (strcmp(type, "batterylow") == 0)
00201 {
00202 show_splash("batterylow",
00203 _("Low Battery"),
00204 _("Connect to a power source to keep using the device."));
00205 }
00206 else if (strcmp(type, "safelyremove") == 0)
00207 {
00208 show_splash("nosd",
00209 _("Eject Memory Card"),
00210 _("You can now safely remove the card from the device."));
00211 }
00212 else if (strcmp(type, "nosd") == 0)
00213 {
00214 show_splash("nosd",
00215 _("No Memory Card Found"),
00216 _("Insert a card into the device to continue use."));
00217 }
00218 else if (strcmp(type, "sdfull") == 0)
00219 {
00220 show_splash("nosd",
00221 _("Memory Card Full"),
00222 _("Free space by deleting files to continue use."));
00223 }
00224 else if (strcmp(type, "sdreadonly") == 0)
00225 {
00226 show_splash("nosd",
00227 _("Memory Card Locked"),
00228 _("Remove the write lock to continue use."));
00229 }
00230 else
00231 {
00232 WARNPRINTF("splash screen not found: %s", type);
00233 retval = FALSE;
00234 }
00235
00236 return retval;
00237 }
00238
00239
00240 void dialog_wait_show(const char *message)
00241 {
00242 LOGPRINTF("entry");
00243 dialog_wait_close();
00244 dialog_wait = ergtk_busy_dialog_new(message);
00245 gtk_widget_show(dialog_wait);
00246 }
00247
00248
00249 GtkWidget *dialog_message_info(GtkMessageType type,
00250 const char *title,
00251 const char *message,
00252 eripc_context_t *context,
00253 const char *message_id)
00254 {
00255 LOGPRINTF("entry");
00256
00257 GtkWidget *dialog = NULL;
00258
00259 dialog_message_info_destroy();
00260
00261 ipc_send_request_popup("block");
00262
00263 dialog = gtk_message_dialog_new(g_statusbar_window,
00264 GTK_DIALOG_DESTROY_WITH_PARENT,
00265 type,
00266 GTK_BUTTONS_OK,
00267 message);
00268
00269
00270 gtk_window_set_transient_for(GTK_WINDOW(dialog), NULL);
00271 gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
00272
00273 if (title)
00274 {
00275 gtk_window_set_title(GTK_WINDOW(dialog), title);
00276 }
00277
00278 dialog_info = g_new0(dialog_t, 1);
00279 if (!dialog_info)
00280 {
00281 ERRORPRINTF("mem alloc failed");
00282 return FALSE;
00283 }
00284 dialog_info->widget = dialog;
00285 dialog_info->context = context;
00286 dialog_info->message_id = g_strdup(message_id);
00287
00288
00289 g_signal_connect(dialog, "response", G_CALLBACK (on_dialog_close), NULL);
00290 gtk_widget_show(dialog);
00291
00292 return dialog;
00293 }
00294
00295
00296 gboolean dialog_message_confirm(const char *title,
00297 const char *message,
00298 eripc_context_t *context,
00299 const char *message_id,
00300 const char *button_no,
00301 const char *button_yes)
00302 {
00303 LOGPRINTF("entry");
00304
00305 GtkWidget *widget = NULL;
00306
00307 dialog_message_confirm_destroy();
00308
00309 ipc_send_request_popup("block");
00310
00311 widget = gtk_message_dialog_new(g_statusbar_window,
00312 GTK_DIALOG_DESTROY_WITH_PARENT,
00313 GTK_MESSAGE_QUESTION,
00314 GTK_BUTTONS_NONE,
00315 message);
00316
00317 gtk_dialog_add_buttons(GTK_DIALOG(widget),
00318 button_no, GTK_RESPONSE_NO,
00319 button_yes, GTK_RESPONSE_YES,
00320 NULL);
00321
00322
00323 gtk_window_set_transient_for(GTK_WINDOW(widget), NULL);
00324 gtk_window_set_keep_above(GTK_WINDOW(widget), TRUE);
00325
00326 if (title)
00327 {
00328 gtk_window_set_title(GTK_WINDOW(widget), title);
00329 }
00330
00331 dialog_response = g_new0(dialog_t, 1);
00332 if (!dialog_response)
00333 {
00334 ERRORPRINTF("mem alloc failed");
00335 return FALSE;
00336 }
00337 dialog_response->widget = widget;
00338 dialog_response->context = context;
00339 dialog_response->message_id = g_strdup(message_id);
00340
00341
00342 g_signal_connect(widget, "response", G_CALLBACK (on_dialog_response), NULL);
00343 gtk_widget_show(widget);
00344
00345 return TRUE;
00346 }
00347
00348
00349 void dialog_wait_close(void)
00350 {
00351 LOGPRINTF("entry");
00352 if (dialog_wait)
00353 {
00354 gtk_widget_destroy(dialog_wait);
00355 dialog_wait = NULL;
00356 }
00357 }
00358
00359
00360 void dialog_message_confirm_close(void)
00361 {
00362 if (dialog_response && dialog_response->widget)
00363 {
00364 gtk_dialog_response(GTK_DIALOG(dialog_response->widget), GTK_RESPONSE_CLOSE);
00365 }
00366 }
00367
00368
00369 void dialog_message_info_close(void)
00370 {
00371 if (dialog_info && dialog_info->widget)
00372 {
00373 gtk_dialog_response(GTK_DIALOG(dialog_info->widget), GTK_RESPONSE_CLOSE);
00374 }
00375 }
00376
00377
00378 void dialog_rotated(const char *orientation)
00379 {
00380 LOGPRINTF("entry");
00381
00382 if (strcmp(orientation, "portrait") == 0)
00383 {
00384 g_is_rotated = FALSE;
00385 if (g_temp_rotation)
00386 {
00387
00388 redraw_splash();
00389 gtk_widget_show(splash_window);
00390 display_update_keep_splash_lock();
00391 }
00392 }
00393 else if (g_str_has_prefix(orientation, "landscape"))
00394 {
00395 g_is_rotated = TRUE;
00396 if (g_temp_rotation)
00397 {
00398 g_temp_rotation = FALSE;
00399 dialog_splash_remove();
00400 }
00401 }
00402 }
00403
00404
00405
00406
00407
00408
00409 static void redraw_splash(void)
00410 {
00411 LOGPRINTF("entry");
00412
00413 GdkRectangle rect;
00414 rect.x = 0;
00415 rect.y = 0;
00416 rect.width = 1024;
00417 rect.height = 1268;
00418 gtk_widget_show(splash_window);
00419 gdk_window_invalidate_rect(splash_window->window, &rect, TRUE);
00420
00421 g_expect_expose = TRUE;
00422 }
00423
00424
00425 static void show_splash(const char *image, const char *title, const char *message)
00426 {
00427 LOGPRINTF("entry");
00428
00429 g_return_if_fail(splash_window != NULL);
00430
00431 display_splash_lock();
00432 display_gain_control();
00433 g_got_control = TRUE;
00434
00435
00436 dialog_wait_close();
00437 dialog_message_info_close();
00438 dialog_message_confirm_close();
00439
00440
00441 gchar *background_file = NULL;
00442 if (strcmp(image, "usbconnect") == 0
00443 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00444 || strcmp(image, "batterylow") == 0
00445 || strcmp(image, "nosd") == 0
00446 || strcmp(image, "softwareupdate") == 0
00447 #endif
00448 )
00449 {
00450 background_file = g_strdup_printf("/usr/share/popupmenu/background_%s.png", image);
00451 }
00452 else
00453 {
00454 background_file = g_strdup("/usr/share/popupmenu/background_general.png");
00455 }
00456
00457 if (splash_pixbuf) g_object_unref(splash_pixbuf);
00458 splash_pixbuf = gdk_pixbuf_new_from_file(background_file, NULL);
00459 if (!splash_pixbuf)
00460 {
00461 WARNPRINTF("splash background not found [%s]", background_file);
00462 }
00463 g_free(background_file);
00464
00465
00466 gtk_label_set_text(GTK_LABEL(splash_title), title);
00467 gtk_label_set_text(GTK_LABEL(splash_message), message);
00468
00469 if (g_is_rotated)
00470 {
00471
00472 ipc_set_orientation("portrait");
00473 g_ignore_next_expose = TRUE;
00474 g_temp_rotation = TRUE;
00475 }
00476 else
00477 {
00478 redraw_splash();
00479 }
00480
00481 ipc_send_request_popup("block");
00482 }
00483
00484
00485 static gboolean on_splash_expose(GtkWidget *widget,
00486 GdkEventExpose *event,
00487 gpointer data)
00488 {
00489 LOGPRINTF("entry: expect expose [%d] is rotated [%d] temp_rotation [%d] ignore next [%d]", g_expect_expose, g_is_rotated, g_temp_rotation, g_ignore_next_expose);
00490
00491 if (g_ignore_next_expose)
00492 {
00493 g_ignore_next_expose = FALSE;
00494 return FALSE;
00495 }
00496
00497 if (g_expect_expose)
00498 {
00499 gdk_draw_pixbuf(widget->window, NULL, splash_pixbuf, 0, 0, 0, 0, -1, -1, GDK_RGB_DITHER_MAX, 0, 0);
00500
00501 GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget));
00502 if (child)
00503 {
00504 gtk_container_propagate_expose(GTK_CONTAINER(widget), child, event);
00505 }
00506
00507 if (!g_is_rotated)
00508 {
00509 display_update_keep_splash_lock();
00510 }
00511
00512 g_expect_expose = FALSE;
00513 }
00514 return TRUE;
00515 }
00516
00517
00518 static void create_splash()
00519 {
00520 LOGPRINTF("entry");
00521
00522 GtkWidget *window = NULL;
00523 GtkWidget *widget = NULL;
00524 GtkBox *vbox = NULL;
00525 GtkWidget *alignment = NULL;
00526
00527
00528
00529
00530
00531 widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00532 window = widget;
00533 splash_window = GTK_WIDGET(widget);
00534 gtk_window_set_resizable(GTK_WINDOW(splash_window), FALSE);
00535 gtk_window_fullscreen(GTK_WINDOW(splash_window));
00536 gtk_window_set_type_hint(GTK_WINDOW(splash_window), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
00537
00538 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00539
00540
00541 widget = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
00542 gtk_alignment_set_padding(GTK_ALIGNMENT(widget),
00543 TEXT_TOP_PADDING,
00544 TEXT_BOTTOM_PADDING,
00545 TEXT_LEFT_PADDING,
00546 TEXT_RIGHT_PADDING);
00547 gtk_container_add(GTK_CONTAINER(window), widget);
00548 gtk_widget_show(widget);
00549 alignment = widget;
00550
00551
00552
00553 widget = gtk_vbox_new(FALSE, 0);
00554 gtk_container_add(GTK_CONTAINER(alignment), widget);
00555 gtk_widget_show(widget);
00556 vbox = GTK_BOX(widget);
00557 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00558
00559
00560
00561 widget = gtk_vbox_new(FALSE, 0);
00562 gtk_container_add(GTK_CONTAINER(window), widget);
00563 gtk_widget_show(widget);
00564 vbox = GTK_BOX(widget);
00565
00566
00567
00568 widget = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
00569 gtk_box_pack_start(vbox, widget, TRUE, TRUE, 0);
00570 gtk_widget_show(widget);
00571 #else
00572 #error "Unhandled machine type"
00573 #endif
00574
00575
00576
00577 widget = gtk_alignment_new(0.5, 0.5, 0.5, 0.5);
00578 gtk_alignment_set_padding( GTK_ALIGNMENT(widget),
00579 TITLE_TOP_PADDING,
00580 TITLE_BOTTOM_PADDING,
00581 TITLE_LEFT_PADDING,
00582 TITLE_RIGHT_PADDING);
00583 gtk_box_pack_start(vbox, widget, FALSE, FALSE, 0);
00584 gtk_widget_show(widget);
00585 alignment = widget;
00586
00587
00588
00589
00590 widget = gtk_label_new(NULL);
00591 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00592 int LABEL_WIDTH = 768 - TEXT_LEFT_PADDING - TEXT_RIGHT_PADDING
00593 - TITLE_LEFT_PADDING - TITLE_RIGHT_PADDING;
00594 gtk_widget_set_size_request(widget, LABEL_WIDTH, -1);
00595 gtk_label_set_justify(GTK_LABEL(widget), GTK_JUSTIFY_CENTER);
00596 gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE);
00597 #endif
00598 gtk_widget_set_name(widget, "irex-splash-title");
00599 gtk_container_add(GTK_CONTAINER(alignment), widget);
00600 gtk_widget_show(widget);
00601 splash_title = widget;
00602
00603
00604
00605
00606 widget = gtk_alignment_new(0.5, 0.5, 0.5, 0.5);
00607 gtk_alignment_set_padding( GTK_ALIGNMENT(widget),
00608 MESSAGE_TOP_PADDING,
00609 MESSAGE_BOTTOM_PADDING,
00610 MESSAGE_LEFT_PADDING,
00611 MESSAGE_RIGHT_PADDING);
00612 gtk_box_pack_start(vbox, widget, FALSE, FALSE, 0);
00613 gtk_widget_show(widget);
00614 alignment = widget;
00615
00616
00617
00618
00619 widget = gtk_label_new(NULL);
00620 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00621 LABEL_WIDTH = 768 - TEXT_LEFT_PADDING - TEXT_RIGHT_PADDING
00622 - MESSAGE_LEFT_PADDING - MESSAGE_RIGHT_PADDING;
00623 gtk_widget_set_size_request(widget, LABEL_WIDTH, -1);
00624 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00625 gtk_widget_set_size_request(widget, 1024, -1);
00626 #else
00627 #error "Unhandled machine type"
00628 #endif
00629 gtk_widget_set_name(widget, "irex-splash-message");
00630 gtk_label_set_justify(GTK_LABEL(widget), GTK_JUSTIFY_CENTER);
00631 gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE);
00632 gtk_container_add(GTK_CONTAINER(alignment), widget);
00633 gtk_widget_show(widget);
00634 splash_message = widget;
00635
00636
00637 gint w = -1;
00638 gint h = -1;
00639 gdk_window_get_geometry(gdk_get_default_root_window(), NULL, NULL, &w, &h, NULL);
00640 gtk_widget_set_size_request(splash_window, w, h);
00641 g_signal_connect(GTK_OBJECT(splash_window), "expose_event", G_CALLBACK (on_splash_expose), NULL);
00642 }
00643
00644
00645 static void on_dialog_response(GtkDialog *widget, gint rc, gpointer data)
00646 {
00647 gboolean retval = FALSE;
00648
00649 LOGPRINTF("entry");
00650
00651 if (GTK_WIDGET(widget) != dialog_response->widget)
00652 {
00653 WARNPRINTF("huh? expected these to be the same");
00654 }
00655
00656 if ((rc == GTK_RESPONSE_OK) || (rc == GTK_RESPONSE_YES))
00657 {
00658 retval = TRUE;
00659 }
00660
00661 if (dialog_response->context)
00662 {
00663 ipc_send_reply(dialog_response->context, dialog_response->message_id, retval);
00664 }
00665
00666
00667 dialog_message_confirm_destroy();
00668 }
00669
00670
00671 static void on_dialog_close(GtkDialog *widget, gint rc, gpointer data)
00672 {
00673 LOGPRINTF("entry");
00674
00675 if (GTK_WIDGET(widget) != dialog_info->widget)
00676 {
00677 WARNPRINTF("huh? expected these to be the same");
00678 }
00679
00680 if (dialog_info->context)
00681 {
00682 ipc_send_reply(dialog_info->context, dialog_info->message_id, TRUE);
00683 }
00684
00685
00686 dialog_message_info_destroy();
00687 }
00688
00689
00690 static void dialog_message_confirm_destroy(void)
00691 {
00692 LOGPRINTF("entry");
00693 if (dialog_response != NULL)
00694 {
00695 gtk_widget_destroy(dialog_response->widget);
00696 g_free(dialog_response->message_id);
00697 g_free(dialog_response);
00698 dialog_response = NULL;
00699 ipc_send_request_popup("unblock");
00700 }
00701 }
00702
00703
00704 static void dialog_message_info_destroy(void)
00705 {
00706 LOGPRINTF("entry");
00707 if (dialog_info != NULL)
00708 {
00709 gtk_widget_destroy(dialog_info->widget);
00710 g_free(dialog_info->message_id);
00711 g_free(dialog_info);
00712 dialog_info = NULL;
00713 ipc_send_request_popup("unblock");
00714 }
00715 }