00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_GFX_TOGLET_CC_UTC20050626084024_DEFINED
00035 #define GROOVX_GFX_TOGLET_CC_UTC20050626084024_DEFINED
00036
00037 #include "toglet.h"
00038
00039 #include "gfx/glcanvas.h"
00040 #include "gfx/glwindowinterface.h"
00041 #include "gfx/glxopts.h"
00042 #include "gfx/gxfactory.h"
00043 #include "gfx/gxscene.h"
00044 #include "gfx/rgbacolor.h"
00045
00046 #if defined (GVX_GL_PLATFORM_GLX)
00047 # include "gfx/glxwrapper.h"
00048 #elif defined(GVX_GL_PLATFORM_AGL)
00049 # include "gfx/aglwrapper.h"
00050 #endif
00051
00052 #include "nub/ref.h"
00053
00054 #include "tcl/eventloop.h"
00055 #include "tcl/timerscheduler.h"
00056
00057 #include "rutz/fstring.h"
00058 #include "rutz/sfmt.h"
00059
00060 #include <limits>
00061 #include <tk.h>
00062
00063 #ifdef GVX_GL_PLATFORM_AGL
00064 # define HAVE_LIMITS_H
00065 # include <tkMacOSX.h>
00066 #endif
00067
00068 #include "rutz/trace.h"
00069 #include "rutz/debug.h"
00070 GVX_DBG_REGISTER
00071
00072 using rutz::shared_ptr;
00073
00074 namespace
00075 {
00076 nub::soft_ref<Toglet> theCurrentToglet;
00077
00078 const int DEFAULT_SIZE_X = 400;
00079 const int DEFAULT_SIZE_Y = 400;
00080 }
00081
00083
00084
00085
00087
00088 class Toglet::Impl
00089 {
00090 private:
00091 Impl(const Impl&);
00092 Impl& operator=(const Impl&);
00093
00094 public:
00095
00096 Toglet* const owner;
00097 Tk_Window const tkWin;
00098 shared_ptr<GlxOpts> const opts;
00099 #if defined(GVX_GL_PLATFORM_GLX)
00100 shared_ptr<GlxWrapper> const glx;
00101 #elif defined(GVX_GL_PLATFORM_AGL)
00102 shared_ptr<AglWrapper> const glx;
00103 #endif
00104 nub::soft_ref<GLCanvas> const canvas;
00105 GxScene* const scene;
00106
00107 Impl(Toglet* p);
00108 ~Impl() throw()
00109 {
00110 if (scene != 0) scene->destroy();
00111 if (canvas.is_valid()) canvas->destroy();
00112 }
00113 };
00114
00115
00116
00117
00118
00119
00120
00121
00122 Toglet::Impl::Impl(Toglet* p) :
00123 owner(p),
00124 tkWin(owner->tkWin()),
00125 opts(new GlxOpts),
00126 #if defined(GVX_GL_PLATFORM_GLX)
00127 glx(GlxWrapper::make(Tk_Display(tkWin), *opts,
00128 (GlxWrapper*)0 )),
00129 #elif defined(GVX_GL_PLATFORM_AGL)
00130 glx(AglWrapper::make(*opts)),
00131 #endif
00132 canvas(GLCanvas::make(opts, glx)),
00133 scene(new GxScene(canvas, rutz::make_shared(new tcl::timer_scheduler)))
00134 {
00135 GVX_TRACE("Toglet::Impl::Impl");
00136 }
00137
00139
00140
00141
00143
00144 namespace
00145 {
00146
00147 rutz::fstring PARENT = "";
00148
00149 #ifdef GVX_GL_PLATFORM_GLX
00150 void configureGlxWindow(Tk_Window tkWin, const GlxWrapper* glx)
00151 {
00152 Display* dpy = Tk_Display(tkWin);
00153
00154 Visual* visual = glx->visInfo()->visual;
00155 const int screen = glx->visInfo()->screen;
00156
00157 Colormap cmap =
00158 visual == DefaultVisual(dpy, screen)
00159 ? DefaultColormap(dpy, screen)
00160 : XCreateColormap(dpy,
00161 RootWindow(dpy, screen),
00162 visual, AllocNone);
00163
00164
00165
00166 Tk_SetWindowVisual(tkWin, visual, glx->visInfo()->depth, cmap);
00167
00168 XSetWindowAttributes atts;
00169
00170 atts.colormap = cmap;
00171 atts.border_pixel = 0;
00172 atts.event_mask =
00173 KeyPressMask|KeyReleaseMask|
00174 ButtonPressMask|ButtonReleaseMask|
00175 EnterWindowMask|LeaveWindowMask|
00176 PointerMotionMask|ExposureMask|
00177 VisibilityChangeMask|FocusChangeMask|
00178 PropertyChangeMask|ColormapChangeMask;
00179
00180 unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask;
00181
00182 if (Tk_IsTopLevel(tkWin))
00183 {
00184 atts.override_redirect = true;
00185 valuemask |= CWOverrideRedirect;
00186 }
00187
00188 Tk_ChangeWindowAttributes(tkWin, valuemask, &atts);
00189 }
00190 #endif
00191 }
00192
00194
00195
00196
00198
00199 Toglet::Toglet(bool pack, bool topLevel) :
00200 tcl::TkWidget(tcl::event_loop::interp(), "Toglet",
00201 rutz::sfmt("%s.togl_private%lu",
00202 PARENT.c_str(), id()).c_str(),
00203 topLevel),
00204 rep(new Impl(this))
00205 {
00206 GVX_TRACE("Toglet::Toglet");
00207
00208 dbg_eval_nl(3, this);
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 Tk_GeometryRequest(rep->tkWin, DEFAULT_SIZE_X, DEFAULT_SIZE_Y);
00221
00222 #ifdef GVX_GL_PLATFORM_GLX
00223 configureGlxWindow(rep->tkWin, rep->glx.get());
00224 #endif
00225
00226 Tk_MakeWindowExist(rep->tkWin);
00227 Tk_MapWindow(rep->tkWin);
00228
00229 #if defined(GVX_GL_PLATFORM_GLX)
00230 rep->glx->bindWindow(Tk_WindowId(rep->tkWin));
00231 #elif defined(GVX_GL_PLATFORM_AGL)
00232 rep->glx->bindDrawable(TkMacOSXGetDrawablePort(Tk_WindowId(rep->tkWin)));
00233 #endif
00234
00235
00236 this->makeCurrent();
00237
00238 if (rep->canvas->isRgba())
00239 {
00240 GVX_TRACE("GlxWrapper::GlxWrapper::rgbaFlag");
00241 rep->canvas->setColor(Gfx::RgbaColor(0.0, 0.0, 0.0, 1.0));
00242 rep->canvas->setClearColor(Gfx::RgbaColor(1.0, 1.0, 1.0, 1.0));
00243 }
00244 else
00245 {
00246
00247 rep->canvas->setColorIndex(0);
00248 rep->canvas->setClearColorIndex(1);
00249 }
00250
00251 if (pack) tcl::TkWidget::pack();
00252 }
00253
00254 Toglet::~Toglet() throw()
00255 {
00256 GVX_TRACE("Toglet::~Toglet");
00257
00258 dbg_eval_nl(3, this);
00259
00260 delete rep;
00261 }
00262
00263 Toglet* Toglet::make()
00264 {
00265 GVX_TRACE("Toglet::make");
00266
00267 Toglet* p = new Toglet;
00268
00269 return p;
00270 }
00271
00272 Toglet* Toglet::makeToplevel()
00273 {
00274 GVX_TRACE("Toglet::makeToplevel");
00275 Toglet* p = new Toglet(true, true);
00276
00277 return p;
00278 }
00279
00280 nub::soft_ref<Toglet> Toglet::getCurrent()
00281 {
00282 GVX_TRACE("Toglet::getCurrent");
00283 return theCurrentToglet;
00284 }
00285
00286 void Toglet::setCurrent(nub::soft_ref<Toglet> toglet)
00287 {
00288 GVX_TRACE("Toglet::setCurrent");
00289 dbg_eval(1, toglet.id());
00290 toglet->makeCurrent();
00291 }
00292
00293 void Toglet::defaultParent(const char* pathname)
00294 {
00295 GVX_TRACE("Toglet::defaultParent");
00296 PARENT = pathname;
00297 }
00298
00299 nub::soft_ref<Gfx::Canvas> Toglet::getCanvas() const
00300 {
00301 GVX_TRACE("Toglet::getCanvas");
00302 makeCurrent();
00303 return rep->canvas;
00304 }
00305
00306 void Toglet::makeCurrent() const
00307 {
00308 if (theCurrentToglet.id() != this->id() ||
00309 GLCanvas::getCurrent().id() != rep->canvas->id())
00310 {
00311 rep->canvas->makeCurrent();
00312 theCurrentToglet = nub::soft_ref<Toglet>(const_cast<Toglet*>(this));
00313 }
00314 }
00315
00316 void Toglet::displayCallback()
00317 {
00318 GVX_TRACE("Toglet::displayCallback");
00319 fullRender();
00320 }
00321
00322 void Toglet::reshapeCallback(int width, int height)
00323 {
00324 GVX_TRACE("Toglet::reshapeCallback");
00325
00326 GVX_ASSERT(rep->glx.get() != 0);
00327 GVX_ASSERT(rep->scene != 0);
00328
00329 makeCurrent();
00330 rep->glx->onReshape(width, height);
00331 rep->scene->reshape(width, height);
00332 }
00333
00334 void Toglet::swapBuffers()
00335 {
00336 GVX_TRACE("Toglet::swapBuffers");
00337 makeCurrent();
00338 rep->canvas->flushOutput();
00339 }
00340
00341 GxScene& Toglet::scene()
00342 {
00343 GVX_TRACE("Toglet::scene");
00344 return *(rep->scene);
00345 }
00346
00347 void Toglet::render()
00348 {
00349 makeCurrent();
00350 rep->scene->render();
00351 }
00352
00353 void Toglet::fullRender()
00354 {
00355 makeCurrent();
00356 rep->scene->fullRender();
00357 }
00358
00359 void Toglet::clearscreen()
00360 {
00361 makeCurrent();
00362 rep->scene->clearscreen();
00363 }
00364
00365 void Toglet::fullClearscreen()
00366 {
00367 makeCurrent();
00368 rep->scene->fullClearscreen();
00369 }
00370
00371 void Toglet::undraw()
00372 {
00373 makeCurrent();
00374 rep->scene->undraw();
00375 }
00376
00377 void Toglet::setVisibility(bool vis)
00378 {
00379 makeCurrent();
00380 rep->scene->setVisibility(vis);
00381 }
00382
00383 void Toglet::setHold(bool hold_on)
00384 {
00385 makeCurrent();
00386 rep->scene->setHold(hold_on);
00387 }
00388
00389 void Toglet::allowRefresh(bool allow)
00390 {
00391 makeCurrent();
00392 rep->scene->allowRefresh(allow);
00393 }
00394
00395 const nub::ref<GxCamera>& Toglet::getCamera() const
00396 {
00397 makeCurrent();
00398 return rep->scene->getCamera();
00399 }
00400
00401 void Toglet::setCamera(const nub::ref<GxCamera>& cam)
00402 {
00403 makeCurrent();
00404 rep->scene->setCamera(cam);
00405 }
00406
00407 void Toglet::setDrawable(const nub::ref<GxNode>& node)
00408 {
00409 makeCurrent();
00410 rep->scene->setDrawable(node);
00411 }
00412
00413 void Toglet::animate(unsigned int framesPerSecond)
00414 {
00415 makeCurrent();
00416 rep->scene->animate(framesPerSecond);
00417 }
00418
00419 static const char __attribute__((used)) vcid_groovx_gfx_toglet_cc_utc20050626084024[] = "$Id: toglet.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00420 #endif // !GROOVX_GFX_TOGLET_CC_UTC20050626084024_DEFINED