Panda3D
showBase.cxx
1 // Filename: showBase.cxx
2 // Created by: shochet (02Feb00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifdef __APPLE__
16 // We have to include this before we include any Panda libraries,
17 // because one of the things we pick up in Panda defines a macro for
18 // TCP_NODELAY and friends, causing heartaches for the header files
19 // picked up here.
20 #include <Carbon/Carbon.h>
21 extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); }
22 #endif
23 
24 #include "showBase.h"
25 
26 #include "throw_event.h"
27 #include "graphicsWindow.h"
28 #include "renderBuffer.h"
29 #include "camera.h"
30 #include "graphicsPipeSelection.h"
31 
32 #ifdef WIN32
33 #include <windows.h> // For SystemParametersInfo()
34 STICKYKEYS g_StartupStickyKeys = {sizeof(STICKYKEYS), 0};
35 TOGGLEKEYS g_StartupToggleKeys = {sizeof(TOGGLEKEYS), 0};
36 FILTERKEYS g_StartupFilterKeys = {sizeof(FILTERKEYS), 0};
37 #endif
38 
39 ConfigureDef(config_showbase);
40 ConfigureFn(config_showbase) {
41 }
42 
43 ConfigVariableSearchPath particle_path
44 ("particle-path",
45  PRC_DESC("The directories to search for particle files to be loaded."));
46 
48 get_particle_path() {
49  return particle_path;
50 }
51 
52 // Throw the "NewFrame" event in the C++ world. Some of the lerp code
53 // depends on receiving this.
54 void
55 throw_new_frame() {
56  throw_event("NewFrame");
57 }
58 
59 // Returns the configure object for accessing config variables from a
60 // scripting language.
61 DConfig &
62 get_config_showbase() {
63  static DConfig config_showbase;
64  return config_showbase;
65 }
66 
67 // Initialize the application for making a Gui-based app, such as wx.
68 // At the moment, this is a no-op except on Mac.
69 void
70 init_app_for_gui() {
71 #ifdef IS_OSX
72  // Rudely bring the application to the foreground. This is
73  // particularly important when running wx via the plugin, since the
74  // plugin app is seen as separate from the browser app, even though
75  // the user sees them as the same thing. We need to bring the
76  // plugin app to the foreground to make its wx windows visible.
77  activate_osx_application();
78 #endif
79 
80  // We don't appear need to do the following, however, if we launch
81  // the plugin correctly from its own bundle.
82  /*
83  static bool initted_for_gui = false;
84  if (!initted_for_gui) {
85  initted_for_gui = true;
86 #ifdef IS_OSX
87  ProcessSerialNumber psn;
88 
89  GetCurrentProcess(&psn);
90  CPSEnableForegroundOperation(&psn);
91  SetFrontProcess(&psn);
92 #endif // IS_OSX
93  }
94  */
95 }
96 
97 // klunky interface since we cant pass array from python->C++ to use verify_window_sizes directly
98 static int num_fullscreen_testsizes = 0;
99 #define MAX_FULLSCREEN_TESTS 10
100 static int fullscreen_testsizes[MAX_FULLSCREEN_TESTS * 2];
101 
102 void
103 add_fullscreen_testsize(int xsize, int ysize) {
104  if ((xsize == 0) && (ysize == 0)) {
105  num_fullscreen_testsizes = 0;
106  return;
107  }
108 
109  // silently fail if maxtests exceeded
110  if (num_fullscreen_testsizes < MAX_FULLSCREEN_TESTS) {
111  fullscreen_testsizes[num_fullscreen_testsizes * 2] = xsize;
112  fullscreen_testsizes[num_fullscreen_testsizes * 2 + 1] = ysize;
113  num_fullscreen_testsizes++;
114  }
115 }
116 
117 void
118 runtest_fullscreen_sizes(GraphicsWindow *win) {
119  win->verify_window_sizes(num_fullscreen_testsizes, fullscreen_testsizes);
120 }
121 
122 bool
123 query_fullscreen_testresult(int xsize, int ysize) {
124  // stupid linear search that works ok as long as total tests are small
125  int i;
126  for (i=0; i < num_fullscreen_testsizes; i++) {
127  if((fullscreen_testsizes[i * 2] == xsize) &&
128  (fullscreen_testsizes[i * 2 + 1] == ysize))
129  return true;
130  }
131  return false;
132 }
133 
134 void
135 store_accessibility_shortcut_keys() {
136 #ifdef WIN32
137  SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0);
138  SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0);
139  SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0);
140 #endif
141 }
142 
143 void
144 allow_accessibility_shortcut_keys(bool allowKeys) {
145 #ifdef WIN32
146  if( allowKeys )
147  {
148  // Restore StickyKeys/etc to original state and enable Windows key
149  SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0);
150  SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0);
151  SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0);
152  } else {
153  // Disable StickyKeys/etc shortcuts but if the accessibility feature is on,
154  // then leave the settings alone as its probably being usefully used
155 
156  STICKYKEYS skOff = g_StartupStickyKeys;
157  if( (skOff.dwFlags & SKF_STICKYKEYSON) == 0 )
158  {
159  // Disable the hotkey and the confirmation
160  skOff.dwFlags &= ~SKF_HOTKEYACTIVE;
161  skOff.dwFlags &= ~SKF_CONFIRMHOTKEY;
162 
163  SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &skOff, 0);
164  }
165 
166  TOGGLEKEYS tkOff = g_StartupToggleKeys;
167  if( (tkOff.dwFlags & TKF_TOGGLEKEYSON) == 0 )
168  {
169  // Disable the hotkey and the confirmation
170  tkOff.dwFlags &= ~TKF_HOTKEYACTIVE;
171  tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY;
172 
173  SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tkOff, 0);
174  }
175 
176  FILTERKEYS fkOff = g_StartupFilterKeys;
177  if( (fkOff.dwFlags & FKF_FILTERKEYSON) == 0 )
178  {
179  // Disable the hotkey and the confirmation
180  fkOff.dwFlags &= ~FKF_HOTKEYACTIVE;
181  fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY;
182 
183  SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &fkOff, 0);
184  }
185  }
186 #endif
187 }
188 
189 #if 0
190 int TempGridZoneManager::
191 add_grid_zone(unsigned int x,
192  unsigned int y,
193  unsigned int width,
194  unsigned int height,
195  unsigned int zoneBase,
196  unsigned int xZoneResolution,
197  unsigned int yZoneResolution) {
198  // zoneBase is the first zone in the grid (e.g. the upper left)
199  // zoneResolution is the number of cells on each axsis.
200  // returns the next available zoneBase (i.e. zoneBase+xZoneResolution*yZoneResolution)
201  cerr<<"adding grid zone with a zoneBase of "<<zoneBase<<" and a zoneResolution of "<<zoneResolution;
202  _grids.append(TempGridZoneManager::GridZone(x, y, width, height, zoneBase, xZoneResolution, yZoneResolution));
203  return zoneBase+xZoneResolution*yZoneResolution;
204 }
205 
206 void TempGridZoneManager::GridZone
207 GridZone(unsigned int x,
208  unsigned int y,
209  unsigned int width,
210  unsigned int height,
211  unsigned int zoneBase,
212  unsigned int xZoneResolution,
213  unsigned int yZoneResolution) {
214  _x=x;
215  _y=y;
216  _width=width;
217  _height=heigth;
218  _zoneBase=zoneBase;
219  _xZoneResolution=xZoneResolution;
220  _yZoneResolution=yZoneResolution;
221 
222  // The cellVis is the number of cells radius that can
223  // be seen, including the center cell. So, for a 5 x 5
224  // visible area, the cellVis is 3.
225  const float cellVis=3.0;
226  unsigned int xMargine=(unsigned int)((float)width/(float)xZoneResolution*cellVis+0.5);
227  unsigned int yMargine=(unsigned int)((float)height/(float)yZoneResolution*cellVis+0.5);
228  _xMinVis=x-xMargine;
229  _yMinVis=y-yMargine;
230  _xMaxVis=x+width+xMargine;
231  _yMaxVis=y+height+yMargine;
232 }
233 
234 void TempGridZoneManager::
235 get_grids(int x, int y) {
236  TempGridZoneManager::ZoneSet canSee;
237  TempGridZoneManager::GridSet::const_iterator i=_grids.begin();
238  for (; i!=_grids.end(); ++i) {
239  if (x >= i._xMinVis && x < i._xMaxVis && y >= i._yMinVis && y < i._yMaxVis) {
240  add_to_zone_list(i, x, y, canSee);
241  }
242  }
243 }
244 
245 void TempGridZoneManager::
246 add_to_zone_list(const TempGridZoneManager::GridZone &gridZone,
247  unsigned int x,
248  unsigned int y,
249  TempGridZoneManager::ZoneSet &zoneSet) {
250  unsigned int xRes=gridZone._xZoneResolution;
251  unsigned int yRes=gridZone._yZoneResolution;
252  float xP=((float)(x-gridZone._x))/gridZone._width;
253  float yP=((float)(y-gridZone._y))/gridZone._height;
254  int xCell=(int)(xP*xRes);
255  int yCell=(int)(yP*yRes);
256 
257  // range is how many cells can be seen in each direction:
258  const int range=2;
259  int yBegin=max(0, yCell-range);
260  int yEnd=min(yRes, yCell+range);
261  int xBegin=max(0, xCell-range);
262  int xEnd=min(xRes, xCell+range);
263  unsigned int zone=gridZone._zoneBase+yBegin*xRes+xBegin;
264 
265  for (yCell=yBegin; yCell < yEnd; ++yCell) {
266  for (xCell=xBegin; xCell < xEnd; ++xCell) {
267  zoneSet.append(zone+xCell);
268  }
269  zone+=xRes;
270  }
271 }
272 
273 int TempGridZoneManager::
274 get_zone_list(int x, int y, int resolution) {
275  // x is a float in the range 0.0 to 1.0
276  // y is a float in the range 0.0 to 1.0
277  // resolution is the number of cells on each axsis.
278  // returns a list of zone ids.
279  //
280  // Create a box of cell numbers, while clipping
281  // to the edges of the set of cells.
282  if (x < 0.0 || x > 1.0 || y < 0.0 || y > 1.0) {
283  return 0;
284  }
285  cerr<<"resolution="<<resolution;
286  xCell=min(int(x*resolution), resolution-1)
287  yCell=min(int(y*resolution), resolution-1)
288  cell=yCell*resolution+xCell
289  print "cell", cell,
290  zone=zoneBase+cell
291  print "zone", zone
292 
293  zone=zone-2*resolution
294  endZone=zone+5*resolution
295  yCell=yCell-2
296  while zone < endZone:
297  if yCell >= 0 and yCell < resolution:
298  if xCell > 1:
299  zoneList.append(zone-2)
300  zoneList.append(zone-1)
301  elif xCell > 0:
302  zoneList.append(zone-1)
303  r.append(zone)
304  if xCell < resolution-2:
305  zoneList.append(zone+1)
306  zoneList.append(zone+2)
307  elif xCell < resolution-1:
308  zoneList.append(zone+1)
309  yCell+=1
310  zone+=resolution
311  return zoneList
312  return 5;
313 }
314 #endif
315 
This is similar to a ConfigVariableList, but it returns its list as a DSearchPath, as a list of directories.
This class emulates the old dconfig-style interface to our Panda config system.
Definition: dconfig.h:37
A window, fullscreen or on a desktop, into which a graphics device sends its output for interactive d...
virtual int verify_window_sizes(int numsizes, int *dimen)
Determines which of the indicated window sizes are supported by available hardware (e...