15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <gdk/gdk.h>
8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <gdk/gdkx.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/environment.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/aura/window.h"
15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/aura/window_tree_host.h"
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ui/base/accelerators/accelerator.h"
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_constants.h"
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_code_conversion_x.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kAuraTransientParent[] = "aura-transient-parent";
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommonInitFromCommandLine(const CommandLine& command_line,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               void (*init_func)(gint*, gchar***)) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<std::string>& args = command_line.argv();
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc = args.size();
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char *[]> argv(new char *[argc + 1]);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < args.size(); ++i) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(piman@google.com): can gtk_init modify argv? Just being safe
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // here.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    argv[i] = strdup(args[i].c_str());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[argc] = NULL;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char **argv_pointer = argv.get();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_func(&argc, &argv_pointer);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < args.size(); ++i) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    free(argv[i]);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace libgtk2ui {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GtkInitFromCommandLine(const CommandLine& command_line) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommonInitFromCommandLine(command_line, gtk_init);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(erg): This method was copied out of shell_integration_linux.cc. Because
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// of how this library is structured as a stand alone .so, we can't call code
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// from browser and above.
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string GetDesktopName(base::Environment* env) {
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(GOOGLE_CHROME_BUILD)
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return "google-chrome.desktop";
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else  // CHROMIUM_BUILD
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Allow $CHROME_DESKTOP to override the built-in value, so that development
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // versions can set themselves as the default without interfering with
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // non-official, packaged versions using the built-in value.
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string name;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (env->GetVar("CHROME_DESKTOP", &name) && !name.empty())
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return name;
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return "chromium-browser.desktop";
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid SetAlwaysShowImage(GtkWidget* image_menu_item) {
70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  gtk_image_menu_item_set_always_show_image(
71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      GTK_IMAGE_MENU_ITEM(image_menu_item), TRUE);
72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochguint GetGdkKeyCodeForAccelerator(const ui::Accelerator& accelerator) {
75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The second parameter is false because accelerator keys are expressed in
76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // terms of the non-shift-modified key.
77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return XKeysymForWindowsKeyCode(accelerator.key_code(), false);
78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochGdkModifierType GetGdkModifierForAccelerator(
81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const ui::Accelerator& accelerator) {
82ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int event_flag = accelerator.modifiers();
83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int modifier = 0;
84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (event_flag & ui::EF_SHIFT_DOWN)
85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    modifier |= GDK_SHIFT_MASK;
86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (event_flag & ui::EF_CONTROL_DOWN)
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    modifier |= GDK_CONTROL_MASK;
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (event_flag & ui::EF_ALT_DOWN)
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    modifier |= GDK_MOD1_MASK;
90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return static_cast<GdkModifierType>(modifier);
91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochint EventFlagsFromGdkState(guint state) {
94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int flags = ui::EF_NONE;
95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  flags |= (state & GDK_LOCK_MASK) ? ui::EF_CAPS_LOCK_DOWN : ui::EF_NONE;
96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  flags |= (state & GDK_CONTROL_MASK) ? ui::EF_CONTROL_DOWN : ui::EF_NONE;
97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  flags |= (state & GDK_SHIFT_MASK) ? ui::EF_SHIFT_DOWN : ui::EF_NONE;
98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  flags |= (state & GDK_MOD1_MASK) ? ui::EF_ALT_DOWN : ui::EF_NONE;
99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  flags |= (state & GDK_BUTTON1_MASK) ? ui::EF_LEFT_MOUSE_BUTTON : ui::EF_NONE;
100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  flags |=
101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      (state & GDK_BUTTON2_MASK) ? ui::EF_MIDDLE_MOUSE_BUTTON : ui::EF_NONE;
102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  flags |= (state & GDK_BUTTON3_MASK) ? ui::EF_RIGHT_MOUSE_BUTTON : ui::EF_NONE;
103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return flags;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent) {
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!parent || !parent->GetHost())
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  gtk_widget_realize(dialog);
111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GdkWindow* gdk_window = gtk_widget_get_window(dialog);
112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // TODO(erg): Check to make sure we're using X11 if wayland or some other
114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // display server ever happens. Otherwise, this will crash.
115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  XSetTransientForHint(GDK_WINDOW_XDISPLAY(gdk_window),
116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                       GDK_WINDOW_XID(gdk_window),
117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                       parent->GetHost()->GetAcceleratedWidget());
118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // We also set the |parent| as a property of |dialog|, so that we can unlink
120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // the two later.
121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, parent);
122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochaura::Window* GetAuraTransientParent(GtkWidget* dialog) {
125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return reinterpret_cast<aura::Window*>(
126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      g_object_get_data(G_OBJECT(dialog), kAuraTransientParent));
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ClearAuraTransientParent(GtkWidget* dialog) {
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, NULL);
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)GtkStateType GetGtkState(ui::NativeTheme::State state) {
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  switch (state) {
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case ui::NativeTheme::kDisabled:  return GTK_STATE_INSENSITIVE;
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case ui::NativeTheme::kHovered:   return GTK_STATE_PRELIGHT;
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case ui::NativeTheme::kNormal:    return GTK_STATE_NORMAL;
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case ui::NativeTheme::kPressed:   return GTK_STATE_ACTIVE;
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case ui::NativeTheme::kNumStates: NOTREACHED();
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return GTK_STATE_NORMAL;
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace libgtk2ui
145