<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/events/keycodes/keyboard_code_conversion_android.h"

#include <android/keycodes.h>

namespace ui {

namespace {

// The Android NDK does not provide values for these yet:
enum {
  AKEYCODE_ESCAPE          = 111,
  AKEYCODE_FORWARD_DEL     = 112,
  AKEYCODE_CTRL_LEFT       = 113,
  AKEYCODE_CTRL_RIGHT      = 114,
  AKEYCODE_CAPS_LOCK       = 115,
  AKEYCODE_SCROLL_LOCK     = 116,
  AKEYCODE_META_LEFT       = 117,
  AKEYCODE_META_RIGHT      = 118,
  AKEYCODE_BREAK           = 121,
  AKEYCODE_INSERT          = 124,
  AKEYCODE_MEDIA_PLAY      = 126,
  AKEYCODE_MEDIA_PAUSE     = 127,
  AKEYCODE_F1              = 131,
  AKEYCODE_F2              = 132,
  AKEYCODE_F3              = 133,
  AKEYCODE_F4              = 134,
  AKEYCODE_F5              = 135,
  AKEYCODE_F6              = 136,
  AKEYCODE_F7              = 137,
  AKEYCODE_F8              = 138,
  AKEYCODE_F9              = 139,
  AKEYCODE_F10             = 140,
  AKEYCODE_F11             = 141,
  AKEYCODE_F12             = 142,
  AKEYCODE_NUM_LOCK        = 143,
  AKEYCODE_NUMPAD_0        = 144,
  AKEYCODE_NUMPAD_1        = 145,
  AKEYCODE_NUMPAD_2        = 146,
  AKEYCODE_NUMPAD_3        = 147,
  AKEYCODE_NUMPAD_4        = 148,
  AKEYCODE_NUMPAD_5        = 149,
  AKEYCODE_NUMPAD_6        = 150,
  AKEYCODE_NUMPAD_7        = 151,
  AKEYCODE_NUMPAD_8        = 152,
  AKEYCODE_NUMPAD_9        = 153,
  AKEYCODE_NUMPAD_DIVIDE   = 154,
  AKEYCODE_NUMPAD_MULTIPLY = 155,
  AKEYCODE_NUMPAD_SUBTRACT = 156,
  AKEYCODE_NUMPAD_ADD      = 157,
  AKEYCODE_NUMPAD_DOT      = 158,
  AKEYCODE_VOLUME_MUTE     = 164,
  AKEYCODE_CHANNEL_UP      = 166,
  AKEYCODE_CHANNEL_DOWN    = 167,
};

}  // namespace

KeyboardCode KeyboardCodeFromAndroidKeyCode(int keycode) {
  // Does not provide all key codes, and does not handle all keys.
  switch (keycode) {
    case AKEYCODE_DEL:
      return VKEY_BACK;
    case AKEYCODE_TAB:
      return VKEY_TAB;
    case AKEYCODE_CLEAR:
      return VKEY_CLEAR;
    case AKEYCODE_DPAD_CENTER:
    case AKEYCODE_ENTER:
      return VKEY_RETURN;
    case AKEYCODE_SHIFT_LEFT:
      return VKEY_LSHIFT;
    case AKEYCODE_SHIFT_RIGHT:
      return VKEY_RSHIFT;
    // Back will serve as escape, although we may not have access to it.
    case AKEYCODE_BACK:
      return VKEY_ESCAPE;
    case AKEYCODE_SPACE:
      return VKEY_SPACE;
    case AKEYCODE_HOME:
      return VKEY_HOME;
    case AKEYCODE_DPAD_LEFT:
      return VKEY_LEFT;
    case AKEYCODE_DPAD_UP:
      return VKEY_UP;
    case AKEYCODE_DPAD_RIGHT:
      return VKEY_RIGHT;
    case AKEYCODE_DPAD_DOWN:
      return VKEY_DOWN;
    case AKEYCODE_0:
      return VKEY_0;
    case AKEYCODE_1:
      return VKEY_1;
    case AKEYCODE_2:
      return VKEY_2;
    case AKEYCODE_3:
      return VKEY_3;
    case AKEYCODE_4:
      return VKEY_4;
    case AKEYCODE_5:
      return VKEY_5;
    case AKEYCODE_6:
      return VKEY_6;
    case AKEYCODE_7:
      return VKEY_7;
    case AKEYCODE_8:
      return VKEY_8;
    case AKEYCODE_9:
      return VKEY_9;
    case AKEYCODE_A:
      return VKEY_A;
    case AKEYCODE_B:
      return VKEY_B;
    case AKEYCODE_C:
      return VKEY_C;
    case AKEYCODE_D:
      return VKEY_D;
    case AKEYCODE_E:
      return VKEY_E;
    case AKEYCODE_F:
      return VKEY_F;
    case AKEYCODE_G:
      return VKEY_G;
    case AKEYCODE_H:
      return VKEY_H;
    case AKEYCODE_I:
      return VKEY_I;
    case AKEYCODE_J:
      return VKEY_J;
    case AKEYCODE_K:
      return VKEY_K;
    case AKEYCODE_L:
      return VKEY_L;
    case AKEYCODE_M:
      return VKEY_M;
    case AKEYCODE_N:
      return VKEY_N;
    case AKEYCODE_O:
      return VKEY_O;
    case AKEYCODE_P:
      return VKEY_P;
    case AKEYCODE_Q:
      return VKEY_Q;
    case AKEYCODE_R:
      return VKEY_R;
    case AKEYCODE_S:
      return VKEY_S;
    case AKEYCODE_T:
      return VKEY_T;
    case AKEYCODE_U:
      return VKEY_U;
    case AKEYCODE_V:
      return VKEY_V;
    case AKEYCODE_W:
      return VKEY_W;
    case AKEYCODE_X:
      return VKEY_X;
    case AKEYCODE_Y:
      return VKEY_Y;
    case AKEYCODE_Z:
      return VKEY_Z;
    case AKEYCODE_VOLUME_DOWN:
      return VKEY_VOLUME_DOWN;
    case AKEYCODE_VOLUME_UP:
      return VKEY_VOLUME_UP;
    case AKEYCODE_MEDIA_NEXT:
      return VKEY_MEDIA_NEXT_TRACK;
    case AKEYCODE_MEDIA_PREVIOUS:
      return VKEY_MEDIA_PREV_TRACK;
    case AKEYCODE_MEDIA_STOP:
      return VKEY_MEDIA_STOP;
    case AKEYCODE_MEDIA_PAUSE:
      return VKEY_MEDIA_PLAY_PAUSE;
    // Colon key.
    case AKEYCODE_SEMICOLON:
      return VKEY_OEM_1;
    case AKEYCODE_COMMA:
      return VKEY_OEM_COMMA;
    case AKEYCODE_MINUS:
      return VKEY_OEM_MINUS;
    case AKEYCODE_EQUALS:
      return VKEY_OEM_PLUS;
    case AKEYCODE_PERIOD:
      return VKEY_OEM_PERIOD;
    case AKEYCODE_SLASH:
      return VKEY_OEM_2;
    case AKEYCODE_LEFT_BRACKET:
      return VKEY_OEM_4;
    case AKEYCODE_BACKSLASH:
      return VKEY_OEM_5;
    case AKEYCODE_RIGHT_BRACKET:
      return VKEY_OEM_6;
    case AKEYCODE_MUTE:
    case AKEYCODE_VOLUME_MUTE:
      return VKEY_VOLUME_MUTE;
    case AKEYCODE_ESCAPE:
      return VKEY_ESCAPE;
    case AKEYCODE_MEDIA_PLAY:
    case AKEYCODE_MEDIA_PLAY_PAUSE:
      return VKEY_MEDIA_PLAY_PAUSE;
    case AKEYCODE_CALL:
      return VKEY_END;
    case AKEYCODE_ALT_LEFT:
      return VKEY_LMENU;
    case AKEYCODE_ALT_RIGHT:
      return VKEY_RMENU;
    case AKEYCODE_GRAVE:
      return VKEY_OEM_3;
    case AKEYCODE_APOSTROPHE:
      return VKEY_OEM_3;
    case AKEYCODE_MEDIA_REWIND:
      return VKEY_OEM_103;
    case AKEYCODE_MEDIA_FAST_FORWARD:
      return VKEY_OEM_104;
    case AKEYCODE_PAGE_UP:
      return VKEY_PRIOR;
    case AKEYCODE_PAGE_DOWN:
      return VKEY_NEXT;
    case AKEYCODE_FORWARD_DEL:
      return VKEY_DELETE;
    case AKEYCODE_CTRL_LEFT:
      return VKEY_LCONTROL;
    case AKEYCODE_CTRL_RIGHT:
      return VKEY_RCONTROL;
    case AKEYCODE_CAPS_LOCK:
      return VKEY_CAPITAL;
    case AKEYCODE_SCROLL_LOCK:
      return VKEY_SCROLL;
    case AKEYCODE_META_LEFT:
      return VKEY_LWIN;
    case AKEYCODE_META_RIGHT:
      return VKEY_RWIN;
    case AKEYCODE_BREAK:
      return VKEY_PAUSE;
    case AKEYCODE_INSERT:
      return VKEY_INSERT;
    case AKEYCODE_F1:
      return VKEY_F1;
    case AKEYCODE_F2:
      return VKEY_F2;
    case AKEYCODE_F3:
      return VKEY_F3;
    case AKEYCODE_F4:
      return VKEY_F4;
    case AKEYCODE_F5:
      return VKEY_F5;
    case AKEYCODE_F6:
      return VKEY_F6;
    case AKEYCODE_F7:
      return VKEY_F7;
    case AKEYCODE_F8:
      return VKEY_F8;
    case AKEYCODE_F9:
      return VKEY_F9;
    case AKEYCODE_F10:
      return VKEY_F10;
    case AKEYCODE_F11:
      return VKEY_F11;
    case AKEYCODE_F12:
      return VKEY_F12;
    case AKEYCODE_NUM_LOCK:
      return VKEY_NUMLOCK;
    case AKEYCODE_NUMPAD_0:
      return VKEY_NUMPAD0;
    case AKEYCODE_NUMPAD_1:
      return VKEY_NUMPAD1;
    case AKEYCODE_NUMPAD_2:
      return VKEY_NUMPAD2;
    case AKEYCODE_NUMPAD_3:
      return VKEY_NUMPAD3;
    case AKEYCODE_NUMPAD_4:
      return VKEY_NUMPAD4;
    case AKEYCODE_NUMPAD_5:
      return VKEY_NUMPAD5;
    case AKEYCODE_NUMPAD_6:
      return VKEY_NUMPAD6;
    case AKEYCODE_NUMPAD_7:
      return VKEY_NUMPAD7;
    case AKEYCODE_NUMPAD_8:
      return VKEY_NUMPAD8;
    case AKEYCODE_NUMPAD_9:
      return VKEY_NUMPAD9;
    case AKEYCODE_NUMPAD_DIVIDE:
      return VKEY_DIVIDE;
    case AKEYCODE_NUMPAD_MULTIPLY:
      return VKEY_MULTIPLY;
    case AKEYCODE_NUMPAD_SUBTRACT:
      return VKEY_SUBTRACT;
    case AKEYCODE_NUMPAD_ADD:
      return VKEY_ADD;
    case AKEYCODE_NUMPAD_DOT:
      return VKEY_DECIMAL;
    case AKEYCODE_CHANNEL_UP:
      return VKEY_PRIOR;
    case AKEYCODE_CHANNEL_DOWN:
      return VKEY_NEXT;
    default:
      return VKEY_UNKNOWN;
  }
}

}  // namespace ui
<commit_msg>Convert android KEYCODE_MOVE_HOME/END correctly to VKEY_HOME, VKEY_END<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/events/keycodes/keyboard_code_conversion_android.h"

#include <android/keycodes.h>

