graphicsWindow.cxx 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. // Filename: graphicsWindow.cxx
  2. // Created by: mike (09Jan97)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://www.panda3d.org/license.txt .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "graphicsWindow.h"
  19. #include "graphicsPipe.h"
  20. #include "config_display.h"
  21. #include <mouseButton.h>
  22. #include <keyboardButton.h>
  23. #include "pmap.h"
  24. ////////////////////////////////////////////////////////////////////
  25. // Static variables
  26. ////////////////////////////////////////////////////////////////////
  27. TypeHandle GraphicsWindow::_type_handle;
  28. TypeHandle GraphicsWindow::WindowProps::_type_handle;
  29. TypeHandle GraphicsWindow::WindowPipe::_type_handle;
  30. GraphicsWindow::WindowFactory *GraphicsWindow::_factory = NULL;
  31. #ifndef CPPPARSER
  32. // We must compile these lines, even if DO_PSTATS is not defined,
  33. // because the symbols for them are declared in the header file.
  34. // Otherwise they will be undefined symbols at link time. However,
  35. // there's no runtime overhead to speak of for declaring these, so
  36. // there's no harm in compiling them all the time.
  37. PStatCollector GraphicsWindow::_app_pcollector("App");
  38. PStatCollector GraphicsWindow::_show_code_pcollector("App:Show code");
  39. PStatCollector GraphicsWindow::_swap_pcollector("Swap buffers");
  40. PStatCollector GraphicsWindow::_clear_pcollector("Draw:Clear");
  41. PStatCollector GraphicsWindow::_show_fps_pcollector("Draw:Show fps");
  42. PStatCollector GraphicsWindow::_make_current_pcollector("Draw:Make current");
  43. #endif
  44. ////////////////////////////////////////////////////////////////////
  45. // Function: GraphicsWindow::Properties::Constructor
  46. // Access: Published
  47. // Description:
  48. ////////////////////////////////////////////////////////////////////
  49. GraphicsWindow::Properties::
  50. Properties() {
  51. _xorg = 0;
  52. _yorg = 0;
  53. _xsize = 512;
  54. _ysize = 512;
  55. _title = "Panda";
  56. _border = true;
  57. _fullscreen = false;
  58. _mask = W_RGBA | W_DOUBLE | W_DEPTH;
  59. _want_depth_bits = 1;
  60. _want_color_bits = 1;
  61. _bCursorIsVisible=true;
  62. // By default, windows are set up to clear color and depth.
  63. set_clear_color_active(true);
  64. set_clear_depth_active(true);
  65. }
  66. ////////////////////////////////////////////////////////////////////
  67. // Function: GraphicsWindow::Callback::draw
  68. // Access: Public
  69. // Description:
  70. ////////////////////////////////////////////////////////////////////
  71. void GraphicsWindow::Callback::
  72. draw(bool) {
  73. display_cat.error()
  74. << "Callback::draw() - no class defined for this" << endl;
  75. }
  76. ////////////////////////////////////////////////////////////////////
  77. // Function: GraphicsWindow::Callback::idle
  78. // Access: Public
  79. // Description:
  80. ////////////////////////////////////////////////////////////////////
  81. void GraphicsWindow::Callback::
  82. idle() {
  83. display_cat.error()
  84. << "Callback::idle() - no class defined for this" << endl;
  85. }
  86. GraphicsWindow::WindowProps::~WindowProps(void) {}
  87. TypeHandle GraphicsWindow::WindowProps::get_class_type(void) {
  88. return _type_handle;
  89. }
  90. void GraphicsWindow::WindowProps::init_type(void) {
  91. WindowParam::init_type();
  92. register_type(_type_handle, "GraphicsWindow::WindowProps",
  93. WindowParam::get_class_type());
  94. }
  95. TypeHandle GraphicsWindow::WindowProps::get_type(void) const {
  96. return get_class_type();
  97. }
  98. TypeHandle GraphicsWindow::WindowProps::force_init_type(void) {
  99. init_type();
  100. return get_class_type();
  101. }
  102. GraphicsWindow::WindowPipe::~WindowPipe(void) {}
  103. TypeHandle GraphicsWindow::WindowPipe::get_class_type(void) {
  104. return _type_handle;
  105. }
  106. void GraphicsWindow::WindowPipe::init_type(void) {
  107. WindowParam::init_type();
  108. register_type(_type_handle, "GraphicsWindow::WindowPipe",
  109. WindowParam::get_class_type());
  110. }
  111. TypeHandle GraphicsWindow::WindowPipe::get_type(void) const {
  112. return get_class_type();
  113. }
  114. TypeHandle GraphicsWindow::WindowPipe::force_init_type(void) {
  115. init_type();
  116. return get_class_type();
  117. }
  118. ////////////////////////////////////////////////////////////////////
  119. // Function: GraphicsWindow::Constructor
  120. // Access: Public
  121. // Description:
  122. ////////////////////////////////////////////////////////////////////
  123. GraphicsWindow::
  124. GraphicsWindow(GraphicsPipe *pipe,
  125. const GraphicsWindow::Properties &props) :
  126. Configurable(),
  127. ClearableRegion(props)
  128. {
  129. #ifdef DO_MEMORY_USAGE
  130. MemoryUsage::update_type(this, this);
  131. #endif
  132. _pipe = pipe;
  133. _props = props;
  134. _draw_callback = NULL;
  135. _idle_callback = NULL;
  136. _frame_number = 0;
  137. _is_synced = false;
  138. _window_active = true;
  139. _display_regions_stale = false;
  140. }
  141. ////////////////////////////////////////////////////////////////////
  142. // Function: GraphicsWindow::Copy Constructor
  143. // Access: Public
  144. // Description:
  145. ////////////////////////////////////////////////////////////////////
  146. GraphicsWindow::
  147. GraphicsWindow(const GraphicsWindow&) {
  148. display_cat.error()
  149. << "GraphicsWindows should not be copied" << endl;
  150. }
  151. ////////////////////////////////////////////////////////////////////
  152. // Function: GraphicsWindow::Copy Assignment Operator
  153. // Access: Public
  154. // Description:
  155. ////////////////////////////////////////////////////////////////////
  156. GraphicsWindow& GraphicsWindow::
  157. operator=(const GraphicsWindow&) {
  158. display_cat.error()
  159. << "GraphicsWindows should not be assigned" << endl;
  160. return *this;
  161. }
  162. ////////////////////////////////////////////////////////////////////
  163. // Function: GraphicsWindow::Destructor
  164. // Access: Public, Virtual
  165. // Description:
  166. ////////////////////////////////////////////////////////////////////
  167. GraphicsWindow::
  168. ~GraphicsWindow() {
  169. // First, call close_window(). This tells our GSG to let go of its
  170. // pointer to us, and also eventually calls do_close_window().
  171. // However, do_close_window() is a virtual function that might be
  172. // extended in a derived class, but we don't have any derived
  173. // virtual functions by the time the destructor is called.
  174. // Therefore, if a derived class has redefined do_close_window(), it
  175. // should also call close_window() in its own destructor.
  176. close_window();
  177. // We don't have to destruct our child channels explicitly, since
  178. // they are all reference-counted and will go away when their
  179. // pointers do. However, we do need to zero out their pointers to
  180. // us.
  181. Channels::iterator ci;
  182. for (ci = _channels.begin(); ci != _channels.end(); ++ci) {
  183. (*ci)->_window = NULL;
  184. }
  185. // We don't need to remove ourself from the pipe's list of windows.
  186. // We must have already been removed, or we wouldn't be destructing!
  187. }
  188. ////////////////////////////////////////////////////////////////////
  189. // Function: GraphicsWindow::get_channel
  190. // Access: Public
  191. // Description: Returns a GraphicsChannel pointer that can be used to
  192. // access the indicated channel number. All windows
  193. // have at least one channel, channel 0, which
  194. // corresponds to the entire window. If the hardware
  195. // supports it, some kinds of windows may also have a
  196. // number of hardware channels available at indices
  197. // 1..n, which will correspond to a subregion of the
  198. // window.
  199. //
  200. // This function returns a GraphicsChannel pointer if a
  201. // channel is available, or NULL if it is not. If
  202. // called twice with the same index number, it will
  203. // return the same pointer.
  204. ////////////////////////////////////////////////////////////////////
  205. GraphicsChannel *GraphicsWindow::
  206. get_channel(int index) {
  207. nassertr(index >= 0, NULL);
  208. if (index < (int)_channels.size()) {
  209. if (_channels[index] != (GraphicsChannel *)NULL) {
  210. return _channels[index];
  211. }
  212. }
  213. // This channel has never been requested before; define it.
  214. PT(GraphicsChannel) chan;
  215. if (index == 0) {
  216. // Channel 0 is the default channel: the entire screen.
  217. chan = new GraphicsChannel(this);
  218. } else {
  219. // Any other channel is some hardware-specific channel.
  220. nassertr(_pipe != NULL, NULL);
  221. chan = _pipe->get_hw_channel(this, index);
  222. if (chan == NULL) {
  223. display_cat.error()
  224. << "GraphicsWindow::get_channel() - got a NULL channel" << endl;
  225. } else {
  226. if (chan->get_window() != this) {
  227. chan = NULL;
  228. }
  229. }
  230. }
  231. if (chan != (GraphicsChannel *)NULL) {
  232. declare_channel(index, chan);
  233. }
  234. return chan;
  235. }
  236. ////////////////////////////////////////////////////////////////////
  237. // Function: GraphicsWindow::remove_channel
  238. // Access: Public
  239. // Description: Deletes a GraphicsChannel that was previously created
  240. // via a call to get_channel(). Note that the channel
  241. // is not actually deleted until all pointers to it are
  242. // cleared.
  243. ////////////////////////////////////////////////////////////////////
  244. void GraphicsWindow::
  245. remove_channel(int index) {
  246. if (index >= 0 && index < (int)_channels.size()) {
  247. _channels[index].clear();
  248. }
  249. }
  250. ////////////////////////////////////////////////////////////////////
  251. // Function: GraphicsWindow::get_max_channel_index
  252. // Access: Public
  253. // Description: Returns the largest channel index number yet created,
  254. // plus 1. All channels associated with this window
  255. // will have an index number in the range [0,
  256. // get_max_channel_index()). This function, in
  257. // conjunction with is_channel_defined(), below, may be
  258. // used to determine the complete set of channels
  259. // associated with the window.
  260. ////////////////////////////////////////////////////////////////////
  261. int GraphicsWindow::
  262. get_max_channel_index() const {
  263. return _channels.size();
  264. }
  265. ////////////////////////////////////////////////////////////////////
  266. // Function: GraphicsWindow::is_channel_defined
  267. // Access: Public
  268. // Description: Returns true if the channel with the given index
  269. // number has already been defined, false if it hasn't.
  270. // If this returns true, calling get_channel() on the
  271. // given index number will return the channel pointer.
  272. // If it returns false, calling get_channel() will
  273. // create and return a new channel pointer.
  274. ////////////////////////////////////////////////////////////////////
  275. bool GraphicsWindow::
  276. is_channel_defined(int index) const {
  277. if (index < 0 || index >= (int)_channels.size()) {
  278. return false;
  279. }
  280. return (_channels[index] != (GraphicsChannel *)NULL);
  281. }
  282. ////////////////////////////////////////////////////////////////////
  283. // Function: GraphicsWindow::declare_channel
  284. // Access: Protected
  285. // Description: An internal function to add the indicated
  286. // newly-created channel to the list at the indicated
  287. // channel number.
  288. ////////////////////////////////////////////////////////////////////
  289. void GraphicsWindow::
  290. declare_channel(int index, GraphicsChannel *chan) {
  291. nassertv(index >= 0);
  292. if (index >= (int)_channels.size()) {
  293. _channels.reserve(index);
  294. while (index >= (int)_channels.size()) {
  295. _channels.push_back(NULL);
  296. }
  297. }
  298. nassertv(index < (int)_channels.size());
  299. _channels[index] = chan;
  300. }
  301. ////////////////////////////////////////////////////////////////////
  302. // Function: GraphicsWindow::do_determine_display_regions
  303. // Access: Private
  304. // Description: Recomputes the list of active DisplayRegions within
  305. // the window.
  306. ////////////////////////////////////////////////////////////////////
  307. void GraphicsWindow::
  308. do_determine_display_regions() {
  309. _display_regions.clear();
  310. Channels::const_iterator ci;
  311. for (ci = _channels.begin(); ci != _channels.end(); ++ci) {
  312. GraphicsChannel *chan = (*ci);
  313. if (chan->is_active()) {
  314. GraphicsChannel::GraphicsLayers::const_iterator li;
  315. for (li = chan->_layers.begin(); li != chan->_layers.end(); ++li) {
  316. GraphicsLayer *layer = (*li);
  317. if (layer->is_active()) {
  318. GraphicsLayer::DisplayRegions::const_iterator dri;
  319. for (dri = layer->_display_regions.begin();
  320. dri != layer->_display_regions.end();
  321. ++dri) {
  322. DisplayRegion *dr = (*dri);
  323. if (dr->is_active()) {
  324. _display_regions.push_back(dr);
  325. }
  326. }
  327. }
  328. }
  329. }
  330. }
  331. _display_regions_stale = false;
  332. }
  333. ////////////////////////////////////////////////////////////////////
  334. // Function: GraphicsWindow::resized
  335. // Access: Public, Virtual
  336. // Description: Called whenever the window gets the resize event.
  337. ////////////////////////////////////////////////////////////////////
  338. void GraphicsWindow::
  339. resized(const unsigned int x, const unsigned int y) {
  340. Channels::iterator ci;
  341. for (ci = _channels.begin(); ci != _channels.end(); ++ci) {
  342. GraphicsChannel *chan = (*ci);
  343. chan->window_resized(x, y);
  344. }
  345. _props._xsize = x;
  346. _props._ysize = y;
  347. }
  348. ////////////////////////////////////////////////////////////////////
  349. // Function: GraphicsWindow::make_scratch_display_region
  350. // Access: Public
  351. // Description: Allocates and returns a temporary DisplayRegion that
  352. // may be used to render offscreen into. This
  353. // DisplayRegion is not associated with any layer.
  354. //
  355. // To allocate a normal DisplayRegion for rendering, use
  356. // the interface provided in GraphicsLayer.
  357. ////////////////////////////////////////////////////////////////////
  358. PT(DisplayRegion) GraphicsWindow::
  359. make_scratch_display_region(int xsize, int ysize) const {
  360. if (xsize > _props._xsize) {
  361. display_cat.error()
  362. << "GraphicsWindow::make_scratch_display_region() - x size is larger "
  363. << "than window x size" << endl;
  364. xsize = _props._xsize;
  365. }
  366. if (ysize > _props._ysize) {
  367. display_cat.error()
  368. << "GraphicsWindow::make_scratch_display_region() - y size is larger "
  369. << "than window y size" << endl;
  370. ysize = _props._ysize;
  371. }
  372. PT(DisplayRegion) region = new DisplayRegion(xsize, ysize);
  373. region->copy_clear_settings(*this);
  374. return region;
  375. }
  376. ////////////////////////////////////////////////////////////////////
  377. // Function: GraphicsWindow::make_current
  378. // Access: Public, Virtual
  379. // Description: Makes the window's graphics context the currently
  380. // active context that will be next rendered into by the
  381. // GSG, if this makes sense for the particular type of
  382. // GraphicsWindow.
  383. ////////////////////////////////////////////////////////////////////
  384. void GraphicsWindow::
  385. make_current(void) {
  386. }
  387. ////////////////////////////////////////////////////////////////////
  388. // Function: GraphicsWindow::unmake_current
  389. // Access: Public, Virtual
  390. // Description:
  391. ////////////////////////////////////////////////////////////////////
  392. void GraphicsWindow::
  393. unmake_current(void) {
  394. }
  395. ////////////////////////////////////////////////////////////////////
  396. // Function: GraphicsWindow::flag_redisplay
  397. // Access: Public, Virtual
  398. // Description:
  399. ////////////////////////////////////////////////////////////////////
  400. void GraphicsWindow::
  401. flag_redisplay() {
  402. }
  403. ////////////////////////////////////////////////////////////////////
  404. // Function: GraphicsWindow::register_draw_function
  405. // Access: Public, Virtual
  406. // Description:
  407. ////////////////////////////////////////////////////////////////////
  408. void GraphicsWindow::
  409. register_draw_function(GraphicsWindow::vfn f) {
  410. _draw_function = f;
  411. }
  412. ////////////////////////////////////////////////////////////////////
  413. // Function: GraphicsWindow::register_idle_function
  414. // Access: Public, Virtual
  415. // Description:
  416. ////////////////////////////////////////////////////////////////////
  417. void GraphicsWindow::
  418. register_idle_function(GraphicsWindow::vfn f) {
  419. _idle_function = f;
  420. }
  421. ////////////////////////////////////////////////////////////////////
  422. // Function: GraphicsWindow::begin_frame
  423. // Access: Public, Virtual
  424. // Description: This function will be called by the GSG before
  425. // beginning processing for a given frame. It should do
  426. // whatever setup is required.
  427. ////////////////////////////////////////////////////////////////////
  428. void GraphicsWindow::
  429. begin_frame() {
  430. _gsg->begin_frame();
  431. }
  432. ////////////////////////////////////////////////////////////////////
  433. // Function: GraphicsWindow::clear
  434. // Access: Public
  435. // Description: Clears the entire framebuffer before rendering,
  436. // according to the settings of get_color_clear_active()
  437. // and get_depth_clear_active() (inherited from
  438. // ClearableRegion).
  439. ////////////////////////////////////////////////////////////////////
  440. void GraphicsWindow::
  441. clear() {
  442. if (is_any_clear_active()) {
  443. nassertv(_gsg != (GraphicsStateGuardian *)NULL);
  444. PT(DisplayRegion) win_dr =
  445. make_scratch_display_region(get_width(), get_height());
  446. DisplayRegionStack old_dr = _gsg->push_display_region(win_dr);
  447. _gsg->clear(this);
  448. _gsg->pop_display_region(old_dr);
  449. }
  450. }
  451. ////////////////////////////////////////////////////////////////////
  452. // Function: GraphicsWindow::end_frame
  453. // Access: Public, Virtual
  454. // Description: This function will be called by the GSG after
  455. // processing is completed for a given frame. It should
  456. // do whatever finalization is required.
  457. ////////////////////////////////////////////////////////////////////
  458. void GraphicsWindow::
  459. end_frame() {
  460. _gsg->end_frame();
  461. _frame_number++;
  462. }
  463. ////////////////////////////////////////////////////////////////////
  464. // Function: GraphicsWindow::process_events
  465. // Access: Public, Virtual
  466. // Description: Do whatever processing is necessary to ensure that
  467. // the window responds to user events.
  468. ////////////////////////////////////////////////////////////////////
  469. void GraphicsWindow::
  470. process_events() {
  471. }
  472. ////////////////////////////////////////////////////////////////////
  473. // Function: GraphicsWindow::deactivate_window
  474. // Access: Public, Virtual
  475. // Description: Indicates the window should stop rendering
  476. // temporarily, and does whatever else is associated
  477. // with that. This is normally called only by the
  478. // GraphicsWindow itself, or by the GSG.
  479. ////////////////////////////////////////////////////////////////////
  480. void GraphicsWindow::
  481. deactivate_window() {
  482. _window_active = false;
  483. }
  484. ////////////////////////////////////////////////////////////////////
  485. // Function: GraphicsWindow::reactivate_window
  486. // Access: Public, Virtual
  487. // Description: Restores the normal window rendering behavior after a
  488. // previous call to deactivate_window().
  489. ////////////////////////////////////////////////////////////////////
  490. void GraphicsWindow::
  491. reactivate_window() {
  492. _window_active = true;
  493. }
  494. ////////////////////////////////////////////////////////////////////
  495. // Function: GraphicsWindow::make_gsg
  496. // Access: Protected
  497. // Description: Creates a new GSG for the window and stores it in the
  498. // _gsg pointer.
  499. ////////////////////////////////////////////////////////////////////
  500. void GraphicsWindow::
  501. make_gsg() {
  502. FactoryParams params;
  503. params.add_param(new GraphicsStateGuardian::GsgWindow(this));
  504. _gsg = GraphicsStateGuardian::get_factory().
  505. make_instance(get_gsg_type(), params);
  506. nassertv(_gsg != (GraphicsStateGuardian *)NULL);
  507. }
  508. ////////////////////////////////////////////////////////////////////
  509. // Function: GraphicsWindow::release_gsg
  510. // Access: Protected
  511. // Description: Releases the current GSG pointer, if it is currently
  512. // held. This invalidates the window and marks it
  513. // closed; it should not be called unless the code to
  514. // close the window is also called.
  515. ////////////////////////////////////////////////////////////////////
  516. void GraphicsWindow::
  517. release_gsg() {
  518. if (_gsg != (GraphicsStateGuardian *)NULL) {
  519. // First, we save the GSG pointer and then NULL it out. That way,
  520. // if the GSG happens to call close_window() while it is closing
  521. // itself, it won't be recursive (because we'll already be marked
  522. // closed).
  523. PT(GraphicsStateGuardian) gsg = _gsg;
  524. _gsg.clear();
  525. // Now we tell the GSG it's time to sleep.
  526. gsg->close_gsg();
  527. }
  528. }
  529. ////////////////////////////////////////////////////////////////////
  530. // Function: GraphicsWindow::do_close_window
  531. // Access: Protected, Virtual
  532. // Description: An internal function to release whatever system
  533. // resources are held by the window and actually close
  534. // it. This is called by close_window().
  535. //
  536. // If a derived class redefines this function, it should
  537. // also arrange to call close_window() (or its
  538. // equivalent) from its own destructor, since we cannot
  539. // call a virtual function from this destructor.
  540. ////////////////////////////////////////////////////////////////////
  541. void GraphicsWindow::
  542. do_close_window() {
  543. display_cat.info()
  544. << "Closing " << get_type() << "\n";
  545. }
  546. ////////////////////////////////////////////////////////////////////
  547. // Function: GraphicsWindow::get_factory
  548. // Access: Public, Static
  549. // Description: Returns the factory object that can be used to
  550. // register new kinds of GraphicsWindow objects that may
  551. // be created.
  552. ////////////////////////////////////////////////////////////////////
  553. GraphicsWindow::WindowFactory &GraphicsWindow::
  554. get_factory() {
  555. if (_factory == (WindowFactory *)NULL) {
  556. _factory = new WindowFactory;
  557. }
  558. return (*_factory);
  559. }
  560. void GraphicsWindow::read_priorities(void) {
  561. WindowFactory &factory = get_factory();
  562. if (factory.get_num_preferred() == 0) {
  563. Config::ConfigTable::Symbol::iterator i;
  564. for (i = preferred_window_begin(); i != preferred_window_end(); ++i) {
  565. ConfigString type_name = (*i).Val();
  566. TypeHandle type = TypeRegistry::ptr()->find_type(type_name);
  567. if (type == TypeHandle::none()) {
  568. display_cat.warning()
  569. << "Unknown type requested for window preference: " << type_name
  570. << "\n";
  571. } else {
  572. display_cat.debug()
  573. << "Specifying type " << type << " for window preference.\n";
  574. factory.add_preferred(type);
  575. }
  576. }
  577. }
  578. }
  579. ////////////////////////////////////////////////////////////////////
  580. // Function: GraphicsWindow::swap
  581. // Access: Public
  582. // Description: Swaps buffers explicitely as synchronization
  583. // mechanism.
  584. ////////////////////////////////////////////////////////////////////
  585. void GraphicsWindow::
  586. swap() {
  587. display_cat.warning() << "swap() unimplemented by " << get_type() << endl;
  588. }
  589. ////////////////////////////////////////////////////////////////////
  590. // Function: GraphicsWindow::resize
  591. // Access: Public
  592. // Description: Resizes the window to the given size.
  593. // Should try to preserve current window bitdepths,
  594. // if possible. If it is not possible to resize window to
  595. // the given size, return false and maintain current
  596. // window size.
  597. ////////////////////////////////////////////////////////////////////
  598. bool GraphicsWindow::
  599. resize(unsigned int xsize,unsigned int ysize) {
  600. display_cat.warning() << "resize() unimplemented by " << get_type() << endl;
  601. return false;
  602. }
  603. unsigned int GraphicsWindow::
  604. verify_window_sizes(unsigned int numsizes,unsigned int *dimen) {
  605. // see if window sizes are supported (i.e. in fullscrn mode)
  606. // dimen is an array containing contiguous x,y pairs specifying
  607. // possible display sizes, it is numsizes*2 long. fn will zero
  608. // out any invalid x,y size pairs. return value is number of valid
  609. // sizes that were found.
  610. //
  611. // note: it might be better to implement some sort of query
  612. // interface that returns an array of supported sizes,
  613. // but this way is somewhat simpler and will do the job
  614. // on most cards, assuming they handle the std sizes the app
  615. // knows about.
  616. // Also note this doesnt guarantee resize() will work, you still need to check its return value.
  617. display_cat.warning() << "verify_window_sizes() unimplemented by " << get_type() << endl;
  618. return numsizes;
  619. }
  620. int GraphicsWindow::
  621. get_depth_bitwidth(void) {
  622. display_cat.warning() << "get_depth_bitwidth() unimplemented by " << get_type() << endl;
  623. return -1;
  624. }