Reorganize the window code a bit
[lsnes.git] / generic / window.cpp
blob5c52e0b2b4b0e4aef96521100672e4d1e38964a6
1 #include "window.hpp"
2 #include "command.hpp"
3 #include <boost/iostreams/categories.hpp>
4 #include <boost/iostreams/copy.hpp>
5 #include <boost/iostreams/stream.hpp>
6 #include <boost/iostreams/stream_buffer.hpp>
7 #include <boost/iostreams/filter/symmetric.hpp>
8 #include <boost/iostreams/filter/zlib.hpp>
9 #include <boost/iostreams/filtering_stream.hpp>
10 #include <boost/iostreams/device/back_inserter.hpp>
12 namespace
14 function_ptr_command<> identify_key("show-plugins", "Show plugins in use",
15 "Syntax: show-plugins\nShows plugins in use.\n",
16 []() throw(std::bad_alloc, std::runtime_error) {
17 window::message(std::string("Graphics:\t") + graphics_plugin_name);
18 window::message(std::string("Sound:\t") + sound_plugin_name);
19 window::message(std::string("Joystick:\t") + joystick_plugin_name);
20 });
22 function_ptr_command<const std::string&> enable_sound("enable-sound", "Enable/Disable sound",
23 "Syntax: enable-sound <on/off>\nEnable or disable sound.\n",
24 [](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
25 std::string s = args;
26 if(s == "on" || s == "true" || s == "1" || s == "enable" || s == "enabled") {
27 if(!window::sound_initialized())
28 throw std::runtime_error("Sound failed to initialize and is disabled");
29 window::sound_enable(true);
30 } else if(s == "off" || s == "false" || s == "0" || s == "disable" || s == "disabled") {
31 if(window::sound_initialized())
32 window::sound_enable(false);
33 } else
34 throw std::runtime_error("Bad sound setting");
35 });
37 function_ptr_command<const std::string&> set_sound_device("set-sound-device", "Set sound device",
38 "Syntax: set-sound-device <id>\nSet sound device to <id>.\n",
39 [](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
40 if(!window::sound_initialized())
41 throw std::runtime_error("Sound failed to initialize and is disabled");
42 window::set_sound_device(args);
43 });
45 function_ptr_command<> get_sound_devices("show-sound-devices", "Show sound devices",
46 "Syntax: show-sound-devices\nShow listing of available sound devices\n",
47 []() throw(std::bad_alloc, std::runtime_error) {
48 if(!window::sound_initialized())
49 throw std::runtime_error("Sound failed to initialize and is disabled");
50 auto r = window::get_sound_devices();
51 auto s = window::get_current_sound_device();
52 std::string dname = "unknown";
53 if(r.count(s))
54 dname = r[s];
55 window::out() << "Detected " << r.size() << " sound output devices."
56 << std::endl;
57 for(auto i : r)
58 window::out() << "Audio device " << i.first << ": " << i.second << std::endl;
59 window::out() << "Currently using device " << window::get_current_sound_device() << " ("
60 << dname << ")" << std::endl;
61 });
63 function_ptr_command<> get_sound_status("show-sound-status", "Show sound status",
64 "Syntax: show-sound-status\nShow current sound status\n",
65 []() throw(std::bad_alloc, std::runtime_error) {
66 window::out() << "Sound plugin: " << sound_plugin_name << std::endl;
67 if(!window::sound_initialized())
68 window::out() << "Sound initialization failed, sound disabled" << std::endl;
69 else {
70 auto r = window::get_sound_devices();
71 auto s = window::get_current_sound_device();
72 std::string dname = "unknown";
73 if(r.count(s))
74 dname = r[s];
75 window::out() << "Current sound device " << s << " (" << dname << ")" << std::endl;
77 });
79 std::map<std::string, std::string> emustatus;
81 class window_output
83 public:
84 typedef char char_type;
85 typedef boost::iostreams::sink_tag category;
86 window_output(window* win)
90 void close()
94 std::streamsize write(const char* s, std::streamsize n)
96 size_t oldsize = stream.size();
97 stream.resize(oldsize + n);
98 memcpy(&stream[oldsize], s, n);
99 while(true) {
100 size_t lf = stream.size();
101 for(size_t i = 0; i < stream.size(); i++)
102 if(stream[i] == '\n') {
103 lf = i;
104 break;
106 if(lf == stream.size())
107 break;
108 std::string foo(stream.begin(), stream.begin() + lf);
109 window::message(foo);
110 if(lf + 1 < stream.size())
111 memmove(&stream[0], &stream[lf + 1], stream.size() - lf - 1);
112 stream.resize(stream.size() - lf - 1);
114 return n;
116 protected:
117 std::vector<char> stream;
120 window_callback* wcb = NULL;
123 std::map<std::string, std::string>& window::get_emustatus() throw()
125 return emustatus;
128 void window::init()
130 graphics_init();
131 sound_init();
132 joystick_init();
135 void window::quit()
137 joystick_quit();
138 sound_quit();
139 graphics_quit();
142 std::ostream& window::out() throw(std::bad_alloc)
144 static std::ostream* cached = NULL;
145 window* win = NULL;
146 if(!cached)
147 cached = new boost::iostreams::stream<window_output>(win);
148 return *cached;
151 window_callback::~window_callback() throw()
155 void window_callback::on_close() throw()
159 void window_callback::on_click(int32_t x, int32_t y, uint32_t buttonmask) throw()
163 void window_callback::do_close() throw()
165 if(wcb)
166 wcb->on_close();
169 void window_callback::do_click(int32_t x, int32_t y, uint32_t buttonmask) throw()
171 if(wcb)
172 wcb->on_click(x, y, buttonmask);
175 void window_callback::set_callback_handler(window_callback& cb) throw()
177 wcb = &cb;