namespace ui {

namespace {

// The Android NDK does not provide values for these yet:
enum {
  AKEYCODE_ESCAPE          = 111,
  AKEYCODE_FORWARD_DEL     = 112,
  AKEYCODE_CTRL_LEFT       = 113,
  AKEYCODE_CTRL_RIGHT      = 114,
  AKEYCODE_CAPS_LOCK       = 115,
  AKEYCODE_SCROLL_LOCK     = 116,
  AKEYCODE_META_LEFT       = 117,
  AKEYCODE_META_RIGHT      = 118,
  AKEYCODE_BREAK           = 121,
  AKEYCODE_MOVE_HOME       = 122,
  AKEYCODE_MOVE_END        = 123,
  AKEYCODE_INSERT          = 124,
  AKEYCODE_MEDIA_PLAY      = 126,
  AKEYCODE_MEDIA_PAUSE     = 127,
  AKEYCODE_F1              = 131,
  AKEYCODE_F2              = 132,
  AKEYCODE_F3              = 133,
  AKEYCODE_F4              = 134,
  AKEYCODE_F5              = 135,
  AKEYCODE_F6              = 136,
  AKEYCODE_F7              = 137,
  AKEYCODE_F8              = 138,
  AKEYCODE_F9              = 139,
  AKEYCODE_F10             = 140,
  AKEYCODE_F11             = 141,
  AKEYCODE_F12             = 142,
  AKEYCODE_NUM_LOCK        = 143,
  AKEYCODE_NUMPAD_0        = 144,
  AKEYCODE_NUMPAD_1        = 145,
  AKEYCODE_NUMPAD_2        = 146,
  AKEYCODE_NUMPAD_3        = 147,
  AKEYCODE_NUMPAD_4        = 148,
  AKEYCODE_NUMPAD_5        = 149,
  AKEYCODE_NUMPAD_6        = 150,
  AKEYCODE_NUMPAD_7        = 151,
  AKEYCODE_NUMPAD_8        = 152,
  AKEYCODE_NUMPAD_9        = 153,
  AKEYCODE_NUMPAD_DIVIDE   = 154,
  AKEYCODE_NUMPAD_MULTIPLY = 155,
  AKEYCODE_NUMPAD_SUBTRACT = 156,
  AKEYCODE_NUMPAD_ADD      = 157,
  AKEYCODE_NUMPAD_DOT      = 158,
  AKEYCODE_VOLUME_MUTE     = 164,
  AKEYCODE_CHANNEL_UP      = 166,
  AKEYCODE_CHANNEL_DOWN    = 167,
};

}  // namespace

KeyboardCode KeyboardCodeFromAndroidKeyCode(int keycode) {
  // Does not provide all key codes, and does not handle all keys.
  switch (keycode) {
    case AKEYCODE_DEL:
      return VKEY_BACK;
    case AKEYCODE_TAB:
      return VKEY_TAB;
    case AKEYCODE_CLEAR:
      return VKEY_CLEAR;
    case AKEYCODE_DPAD_CENTER:
    case AKEYCODE_ENTER:
      return VKEY_RETURN;
    case AKEYCODE_SHIFT_LEFT:
      return VKEY_LSHIFT;
    case AKEYCODE_SHIFT_RIGHT:
      return VKEY_RSHIFT;
    // Back will serve as escape, although we may not have access to it.
    case AKEYCODE_BACK:
      return VKEY_ESCAPE;
    case AKEYCODE_SPACE:
      return VKEY_SPACE;
    case AKEYCODE_MOVE_HOME:
      return VKEY_HOME;
    case AKEYCODE_DPAD_LEFT:
      return VKEY_LEFT;
    case AKEYCODE_DPAD_UP:
      return VKEY_UP;
    case AKEYCODE_DPAD_RIGHT:
      return VKEY_RIGHT;
    case AKEYCODE_DPAD_DOWN:
      return VKEY_DOWN;
    case AKEYCODE_0:
      return VKEY_0;
    case AKEYCODE_1:
      return VKEY_1;
    case AKEYCODE_2:
      return VKEY_2;
    case AKEYCODE_3:
      return VKEY_3;
    case AKEYCODE_4:
      return VKEY_4;
    case AKEYCODE_5:
      return VKEY_5;
    case AKEYCODE_6:
      return VKEY_6;
    case AKEYCODE_7:
      return VKEY_7;
    case AKEYCODE_8:
      return VKEY_8;
    case AKEYCODE_9:
      return VKEY_9;
    case AKEYCODE_A:
      return VKEY_A;
    case AKEYCODE_B:
      return VKEY_B;
    case AKEYCODE_C:
      return VKEY_C;
    case AKEYCODE_D:
      return VKEY_D;
    case AKEYCODE_E:
      return VKEY_E;
    case AKEYCODE_F:
      return VKEY_F;
    case AKEYCODE_G:
      return VKEY_G;
    case AKEYCODE_H:
      return VKEY_H;
    case AKEYCODE_I:
      return VKEY_I;
    case AKEYCODE_J:
      return VKEY_J;
    case AKEYCODE_K:
      return VKEY_K;
    case AKEYCODE_L:
      return VKEY_L;
    case AKEYCODE_M:
      return VKEY_M;
    case AKEYCODE_N:
      return VKEY_N;
    case AKEYCODE_O:
      return VKEY_O;
    case AKEYCODE_P:
      return VKEY_P;
    case AKEYCODE_Q:
      return VKEY_Q;
    case AKEYCODE_R:
      return VKEY_R;
    case AKEYCODE_S:
      return VKEY_S;
    case AKEYCODE_T:
      return VKEY_T;
    case AKEYCODE_U:
      return VKEY_U;
    case AKEYCODE_V:
      return VKEY_V;
    case AKEYCODE_W:
      return VKEY_W;
    case AKEYCODE_X:
      return VKEY_X;
    case AKEYCODE_Y:
      return VKEY_Y;
    case AKEYCODE_Z:
      return VKEY_Z;
    case AKEYCODE_VOLUME_DOWN:
      return VKEY_VOLUME_DOWN;
    case AKEYCODE_VOLUME_UP:
      return VKEY_VOLUME_UP;
    case AKEYCODE_MEDIA_NEXT:
      return VKEY_MEDIA_NEXT_TRACK;
    case AKEYCODE_MEDIA_PREVIOUS:
      return VKEY_MEDIA_PREV_TRACK;
    case AKEYCODE_MEDIA_STOP:
      return VKEY_MEDIA_STOP;
    case AKEYCODE_MEDIA_PAUSE:
      return VKEY_MEDIA_PLAY_PAUSE;
    // Colon key.
    case AKEYCODE_SEMICOLON:
      return VKEY_OEM_1;
    case AKEYCODE_COMMA:
      return VKEY_OEM_COMMA;
    case AKEYCODE_MINUS:
      return VKEY_OEM_MINUS;
    case AKEYCODE_EQUALS:
      return VKEY_OEM_PLUS;
    case AKEYCODE_PERIOD:
      return VKEY_OEM_PERIOD;
    case AKEYCODE_SLASH:
      return VKEY_OEM_2;
    case AKEYCODE_LEFT_BRACKET:
      return VKEY_OEM_4;
    case AKEYCODE_BACKSLASH:
      return VKEY_OEM_5;
    case AKEYCODE_RIGHT_BRACKET:
      return VKEY_OEM_6;
    case AKEYCODE_MUTE:
    case AKEYCODE_VOLUME_MUTE:
      return VKEY_VOLUME_MUTE;
    case AKEYCODE_ESCAPE:
      return VKEY_ESCAPE;
    case AKEYCODE_MEDIA_PLAY:
    case AKEYCODE_MEDIA_PLAY_PAUSE:
      return VKEY_MEDIA_PLAY_PAUSE;
    case AKEYCODE_MOVE_END:
      return VKEY_END;
    case AKEYCODE_ALT_LEFT:
      return VKEY_LMENU;
    case AKEYCODE_ALT_RIGHT:
      return VKEY_RMENU;
    case AKEYCODE_GRAVE:
      return VKEY_OEM_3;
    case AKEYCODE_APOSTROPHE:
      return VKEY_OEM_3;
    case AKEYCODE_MEDIA_REWIND:
      return VKEY_OEM_103;
    case AKEYCODE_MEDIA_FAST_FORWARD:
      return VKEY_OEM_104;
    case AKEYCODE_PAGE_UP:
      return VKEY_PRIOR;
    case AKEYCODE_PAGE_DOWN:
      return VKEY_NEXT;
    case AKEYCODE_FORWARD_DEL:
      return VKEY_DELETE;
    case AKEYCODE_CTRL_LEFT:
      return VKEY_LCONTROL;
    case AKEYCODE_CTRL_RIGHT:
      return VKEY_RCONTROL;
    case AKEYCODE_CAPS_LOCK:
      return VKEY_CAPITAL;
    case AKEYCODE_SCROLL_LOCK:
      return VKEY_SCROLL;
    case AKEYCODE_META_LEFT:
      return VKEY_LWIN;
    case AKEYCODE_META_RIGHT:
      return VKEY_RWIN;
    case AKEYCODE_BREAK:
      return VKEY_PAUSE;
    case AKEYCODE_INSERT:
      return VKEY_INSERT;
    case AKEYCODE_F1:
      return VKEY_F1;
    case AKEYCODE_F2:
      return VKEY_F2;
    case AKEYCODE_F3:
      return VKEY_F3;
    case AKEYCODE_F4:
      return VKEY_F4;
    case AKEYCODE_F5:
      return VKEY_F5;
    case AKEYCODE_F6:
      return VKEY_F6;
    case AKEYCODE_F7:
      return VKEY_F7;
    case AKEYCODE_F8:
      return VKEY_F8;
    case AKEYCODE_F9:
      return VKEY_F9;
    case AKEYCODE_F10:
      return VKEY_F10;
    case AKEYCODE_F11:
      return VKEY_F11;
    case AKEYCODE_F12:
      return VKEY_F12;
    case AKEYCODE_NUM_LOCK:
      return VKEY_NUMLOCK;
    case AKEYCODE_NUMPAD_0:
      return VKEY_NUMPAD0;
    case AKEYCODE_NUMPAD_1:
      return VKEY_NUMPAD1;
    case AKEYCODE_NUMPAD_2:
      return VKEY_NUMPAD2;
    case AKEYCODE_NUMPAD_3:
      return VKEY_NUMPAD3;
    case AKEYCODE_NUMPAD_4:
      return VKEY_NUMPAD4;
    case AKEYCODE_NUMPAD_5:
      return VKEY_NUMPAD5;
    case AKEYCODE_NUMPAD_6:
      return VKEY_NUMPAD6;
    case AKEYCODE_NUMPAD_7:
      return VKEY_NUMPAD7;
    case AKEYCODE_NUMPAD_8:
      return VKEY_NUMPAD8;
    case AKEYCODE_NUMPAD_9:
      return VKEY_NUMPAD9;
    case AKEYCODE_NUMPAD_DIVIDE:
      return VKEY_DIVIDE;
    case AKEYCODE_NUMPAD_MULTIPLY:
      return VKEY_MULTIPLY;
    case AKEYCODE_NUMPAD_SUBTRACT:
      return VKEY_SUBTRACT;
    case AKEYCODE_NUMPAD_ADD:
      return VKEY_ADD;
    case AKEYCODE_NUMPAD_DOT:
      return VKEY_DECIMAL;
    case AKEYCODE_CHANNEL_UP:
      return VKEY_PRIOR;
    case AKEYCODE_CHANNEL_DOWN:
      return VKEY_NEXT;
    default:
      return VKEY_UNKNOWN;
  }
}

}  // namespace ui
<|endoftext|>


<commit_before>/****************************************************************************
 * Sample urbi client that sends commands contained in a file.
 *
 * Copyright (C) 2004, 2006, 2007, 2008, 2009 Jean-Christophe Baillie.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**********************************************************************/

/* This demonstration program sends commands to an Urbi server. */

#include <list>
#include <string>

#include <libport/cstdio>
#include <libport/sysexits.hh>
#include <libport/foreach.hh>

#include <libport/cli.hh>
#include <libport/package-info.hh>
#include <libport/program-name.hh>
#include <libport/option-parser.hh>

#include <urbi/package-info.hh>
#include <urbi/uclient.hh>

using libport::program_name;

namespace
{
  static
  void
  usage(libport::OptionParser& parser)
  {
    std::cout <<
      "usage: " << program_name() << " [OPTION].. [FILE]...\n"
      "\n"
      "  FILE    to upload onto the server\n"
      "\n"
      "Options:\n";
    parser.options_doc(std::cout);
    std::cout << "\n"
	      << urbi::package_info().report_bugs()
	      << std::endl
	      << libport::exit(EX_OK);
  }

  static
  void
  version()
  {
    std::cout << "urbi-send" << std::endl
              << urbi::package_info() << std::endl
              << libport::exit(EX_OK);
  }
}

static urbi::UCallbackAction
dump(void* banner, const urbi::UMessage& msg)
{
  if ((msg.tag == "start" || msg.tag == "ident")
      && !*static_cast<bool*>(banner))
    return urbi::URBI_CONTINUE;

  switch (msg.type)
  {
    case urbi::MESSAGE_DATA:
    case urbi::MESSAGE_SYSTEM:
      std::cout << msg << std::endl;
      break;

    case urbi::MESSAGE_ERROR:
      std::cerr << msg << std::endl;
      break;
  }
  return urbi::URBI_CONTINUE;
}

static urbi::UCallbackAction
error(void* banner, const urbi::UMessage& msg)
{
  dump(banner, msg);
  exit(0);
}

/*-----------------.
| Things to send.  |
`-----------------*/

struct Data
{
  virtual ~Data() {};
  virtual void send(urbi::UClient& u) const = 0;
};

struct TextData: Data
{
  TextData(const std::string& s)
    : command_(s)
  {}

  virtual
  void
  send(urbi::UClient& u) const
  {
    u.send("%s", command_.c_str());
  }

  std::string command_;
};

struct FileData: Data
{
  FileData(const std::string& s)
    : filename_(s)
  {}

  virtual
  void
  send(urbi::UClient& u) const
  {
    u.sendFile(filename_ == "-" ? "/dev/stdin" : filename_);
  }

  std::string filename_;
};

/*-------.
| Main.  |
`-------*/

