Lots of #include <iostream>s for Arch.
[dcpomatic.git] / src / tools / dcpomatic_server.cc
1 /*
2     Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "wx/wx_util.h"
21 #include "lib/util.h"
22 #include "lib/server.h"
23 #include "lib/config.h"
24 #include "lib/log.h"
25 #include <wx/taskbar.h>
26 #include <wx/icon.h>
27 #include <boost/thread.hpp>
28 #include <iostream>
29
30 using std::cout;
31 using std::string;
32 using std::exception;
33 using boost::shared_ptr;
34 using boost::thread;
35 using boost::bind;
36
37 enum {
38         ID_status = 1,
39         ID_quit,
40         ID_timer
41 };
42
43 class MemoryLog : public Log
44 {
45 public:
46
47         string get () const {
48                 boost::mutex::scoped_lock (_mutex);
49                 return _log;
50         }
51
52         string head_and_tail (int amount = 1024) const {
53                 if (int (_log.size ()) < (2 * amount)) {
54                         return _log;
55                 }
56
57                 return _log.substr (0, amount) + _log.substr (_log.size() - amount - 1, amount);
58         }
59
60 private:
61         void do_log (string m)
62         {
63                 _log = m;
64         }
65
66         string _log;
67 };
68
69 static shared_ptr<MemoryLog> memory_log (new MemoryLog);
70
71 class StatusDialog : public wxDialog
72 {
73 public:
74         StatusDialog ()
75                 : wxDialog (0, wxID_ANY, _("DCP-o-matic encode server"), wxDefaultPosition, wxSize (600, 80), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
76                 , _timer (this, ID_timer)
77         {
78                 _sizer = new wxFlexGridSizer (1, 6, 6);
79                 _sizer->AddGrowableCol (0, 1);
80
81                 _text = new wxTextCtrl (this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
82                 _sizer->Add (_text, 1, wxEXPAND);
83
84                 SetSizer (_sizer);
85                 _sizer->Layout ();
86
87                 Bind (wxEVT_TIMER, boost::bind (&StatusDialog::update, this), ID_timer);
88                 _timer.Start (1000);
89         }
90
91 private:
92         void update ()
93         {
94                 _text->ChangeValue (std_to_wx (memory_log->get ()));
95                 _sizer->Layout ();
96         }
97
98         wxFlexGridSizer* _sizer;
99         wxTextCtrl* _text;
100         wxTimer _timer;
101 };
102
103 class TaskBarIcon : public wxTaskBarIcon
104 {
105 public:
106         TaskBarIcon ()
107         {
108 #ifdef __WXMSW__
109                 wxIcon icon (std_to_wx ("taskbar_icon"));
110 #endif
111 #ifdef __WXGTK__
112                 wxInitAllImageHandlers();
113                 wxBitmap bitmap (wxString::Format (wxT ("%s/taskbar_icon.png"), LINUX_SHARE_PREFIX), wxBITMAP_TYPE_PNG);
114                 wxIcon icon;
115                 icon.CopyFromBitmap (bitmap);
116 #endif
117 #ifndef __WXOSX__
118                 /* XXX: fix this for OS X */
119                 SetIcon (icon, std_to_wx ("DCP-o-matic encode server"));
120 #endif
121
122                 Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&TaskBarIcon::status, this), ID_status);
123                 Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&TaskBarIcon::quit, this), ID_quit);
124         }
125
126         wxMenu* CreatePopupMenu ()
127         {
128                 wxMenu* menu = new wxMenu;
129                 menu->Append (ID_status, std_to_wx ("Status..."));
130                 menu->Append (ID_quit, std_to_wx ("Quit"));
131                 return menu;
132         }
133
134 private:
135         void status ()
136         {
137                 StatusDialog* d = new StatusDialog;
138                 d->Show ();
139         }
140
141         void quit ()
142         {
143                 wxTheApp->ExitMainLoop ();
144         }
145 };
146
147 class App : public wxApp, public ExceptionStore
148 {
149 public:
150         App ()
151                 : wxApp ()
152                 , _thread (0)
153                 , _icon (0)
154         {}
155
156 private:
157
158         bool OnInit ()
159         {
160                 if (!wxApp::OnInit ()) {
161                         return false;
162                 }
163
164                 dcpomatic_setup_path_encoding ();
165                 dcpomatic_setup ();
166
167                 _icon = new TaskBarIcon;
168                 _thread = new thread (bind (&App::main_thread, this));
169
170                 Bind (wxEVT_TIMER, boost::bind (&App::check, this));
171                 _timer.reset (new wxTimer (this));
172                 _timer->Start (1000);
173
174                 return true;
175         }
176
177         int OnExit ()
178         {
179                 delete _icon;
180                 return wxApp::OnExit ();
181         }
182
183         void main_thread ()
184         try {
185                 Server server (memory_log, false);
186                 server.run (Config::instance()->num_local_encoding_threads ());
187         } catch (...) {
188                 store_current ();
189         }
190
191         void check ()
192         {
193                 try {
194                         rethrow ();
195                 } catch (exception& e) {
196                         error_dialog (0, std_to_wx (e.what ()));
197                         wxTheApp->ExitMainLoop ();
198                 } catch (...) {
199                         error_dialog (0, _("An unknown error has occurred with the DCP-o-matic server."));
200                         wxTheApp->ExitMainLoop ();
201                 }
202         }
203
204         boost::thread* _thread;
205         TaskBarIcon* _icon;
206         shared_ptr<wxTimer> _timer;
207 };
208
209 IMPLEMENT_APP (App)