00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "graphicsWindow.h"
00016 #include "graphicsPipe.h"
00017 #include "config_display.h"
00018 #include "mouseButton.h"
00019 #include "keyboardButton.h"
00020 #include "lightMutexHolder.h"
00021 #include "lightReMutexHolder.h"
00022 #include "throw_event.h"
00023 #include "string_utils.h"
00024
00025 TypeHandle GraphicsWindow::_type_handle;
00026
00027
00028
00029
00030
00031
00032
00033
00034 GraphicsWindow::
00035 GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
00036 const string &name,
00037 const FrameBufferProperties &fb_prop,
00038 const WindowProperties &win_prop,
00039 int flags,
00040 GraphicsStateGuardian *gsg,
00041 GraphicsOutput *host) :
00042 GraphicsOutput(engine, pipe, name, fb_prop, win_prop, flags, gsg, host),
00043 _input_lock("GraphicsWindow::_input_lock"),
00044 _properties_lock("GraphicsWindow::_properties_lock")
00045 {
00046 #ifdef DO_MEMORY_USAGE
00047 MemoryUsage::update_type(this, this);
00048 #endif
00049
00050 if (display_cat.is_debug()) {
00051 display_cat.debug()
00052 << "Creating new window " << get_name() << "\n";
00053 }
00054
00055 _red_blue_stereo = red_blue_stereo && !fb_prop.is_stereo();
00056 if (_red_blue_stereo) {
00057 _left_eye_color_mask = parse_color_mask(red_blue_stereo_colors.get_word(0)); _right_eye_color_mask = parse_color_mask(red_blue_stereo_colors.get_word(1));
00058 }
00059
00060 _properties.set_open(false);
00061 _properties.set_undecorated(false);
00062 _properties.set_fullscreen(false);
00063 _properties.set_minimized(false);
00064 _properties.set_cursor_hidden(false);
00065
00066 request_properties(WindowProperties::get_default());
00067 request_properties(win_prop);
00068
00069 _window_event = "window-event";
00070 set_pixel_zoom(pixel_zoom);
00071 }
00072
00073
00074
00075
00076
00077
00078 GraphicsWindow::
00079 ~GraphicsWindow() {
00080 }
00081
00082
00083
00084
00085
00086
00087 const WindowProperties GraphicsWindow::
00088 get_properties() const {
00089 WindowProperties result;
00090 {
00091 LightReMutexHolder holder(_properties_lock);
00092 result = _properties;
00093 }
00094 return result;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 const WindowProperties GraphicsWindow::
00106 get_requested_properties() const {
00107 WindowProperties result;
00108 {
00109 LightReMutexHolder holder(_properties_lock);
00110 result = _requested_properties;
00111 }
00112 return result;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 void GraphicsWindow::
00122 clear_rejected_properties() {
00123 LightReMutexHolder holder(_properties_lock);
00124 _rejected_properties.clear();
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 WindowProperties GraphicsWindow::
00137 get_rejected_properties() const {
00138 WindowProperties result;
00139 {
00140 LightReMutexHolder holder(_properties_lock);
00141 result = _rejected_properties;
00142 }
00143 return result;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 void GraphicsWindow::
00158 request_properties(const WindowProperties &requested_properties) {
00159 LightReMutexHolder holder(_properties_lock);
00160 _requested_properties.add_properties(requested_properties);
00161
00162 if (!_has_size && _requested_properties.has_size()) {
00163
00164
00165
00166
00167 _x_size = _requested_properties.get_x_size();
00168 _y_size = _requested_properties.get_y_size();
00169
00170
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 bool GraphicsWindow::
00181 is_active() const {
00182
00183 return _active && _properties.get_open() && !_properties.get_minimized();
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 void GraphicsWindow::
00199 set_window_event(const string &window_event) {
00200 LightReMutexHolder holder(_properties_lock);
00201 _window_event = window_event;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211 string GraphicsWindow::
00212 get_window_event() const {
00213 string result;
00214 LightReMutexHolder holder(_properties_lock);
00215 result = _window_event;
00216 return result;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 void GraphicsWindow::
00244 set_close_request_event(const string &close_request_event) {
00245 LightReMutexHolder holder(_properties_lock);
00246 _close_request_event = close_request_event;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 string GraphicsWindow::
00259 get_close_request_event() const {
00260 string result;
00261 LightReMutexHolder holder(_properties_lock);
00262 result = _close_request_event;
00263 return result;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 int GraphicsWindow::
00277 get_num_input_devices() const {
00278 int result;
00279 {
00280 LightMutexHolder holder(_input_lock);
00281 result = _input_devices.size();
00282 }
00283 return result;
00284 }
00285
00286
00287
00288
00289
00290
00291 string GraphicsWindow::
00292 get_input_device_name(int device) const {
00293 string result;
00294 {
00295 LightMutexHolder holder(_input_lock);
00296 nassertr(device >= 0 && device < (int)_input_devices.size(), "");
00297 result = _input_devices[device].get_name();
00298 }
00299 return result;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309 bool GraphicsWindow::
00310 has_pointer(int device) const {
00311 bool result;
00312 {
00313 LightMutexHolder holder(_input_lock);
00314 nassertr(device >= 0 && device < (int)_input_devices.size(), false);
00315 result = _input_devices[device].has_pointer();
00316 }
00317 return result;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 bool GraphicsWindow::
00327 has_keyboard(int device) const {
00328 bool result;
00329 {
00330 LightMutexHolder holder(_input_lock);
00331 nassertr(device >= 0 && device < (int)_input_devices.size(), false);
00332 result = _input_devices[device].has_keyboard();
00333 }
00334 return result;
00335 }
00336
00337
00338
00339
00340
00341
00342 void GraphicsWindow::
00343 enable_pointer_events(int device) {
00344 LightMutexHolder holder(_input_lock);
00345 nassertv(device >= 0 && device < (int)_input_devices.size());
00346 _input_devices[device].enable_pointer_events();
00347 }
00348
00349
00350
00351
00352
00353
00354 void GraphicsWindow::
00355 disable_pointer_events(int device) {
00356 LightMutexHolder holder(_input_lock);
00357 nassertv(device >= 0 && device < (int)_input_devices.size());
00358 _input_devices[device].disable_pointer_events();
00359 }
00360
00361
00362
00363
00364
00365
00366 void GraphicsWindow::
00367 enable_pointer_mode(int device, double speed) {
00368 LightMutexHolder holder(_input_lock);
00369 nassertv(device >= 0 && device < (int)_input_devices.size());
00370 _input_devices[device].enable_pointer_mode(speed);
00371 }
00372
00373
00374
00375
00376
00377
00378 void GraphicsWindow::
00379 disable_pointer_mode(int device) {
00380 LightMutexHolder holder(_input_lock);
00381 nassertv(device >= 0 && device < (int)_input_devices.size());
00382 _input_devices[device].disable_pointer_mode();
00383 }
00384
00385
00386
00387
00388
00389
00390
00391 MouseData GraphicsWindow::
00392 get_pointer(int device) const {
00393 MouseData result;
00394 {
00395 LightMutexHolder holder(_input_lock);
00396 nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData());
00397 result = _input_devices[device].get_pointer();
00398 }
00399 return result;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 bool GraphicsWindow::
00413 move_pointer(int, int, int) {
00414 return false;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423 void GraphicsWindow::
00424 close_ime() {
00425 return;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 bool GraphicsWindow::
00438 has_button_event(int device) const {
00439 bool result;
00440 {
00441 LightMutexHolder holder(_input_lock);
00442 nassertr(device >= 0 && device < (int)_input_devices.size(), false);
00443 result = _input_devices[device].has_button_event();
00444 }
00445 return result;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454 ButtonEvent GraphicsWindow::
00455 get_button_event(int device) {
00456 ButtonEvent result;
00457 {
00458 LightMutexHolder holder(_input_lock);
00459 nassertr(device >= 0 && device < (int)_input_devices.size(), ButtonEvent());
00460 nassertr(_input_devices[device].has_button_event(), ButtonEvent());
00461 result = _input_devices[device].get_button_event();
00462 }
00463 return result;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 bool GraphicsWindow::
00475 has_pointer_event(int device) const {
00476 bool result;
00477 {
00478 LightMutexHolder holder(_input_lock);
00479 nassertr(device >= 0 && device < (int)_input_devices.size(), false);
00480 result = _input_devices[device].has_pointer_event();
00481 }
00482 return result;
00483 }
00484
00485
00486
00487
00488
00489
00490
00491 PT(PointerEventList) GraphicsWindow::
00492 get_pointer_events(int device) {
00493 PT(PointerEventList) result;
00494 {
00495 LightMutexHolder holder(_input_lock);
00496 nassertr(device >= 0 && device < (int)_input_devices.size(), NULL);
00497 nassertr(_input_devices[device].has_pointer_event(), NULL);
00498 result = _input_devices[device].get_pointer_events();
00499 }
00500 return result;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 int GraphicsWindow::
00526 verify_window_sizes(int numsizes, int *dimen) {
00527 return numsizes;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 void GraphicsWindow::
00539 request_open() {
00540 WindowProperties open_properties;
00541 open_properties.set_open(true);
00542 request_properties(open_properties);
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 void GraphicsWindow::
00555 request_close() {
00556 WindowProperties close_properties;
00557 close_properties.set_open(false);
00558 request_properties(close_properties);
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568 void GraphicsWindow::
00569 set_close_now() {
00570 WindowProperties close_properties;
00571 close_properties.set_open(false);
00572 set_properties_now(close_properties);
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 void GraphicsWindow::
00586 process_events() {
00587 if (_requested_properties.is_any_specified()) {
00588
00589
00590
00591
00592 WindowProperties properties;
00593 {
00594 LightReMutexHolder holder(_properties_lock);
00595 properties = _requested_properties;
00596 _requested_properties.clear();
00597
00598 set_properties_now(properties);
00599 if (properties.is_any_specified()) {
00600 display_cat.info()
00601 << "Unable to set window properties: " << properties << "\n";
00602 _rejected_properties.add_properties(properties);
00603 }
00604 }
00605 }
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 void GraphicsWindow::
00628 set_properties_now(WindowProperties &properties) {
00629 if (properties.has_open() &&
00630 properties.get_open() != _properties.get_open()) {
00631
00632
00633
00634 _properties.add_properties(properties);
00635 properties.clear();
00636
00637 if (_properties.get_open()) {
00638 if (open_window()) {
00639
00640
00641 _is_valid = true;
00642 set_size_and_recalc(_properties.get_x_size(),
00643 _properties.get_y_size());
00644 } else {
00645
00646
00647
00648 _rejected_properties.add_properties(_properties);
00649
00650
00651 _properties.set_open(false);
00652 _is_valid = false;
00653 }
00654
00655 } else {
00656
00657
00658
00659 close_window();
00660 _is_valid = false;
00661 }
00662 return;
00663 }
00664
00665 if (!_properties.get_open()) {
00666
00667
00668 _properties.add_properties(properties);
00669 properties.clear();
00670 return;
00671 }
00672
00673 properties.clear_open();
00674
00675
00676
00677
00678 if (properties.has_size() || properties.has_origin()) {
00679
00680 WindowProperties reshape_props;
00681 if (properties.has_size()) {
00682 reshape_props.set_size(properties.get_x_size(), properties.get_y_size());
00683 } else {
00684 reshape_props.set_size(_properties.get_x_size(), _properties.get_y_size());
00685 }
00686
00687 if (properties.has_origin() && !is_fullscreen()) {
00688 reshape_props.set_origin(properties.get_x_origin(), properties.get_y_origin());
00689 } else if (_properties.has_origin()) {
00690 reshape_props.set_origin(_properties.get_x_origin(), _properties.get_y_origin());
00691 }
00692
00693 bool has_origin = reshape_props.has_origin();
00694 int x_origin = 0, y_origin = 0;
00695 if (has_origin) {
00696 x_origin = reshape_props.get_x_origin();
00697 y_origin = reshape_props.get_y_origin();
00698 }
00699
00700 if (reshape_props.get_x_size() != _properties.get_x_size() ||
00701 reshape_props.get_y_size() != _properties.get_y_size() ||
00702 (has_origin && (x_origin != _properties.get_x_origin() ||
00703 y_origin != _properties.get_y_origin()))) {
00704 if (do_reshape_request(x_origin, y_origin, has_origin,
00705 reshape_props.get_x_size(),
00706 reshape_props.get_y_size())) {
00707 properties.clear_size();
00708 properties.clear_origin();
00709 }
00710 } else {
00711 properties.clear_size();
00712 properties.clear_origin();
00713 }
00714 }
00715
00716 if (properties.has_fullscreen() &&
00717 properties.get_fullscreen() == _properties.get_fullscreen()) {
00718
00719 properties.clear_fullscreen();
00720 }
00721 if (properties.has_mouse_mode() ) {
00722
00723 if (properties.get_mouse_mode() == _properties.get_mouse_mode()) {
00724 properties.clear_mouse_mode();
00725 }
00726 else {
00727 if(properties.get_mouse_mode() == WindowProperties::M_absolute) {
00728 _properties.set_mouse_mode(WindowProperties::M_absolute);
00729 mouse_mode_absolute();
00730 properties.clear_mouse_mode();
00731 }
00732 else
00733 {
00734 _properties.set_mouse_mode(WindowProperties::M_relative);
00735 mouse_mode_relative();
00736 properties.clear_mouse_mode();
00737 }
00738 }
00739 }
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 void GraphicsWindow::
00749 close_window() {
00750 display_cat.info()
00751 << "Closing " << get_type() << "\n";
00752
00753
00754 if (_window_handle != (WindowHandle *)NULL &&
00755 _parent_window_handle != (WindowHandle *)NULL) {
00756 _parent_window_handle->detach_child(_window_handle);
00757 }
00758
00759 _window_handle = NULL;
00760 _parent_window_handle = NULL;
00761 _is_valid = false;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771 bool GraphicsWindow::
00772 open_window() {
00773 return false;
00774 }
00775
00776
00777
00778
00779
00780
00781
00782 void GraphicsWindow::
00783 reset_window(bool swapchain) {
00784 display_cat.info()
00785 << "Resetting " << get_type() << "\n";
00786 }
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 bool GraphicsWindow::
00798 do_reshape_request(int x_origin, int y_origin, bool has_origin,
00799 int x_size, int y_size) {
00800 return false;
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 void GraphicsWindow::
00812 system_changed_properties(const WindowProperties &properties) {
00813 if (display_cat.is_debug()) {
00814 display_cat.debug()
00815 << "system_changed_properties(" << properties << ")\n";
00816 }
00817
00818 LightReMutexHolder holder(_properties_lock);
00819
00820 if (properties.has_size()) {
00821 system_changed_size(properties.get_x_size(), properties.get_y_size());
00822 }
00823
00824 WindowProperties old_properties = _properties;
00825 _properties.add_properties(properties);
00826 if (_properties != old_properties) {
00827 throw_event(_window_event, this);
00828 }
00829 }
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 void GraphicsWindow::
00840 system_changed_size(int x_size, int y_size) {
00841 if (display_cat.is_debug()) {
00842 display_cat.debug()
00843 << "system_changed_size(" << x_size << ", " << y_size << ")\n";
00844 }
00845
00846 if (!_properties.has_size() || (x_size != _properties.get_x_size() ||
00847 y_size != _properties.get_y_size())) {
00848 set_size_and_recalc(x_size, y_size);
00849 }
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861 unsigned int GraphicsWindow::
00862 parse_color_mask(const string &word) {
00863 unsigned int result = 0;
00864 vector_string components;
00865 tokenize(word, components, "|");
00866
00867 vector_string::const_iterator ci;
00868 for (ci = components.begin(); ci != components.end(); ++ci) {
00869 string w = downcase(*ci);
00870 if (w == "red" || w == "r") {
00871 result |= 0x001;
00872
00873 } else if (w == "green" || w == "g") {
00874 result |= 0x002;
00875
00876 } else if (w == "blue" || w == "b") {
00877 result |= 0x004;
00878
00879 } else if (w == "yellow" || w == "y") {
00880 result |= 0x003;
00881
00882 } else if (w == "magenta" || w == "m") {
00883 result |= 0x005;
00884
00885 } else if (w == "cyan" || w == "c") {
00886 result |= 0x006;
00887
00888 } else if (w == "alpha" || w == "a") {
00889 result |= 0x008;
00890
00891 } else if (w == "off") {
00892
00893 } else {
00894 display_cat.warning()
00895 << "Invalid color in red-blue-stereo-colors: " << (*ci) << "\n";
00896 }
00897 }
00898
00899 return result;
00900 }
00901
00902
00903
00904
00905
00906
00907
00908 void GraphicsWindow::
00909 mouse_mode_relative() {
00910
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920 void GraphicsWindow::
00921 mouse_mode_absolute() {
00922
00923 }