int
main(int argc, char* argv[])
{
  libport::program_initialize(argc, argv);
  /// Things to send to the server.
  typedef std::list<Data*> data_list;
  data_list data;
  /// Display the server's banner.
  bool banner = false;
  /// Server host name.
  std::string host;
  /// Server port.
  int port;

  // Parse the command line.
  libport::OptionValue arg_exp("send SCRIPT to the server", "expression", 'e');
  libport::OptionValue arg_file("send the contents of FILE to the server", "file", 'f');
  libport::OptionValue arg_pfile("file containing the port to listen to", "port-file");
  libport::OptionFlag arg_banner("do not hide the server-sent banner", "banner", 'b');

  libport::OptionParser opt_parser;
  opt_parser << arg_exp << arg_file << arg_pfile << libport::opts::help
	     << libport::opts::host_l << libport::opts::port_l
	     << libport::opts::version << arg_banner;
  libport::cli_args_type remainings_args = opt_parser(libport::program_arguments());

  if (libport::opts::help.get())
    usage(opt_parser);
  banner = arg_banner.get();
  if (arg_exp.filled())
    data.push_back(new TextData(arg_exp.value()));
  if (arg_file.filled())
    data.push_back(new FileData(arg_file.value()));
  host = libport::opts::host_l.value("localhost");
  port = libport::opts::port_l.get<int>(urbi::UClient::URBI_PORT);
  if (arg_pfile.filled())
    port = libport::file_contents_get<int>(arg_pfile.value());
  if (libport::opts::version.get())
    version();

  foreach(std::string arg, remainings_args)
    if (arg[0] == '-' && arg[1] != 0)
      libport::invalid_option (arg);
    else
      data.push_back(new FileData(arg));

  urbi::UClient client(host, port);
  client.setKeepAliveCheck(3000, 1000);
  if (client.error())
    std::cerr << libport::program_name() << ": client failed to set up"
	      << std::endl
              << libport::exit(1);

  client.setWildcardCallback(callback(&dump, &banner));
  client.setClientErrorCallback(callback(&error, &banner));

  /*----------------.
  | Send contents.  |
  `----------------*/
  for (data_list::const_iterator i = data.begin(),
         i_end = data.end();
       i != i_end;
       ++i)
  {
    (*i)->send(client);
    delete *i;
  }

  std::cout << libport::program_name()
	    << ": file sent, hit Ctrl-C to terminate."
            << std::endl;
  urbi::execute();
}
<commit_msg>Revert "Make use of option parser."<commit_after>/****************************************************************************
 * Sample urbi client that sends commands contained in a file.
 *
 * Copyright (C) 2004, 2006, 2007, 2008, 2009 Jean-Christophe Baillie.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**********************************************************************/

/* This demonstration program sends commands to an Urbi server. */

#include <list>
#include <string>

#include <libport/cstdio>
#include <libport/sysexits.hh>

#include <libport/cli.hh>
#include <libport/package-info.hh>
#include <libport/program-name.hh>

#include <urbi/package-info.hh>
#include <urbi/uclient.hh>

using libport::program_name;

namespace
{
  static
  void
  usage()
  {
    std::cout <<
      "usage: " << program_name() << " [OPTION].. [FILE]...\n"
      "\n"
      "  FILE    to upload onto the server\n"
      "\n"
      "Options:\n"
      "  -b, --banner             do not hide the server-sent banner\n"
      "  -e, --expression SCRIPT  send SCRIPT to the server\n"
      "  -f, --file FILE          send the contents of FILE to the server\n"
      "  -h, --help               display this message and exit\n"
      "  -H, --host HOST          Urbi server host [localhost]\n"
      "  -p, --port PORT          Urbi server port\n"
      "      --port-file FILE     file containing the port to listen to\n"
      "  -v, --version            display version information and exit\n"
      "\n"
                << urbi::package_info().report_bugs()
                << std::endl
                << libport::exit(EX_OK);
  }

  static
  void
  version()
  {
    std::cout << "urbi-send" << std::endl
              << urbi::package_info() << std::endl
              << libport::exit(EX_OK);
  }
}

static urbi::UCallbackAction
dump(void* banner, const urbi::UMessage& msg)
{
  if ((msg.tag == "start" || msg.tag == "ident")
      && !*static_cast<bool*>(banner))
    return urbi::URBI_CONTINUE;

  switch (msg.type)
  {
    case urbi::MESSAGE_DATA:
    case urbi::MESSAGE_SYSTEM:
      std::cout << msg << std::endl;
      break;

    case urbi::MESSAGE_ERROR:
      std::cerr << msg << std::endl;
      break;
  }
  return urbi::URBI_CONTINUE;
}

static urbi::UCallbackAction
error(void* banner, const urbi::UMessage& msg)
{
  dump(banner, msg);
  exit(0);
}

/*-----------------.
| Things to send.  |
`-----------------*/

struct Data
{
  virtual ~Data() {};
  virtual void send(urbi::UClient& u) const = 0;
};

struct TextData: Data
{
  TextData(const std::string& s)
    : command_(s)
  {}

  virtual
  void
  send(urbi::UClient& u) const
  {
    u.send("%s", command_.c_str());
  }

  std::string command_;
};

struct FileData: Data
{
  FileData(const std::string& s)
    : filename_(s)
  {}

  virtual
  void
  send(urbi::UClient& u) const
  {
    u.sendFile(filename_ == "-" ? "/dev/stdin" : filename_);
  }

  std::string filename_;
};

/*-------.
| Main.  |
`-------*/

