1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/platform_util.h"
6
7 #include <gtk/gtk.h>
8
9 #include "base/file_util.h"
10 #include "base/message_loop.h"
11 #include "base/process_util.h"
12 #include "base/string_util.h"
13 #include "base/utf_string_conversions.h"
14 #include "chrome/browser/ui/gtk/gtk_util.h"
15 #include "content/common/process_watcher.h"
16 #include "googleurl/src/gurl.h"
17 #include "ui/gfx/native_widget_types.h"
18
19 namespace {
20
SetDialogTitle(GtkWidget * dialog,const string16 & title)21 void SetDialogTitle(GtkWidget* dialog, const string16& title) {
22 gtk_window_set_title(GTK_WINDOW(dialog), UTF16ToUTF8(title).c_str());
23
24 #if !defined(OS_CHROMEOS)
25 // The following code requires the dialog to be realized. However, we host
26 // dialog's content in a Chrome window without really realize the dialog
27 // on ChromeOS. Thus, skip the following code for ChromeOS.
28 gtk_widget_realize(dialog);
29
30 // Make sure it's big enough to show the title.
31 GtkRequisition req;
32 gtk_widget_size_request(dialog, &req);
33 int width;
34 gtk_util::GetWidgetSizeFromCharacters(dialog, title.length(), 0,
35 &width, NULL);
36 // The fudge factor accounts for extra space needed by the frame
37 // decorations as well as width differences between average text and the
38 // actual title text.
39 width = width * 1.2 + 50;
40
41 if (width > req.width)
42 gtk_widget_set_size_request(dialog, width, -1);
43 #endif // !defined(OS_CHROMEOS)
44 }
45
46 int g_dialog_response;
47
HandleOnResponseDialog(GtkWidget * widget,int response,void * user_data)48 void HandleOnResponseDialog(GtkWidget* widget,
49 int response,
50 void* user_data) {
51 g_dialog_response = response;
52 gtk_widget_destroy(widget);
53 MessageLoop::current()->QuitNow();
54 }
55
56 } // namespace
57
58 namespace platform_util {
59
GetTopLevel(gfx::NativeView view)60 gfx::NativeWindow GetTopLevel(gfx::NativeView view) {
61 // A detached widget won't have a toplevel window as an ancestor, so we can't
62 // assume that the query for toplevel will return a window.
63 GtkWidget* toplevel = gtk_widget_get_ancestor(view, GTK_TYPE_WINDOW);
64 return GTK_IS_WINDOW(toplevel) ? GTK_WINDOW(toplevel) : NULL;
65 }
66
GetParent(gfx::NativeView view)67 gfx::NativeView GetParent(gfx::NativeView view) {
68 return gtk_widget_get_parent(view);
69 }
70
IsWindowActive(gfx::NativeWindow window)71 bool IsWindowActive(gfx::NativeWindow window) {
72 return gtk_window_is_active(window);
73 }
74
ActivateWindow(gfx::NativeWindow window)75 void ActivateWindow(gfx::NativeWindow window) {
76 gtk_window_present(window);
77 }
78
IsVisible(gfx::NativeView view)79 bool IsVisible(gfx::NativeView view) {
80 return GTK_WIDGET_VISIBLE(view);
81 }
82
SimpleErrorBox(gfx::NativeWindow parent,const string16 & title,const string16 & message)83 void SimpleErrorBox(gfx::NativeWindow parent,
84 const string16& title,
85 const string16& message) {
86 GtkWidget* dialog = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL,
87 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", UTF16ToUTF8(message).c_str());
88 gtk_util::ApplyMessageDialogQuirks(dialog);
89 SetDialogTitle(dialog, title);
90
91 g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
92 gtk_util::ShowDialog(dialog);
93 }
94
SimpleYesNoBox(gfx::NativeWindow parent,const string16 & title,const string16 & message)95 bool SimpleYesNoBox(gfx::NativeWindow parent,
96 const string16& title,
97 const string16& message) {
98 GtkWidget* dialog = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL,
99 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "%s",
100 UTF16ToUTF8(message).c_str());
101 gtk_util::ApplyMessageDialogQuirks(dialog);
102 SetDialogTitle(dialog, title);
103
104 g_signal_connect(dialog,
105 "response",
106 G_CALLBACK(HandleOnResponseDialog),
107 NULL);
108 gtk_util::ShowDialog(dialog);
109 // Not gtk_dialog_run as it prevents timers from running in the unit tests.
110 MessageLoop::current()->Run();
111 return g_dialog_response == GTK_RESPONSE_YES;
112 }
113
114 // Warning: this may be either Linux or ChromeOS.
GetVersionStringModifier()115 std::string GetVersionStringModifier() {
116 char* env = getenv("CHROME_VERSION_EXTRA");
117 if (!env)
118 return std::string();
119 std::string modifier(env);
120
121 #if defined(GOOGLE_CHROME_BUILD)
122 // Only ever return "", "unknown", "dev" or "beta" in a branded build.
123 if (modifier == "unstable") // linux version of "dev"
124 modifier = "dev";
125 if (modifier == "stable") {
126 modifier = "";
127 } else if ((modifier == "dev") || (modifier == "beta")) {
128 // do nothing.
129 } else {
130 modifier = "unknown";
131 }
132 #endif
133
134 return modifier;
135 }
136
CanSetAsDefaultBrowser()137 bool CanSetAsDefaultBrowser() {
138 return true;
139 }
140
141 } // namespace platform_util
142