Go to the documentation of this file.00001
00002
00003
00004 #include "vgui_glut_impl.h"
00005 #include "vgui_glut_window.h"
00006 #include <vcl_cstdlib.h>
00007 #include <vcl_cassert.h>
00008 #include <vgui/vgui_glut.h>
00009
00010
00011
00012 vgui_glut_impl* vgui_glut_impl::instance()
00013 {
00014 static vgui_glut_impl instance_;
00015 return &instance_;
00016 }
00017
00018
00019
00020 int vgui_glut_impl::count = 0;
00021
00022 vgui_glut_impl::vgui_glut_impl()
00023 {
00024 ++count;
00025 assert(count == 1);
00026 }
00027
00028 vgui_glut_impl::~vgui_glut_impl()
00029 {
00030 --count;
00031 assert(count==0);
00032 }
00033
00034
00035
00036
00037 extern bool glut_was_initialized;
00038
00039 void vgui_glut_impl::init(int &argc, char **argv)
00040 {
00041 #ifdef DEBUG
00042 vcl_cerr << __FILE__ " init() :\n";
00043 for (unsigned i=0; i<argc; ++i)
00044 vcl_cerr << i << ' ' << (void*)argv[i] << ' ' << argv[i] << vcl_endl;
00045 #endif
00046 if( ! glut_was_initialized ) {
00047 glut_was_initialized = true;
00048 glutInit( &argc, argv );
00049 }
00050 }
00051
00052 vcl_string vgui_glut_impl::name() const
00053 {
00054 return "glut";
00055 }
00056
00057 vgui_window *vgui_glut_impl::produce_window(int width, int height,
00058 vgui_menu const &menubar,
00059 char const *title)
00060 {
00061 vgui_glut_window *win = new vgui_glut_window(title, width, height);
00062 win->menubar = menubar;
00063 return win;
00064 }
00065
00066 vgui_window *vgui_glut_impl::produce_window(int width, int height,
00067 char const *title)
00068 {
00069 return new vgui_glut_window(title, width, height);
00070 }
00071
00072
00073
00074 #include <vcl_cstring.h>
00075 #include <vcl_csetjmp.h>
00076 #include <vcl_iostream.h>
00077 #include <vgui/vgui_macro.h>
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 static int const internal_label = 1234;
00104 static vcl_jmp_buf internal_buf;
00105
00106
00107
00108 static
00109 void internal_longjmp_idler()
00110 {
00111 vcl_longjmp(internal_buf, internal_label);
00112 assert(false);
00113 }
00114
00115
00116
00117
00118 static
00119 void internal_run_till_idle()
00120 {
00121
00122 vcl_jmp_buf saved_buf;
00123 vcl_memcpy(&saved_buf, &internal_buf, sizeof internal_buf);
00124
00125
00126 int t = setjmp(internal_buf);
00127
00128
00129
00130
00131 if (t != 0) {
00132 assert(t == internal_label);
00133 vcl_memcpy(&internal_buf, &saved_buf, sizeof internal_buf);
00134 return;
00135 }
00136
00137
00138
00139 glutIdleFunc(internal_longjmp_idler);
00140
00141
00142
00143 glutMainLoop();
00144
00145
00146
00147 vgui_macro_warning << "internal error in internal_run_till_idle_wrapped()\n"
00148 << "please report to fsm\n";
00149 vcl_abort();
00150 }
00151
00152
00153
00154 #include <vcl_list.h>
00155 #include <vcl_utility.h>
00156 #include <vgui/vgui_command.h>
00157 #include "vgui_glut_adaptor.h"
00158
00159 static
00160 vcl_list<vcl_pair<void *, void *> > vgui_glut_impl_command_queue;
00161
00162 void vgui_glut_impl_queue_command(vgui_glut_adaptor *a, vgui_command *c)
00163 {
00164 c->ref();
00165 vgui_glut_impl_command_queue.push_back(vcl_pair<void *, void *>(a, c));
00166 }
00167
00168 static
00169 void vgui_glut_impl_process_command_queue()
00170 {
00171 while (! vgui_glut_impl_command_queue.empty()) {
00172
00173 vcl_pair<void *, void *> p = vgui_glut_impl_command_queue.front();
00174 vgui_glut_impl_command_queue.pop_front();
00175
00176
00177 vgui_glut_adaptor *a = static_cast<vgui_glut_adaptor *>(p.first );
00178 vgui_command *c = static_cast<vgui_command *>(p.second);
00179
00180
00181 int old_win = glutGetWindow();
00182 if (old_win != a->get_id())
00183 glutSetWindow(a->get_id());
00184
00185
00186 #ifdef DEBUG
00187 vcl_cerr << "cmnd = " << (void*)vgui_glut_impl_adaptor_menu_command << vcl_endl;
00188 #endif
00189 c->execute();
00190 #ifdef DEBUG
00191 vcl_cerr << "returned successfully\n";
00192 #endif
00193
00194
00195 c->unref();
00196
00197
00198 if (old_win != 0 && old_win != a->get_id())
00199 glutSetWindow(old_win);
00200 }
00201 }
00202
00203
00204
00205 static bool internal_quit_flag = false;
00206
00207 void vgui_glut_impl::run()
00208 {
00209 internal_quit_flag = false;
00210 while (! internal_quit_flag) {
00211 internal_run_till_idle();
00212 vgui_glut_impl_process_command_queue();
00213 }
00214 vgui_macro_warning << "end of vgui_glut_impl event loop\n";
00215 }
00216
00217
00218 void vgui_glut_impl_quit()
00219 {
00220 internal_quit_flag = true;
00221 }
00222
00223 void vgui_glut_impl::quit()
00224 {
00225 internal_quit_flag = true;
00226 }
00227
00228
00229 void vgui_glut_impl::run_one_event()
00230 {
00231 internal_run_till_idle();
00232 vgui_glut_impl_process_command_queue();
00233 }
00234
00235 void vgui_glut_impl::run_till_idle()
00236 {
00237 internal_run_till_idle();
00238 vgui_glut_impl_process_command_queue();
00239 }
00240
00241 void vgui_glut_impl::flush()
00242 {
00243 glFlush();
00244 run_till_idle();
00245 }
00246
00247