int
main(int argc, char* argv[])
{
  libport::program_initialize(argc, argv);
  /// Things to send to the server.
  typedef std::list<Data*> data_list;
  data_list data;
  /// Display the server's banner.
  bool banner = false;
  /// Server host name.
  std::string host = "localhost";
  /// Server port.
  int port = urbi::UClient::URBI_PORT;

  // Parse the command line.
  for (int i = 1; i < argc; ++i)
  {
    std::string arg = argv[i];

    if (arg == "--banner" || arg == "-b")
      banner = true;
    else if (arg == "--expression" || arg == "-e")
      data.push_back(
        new TextData(libport::convert_argument<std::string>(arg, argv[++i])));
    else if (arg == "--file" || arg == "-f")
      data.push_back(
        new FileData(libport::convert_argument<std::string>(arg, argv[++i])));
    else if (arg == "--help" || arg == "-h")
      usage();
    else if (arg == "--host" || arg == "-H")
      host = argv[++i];
    else if (arg == "--port" || arg == "-p")
      port = libport::convert_argument<int> (arg, argv[++i]);
    else if (arg == "--port-file")
      port =
        (libport::file_contents_get<int>
         (libport::convert_argument<const char*>(arg, argv[++i])));
    else if (arg == "--version" || arg == "-v")
      version();
    else if (arg[0] == '-' && arg[1] != 0)
      libport::invalid_option (arg);
    else
      // An argument: a file.
      data.push_back(new FileData(argv[i]));
  }

  urbi::UClient client(host, port);
  client.setKeepAliveCheck(3000, 1000);
  if (client.error())
    std::cerr << libport::program_name() << ": client failed to set up"
	      << std::endl
              << libport::exit(1);

  client.setWildcardCallback(callback(&dump, &banner));
  client.setClientErrorCallback(callback(&error, &banner));

  /*----------------.
  | Send contents.  |
  `----------------*/
  for (data_list::const_iterator i = data.begin(),
         i_end = data.end();
       i != i_end;
       ++i)
  {
    (*i)->send(client);
    delete *i;
  }

  std::cout << libport::program_name()
	    << ": file sent, hit Ctrl-C to terminate."
            << std::endl;
  urbi::execute();
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/view_manager/server_view.h"

#include "base/strings/stringprintf.h"
#include "services/view_manager/server_view_delegate.h"

namespace mojo {
namespace service {

ServerView::ServerView(ServerViewDelegate* delegate, const ViewId& id)
    : delegate_(delegate),
      id_(id),
      parent_(nullptr),
      visible_(false),
      opacity_(1) {
  DCHECK(delegate);  // Must provide a delegate.
}

ServerView::~ServerView() {
  delegate_->OnWillDestroyView(this);

  while (!children_.empty())
    children_.front()->parent()->Remove(children_.front());

  if (parent_)
    parent_->Remove(this);

  delegate_->OnViewDestroyed(this);
}

void ServerView::Add(ServerView* child) {
  // We assume validation checks happened already.
  DCHECK(child);
  DCHECK(child != this);
  DCHECK(!child->Contains(this));
  if (child->parent() == this) {
    if (children_.size() == 1)
      return;  // Already in the right position.
    Reorder(child, children_.back(), ORDER_DIRECTION_ABOVE);
    return;
  }

  ServerView* old_parent = child->parent();
  child->delegate_->OnWillChangeViewHierarchy(child, this, old_parent);
  if (child->parent())
    child->parent()->RemoveImpl(child);

  child->parent_ = this;
  children_.push_back(child);
  child->delegate_->OnViewHierarchyChanged(child, this, old_parent);
}

void ServerView::Remove(ServerView* child) {
  // We assume validation checks happened else where.
  DCHECK(child);
  DCHECK(child != this);
  DCHECK(child->parent() == this);

  child->delegate_->OnWillChangeViewHierarchy(child, NULL, this);
  RemoveImpl(child);
  child->delegate_->OnViewHierarchyChanged(child, NULL, this);
}

void ServerView::Reorder(ServerView* child,
                         ServerView* relative,
                         OrderDirection direction) {
  // We assume validation checks happened else where.
  DCHECK(child);
  DCHECK(child->parent() == this);
  DCHECK_GT(children_.size(), 1u);
  children_.erase(std::find(children_.begin(), children_.end(), child));
  Views::iterator i = std::find(children_.begin(), children_.end(), relative);
  if (direction == ORDER_DIRECTION_ABOVE) {
    DCHECK(i != children_.end());
    children_.insert(++i, child);
  } else if (direction == ORDER_DIRECTION_BELOW) {
    DCHECK(i != children_.end());
    children_.insert(i, child);
  }
  delegate_->OnViewReordered(this, relative, direction);
}

void ServerView::SetBounds(const gfx::Rect& bounds) {
  if (bounds_ == bounds)
    return;

  const gfx::Rect old_bounds = bounds_;
  bounds_ = bounds;
  delegate_->OnViewBoundsChanged(this, old_bounds, bounds);
}

const ServerView* ServerView::GetRoot() const {
  const ServerView* view = this;
  while (view && view->parent())
    view = view->parent();
  return view;
}

std::vector<const ServerView*> ServerView::GetChildren() const {
  std::vector<const ServerView*> children;
  children.reserve(children_.size());
  for (size_t i = 0; i < children_.size(); ++i)
    children.push_back(children_[i]);
  return children;
}

std::vector<ServerView*> ServerView::GetChildren() {
  // TODO(sky): rename to children() and fix return type.
  return children_;
}

bool ServerView::Contains(const ServerView* view) const {
  for (const ServerView* parent = view; parent; parent = parent->parent_) {
    if (parent == this)
      return true;
  }
  return false;
}

void ServerView::SetVisible(bool value) {
  if (visible_ == value)
    return;

  delegate_->OnWillChangeViewVisibility(this);
  visible_ = value;
}

void ServerView::SetOpacity(float value) {
  if (value == opacity_)
    return;
  opacity_ = value;
  delegate_->OnScheduleViewPaint(this);
}

void ServerView::SetTransform(const gfx::Transform& transform) {
  if (transform_ == transform)
    return;

  transform_ = transform;
  delegate_->OnScheduleViewPaint(this);
}

void ServerView::SetProperty(const std::string& name,
                             const std::vector<uint8_t>* value) {
  auto it = properties_.find(name);
  if (it != properties_.end()) {
    if (value && it->second == *value)
      return;
  } else if (!value) {
    // This property isn't set in |properties_| and |value| is NULL, so there's
    // no change.
    return;
  }

  if (value) {
    properties_[name] = *value;
  } else if (it != properties_.end()) {
    properties_.erase(it);
  }

  delegate_->OnViewSharedPropertyChanged(this, name, value);
}

bool ServerView::IsDrawn(const ServerView* root) const {
  if (!root->visible_)
    return false;
  const ServerView* view = this;
  while (view && view != root && view->visible_)
    view = view->parent_;
  return view == root;
}

void ServerView::SetSurfaceId(cc::SurfaceId surface_id) {
  surface_id_ = surface_id;
  delegate_->OnViewSurfaceIdChanged(this);
}

#if !defined(NDEBUG)
std::string ServerView::GetDebugWindowHierarchy() const {
  std::string result;
  BuildDebugInfo(std::string(), &result);
  return result;
}

void ServerView::BuildDebugInfo(const std::string& depth,
                                std::string* result) const {
  *result += base::StringPrintf(
      "%sid=%d,%d visible=%s bounds=%d,%d %dx%d surface_id=%ld\n",
      depth.c_str(), static_cast<int>(id_.connection_id),
      static_cast<int>(id_.view_id), visible_ ? "true" : "false", bounds_.x(),
      bounds_.y(), bounds_.width(), bounds_.height(), surface_id_.id);
  for (const ServerView* child : children_)
    child->BuildDebugInfo(depth + "  ", result);
}
#endif

void ServerView::RemoveImpl(ServerView* view) {
  view->parent_ = NULL;
  children_.erase(std::find(children_.begin(), children_.end(), view));
}

}  // namespace service
}  // namespace mojo
<commit_msg>I think this is the right one<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/view_manager/server_view.h"

#include <inttypes.h>

#include "base/strings/stringprintf.h"
#include "services/view_manager/server_view_delegate.h"

namespace mojo {
namespace service {

ServerView::ServerView(ServerViewDelegate* delegate, const ViewId& id)
    : delegate_(delegate),
      id_(id),
      parent_(nullptr),
      visible_(false),
      opacity_(1) {
  DCHECK(delegate);  // Must provide a delegate.
}

ServerView::~ServerView() {
  delegate_->OnWillDestroyView(this);

  while (!children_.empty())
    children_.front()->parent()->Remove(children_.front());

  if (parent_)
    parent_->Remove(this);

  delegate_->OnViewDestroyed(this);
}

void ServerView::Add(ServerView* child) {
  // We assume validation checks happened already.
  DCHECK(child);
  DCHECK(child != this);
  DCHECK(!child->Contains(this));
  if (child->parent() == this) {
    if (children_.size() == 1)
      return;  // Already in the right position.
    Reorder(child, children_.back(), ORDER_DIRECTION_ABOVE);
    return;
  }

  ServerView* old_parent = child->parent();
  child->delegate_->OnWillChangeViewHierarchy(child, this, old_parent);
  if (child->parent())
    child->parent()->RemoveImpl(child);

  child->parent_ = this;
  children_.push_back(child);
  child->delegate_->OnViewHierarchyChanged(child, this, old_parent);
}

void ServerView::Remove(ServerView* child) {
  // We assume validation checks happened else where.
  DCHECK(child);
  DCHECK(child != this);
  DCHECK(child->parent() == this);

  child->delegate_->OnWillChangeViewHierarchy(child, NULL, this);
  RemoveImpl(child);
  child->delegate_->OnViewHierarchyChanged(child, NULL, this);
}

void ServerView::Reorder(ServerView* child,
                         ServerView* relative,
                         OrderDirection direction) {
  // We assume validation checks happened else where.
  DCHECK(child);
  DCHECK(child->parent() == this);
  DCHECK_GT(children_.size(), 1u);
  children_.erase(std::find(children_.begin(), children_.end(), child));
  Views::iterator i = std::find(children_.begin(), children_.end(), relative);
  if (direction == ORDER_DIRECTION_ABOVE) {
    DCHECK(i != children_.end());
    children_.insert(++i, child);
  } else if (direction == ORDER_DIRECTION_BELOW) {
    DCHECK(i != children_.end());
    children_.insert(i, child);
  }
  delegate_->OnViewReordered(this, relative, direction);
}

void ServerView::SetBounds(const gfx::Rect& bounds) {
  if (bounds_ == bounds)
    return;

  const gfx::Rect old_bounds = bounds_;
  bounds_ = bounds;
  delegate_->OnViewBoundsChanged(this, old_bounds, bounds);
}

const ServerView* ServerView::GetRoot() const {
  const ServerView* view = this;
  while (view && view->parent())
    view = view->parent();
  return view;
}

std::vector<const ServerView*> ServerView::GetChildren() const {
  std::vector<const ServerView*> children;
  children.reserve(children_.size());
  for (size_t i = 0; i < children_.size(); ++i)
    children.push_back(children_[i]);
  return children;
}

std::vector<ServerView*> ServerView::GetChildren() {
  // TODO(sky): rename to children() and fix return type.
  return children_;
}

bool ServerView::Contains(const ServerView* view) const {
  for (const ServerView* parent = view; parent; parent = parent->parent_) {
    if (parent == this)
      return true;
  }
  return false;
}

void ServerView::SetVisible(bool value) {
  if (visible_ == value)
    return;

  delegate_->OnWillChangeViewVisibility(this);
  visible_ = value;
}

void ServerView::SetOpacity(float value) {
  if (value == opacity_)
    return;
  opacity_ = value;
  delegate_->OnScheduleViewPaint(this);
}

void ServerView::SetTransform(const gfx::Transform& transform) {
  if (transform_ == transform)
    return;

  transform_ = transform;
  delegate_->OnScheduleViewPaint(this);
}

void ServerView::SetProperty(const std::string& name,
                             const std::vector<uint8_t>* value) {
  auto it = properties_.find(name);
  if (it != properties_.end()) {
    if (value && it->second == *value)
      return;
  } else if (!value) {
    // This property isn't set in |properties_| and |value| is NULL, so there's
    // no change.
    return;
  }

  if (value) {
    properties_[name] = *value;
  } else if (it != properties_.end()) {
    properties_.erase(it);
  }

  delegate_->OnViewSharedPropertyChanged(this, name, value);
}

bool ServerView::IsDrawn(const ServerView* root) const {
  if (!root->visible_)
    return false;
  const ServerView* view = this;
  while (view && view != root && view->visible_)
    view = view->parent_;
  return view == root;
}

void ServerView::SetSurfaceId(cc::SurfaceId surface_id) {
  surface_id_ = surface_id;
  delegate_->OnViewSurfaceIdChanged(this);
}

#if !defined(NDEBUG)
std::string ServerView::GetDebugWindowHierarchy() const {
  std::string result;
  BuildDebugInfo(std::string(), &result);
  return result;
}

void ServerView::BuildDebugInfo(const std::string& depth,
                                std::string* result) const {
  *result += base::StringPrintf(
      "%sid=%d,%d visible=%s bounds=%d,%d %dx%d surface_id=%" PRIu64 "\n",
      depth.c_str(), static_cast<int>(id_.connection_id),
      static_cast<int>(id_.view_id), visible_ ? "true" : "false", bounds_.x(),
      bounds_.y(), bounds_.width(), bounds_.height(), surface_id_.id);
  for (const ServerView* child : children_)
    child->BuildDebugInfo(depth + "  ", result);
}
#endif

void ServerView::RemoveImpl(ServerView* view) {
  view->parent_ = NULL;
  children_.erase(std::find(children_.begin(), children_.end(), view));
}

}  // namespace service
}  // namespace mojo
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

#ifdef ENABLE_QUICKSTART_APPLET

#include <unotools/moduleoptions.hxx>

#include <unotools/dynamicmenuoptions.hxx>

#include <gtk/gtk.h>
#include <glib.h>
#include <eggtray/eggtrayicon.h>
#include <osl/mutex.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/bmpacc.hxx>
#include <sfx2/app.hxx>
#include "app.hrc"
#ifndef __SHUTDOWNICON_HXX__
#define USE_APP_SHORTCUTS
#include "shutdownicon.hxx"
#endif

// Cut/paste from vcl/inc/svids.hrc
#define SV_ICON_SMALL_START                 25000

#define SV_ICON_ID_OFFICE                       1
#define SV_ICON_ID_TEXT                         2
#define SV_ICON_ID_SPREADSHEET                  4
#define SV_ICON_ID_DRAWING                      6
#define SV_ICON_ID_PRESENTATION                 8
#define SV_ICON_ID_DATABASE                    14
#define SV_ICON_ID_FORMULA                     15
#define SV_ICON_ID_TEMPLATE                    16

using namespace ::rtl;
using namespace ::osl;

static ResMgr *pVCLResMgr;
static EggTrayIcon *pTrayIcon;
static GtkWidget *pExitMenuItem = NULL;
static GtkWidget *pOpenMenuItem = NULL;
static GtkWidget *pDisableMenuItem = NULL;

static void open_url_cb( GtkWidget *, gpointer data )
{
    ShutdownIcon::OpenURL( *(OUString *)data,
                           OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
}

static void open_file_cb( GtkWidget * )
{
    if ( !ShutdownIcon::bModalMode )
        ShutdownIcon::FileOpen();
}

static void open_template_cb( GtkWidget * )
{
    if ( !ShutdownIcon::bModalMode )
        ShutdownIcon::FromTemplate();
}

static void systray_disable_cb()
{
    ShutdownIcon::SetAutostart( false );
    ShutdownIcon::terminateDesktop();
}

static void exit_quickstarter_cb( GtkWidget * )
{
    if (pTrayIcon)
    {
        egg_tray_icon_cancel_message (pTrayIcon, 1 );
        plugin_shutdown_sys_tray();
        //terminate may cause this .so to be unloaded. So we must be hands off
        //all calls into this .so after this call
        ShutdownIcon::terminateDesktop();
    }
}

static void menu_deactivate_cb( GtkWidget *pMenu )
{
    gtk_menu_popdown( GTK_MENU( pMenu ) );
}

static GdkPixbuf * ResIdToPixbuf( USHORT nResId )
{
    ResId aResId( SV_ICON_SMALL_START + nResId, *pVCLResMgr );
    BitmapEx aIcon( aResId );
    Bitmap pInSalBitmap = aIcon.GetBitmap();
    AlphaMask pInSalAlpha = aIcon.GetAlpha();

    BitmapReadAccess* pSalBitmap = pInSalBitmap.AcquireReadAccess();
    BitmapReadAccess* pSalAlpha = pInSalAlpha.AcquireReadAccess();

    g_return_val_if_fail( pSalBitmap != NULL, NULL );

    Size aSize( pSalBitmap->Width(), pSalBitmap->Height() );
    g_return_val_if_fail( Size( pSalAlpha->Width(), pSalAlpha->Height() ) == aSize, NULL );

    int nX, nY;
    guchar *pPixbufData = ( guchar * )g_malloc( 4 * aSize.Width() * aSize.Height() );
    guchar *pDestData = pPixbufData;

    for( nY = 0; nY < pSalBitmap->Height(); nY++ )
    {
        for( nX = 0; nX < pSalBitmap->Width(); nX++ )
        {
            BitmapColor aPix;
            aPix = pSalBitmap->GetPixel( nY, nX );
            pDestData[0] = aPix.GetRed();
            pDestData[1] = aPix.GetGreen();
            pDestData[2] = aPix.GetBlue();
            if (pSalAlpha)
            {
                aPix = pSalAlpha->GetPixel( nY, nX );
                pDestData[3] = 255 - aPix.GetIndex();
            }
            else
                pDestData[3] = 255;
            pDestData += 4;
        }
    }

    pInSalBitmap.ReleaseAccess( pSalBitmap );
    if( pSalAlpha )
        pInSalAlpha.ReleaseAccess( pSalAlpha );

    return gdk_pixbuf_new_from_data( pPixbufData,
        GDK_COLORSPACE_RGB, TRUE, 8,
        aSize.Width(), aSize.Height(),
        aSize.Width() * 4,
        (GdkPixbufDestroyNotify) g_free,
        NULL );
}

extern "C" {
static void oustring_delete (gpointer  data,
                             GClosure * /* closure */)
{
    OUString *pURL = (OUString *) data;
    delete pURL;
}
}

static void add_item( GtkMenuShell *pMenuShell, const char *pAsciiURL,
                      OUString *pOverrideLabel,
                      USHORT nResId, GCallback pFnCallback )
{
    OUString *pURL = new OUString (OStringToOUString( pAsciiURL,
                                                      RTL_TEXTENCODING_UTF8 ));
    OString aLabel;
    if (pOverrideLabel)
        aLabel = OUStringToOString (*pOverrideLabel, RTL_TEXTENCODING_UTF8);
    else
    {
        ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();
        aLabel = OUStringToOString (pShutdownIcon->GetUrlDescription( *pURL ),
                                    RTL_TEXTENCODING_UTF8);
    }

    GdkPixbuf *pPixbuf= ResIdToPixbuf( nResId );
    GtkWidget *pImage = gtk_image_new_from_pixbuf( pPixbuf );
    g_object_unref( G_OBJECT( pPixbuf ) );

    GtkWidget *pMenuItem = gtk_image_menu_item_new_with_label( aLabel );
    gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM( pMenuItem ), pImage );
    g_signal_connect_data( pMenuItem, "activate", pFnCallback, pURL,
                           oustring_delete, GConnectFlags(0));

    gtk_menu_shell_append( pMenuShell, pMenuItem );
}

// Unbelievably nasty
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;

static void add_ugly_db_item( GtkMenuShell *pMenuShell, const char *pAsciiURL,
                              USHORT nResId, GCallback pFnCallback )
{
    SvtDynamicMenuOptions aOpt;
    Sequence < Sequence < PropertyValue > > aMenu = aOpt.GetMenu( E_NEWMENU );
    for ( sal_Int32 n=0; n<aMenu.getLength(); n++ )
    {
        ::rtl::OUString aURL;
        ::rtl::OUString aDescription;
        Sequence < PropertyValue >& aEntry = aMenu[n];
        for ( sal_Int32 m=0; m<aEntry.getLength(); m++ )
        {
            if ( aEntry[m].Name.equalsAsciiL( "URL", 3 ) )
                aEntry[m].Value >>= aURL;
            if ( aEntry[m].Name.equalsAsciiL( "Title", 5 ) )
                aEntry[m].Value >>= aDescription;
        }

        if ( aURL.equalsAscii( BASE_URL ) && aDescription.getLength() )
        {
            add_item (pMenuShell, pAsciiURL, &aDescription, nResId, pFnCallback);
            break;
        }
    }
}

static GtkWidget *
add_image_menu_item( GtkMenuShell *pMenuShell,
                     const gchar *stock_id,
                     rtl::OUString aLabel,
                     GCallback     activate_cb )
{
    OString aUtfLabel = rtl::OUStringToOString (aLabel, RTL_TEXTENCODING_UTF8 );

    GtkWidget *pImage;
    pImage = gtk_image_new_from_stock( stock_id, GTK_ICON_SIZE_MENU );

    GtkWidget *pMenuItem;
    pMenuItem = gtk_image_menu_item_new_with_label( aUtfLabel );
    gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM( pMenuItem ), pImage );

    gtk_menu_shell_append( pMenuShell, pMenuItem );
    g_signal_connect( pMenuItem, "activate", activate_cb, NULL);

    return pMenuItem;
}

