00001 // Filename: basicGtkWindow.cxx 00002 // Created by: drose (14Jul00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "basicGtkWindow.h" 00020 #include "gtkBase.h" 00021 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: BasicGtkWindow::Constructor 00025 // Access: Public 00026 // Description: The free_store parameter should be true if the window 00027 // object has been allocated from the free store (using 00028 // new) and can be safely deleted using delete when the 00029 // window is destroyed by the user, or false if this is 00030 // not the case. 00031 //////////////////////////////////////////////////////////////////// 00032 BasicGtkWindow:: 00033 BasicGtkWindow(bool free_store) : _free_store(free_store) { 00034 _destroyed = false; 00035 _state = S_virgin; 00036 } 00037 00038 //////////////////////////////////////////////////////////////////// 00039 // Function: BasicGtkWindow::Destructor 00040 // Access: Public 00041 // Description: 00042 //////////////////////////////////////////////////////////////////// 00043 BasicGtkWindow:: 00044 ~BasicGtkWindow() { 00045 destruct(); 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: BasicGtkWindow::setup 00050 // Access: Public 00051 // Description: Call this after initializing the window. 00052 //////////////////////////////////////////////////////////////////// 00053 void BasicGtkWindow:: 00054 setup() { 00055 _state = S_setup; 00056 _destroy_connection = 00057 destroy.connect(slot(this, &BasicGtkWindow::window_destroyed)); 00058 show(); 00059 00060 // Calling show() sets in motion some X events that must flow 00061 // completely through the queue before we can safely hide() the 00062 // thing again. To measure when this has happened, we'll drop our 00063 // own event into the queue. When this event makes it through the 00064 // queue, we'll assume all relevant X events have also, and it will 00065 // be safe to hide the window. 00066 Gtk::Main::idle.connect(slot(this, &BasicGtkWindow::idle_event)); 00067 } 00068 00069 //////////////////////////////////////////////////////////////////// 00070 // Function: BasicGtkWindow::destruct 00071 // Access: Public, Virtual 00072 // Description: Call this to remove the window, etc. It's not tied 00073 // directly to the real destructor because that seems to 00074 // just lead to trouble. This returns true if it 00075 // actually destructed, or false if it had already 00076 // destructed previously and did nothing this time. 00077 //////////////////////////////////////////////////////////////////// 00078 bool BasicGtkWindow:: 00079 destruct() { 00080 if (_state != S_gone) { 00081 // We must hide the window before we destruct, or it won't disappear 00082 // from the screen. Strange. But we also don't want to try to hide 00083 // the window if we're destructing because of a window_destroyed 00084 // event, so we check our little flag. 00085 if (!_destroyed && _state != S_virgin) { 00086 // Now, in case the window was never completely shown, we must 00087 // wait for that to happen before we can hide it. 00088 while (!_destroyed && _state == S_setup) { 00089 GtkBase::_gtk->iteration(); 00090 } 00091 00092 if (!_destroyed) { 00093 hide(); 00094 } 00095 } 00096 _state = S_gone; 00097 return true; 00098 } 00099 00100 return false; 00101 } 00102 00103 //////////////////////////////////////////////////////////////////// 00104 // Function: BasicGtkWindow::delete_self 00105 // Access: Protected 00106 // Description: 00107 //////////////////////////////////////////////////////////////////// 00108 void BasicGtkWindow:: 00109 delete_self() { 00110 destruct(); 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: BasicGtkWindow::window_destroyed 00115 // Access: Private 00116 // Description: 00117 //////////////////////////////////////////////////////////////////// 00118 void BasicGtkWindow:: 00119 window_destroyed() { 00120 _destroyed = true; 00121 destruct(); 00122 00123 // We should probably also delete the pointer here. But maybe not. 00124 // Gtk-- is very mysterious about this, so we'll just let it maybe 00125 // leak. 00126 } 00127 00128 //////////////////////////////////////////////////////////////////// 00129 // Function: BasicGtkWindow::idle_event 00130 // Access: Private 00131 // Description: 00132 //////////////////////////////////////////////////////////////////// 00133 gint BasicGtkWindow:: 00134 idle_event() { 00135 // Now, we're finally a bona fide window with all rights thereunto 00136 // appertaining. 00137 _state = S_ready; 00138 return false; 00139 } 00140