static void populate_menu( GtkWidget *pMenu )
{
    ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();
    GtkMenuShell *pMenuShell = GTK_MENU_SHELL( pMenu );
    SvtModuleOptions aModuleOptions;

    if ( aModuleOptions.IsWriter() )
        add_item (pMenuShell, WRITER_URL, NULL,
                  SV_ICON_ID_TEXT, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsCalc() )
        add_item (pMenuShell, CALC_URL, NULL,
                  SV_ICON_ID_SPREADSHEET, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsImpress() )
        add_item (pMenuShell, IMPRESS_URL, NULL,
                  SV_ICON_ID_PRESENTATION, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsDraw() )
        add_item (pMenuShell, DRAW_URL, NULL,
                  SV_ICON_ID_DRAWING, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsDataBase() )
        add_ugly_db_item (pMenuShell, BASE_URL,
                          SV_ICON_ID_DATABASE, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsMath() )
        add_item (pMenuShell, MATH_URL, NULL,
                  SV_ICON_ID_FORMULA, G_CALLBACK( open_url_cb ));

    OUString aULabel = pShutdownIcon->GetResString( STR_QUICKSTART_FROMTEMPLATE );
    add_item (pMenuShell, "dummy", &aULabel,
              SV_ICON_ID_TEMPLATE, G_CALLBACK( open_template_cb ));

    OString aLabel;
    GtkWidget *pMenuItem;

    pMenuItem = gtk_separator_menu_item_new();
    gtk_menu_shell_append( pMenuShell, pMenuItem );

    pOpenMenuItem = add_image_menu_item
        (pMenuShell, GTK_STOCK_OPEN,
         pShutdownIcon->GetResString( STR_QUICKSTART_FILEOPEN ),
         G_CALLBACK( open_file_cb ));

    pMenuItem = gtk_separator_menu_item_new();
    gtk_menu_shell_append( pMenuShell, pMenuItem );

    pDisableMenuItem = add_image_menu_item
        ( pMenuShell, GTK_STOCK_CLOSE,
          pShutdownIcon->GetResString( STR_QUICKSTART_PRELAUNCH_UNX ),
          G_CALLBACK( systray_disable_cb ) );

    pMenuItem = gtk_separator_menu_item_new();
    gtk_menu_shell_append( pMenuShell, pMenuItem );

    pExitMenuItem = add_image_menu_item
        ( pMenuShell, GTK_STOCK_QUIT,
          pShutdownIcon->GetResString( STR_QUICKSTART_EXIT ),
          G_CALLBACK( exit_quickstarter_cb ) );

    gtk_widget_show_all( pMenu );
}

static void refresh_menu( GtkWidget *pMenu )
{
    if (!pExitMenuItem)
        populate_menu( pMenu );

    bool bModal = ShutdownIcon::bModalMode;
    gtk_widget_set_sensitive( pExitMenuItem, !bModal);
    gtk_widget_set_sensitive( pOpenMenuItem, !bModal);
    gtk_widget_set_sensitive( pDisableMenuItem, !bModal);
}

extern "C" {
static void
layout_menu( GtkMenu *menu,
             gint *x, gint *y, gboolean *push_in,
             gpointer )
{
    GtkRequisition req;
    GtkWidget *ebox = GTK_BIN( pTrayIcon )->child;

    gtk_widget_size_request( GTK_WIDGET( menu ), &req );
    gdk_window_get_origin( ebox->window, x, y );

    (*x) += ebox->allocation.x;
    (*y) += ebox->allocation.y;

    if (*y >= gdk_screen_get_height (gtk_widget_get_screen (ebox)) / 2)
        (*y) -= req.height;
    else
        (*y) += ebox->allocation.height;

    *push_in = TRUE;
}
}

static gboolean display_menu_cb( GtkWidget *,
                                 GdkEventButton *event, GtkWidget *pMenu )
{
    if (event->button == 2)
        return FALSE;

#ifdef TEMPLATE_DIALOG_MORE_POLISHED
    if (event->button == 1 &&
        event->type == GDK_2BUTTON_PRESS)
    {
        open_template_cb( NULL );
        return TRUE;
    }
    if (event->button == 3)
    {
        ... as below ...
#endif

    refresh_menu( pMenu );

    gtk_menu_popup( GTK_MENU( pMenu ), NULL, NULL,
                    layout_menu, NULL, 0, event->time );

    return TRUE;
}

extern "C" {
    static gboolean
    show_at_idle( gpointer )
    {
        ::SolarMutexGuard aGuard;
        gtk_widget_show_all( GTK_WIDGET( pTrayIcon ) );
        return FALSE;
    }
}

void SAL_DLLPUBLIC_EXPORT plugin_init_sys_tray()
{
    ::SolarMutexGuard aGuard;

    if( !g_type_from_name( "GdkDisplay" ) )
        return;

    OString aLabel;
    ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();

    aLabel = rtl::OUStringToOString (
            pShutdownIcon->GetResString( STR_QUICKSTART_TIP ),
            RTL_TEXTENCODING_UTF8 );

    pTrayIcon = egg_tray_icon_new( aLabel );

    GtkWidget *pParent = gtk_event_box_new();
    GtkTooltips *pTooltips = gtk_tooltips_new();
    gtk_tooltips_set_tip( GTK_TOOLTIPS( pTooltips ), pParent, aLabel, NULL );

    GtkWidget *pIconImage = gtk_image_new();
    gtk_container_add( GTK_CONTAINER( pParent ), pIconImage );

    pVCLResMgr = CREATEVERSIONRESMGR( vcl );

    GdkPixbuf *pPixbuf = ResIdToPixbuf( SV_ICON_ID_OFFICE );
    gtk_image_set_from_pixbuf( GTK_IMAGE( pIconImage ), pPixbuf );
    g_object_unref( pPixbuf );

    GtkWidget *pMenu = gtk_menu_new();
    g_signal_connect (pMenu, "deactivate",
                      G_CALLBACK (menu_deactivate_cb), NULL);
    g_signal_connect( pParent, "button_press_event",
                      G_CALLBACK( display_menu_cb ), pMenu );
    gtk_container_add( GTK_CONTAINER( pTrayIcon ), pParent );

    // Show at idle to avoid artefacts at startup
    g_idle_add (show_at_idle, (gpointer) pTrayIcon);

    // disable shutdown
    pShutdownIcon->SetVeto( true );
    pShutdownIcon->addTerminateListener();

    g_signal_connect(GTK_WIDGET(pTrayIcon), "destroy",
            G_CALLBACK(exit_quickstarter_cb), NULL);
}

void SAL_DLLPUBLIC_EXPORT plugin_shutdown_sys_tray()
{
    ::SolarMutexGuard aGuard;
    if( !pTrayIcon )
        return;
    gtk_widget_destroy( GTK_WIDGET( pTrayIcon ) );
    pTrayIcon = NULL;
    pExitMenuItem = NULL;
    pOpenMenuItem = NULL;
    pDisableMenuItem = NULL;
}

#endif // ENABLE_QUICKSTART_APPLET

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Related: rhbz#650170 don't crash when quickstarter is exited by user<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

#ifdef ENABLE_QUICKSTART_APPLET

#include <unotools/moduleoptions.hxx>

#include <unotools/dynamicmenuoptions.hxx>

#include <gtk/gtk.h>
#include <glib.h>
#include <eggtray/eggtrayicon.h>
#include <osl/mutex.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/bmpacc.hxx>
#include <sfx2/app.hxx>
#include "app.hrc"
#ifndef __SHUTDOWNICON_HXX__
#define USE_APP_SHORTCUTS
#include "shutdownicon.hxx"
#endif

// Cut/paste from vcl/inc/svids.hrc
#define SV_ICON_SMALL_START                 25000

#define SV_ICON_ID_OFFICE                       1
#define SV_ICON_ID_TEXT                         2
#define SV_ICON_ID_SPREADSHEET                  4
#define SV_ICON_ID_DRAWING                      6
#define SV_ICON_ID_PRESENTATION                 8
#define SV_ICON_ID_DATABASE                    14
#define SV_ICON_ID_FORMULA                     15
#define SV_ICON_ID_TEMPLATE                    16

using namespace ::rtl;
using namespace ::osl;

static ResMgr *pVCLResMgr;
static EggTrayIcon *pTrayIcon;
static GtkWidget *pExitMenuItem = NULL;
static GtkWidget *pOpenMenuItem = NULL;
static GtkWidget *pDisableMenuItem = NULL;

static void open_url_cb( GtkWidget *, gpointer data )
{
    ShutdownIcon::OpenURL( *(OUString *)data,
                           OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
}

static void open_file_cb( GtkWidget * )
{
    if ( !ShutdownIcon::bModalMode )
        ShutdownIcon::FileOpen();
}

static void open_template_cb( GtkWidget * )
{
    if ( !ShutdownIcon::bModalMode )
        ShutdownIcon::FromTemplate();
}

static void systray_disable_cb()
{
    ShutdownIcon::SetAutostart( false );
    ShutdownIcon::terminateDesktop();
}

static void exit_quickstarter_cb( GtkWidget * )
{
    if (pTrayIcon)
    {
        egg_tray_icon_cancel_message (pTrayIcon, 1 );
        plugin_shutdown_sys_tray();
        //terminate may cause this .so to be unloaded. So we must be hands off
        //all calls into this .so after this call
        ShutdownIcon::terminateDesktop();
    }
}

static void menu_deactivate_cb( GtkWidget *pMenu )
{
    gtk_menu_popdown( GTK_MENU( pMenu ) );
}

static GdkPixbuf * ResIdToPixbuf( USHORT nResId )
{
    ResId aResId( SV_ICON_SMALL_START + nResId, *pVCLResMgr );
    BitmapEx aIcon( aResId );
    Bitmap pInSalBitmap = aIcon.GetBitmap();
    AlphaMask pInSalAlpha = aIcon.GetAlpha();

    BitmapReadAccess* pSalBitmap = pInSalBitmap.AcquireReadAccess();
    BitmapReadAccess* pSalAlpha = pInSalAlpha.AcquireReadAccess();

    g_return_val_if_fail( pSalBitmap != NULL, NULL );

    Size aSize( pSalBitmap->Width(), pSalBitmap->Height() );
    g_return_val_if_fail( Size( pSalAlpha->Width(), pSalAlpha->Height() ) == aSize, NULL );

    int nX, nY;
    guchar *pPixbufData = ( guchar * )g_malloc( 4 * aSize.Width() * aSize.Height() );
    guchar *pDestData = pPixbufData;

    for( nY = 0; nY < pSalBitmap->Height(); nY++ )
    {
        for( nX = 0; nX < pSalBitmap->Width(); nX++ )
        {
            BitmapColor aPix;
            aPix = pSalBitmap->GetPixel( nY, nX );
            pDestData[0] = aPix.GetRed();
            pDestData[1] = aPix.GetGreen();
            pDestData[2] = aPix.GetBlue();
            if (pSalAlpha)
            {
                aPix = pSalAlpha->GetPixel( nY, nX );
                pDestData[3] = 255 - aPix.GetIndex();
            }
            else
                pDestData[3] = 255;
            pDestData += 4;
        }
    }

    pInSalBitmap.ReleaseAccess( pSalBitmap );
    if( pSalAlpha )
        pInSalAlpha.ReleaseAccess( pSalAlpha );

    return gdk_pixbuf_new_from_data( pPixbufData,
        GDK_COLORSPACE_RGB, TRUE, 8,
        aSize.Width(), aSize.Height(),
        aSize.Width() * 4,
        (GdkPixbufDestroyNotify) g_free,
        NULL );
}

extern "C" {
static void oustring_delete (gpointer  data,
                             GClosure * /* closure */)
{
    OUString *pURL = (OUString *) data;
    delete pURL;
}
}

static void add_item( GtkMenuShell *pMenuShell, const char *pAsciiURL,
                      OUString *pOverrideLabel,
                      USHORT nResId, GCallback pFnCallback )
{
    OUString *pURL = new OUString (OStringToOUString( pAsciiURL,
                                                      RTL_TEXTENCODING_UTF8 ));
    OString aLabel;
    if (pOverrideLabel)
        aLabel = OUStringToOString (*pOverrideLabel, RTL_TEXTENCODING_UTF8);
    else
    {
        ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();
        aLabel = OUStringToOString (pShutdownIcon->GetUrlDescription( *pURL ),
                                    RTL_TEXTENCODING_UTF8);
    }

    GdkPixbuf *pPixbuf= ResIdToPixbuf( nResId );
    GtkWidget *pImage = gtk_image_new_from_pixbuf( pPixbuf );
    g_object_unref( G_OBJECT( pPixbuf ) );

    GtkWidget *pMenuItem = gtk_image_menu_item_new_with_label( aLabel );
    gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM( pMenuItem ), pImage );
    g_signal_connect_data( pMenuItem, "activate", pFnCallback, pURL,
                           oustring_delete, GConnectFlags(0));

    gtk_menu_shell_append( pMenuShell, pMenuItem );
}

// Unbelievably nasty
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;

static void add_ugly_db_item( GtkMenuShell *pMenuShell, const char *pAsciiURL,
                              USHORT nResId, GCallback pFnCallback )
{
    SvtDynamicMenuOptions aOpt;
    Sequence < Sequence < PropertyValue > > aMenu = aOpt.GetMenu( E_NEWMENU );
    for ( sal_Int32 n=0; n<aMenu.getLength(); n++ )
    {
        ::rtl::OUString aURL;
        ::rtl::OUString aDescription;
        Sequence < PropertyValue >& aEntry = aMenu[n];
        for ( sal_Int32 m=0; m<aEntry.getLength(); m++ )
        {
            if ( aEntry[m].Name.equalsAsciiL( "URL", 3 ) )
                aEntry[m].Value >>= aURL;
            if ( aEntry[m].Name.equalsAsciiL( "Title", 5 ) )
                aEntry[m].Value >>= aDescription;
        }

        if ( aURL.equalsAscii( BASE_URL ) && aDescription.getLength() )
        {
            add_item (pMenuShell, pAsciiURL, &aDescription, nResId, pFnCallback);
            break;
        }
    }
}

static GtkWidget *
add_image_menu_item( GtkMenuShell *pMenuShell,
                     const gchar *stock_id,
                     rtl::OUString aLabel,
                     GCallback     activate_cb )
{
    OString aUtfLabel = rtl::OUStringToOString (aLabel, RTL_TEXTENCODING_UTF8 );

    GtkWidget *pImage;
    pImage = gtk_image_new_from_stock( stock_id, GTK_ICON_SIZE_MENU );

    GtkWidget *pMenuItem;
    pMenuItem = gtk_image_menu_item_new_with_label( aUtfLabel );
    gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM( pMenuItem ), pImage );

    gtk_menu_shell_append( pMenuShell, pMenuItem );
    g_signal_connect( pMenuItem, "activate", activate_cb, NULL);

    return pMenuItem;
}

static void populate_menu( GtkWidget *pMenu )
{
    ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();
    GtkMenuShell *pMenuShell = GTK_MENU_SHELL( pMenu );
    SvtModuleOptions aModuleOptions;

    if ( aModuleOptions.IsWriter() )
        add_item (pMenuShell, WRITER_URL, NULL,
                  SV_ICON_ID_TEXT, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsCalc() )
        add_item (pMenuShell, CALC_URL, NULL,
                  SV_ICON_ID_SPREADSHEET, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsImpress() )
        add_item (pMenuShell, IMPRESS_URL, NULL,
                  SV_ICON_ID_PRESENTATION, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsDraw() )
        add_item (pMenuShell, DRAW_URL, NULL,
                  SV_ICON_ID_DRAWING, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsDataBase() )
        add_ugly_db_item (pMenuShell, BASE_URL,
                          SV_ICON_ID_DATABASE, G_CALLBACK( open_url_cb ));

    if ( aModuleOptions.IsMath() )
        add_item (pMenuShell, MATH_URL, NULL,
                  SV_ICON_ID_FORMULA, G_CALLBACK( open_url_cb ));

    OUString aULabel = pShutdownIcon->GetResString( STR_QUICKSTART_FROMTEMPLATE );
    add_item (pMenuShell, "dummy", &aULabel,
              SV_ICON_ID_TEMPLATE, G_CALLBACK( open_template_cb ));

    OString aLabel;
    GtkWidget *pMenuItem;

    pMenuItem = gtk_separator_menu_item_new();
    gtk_menu_shell_append( pMenuShell, pMenuItem );

    pOpenMenuItem = add_image_menu_item
        (pMenuShell, GTK_STOCK_OPEN,
         pShutdownIcon->GetResString( STR_QUICKSTART_FILEOPEN ),
         G_CALLBACK( open_file_cb ));

    pMenuItem = gtk_separator_menu_item_new();
    gtk_menu_shell_append( pMenuShell, pMenuItem );

    pDisableMenuItem = add_image_menu_item
        ( pMenuShell, GTK_STOCK_CLOSE,
          pShutdownIcon->GetResString( STR_QUICKSTART_PRELAUNCH_UNX ),
          G_CALLBACK( systray_disable_cb ) );

    pMenuItem = gtk_separator_menu_item_new();
    gtk_menu_shell_append( pMenuShell, pMenuItem );

    pExitMenuItem = add_image_menu_item
        ( pMenuShell, GTK_STOCK_QUIT,
          pShutdownIcon->GetResString( STR_QUICKSTART_EXIT ),
          G_CALLBACK( exit_quickstarter_cb ) );

    gtk_widget_show_all( pMenu );
}

static void refresh_menu( GtkWidget *pMenu )
{
    if (!pExitMenuItem)
        populate_menu( pMenu );

    bool bModal = ShutdownIcon::bModalMode;
    gtk_widget_set_sensitive( pExitMenuItem, !bModal);
    gtk_widget_set_sensitive( pOpenMenuItem, !bModal);
    gtk_widget_set_sensitive( pDisableMenuItem, !bModal);
}

extern "C" {
static void
layout_menu( GtkMenu *menu,
             gint *x, gint *y, gboolean *push_in,
             gpointer )
{
    GtkRequisition req;
    GtkWidget *ebox = GTK_BIN( pTrayIcon )->child;

    gtk_widget_size_request( GTK_WIDGET( menu ), &req );
    gdk_window_get_origin( ebox->window, x, y );

    (*x) += ebox->allocation.x;
    (*y) += ebox->allocation.y;

    if (*y >= gdk_screen_get_height (gtk_widget_get_screen (ebox)) / 2)
        (*y) -= req.height;
    else
        (*y) += ebox->allocation.height;

    *push_in = TRUE;
}
}

static gboolean display_menu_cb( GtkWidget *,
                                 GdkEventButton *event, GtkWidget *pMenu )
{
    if (event->button == 2)
        return FALSE;

#ifdef TEMPLATE_DIALOG_MORE_POLISHED
    if (event->button == 1 &&
        event->type == GDK_2BUTTON_PRESS)
    {
        open_template_cb( NULL );
        return TRUE;
    }
    if (event->button == 3)
    {
        ... as below ...
#endif

    refresh_menu( pMenu );

    gtk_menu_popup( GTK_MENU( pMenu ), NULL, NULL,
                    layout_menu, NULL, 0, event->time );

    return TRUE;
}

extern "C" {
    static gboolean
    show_at_idle( gpointer )
    {
        ::SolarMutexGuard aGuard;
        gtk_widget_show_all( GTK_WIDGET( pTrayIcon ) );
        return FALSE;
    }
}

void SAL_DLLPUBLIC_EXPORT plugin_init_sys_tray()
{
    ::SolarMutexGuard aGuard;

    if( !g_type_from_name( "GdkDisplay" ) )
        return;

    OString aLabel;
    ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();

    aLabel = rtl::OUStringToOString (
            pShutdownIcon->GetResString( STR_QUICKSTART_TIP ),
            RTL_TEXTENCODING_UTF8 );

    pTrayIcon = egg_tray_icon_new( aLabel );

    GtkWidget *pParent = gtk_event_box_new();
    GtkTooltips *pTooltips = gtk_tooltips_new();
    gtk_tooltips_set_tip( GTK_TOOLTIPS( pTooltips ), pParent, aLabel, NULL );

    GtkWidget *pIconImage = gtk_image_new();
    gtk_container_add( GTK_CONTAINER( pParent ), pIconImage );

    pVCLResMgr = CREATEVERSIONRESMGR( vcl );

    GdkPixbuf *pPixbuf = ResIdToPixbuf( SV_ICON_ID_OFFICE );
    gtk_image_set_from_pixbuf( GTK_IMAGE( pIconImage ), pPixbuf );
    g_object_unref( pPixbuf );

    GtkWidget *pMenu = gtk_menu_new();
    g_signal_connect (pMenu, "deactivate",
                      G_CALLBACK (menu_deactivate_cb), NULL);
    g_signal_connect( pParent, "button_press_event",
                      G_CALLBACK( display_menu_cb ), pMenu );
    gtk_container_add( GTK_CONTAINER( pTrayIcon ), pParent );

    // Show at idle to avoid artefacts at startup
    g_idle_add (show_at_idle, (gpointer) pTrayIcon);

    // disable shutdown
    pShutdownIcon->SetVeto( true );
    pShutdownIcon->addTerminateListener();

    g_signal_connect(GTK_WIDGET(pTrayIcon), "destroy",
            G_CALLBACK(exit_quickstarter_cb), NULL);
}

void SAL_DLLPUBLIC_EXPORT plugin_shutdown_sys_tray()
{
    ::SolarMutexGuard aGuard;
    if( !pTrayIcon )
        return;

    /* we have to set pTrayIcon to NULL now, because gtk_widget_destroy
     * causes calling exit_quickstarter_cb (which then calls this func.)
     * again -> crash.
     * As an alternative, we could deregister the "destroy" signal here,
     * but this is simpler .-)
     */
    GtkWidget* const pIcon = GTK_WIDGET( pTrayIcon );
    pTrayIcon = NULL;
    gtk_widget_destroy( pIcon );

    pExitMenuItem = NULL;
    pOpenMenuItem = NULL;
    pDisableMenuItem = NULL;
}

#endif // ENABLE_QUICKSTART_APPLET

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>
#include <gtest/gtest.h>
#include <alcommon-ng/common/common.hpp>
#include <alcommon-ng/tools/dataperftimer.hpp>
#include <alcommon-ng/exceptions/exceptions.hpp>
#include <boost/timer.hpp>
#include <string>

using namespace AL::Common;
using namespace AL::Messaging;

std::string gMasterAddress = "127.0.0.1:5555";
std::string gServerName = "server";
std::string gServerAddress = "127.0.0.1:5556";

static int gGlobalResult = 0;

void vfun0()                                                                                { gGlobalResult = 0; }
void vfun1(const int &p0)                                                                         { gGlobalResult = p0; }
void vfun2(const int &p0,const int &p1)                                                           { gGlobalResult = p0 + p1; }
void vfun3(const int &p0,const int &p1,const int &p2)                                             { gGlobalResult = p0 + p1 + p2; }
void vfun4(const int &p0,const int &p1,const int &p2,const int &p3)                               { gGlobalResult = p0 + p1 + p2 + p3; }
void vfun5(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4)                { gGlobalResult = p0 + p1 + p2 + p3 + p4; }
void vfun6(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4,const  int &p5) { gGlobalResult = p0 + p1 + p2 + p3 + p4 + p5; }

int fun0()                                                                                { return 0; }
int fun1(const int &p0)                                                                         { return p0; }
int fun2(const int &p0,const int &p1)                                                           { return p0 + p1; }
int fun3(const int &p0,const int &p1,const int &p2)                                             { return p0 + p1 + p2; }
int fun4(const int &p0,const int &p1,const int &p2,const int &p3)                               { return p0 + p1 + p2 + p3; }
int fun5(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4)                { return p0 + p1 + p2 + p3 + p4; }
int fun6(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4,const  int &p5) { return p0 + p1 + p2 + p3 + p4 + p5; }

struct Foo {
  void voidCall()                                          { return; }
  int intStringCall(const std::string &plouf)              { return plouf.size(); }

  int fun0()                                                                                { return 0; }
  int fun1(const int &p0)                                                                         { return p0; }
  int fun2(const int &p0,const int &p1)                                                           { return p0 + p1; }
  int fun3(const int &p0,const int &p1,const int &p2)                                             { return p0 + p1 + p2; }
  int fun4(const int &p0,const int &p1,const int &p2,const int &p3)                               { return p0 + p1 + p2 + p3; }
  int fun5(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4)                { return p0 + p1 + p2 + p3 + p4; }
  int fun6(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4,const  int &p5) { return p0 + p1 + p2 + p3 + p4 + p5; }

  void vfun0()                                                                                { gGlobalResult = 0; }
  void vfun1(const int &p0)                                                                         { gGlobalResult = p0; }
  void vfun2(const int &p0,const int &p1)                                                           { gGlobalResult = p0 + p1; }
  void vfun3(const int &p0,const int &p1,const int &p2)                                             { gGlobalResult = p0 + p1 + p2; }
  void vfun4(const int &p0,const int &p1,const int &p2,const int &p3)                               { gGlobalResult = p0 + p1 + p2 + p3; }
  void vfun5(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4)                { gGlobalResult = p0 + p1 + p2 + p3 + p4; }
  void vfun6(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4,const  int &p5) { gGlobalResult = p0 + p1 + p2 + p3 + p4 + p5; }
};

MasterNode master(gMasterAddress);
ServerNode server(gServerName, gServerAddress, gMasterAddress);
ClientNode client("client", gMasterAddress);

TEST(NodeSignatures, allFunctorsBindAndCall)
{
  server.addService("vfun0", &vfun0);
  server.addService("vfun1", &vfun1);
  server.addService("vfun2", &vfun2);
  server.addService("vfun3", &vfun3);
  server.addService("vfun4", &vfun4);
  server.addService("vfun5", &vfun5);
  server.addService("vfun6", &vfun6);

  server.addService("fun0", &fun0);
  server.addService("fun1", &fun1);
  server.addService("fun2", &fun2);
  server.addService("fun3", &fun3);
  server.addService("fun4", &fun4);
  server.addService("fun5", &fun5);
  server.addService("fun6", &fun6);

  Foo f;
  server.addService("foo.vfun0", &f, &Foo::vfun0);
  server.addService("foo.vfun1", &f, &Foo::vfun1);
  server.addService("foo.vfun2", &f, &Foo::vfun2);
  server.addService("foo.vfun3", &f, &Foo::vfun3);
  server.addService("foo.vfun4", &f, &Foo::vfun4);
  server.addService("foo.vfun5", &f, &Foo::vfun5);
  server.addService("foo.vfun6", &f, &Foo::vfun6);

  server.addService("foo.fun0", &f, &Foo::fun0);
  server.addService("foo.fun1", &f, &Foo::fun1);
  server.addService("foo.fun2", &f, &Foo::fun2);
  server.addService("foo.fun3", &f, &Foo::fun3);
  server.addService("foo.fun4", &f, &Foo::fun4);
  server.addService("foo.fun5", &f, &Foo::fun5);
  server.addService("foo.fun6", &f, &Foo::fun6);

  client.callVoid("vfun0");
  client.callVoid("vfun1", 1);
  client.callVoid("vfun2", 1, 2);
  client.callVoid("vfun3", 1, 2, 3);
  client.callVoid("vfun4", 1, 2, 3, 4);
  client.callVoid("vfun5", 1, 2, 3, 4, 5);
  client.callVoid("vfun6", 1, 2, 3, 4, 5, 6);

  int i0 = client.call<int>("fun0");
  int i1 = client.call<int>("fun1", 1);
  int i2 = client.call<int>("fun2", 1, 2);
  int i3 = client.call<int>("fun3", 1, 2, 3);
  int i4 = client.call<int>("fun4", 1, 2, 3, 4);
  int i5 = client.call<int>("fun5", 1, 2, 3, 4, 5);
  int i6 = client.call<int>("fun6", 1, 2, 3, 4, 5, 6);

  client.callVoid("foo.vfun0");
  client.callVoid("foo.vfun1", 1);
  client.callVoid("foo.vfun2", 1, 2);
  client.callVoid("foo.vfun3", 1, 2, 3);
  client.callVoid("foo.vfun4", 1, 2, 3, 4);
  client.callVoid("foo.vfun5", 1, 2, 3, 4, 5);
  client.callVoid("foo.vfun6", 1, 2, 3, 4, 5, 6);

  int fi0 = client.call<int>("foo.fun0");
  int fi1 = client.call<int>("foo.fun1", 1);
  int fi2 = client.call<int>("foo.fun2", 1, 2);
  int fi3 = client.call<int>("foo.fun3", 1, 2, 3);
  int fi4 = client.call<int>("foo.fun4", 1, 2, 3, 4);
  int fi5 = client.call<int>("foo.fun5", 1, 2, 3, 4, 5);
  int fi6 = client.call<int>("foo.fun6", 1, 2, 3, 4, 5, 6);
}

TEST(NodeSignatures, MethodOverloading)
{
  server.addService("overload.fun1", &fun1);
  server.addService("overload.fun1", &fun2);
  int r2 = client.call<int>("overload.fun1", 1, 2);
  ASSERT_EQ(3, r2);
  int r1 = client.call<int>("overload.fun1", 1);
  ASSERT_EQ(1, r1);
}

TEST(NodeSignatures, MultipleBind)
{
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
}

TEST(NodeSignatures, paramTypeChecking)
{
  server.addService("typechecking.fun1", &fun1);
  int r2 = client.call<int>("typechecking.fun1", 1);
  try {
    int r3 = client.call<int>("typechecking.fun1", std::string("anything"));
  } catch (const AL::Transport::ServiceNotFoundException& e) {
    std::cout << "ServiceNotFoundException:" << e.what() << std::endl;
  }
}

TEST(NodeSignatures, paramNumChecking)
{
  server.addService("paramnumchecking.fun1", &fun1);
  int r2 = client.call<int>("paramnumchecking.fun1", 1);
  try {
    int r3 = client.call<int>("paramnumchecking.fun1", 1, 2);
  } catch (const AL::Transport::ServiceNotFoundException& e) {
    std::cout << "ServiceNotFoundException:" << e.what() << std::endl;
  }
}

TEST(NodeSignatures, ReturnTypeChecking)
{
  server.addService("returntype.fun1", &fun1);
  //KABOOOM!
  int r2 = client.call<int>("returntype.fun1", 1);
  try {
    std::string s = client.call<std::string>("returntype.fun1", 1);
  } catch (const AL::Transport::ServiceNotFoundException& e) {
    std::cout << "ServiceNotFoundException:" << e.what() << std::endl;
  }
}<commit_msg>test_nodes clean up<commit_after>
#include <gtest/gtest.h>
#include <alcommon-ng/common/common.hpp>
#include <alcommon-ng/tools/dataperftimer.hpp>
#include <alcommon-ng/exceptions/exceptions.hpp>
#include <boost/timer.hpp>
#include <string>

using namespace AL::Common;
using namespace AL::Messaging;

static int gGlobalResult = 0;

void vfun0()                                                                                { gGlobalResult = 0; }
void vfun1(const int &p0)                                                                         { gGlobalResult = p0; }
void vfun2(const int &p0,const int &p1)                                                           { gGlobalResult = p0 + p1; }
void vfun3(const int &p0,const int &p1,const int &p2)                                             { gGlobalResult = p0 + p1 + p2; }
void vfun4(const int &p0,const int &p1,const int &p2,const int &p3)                               { gGlobalResult = p0 + p1 + p2 + p3; }
void vfun5(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4)                { gGlobalResult = p0 + p1 + p2 + p3 + p4; }
void vfun6(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4,const  int &p5) { gGlobalResult = p0 + p1 + p2 + p3 + p4 + p5; }

int fun0()                                                                                { return 0; }
int fun1(const int &p0)                                                                         { return p0; }
int fun2(const int &p0,const int &p1)                                                           { return p0 + p1; }
int fun3(const int &p0,const int &p1,const int &p2)                                             { return p0 + p1 + p2; }
int fun4(const int &p0,const int &p1,const int &p2,const int &p3)                               { return p0 + p1 + p2 + p3; }
int fun5(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4)                { return p0 + p1 + p2 + p3 + p4; }
int fun6(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4,const  int &p5) { return p0 + p1 + p2 + p3 + p4 + p5; }

struct Foo {
  void voidCall()                                          { return; }
  int intStringCall(const std::string &plouf)              { return plouf.size(); }

  int fun0()                                                                                { return 0; }
  int fun1(const int &p0)                                                                         { return p0; }
  int fun2(const int &p0,const int &p1)                                                           { return p0 + p1; }
  int fun3(const int &p0,const int &p1,const int &p2)                                             { return p0 + p1 + p2; }
  int fun4(const int &p0,const int &p1,const int &p2,const int &p3)                               { return p0 + p1 + p2 + p3; }
  int fun5(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4)                { return p0 + p1 + p2 + p3 + p4; }
  int fun6(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4,const  int &p5) { return p0 + p1 + p2 + p3 + p4 + p5; }

  void vfun0()                                                                                { gGlobalResult = 0; }
  void vfun1(const int &p0)                                                                         { gGlobalResult = p0; }
  void vfun2(const int &p0,const int &p1)                                                           { gGlobalResult = p0 + p1; }
  void vfun3(const int &p0,const int &p1,const int &p2)                                             { gGlobalResult = p0 + p1 + p2; }
  void vfun4(const int &p0,const int &p1,const int &p2,const int &p3)                               { gGlobalResult = p0 + p1 + p2 + p3; }
  void vfun5(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4)                { gGlobalResult = p0 + p1 + p2 + p3 + p4; }
  void vfun6(const int &p0,const int &p1,const int &p2,const int &p3,const  int &p4,const  int &p5) { gGlobalResult = p0 + p1 + p2 + p3 + p4 + p5; }
};

std::string gMasterAddress = "127.0.0.1:5555";
std::string gServerName = "server";
std::string gServerAddress = "127.0.0.1:5556";

MasterNode master(gMasterAddress);
ServerNode server(gServerName, gServerAddress, gMasterAddress);
ClientNode client("client", gMasterAddress);

TEST(NodeSignatures, allFunctorsBindAndCall)
{
  server.addService("vfun0", &vfun0);
  server.addService("vfun1", &vfun1);
  server.addService("vfun2", &vfun2);
  server.addService("vfun3", &vfun3);
  server.addService("vfun4", &vfun4);
  server.addService("vfun5", &vfun5);
  server.addService("vfun6", &vfun6);

  server.addService("fun0", &fun0);
  server.addService("fun1", &fun1);
  server.addService("fun2", &fun2);
  server.addService("fun3", &fun3);
  server.addService("fun4", &fun4);
  server.addService("fun5", &fun5);
  server.addService("fun6", &fun6);

  Foo f;
  server.addService("foo.vfun0", &f, &Foo::vfun0);
  server.addService("foo.vfun1", &f, &Foo::vfun1);
  server.addService("foo.vfun2", &f, &Foo::vfun2);
  server.addService("foo.vfun3", &f, &Foo::vfun3);
  server.addService("foo.vfun4", &f, &Foo::vfun4);
  server.addService("foo.vfun5", &f, &Foo::vfun5);
  server.addService("foo.vfun6", &f, &Foo::vfun6);

  server.addService("foo.fun0", &f, &Foo::fun0);
  server.addService("foo.fun1", &f, &Foo::fun1);
  server.addService("foo.fun2", &f, &Foo::fun2);
  server.addService("foo.fun3", &f, &Foo::fun3);
  server.addService("foo.fun4", &f, &Foo::fun4);
  server.addService("foo.fun5", &f, &Foo::fun5);
  server.addService("foo.fun6", &f, &Foo::fun6);

  client.callVoid("vfun0");
  client.callVoid("vfun1", 1);
  client.callVoid("vfun2", 1, 2);
  client.callVoid("vfun3", 1, 2, 3);
  client.callVoid("vfun4", 1, 2, 3, 4);
  client.callVoid("vfun5", 1, 2, 3, 4, 5);
  client.callVoid("vfun6", 1, 2, 3, 4, 5, 6);

  int i0 = client.call<int>("fun0");
  int i1 = client.call<int>("fun1", 1);
  int i2 = client.call<int>("fun2", 1, 2);
  int i3 = client.call<int>("fun3", 1, 2, 3);
  int i4 = client.call<int>("fun4", 1, 2, 3, 4);
  int i5 = client.call<int>("fun5", 1, 2, 3, 4, 5);
  int i6 = client.call<int>("fun6", 1, 2, 3, 4, 5, 6);

  client.callVoid("foo.vfun0");
  client.callVoid("foo.vfun1", 1);
  client.callVoid("foo.vfun2", 1, 2);
  client.callVoid("foo.vfun3", 1, 2, 3);
  client.callVoid("foo.vfun4", 1, 2, 3, 4);
  client.callVoid("foo.vfun5", 1, 2, 3, 4, 5);
  client.callVoid("foo.vfun6", 1, 2, 3, 4, 5, 6);

  int fi0 = client.call<int>("foo.fun0");
  int fi1 = client.call<int>("foo.fun1", 1);
  int fi2 = client.call<int>("foo.fun2", 1, 2);
  int fi3 = client.call<int>("foo.fun3", 1, 2, 3);
  int fi4 = client.call<int>("foo.fun4", 1, 2, 3, 4);
  int fi5 = client.call<int>("foo.fun5", 1, 2, 3, 4, 5);
  int fi6 = client.call<int>("foo.fun6", 1, 2, 3, 4, 5, 6);
}

TEST(NodeSignatures, MethodOverloading)
{
  server.addService("overload.fun1", &fun1);
  server.addService("overload.fun1", &fun2);
  int r2 = client.call<int>("overload.fun1", 1, 2);
  ASSERT_EQ(3, r2);
  int r1 = client.call<int>("overload.fun1", 1);
  ASSERT_EQ(1, r1);
}

TEST(NodeSignatures, MultipleBind)
{
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
  server.addService("multiple.fun1", &fun1);
}

TEST(NodeSignatures, paramTypeChecking)
{
  server.addService("typechecking.fun1", &fun1);
  int r2 = client.call<int>("typechecking.fun1", 1);
  try {
    int r3 = client.call<int>("typechecking.fun1", std::string("anything"));
  } catch (const AL::Transport::ServiceNotFoundException& e) {
    std::cout << "ServiceNotFoundException:" << e.what() << std::endl;
  }
}

TEST(NodeSignatures, paramNumChecking)
{
  server.addService("paramnumchecking.fun1", &fun1);
  int r2 = client.call<int>("paramnumchecking.fun1", 1);
  try {
    int r3 = client.call<int>("paramnumchecking.fun1", 1, 2);
  } catch (const AL::Transport::ServiceNotFoundException& e) {
    std::cout << "ServiceNotFoundException:" << e.what() << std::endl;
  }
}

TEST(NodeSignatures, ReturnTypeChecking)
{
  server.addService("returntype.fun1", &fun1);
  //KABOOOM!
  int r2 = client.call<int>("returntype.fun1", 1);
  try {
    std::string s = client.call<std::string>("returntype.fun1", 1);
  } catch (const AL::Transport::ServiceNotFoundException& e) {
    std::cout << "ServiceNotFoundException:" << e.what() << std::endl;
  }
}<|endoftext|>


<commit_before>#include "sevensegment.h"
#include <ostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <stdexcept>

namespace sevensegment {
	using digit = std::vector<std::string>;
	using digit_vector = std::vector<digit>;

	const digit_vector digits {
		{ " - ", "| |", "   ", "| |", " - " }, // 0
		{ "   ", "  |", "   ", "  |", "   " }, // 1
		{ " - ", "  |", " - ", "|  ", " - " }, // 2
		{ " - ", "  |", " - ", "  |", " - " }, // 3
		{ "   ", "| |", " - ", "  |", "   " }, // 4
		{ " - ", "|  ", " - ", "  |", " - " }, // 5
		{ " - ", "|  ", " - ", "| |", " - " }, // 6
		{ " - ", "  |", "   ", "  |", "   " }, // 7
		{ " - ", "| |", " - ", "| |", " - " }, // 8
		{ " - ", "| |", " - ", "  |", " - " }  // 9
	};
	const digit minus_sign
		{ "   ", "   ", " - ", "   ", "   " }; // -

	std::string stretchDigitLine(const std::string& line, const unsigned scale_factor) {
		std::string stretched_line(scale_factor+2, line[1]);
		stretched_line.front() = line[0];
		stretched_line.back() = line[2];
		return stretched_line;
	}

	digit_vector split_digits(const int i, digit_vector& vector) {
	    if(i >= 10)
	       split_digits(i / 10, vector);

	    vector.push_back(digits.at(i % 10));
	    return vector;
	}

	digit_vector split_digits(int i) {
		digit_vector vector {};
		if (i<0) {
			vector.push_back(minus_sign);
			i = -i;
		}

		return split_digits(i, vector);
	}

	std::string lineOfLargeDigits(const digit_vector& vector,
			const unsigned line_nr, const unsigned scale_factor){

		std::string line {};
		unsigned digit_nr { 0 };
		const auto number_of_digits = vector.size();

		for(digit d : vector){
			line.append(stretchDigitLine(d[line_nr], scale_factor));

			// between digits (not at the end)
			if (++digit_nr != number_of_digits)
				line.append(scale_factor/2, ' '); // letter spacing for readability
		}
		return line;
	}

	constexpr unsigned display_size { 8 };

	void printDigitSequence(const digit_vector vector,
			std::ostream& out, const unsigned scale_factor){

		if (scale_factor<1)
			throw std::range_error { "invalid scale" };
		if (vector.size() > display_size)
			throw std::overflow_error { "too many digits" };

		std::ostream_iterator<std::string> out_it(out, "\n");

		// iterate through lines, not digits
		// OPTIMIZE: transpose vector first to get more cache hits
		for(int line_nr { 0 }; line_nr < 5; ++line_nr) {
			auto count = (line_nr == 1 || line_nr == 3) ? scale_factor : 1;
			auto line = lineOfLargeDigits(vector, line_nr, scale_factor);
			std::fill_n(out_it, count, line);
		}
	}

	// Requested for the assignment. Used nowhere but in the tests.
	void printLargeDigit(const unsigned i, std::ostream& out, const unsigned scale_factor) {
		const auto d = digits.at(i);
		const digit_vector single_digit_vector { d };
		printDigitSequence(single_digit_vector, out, scale_factor);
	}

	void printLargeNumber(const int i, std::ostream& out, const unsigned scale_factor) {
		printDigitSequence(split_digits(i), out, scale_factor);
	}

	const digit_vector error {
		{ " - ", "|  ", " - ", "|  ", " - " }, // E
		{ "   ", "   ", " - ", "|  ", "   " }, // r
		{ "   ", "   ", " - ", "|  ", "   " }, // r
		{ "   ", "   ", " - ", "| |", " - " }, // o
		{ "   ", "   ", " - ", "|  ", "   " }, // r
	};

	void printLargeError(std::ostream& out, const unsigned scale_factor) {
		printDigitSequence(error, out, scale_factor);
	}
}
<commit_msg>add comments<commit_after>#include "sevensegment.h"
#include <ostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <stdexcept>

namespace sevensegment {
	using digit = std::vector<std::string>;
	using digit_vector = std::vector<digit>;

	const digit_vector digits {
		{ " - ", "| |", "   ", "| |", " - " }, // 0
		{ "   ", "  |", "   ", "  |", "   " }, // 1
		{ " - ", "  |", " - ", "|  ", " - " }, // 2
		{ " - ", "  |", " - ", "  |", " - " }, // 3
		{ "   ", "| |", " - ", "  |", "   " }, // 4
		{ " - ", "|  ", " - ", "  |", " - " }, // 5
		{ " - ", "|  ", " - ", "| |", " - " }, // 6
		{ " - ", "  |", "   ", "  |", "   " }, // 7
		{ " - ", "| |", " - ", "| |", " - " }, // 8
		{ " - ", "| |", " - ", "  |", " - " }  // 9
	};
	const digit minus_sign
		{ "   ", "   ", " - ", "   ", "   " }; // -

	std::string stretchDigitLine(const std::string& line, const unsigned scale_factor) {
		std::string stretched_line(scale_factor+2, line[1]); // stretch the center
		stretched_line.front() = line[0]; // fix first char
		stretched_line.back() = line[2]; // fix last char
		return stretched_line;
	}

	digit_vector split_digits(const int i, digit_vector& vector) {
	    if(i >= 10)
	       split_digits(i / 10, vector);

	    vector.push_back(digits.at(i % 10));
	    return vector;
	}

	digit_vector split_digits(int i) {
		digit_vector vector {};
		if (i<0) {
			vector.push_back(minus_sign);
			i = -i;
		}

		return split_digits(i, vector);
	}

	std::string lineOfLargeDigits(const digit_vector& vector,
			const unsigned line_nr, const unsigned scale_factor){

		std::string line {};
		unsigned digit_nr { 0 };
		const auto number_of_digits = vector.size();

		for(digit d : vector){
			line.append(stretchDigitLine(d[line_nr], scale_factor));

			// between digits (not at the end)
			if (++digit_nr != number_of_digits)
				line.append(scale_factor/2, ' '); // letter spacing for readability
		}
		return line;
	}

	constexpr unsigned display_size { 8 };

	void printDigitSequence(const digit_vector vector,
			std::ostream& out, const unsigned scale_factor){

		if (scale_factor<1)
			throw std::range_error { "invalid scale" };
		if (vector.size() > display_size)
			throw std::overflow_error { "too many digits" };

		std::ostream_iterator<std::string> out_it(out, "\n");

		// iterate through lines, not digits
		// OPTIMIZE: transpose vector first to get more cache hits
		for(int line_nr { 0 }; line_nr < 5; ++line_nr) {
			auto count = (line_nr == 1 || line_nr == 3) ? scale_factor : 1;
			auto line = lineOfLargeDigits(vector, line_nr, scale_factor);
			std::fill_n(out_it, count, line);
		}
	}

	// Requested for the assignment. Used nowhere but in the tests.
	void printLargeDigit(const unsigned i, std::ostream& out, const unsigned scale_factor) {
		const auto d = digits.at(i);
		const digit_vector single_digit_vector { d };
		printDigitSequence(single_digit_vector, out, scale_factor);
	}

	void printLargeNumber(const int i, std::ostream& out, const unsigned scale_factor) {
		printDigitSequence(split_digits(i), out, scale_factor);
	}

	const digit_vector error {
		{ " - ", "|  ", " - ", "|  ", " - " }, // E
		{ "   ", "   ", " - ", "|  ", "   " }, // r
		{ "   ", "   ", " - ", "|  ", "   " }, // r
		{ "   ", "   ", " - ", "| |", " - " }, // o
		{ "   ", "   ", " - ", "|  ", "   " }, // r
	};

	void printLargeError(std::ostream& out, const unsigned scale_factor) {
		printDigitSequence(error, out, scale_factor);
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

#include "test-context.h"

namespace {

class FileStream : public ots::OTSStream {
 public:
  explicit FileStream(std::string& filename)
      : file_(false), off_(0) {
    if (!filename.empty()) {
      stream_.open(filename.c_str(), std::ofstream::out | std::ofstream::binary);
      file_ = true;
    }
  }

  bool WriteRaw(const void *data, size_t length) {
    off_ += length;
    if (file_) {
      stream_.write(static_cast<const char*>(data), length);
      return stream_.good();
    }
    return true;
  }

  bool Seek(off_t position) {
    off_ = position;
    if (file_) {
      stream_.seekp(position);
      return stream_.good();
    }
    return true;
  }

  off_t Tell() const {
    return off_;
  }

 private:
  std::ofstream stream_;
  bool file_;
  off_t off_;
};

int Usage(const char *argv0) {
  std::fprintf(stderr, "Usage: %s font_file [dest_font_file] [index]\n", argv0);
  return 1;
}

}  // namespace

int main(int argc, char **argv) {
  std::string in_filename;
  std::string out_filename;
  int font_index = -1;
  bool verbose = false;
  bool version = false;

  for (int i = 1; i < argc; i++) {
    std::string arg(argv[i]);
    if (arg.at(0) == '-') {
      if (arg == "--version") {
        version = true;
      } else if (arg == "--verbose") {
        verbose = true;
      } else {
        std::cerr << "Unrecognized option: " << arg << std::endl;
        return 1;
      }
    } else if (in_filename.empty()) {
      in_filename = arg;
    } else if (out_filename.empty()) {
      out_filename = arg;
    } else if (font_index == -1) {
      font_index = std::strtol(arg.c_str(), NULL, 10);
    } else {
      std::cerr << "Unrecognized argument: " << arg << std::endl;
      return 1;
    }
  }

  if (version) {
    std::cout << PACKAGE_STRING << std::endl;
    return 0;
  }

  if (in_filename.empty()) {
    return Usage(argv[0]);
  }

  std::ifstream ifs(in_filename);
  if (!ifs.good()) {
    std::cerr << "Failed to open: " << in_filename << std::endl;
    return 1;
  }

  std::vector<uint8_t> in((std::istreambuf_iterator<char>(ifs)),
                          (std::istreambuf_iterator<char>()));

  ots::TestContext context(-1);

  FileStream output(out_filename);
  const bool result = context.Process(&output, in.data(), in.size(), font_index);

  if (verbose) {
    if (result)
      std::cout << "File sanitized successfully!\n";
    else
      std::cout << "Failed to sanitize file!\n";
  }

  return !result;
}
<commit_msg>Fix non C++11 build<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

#include "test-context.h"

namespace {

class FileStream : public ots::OTSStream {
 public:
  explicit FileStream(std::string& filename)
      : file_(false), off_(0) {
    if (!filename.empty()) {
      stream_.open(filename.c_str(), std::ofstream::out | std::ofstream::binary);
      file_ = true;
    }
  }

  bool WriteRaw(const void *data, size_t length) {
    off_ += length;
    if (file_) {
      stream_.write(static_cast<const char*>(data), length);
      return stream_.good();
    }
    return true;
  }

  bool Seek(off_t position) {
    off_ = position;
    if (file_) {
      stream_.seekp(position);
      return stream_.good();
    }
    return true;
  }

  off_t Tell() const {
    return off_;
  }

 private:
  std::ofstream stream_;
  bool file_;
  off_t off_;
};

int Usage(const char *argv0) {
  std::fprintf(stderr, "Usage: %s font_file [dest_font_file] [index]\n", argv0);
  return 1;
}

}  // namespace

int main(int argc, char **argv) {
  std::string in_filename;
  std::string out_filename;
  int font_index = -1;
  bool verbose = false;
  bool version = false;

  for (int i = 1; i < argc; i++) {
    std::string arg(argv[i]);
    if (arg.at(0) == '-') {
      if (arg == "--version") {
        version = true;
      } else if (arg == "--verbose") {
        verbose = true;
      } else {
        std::cerr << "Unrecognized option: " << arg << std::endl;
        return 1;
      }
    } else if (in_filename.empty()) {
      in_filename = arg;
    } else if (out_filename.empty()) {
      out_filename = arg;
    } else if (font_index == -1) {
      font_index = std::strtol(arg.c_str(), NULL, 10);
    } else {
      std::cerr << "Unrecognized argument: " << arg << std::endl;
      return 1;
    }
  }

  if (version) {
    std::cout << PACKAGE_STRING << std::endl;
    return 0;
  }

  if (in_filename.empty()) {
    return Usage(argv[0]);
  }

  std::ifstream ifs(in_filename.c_str());
  if (!ifs.good()) {
    std::cerr << "Failed to open: " << in_filename << std::endl;
    return 1;
  }

  std::vector<uint8_t> in((std::istreambuf_iterator<char>(ifs)),
                          (std::istreambuf_iterator<char>()));

  ots::TestContext context(-1);

  FileStream output(out_filename);
  const bool result = context.Process(&output, in.data(), in.size(), font_index);

  if (verbose) {
    if (result)
      std::cout << "File sanitized successfully!\n";
    else
      std::cout << "Failed to sanitize file!\n";
  }

  return !result;
}
<|endoftext|>