framework2
910 строк · 24.6 Кб
1#include "ofAppGlutWindow.h"
2#include "ofBaseApp.h"
3#include "ofPixels.h"
4#include "ofGLRenderer.h"
5
6#ifdef TARGET_WIN32
7#if (_MSC_VER)
8#define GLUT_BUILDING_LIB
9#include "glut.h"
10#else
11#include <GL/glut.h>
12#include <GL/freeglut_ext.h>
13#endif
14#include <Shellapi.h>
15#endif
16#ifdef TARGET_OSX
17#include <OpenGL/OpenGL.h>
18#include "../../../libs/glut/lib/osx/GLUT.framework/Versions/A/Headers/glut.h"
19#include <Cocoa/Cocoa.h>
20#endif
21#ifdef TARGET_LINUX
22#include <GL/glut.h>
23#include "ofIcon.h"
24#include "ofImage.h"
25#include <X11/Xatom.h>
26#include <GL/freeglut_ext.h>
27#include <GL/glx.h>
28#endif
29
30// glut works with static callbacks UGH, so we need static variables here:
31
32static ofWindowMode windowMode;
33static bool bNewScreenMode;
34static int buttonInUse;
35static bool bEnableSetupScreen;
36static bool bDoubleBuffered;
37
38static int requestedWidth;
39static int requestedHeight;
40static int nonFullScreenX;
41static int nonFullScreenY;
42static int windowW;
43static int windowH;
44static int nFramesSinceWindowResized;
45static ofOrientation orientation;
46static ofAppGlutWindow * instance;
47
48#ifdef TARGET_WIN32
49
50//------------------------------------------------
51
52// this is to fix a bug with glut that doesn't properly close the app
53// with window closing. we grab the window procedure, store it, and parse windows messages,
54// using the close and destroy messages and passing on the others...
55
56//------------------------------------------------
57
58static WNDPROC currentWndProc;
59static HWND handle = nullptr;
60
61// This function takes in a wParam from the WM_DROPFILES message and
62// prints all the files to a message box.
63
64void HandleFiles(WPARAM wParam)
65{
66// DragQueryFile() takes a LPWSTR for the name so we need a TCHAR string
67TCHAR szName[MAX_PATH];
68
69// Here we cast the wParam as a HDROP handle to pass into the next functions
70HDROP hDrop = (HDROP)wParam;
71
72POINT pt;
73DragQueryPoint(hDrop, &pt);
74//ofLogNotice("ofAppGlutWindow") << "drag point: " << pt.x << pt.y;
75
76ofDragInfo info;
77info.position.x = pt.x;
78info.position.y = pt.y;
79
80
81// This functions has a couple functionalities. If you pass in 0xFFFFFFFF in
82// the second parameter then it returns the count of how many filers were drag
83// and dropped. Otherwise, the function fills in the szName string array with
84// the current file being queried.
85int count = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH);
86
87// Here we go through all the files that were drag and dropped then display them
88for(int i = 0; i < count; i++)
89{
90// Grab the name of the file associated with index "i" in the list of files dropped.
91// Be sure you know that the name is attached to the FULL path of the file.
92DragQueryFile(hDrop, i, szName, MAX_PATH);
93
94wchar_t * s = (wchar_t*)szName;
95char dfault = '?';
96const std::locale& loc = std::locale();
97std::ostringstream stm;
98while( *s != L'\0' ) {
99stm << std::use_facet< std::ctype<wchar_t> >( loc ).narrow( *s++, dfault );
100}
101info.files.push_back(std::string(stm.str()));
102
103//toUTF8(udispName, dispName);
104
105// Bring up a message box that displays the current file being processed
106//MessageBox(GetForegroundWindow(), szName, L"Current file received", MB_OK);
107}
108
109// Finally, we destroy the HDROP handle so the extra memory
110// allocated by the application is released.
111DragFinish(hDrop);
112
113instance->events().notifyDragEvent(info);
114
115}
116
117
118static LRESULT CALLBACK winProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam){
119
120//we catch close and destroy messages
121//and send them to OF
122
123switch(Msg){
124
125case WM_CLOSE:
126OF_EXIT_APP(0);
127break;
128case WM_DESTROY:
129OF_EXIT_APP(0);
130break;
131case WM_DROPFILES:
132
133// Call our function we created to display all the files.
134// We pass the wParam because it's the HDROP handle.
135HandleFiles(wParam);
136break;
137default:
138return CallWindowProc(currentWndProc, handle, Msg, wParam, lParam);
139break;
140}
141
142return 0;
143}
144
145//--------------------------------------
146static void fixCloseWindowOnWin32(){
147
148//get the HWND
149handle = WindowFromDC(wglGetCurrentDC());
150
151// enable drag and drop of files.
152DragAcceptFiles (handle, TRUE);
153
154//store the current message event handler for the window
155currentWndProc = (WNDPROC)GetWindowLongPtr(handle, GWLP_WNDPROC);
156
157//tell the window to now use our event handler!
158SetWindowLongPtr(handle, GWLP_WNDPROC, (LONG_PTR)winProc);
159}
160
161#endif
162
163
164
165
166//----------------------------------------------------------
167ofAppGlutWindow::ofAppGlutWindow(){
168windowMode = OF_WINDOW;
169bNewScreenMode = true;
170nFramesSinceWindowResized = 0;
171buttonInUse = 0;
172bEnableSetupScreen = true;
173requestedWidth = 0;
174requestedHeight = 0;
175nonFullScreenX = -1;
176nonFullScreenY = -1;
177displayString = "";
178orientation = OF_ORIENTATION_DEFAULT;
179bDoubleBuffered = true; // LIA
180iconSet = false;
181instance = this;
182windowId = 0;
183}
184
185//lets you enable alpha blending using a display string like:
186// "rgba double samples>=4 depth" ( mac )
187// "rgb double depth alpha samples>=4" ( some pcs )
188//------------------------------------------------------------
189void ofAppGlutWindow::setGlutDisplayString(std::string displayStr){
190displayString = displayStr;
191}
192
193//------------------------------------------------------------
194void ofAppGlutWindow::setDoubleBuffering(bool _bDoubleBuffered){
195bDoubleBuffered = _bDoubleBuffered;
196}
197
198//------------------------------------------------------------
199void ofAppGlutWindow::setup(const ofGLWindowSettings & settings){
200
201int argc = 1;
202char *argv = (char*)"openframeworks";
203char **vptr = &argv;
204glutInit(&argc, vptr);
205
206if( displayString != ""){
207glutInitDisplayString( displayString.c_str() );
208}else{
209if(bDoubleBuffered){
210glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA );
211}else{
212glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH | GLUT_ALPHA );
213}
214}
215
216windowMode = settings.windowMode;
217bNewScreenMode = true;
218
219if (windowMode == OF_FULLSCREEN){
220glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH), glutGet(GLUT_SCREEN_HEIGHT));
221windowId = glutCreateWindow("");
222
223requestedWidth = settings.getWidth();
224requestedHeight = settings.getHeight();
225} else if (windowMode != OF_GAME_MODE){
226glutInitWindowSize(settings.getWidth(), settings.getHeight());
227glutCreateWindow("");
228
229/*
230ofBackground(200,200,200); // default bg color
231ofSetColor(0xFFFFFF); // default draw color
232// used to be black, but
233// black + texture = black
234// so maybe grey bg
235// and "white" fg color
236// as default works the best...
237*/
238
239requestedWidth = glutGet(GLUT_WINDOW_WIDTH);
240requestedHeight = glutGet(GLUT_WINDOW_HEIGHT);
241} else {
242if( displayString != ""){
243glutInitDisplayString( displayString.c_str() );
244}else{
245glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA );
246}
247
248// w x h, 32bit pixel depth, 60Hz refresh rate
249char gameStr[64];
250sprintf( gameStr, "%dx%d:%d@%d", settings.getWidth(), settings.getHeight(), 32, 60 );
251
252glutGameModeString(gameStr);
253
254if (!glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)){
255ofLogError("ofAppGlutWindow") << "setupOpenGL(): selected game mode format " << gameStr << " not available";
256}
257// start fullscreen game mode
258glutEnterGameMode();
259}
260windowW = glutGet(GLUT_WINDOW_WIDTH);
261windowH = glutGet(GLUT_WINDOW_HEIGHT);
262
263currentRenderer = std::shared_ptr<ofBaseRenderer>(new ofGLRenderer(this));
264
265
266#ifndef TARGET_OPENGLES
267glewExperimental = GL_TRUE;
268GLenum err = glewInit();
269if (GLEW_OK != err)
270{
271/* Problem: glewInit failed, something is seriously wrong. */
272ofLogError("ofAppRunner") << "couldn't init GLEW: " << glewGetErrorString(err);
273return;
274}
275#endif
276static_cast<ofGLRenderer*>(currentRenderer.get())->setup();
277setVerticalSync(true);
278
279
280//----------------------
281// setup the callbacks
282
283glutMouseFunc(mouse_cb);
284glutMotionFunc(motion_cb);
285glutPassiveMotionFunc(passive_motion_cb);
286glutIdleFunc(idle_cb);
287glutDisplayFunc(display);
288
289glutKeyboardFunc(keyboard_cb);
290glutKeyboardUpFunc(keyboard_up_cb);
291glutSpecialFunc(special_key_cb);
292glutSpecialUpFunc(special_key_up_cb);
293
294glutReshapeFunc(resize_cb);
295glutEntryFunc(entry_cb);
296#ifdef TARGET_LINUX
297glutCloseFunc(exit_cb);
298#endif
299
300#ifdef TARGET_OSX
301glutDragEventFunc(dragEvent);
302#endif
303
304nFramesSinceWindowResized = 0;
305
306#ifdef TARGET_WIN32
307//----------------------
308// this is specific to windows (respond properly to close / destroy)
309fixCloseWindowOnWin32();
310#endif
311
312#ifdef TARGET_LINUX
313if(!iconSet){
314ofPixels iconPixels;
315#ifdef DEBUG
316iconPixels.allocate(ofIconDebug.width,ofIconDebug.height,ofIconDebug.bytes_per_pixel);
317GIMP_IMAGE_RUN_LENGTH_DECODE(iconPixels.getData(),ofIconDebug.rle_pixel_data,iconPixels.getWidth()*iconPixels.getHeight(),ofIconDebug.bytes_per_pixel);
318#else
319iconPixels.allocate(ofIcon.width,ofIcon.height,ofIcon.bytes_per_pixel);
320GIMP_IMAGE_RUN_LENGTH_DECODE(iconPixels.getData(),ofIcon.rle_pixel_data,iconPixels.getWidth()*iconPixels.getHeight(),ofIcon.bytes_per_pixel);
321#endif
322setWindowIcon(iconPixels);
323}
324#endif
325if (settings.isPositionSet()) {
326setWindowPosition(settings.getPosition().x,settings.getPosition().y);
327}
328
329#ifdef TARGET_OSX
330// The osx implementation of glut changes the cwd, this restores it
331// to wherever it was when the app was started
332ofRestoreWorkingDirectoryToDefault();
333#endif
334}
335
336#ifdef TARGET_LINUX
337//------------------------------------------------------------
338void ofAppGlutWindow::setWindowIcon(const std::string & path){
339ofPixels iconPixels;
340ofLoadImage(iconPixels,path);
341setWindowIcon(iconPixels);
342}
343
344//------------------------------------------------------------
345void ofAppGlutWindow::setWindowIcon(const ofPixels & iconPixels){
346iconSet = true;
347Display *m_display = glXGetCurrentDisplay();
348GLXDrawable m_window = glXGetCurrentDrawable();
349iconSet = true;
350int length = 2+iconPixels.getWidth()*iconPixels.getHeight();
351unsigned long * buffer = new unsigned long[length];
352buffer[0]=iconPixels.getWidth();
353buffer[1]=iconPixels.getHeight();
354for(size_t i=0;i<iconPixels.getWidth()*iconPixels.getHeight();i++){
355buffer[i+2] = iconPixels[i*4+3]<<24;
356buffer[i+2] += iconPixels[i*4]<<16;
357buffer[i+2] += iconPixels[i*4+1]<<8;
358buffer[i+2] += iconPixels[i*4];
359}
360
361XChangeProperty(m_display, m_window, XInternAtom(m_display, "_NET_WM_ICON", False), XA_CARDINAL, 32,
362PropModeReplace, (const unsigned char*)buffer, length);
363delete[] buffer;
364XFlush(m_display);
365}
366#endif
367
368//------------------------------------------------------------
369void ofAppGlutWindow::update(){
370idle_cb();
371}
372
373//------------------------------------------------------------
374void ofAppGlutWindow::draw(){
375display();
376}
377
378//------------------------------------------------------------
379void ofAppGlutWindow::close(){
380events().notifyExit();
381events().disable();
382#ifdef TARGET_LINUX
383glutLeaveMainLoop();
384#else
385std::exit(0);
386#endif
387}
388
389//------------------------------------------------------------
390void ofAppGlutWindow::loop(){
391instance->events().notifySetup();
392instance->events().notifyUpdate();
393glutMainLoop();
394}
395
396//------------------------------------------------------------
397void ofAppGlutWindow::setWindowTitle(std::string title){
398glutSetWindowTitle(title.c_str());
399}
400
401//------------------------------------------------------------
402glm::vec2 ofAppGlutWindow::getWindowSize(){
403return {windowW, windowH};
404}
405
406//------------------------------------------------------------
407glm::vec2 ofAppGlutWindow::getWindowPosition(){
408int x = glutGet(GLUT_WINDOW_X);
409int y = glutGet(GLUT_WINDOW_Y);
410if( orientation == OF_ORIENTATION_DEFAULT || orientation == OF_ORIENTATION_180 ){
411return {x,y};
412}else{
413return {y,x};
414}
415}
416
417//------------------------------------------------------------
418glm::vec2 ofAppGlutWindow::getScreenSize(){
419int width = glutGet(GLUT_SCREEN_WIDTH);
420int height = glutGet(GLUT_SCREEN_HEIGHT);
421if( orientation == OF_ORIENTATION_DEFAULT || orientation == OF_ORIENTATION_180 ){
422return {width, height};
423}else{
424return {height, width};
425}
426}
427
428//------------------------------------------------------------
429int ofAppGlutWindow::getWidth(){
430if( orientation == OF_ORIENTATION_DEFAULT || orientation == OF_ORIENTATION_180 ){
431return windowW;
432}
433return windowH;
434}
435
436//------------------------------------------------------------
437int ofAppGlutWindow::getHeight(){
438if( orientation == OF_ORIENTATION_DEFAULT || orientation == OF_ORIENTATION_180 ){
439return windowH;
440}
441return windowW;
442}
443
444//------------------------------------------------------------
445void ofAppGlutWindow::setOrientation(ofOrientation orientationIn){
446orientation = orientationIn;
447}
448
449//------------------------------------------------------------
450ofOrientation ofAppGlutWindow::getOrientation(){
451return orientation;
452}
453
454//------------------------------------------------------------
455void ofAppGlutWindow::setWindowPosition(int x, int y){
456glutPositionWindow(x,y);
457}
458
459//------------------------------------------------------------
460void ofAppGlutWindow::setWindowShape(int w, int h){
461glutReshapeWindow(w, h);
462// this is useful, esp if we are in the first frame (setup):
463requestedWidth = w;
464requestedHeight = h;
465}
466
467//------------------------------------------------------------
468void ofAppGlutWindow::hideCursor(){
469#if defined(TARGET_OSX) && defined(MAC_OS_X_VERSION_10_7)
470CGDisplayHideCursor(0);
471#else
472glutSetCursor(GLUT_CURSOR_NONE);
473#endif
474}
475
476//------------------------------------------------------------
477void ofAppGlutWindow::showCursor(){
478#if defined(TARGET_OSX) && defined(MAC_OS_X_VERSION_10_7)
479CGDisplayShowCursor(0);
480#else
481glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
482#endif
483}
484
485//------------------------------------------------------------
486ofWindowMode ofAppGlutWindow::getWindowMode(){
487return windowMode;
488}
489
490//------------------------------------------------------------
491void ofAppGlutWindow::toggleFullscreen(){
492if( windowMode == OF_GAME_MODE)return;
493
494if( windowMode == OF_WINDOW ){
495windowMode = OF_FULLSCREEN;
496}else{
497windowMode = OF_WINDOW;
498}
499
500bNewScreenMode = true;
501}
502
503//------------------------------------------------------------
504void ofAppGlutWindow::setFullscreen(bool fullscreen){
505if( windowMode == OF_GAME_MODE)return;
506
507if(fullscreen && windowMode != OF_FULLSCREEN){
508bNewScreenMode = true;
509windowMode = OF_FULLSCREEN;
510}else if(!fullscreen && windowMode != OF_WINDOW) {
511bNewScreenMode = true;
512windowMode = OF_WINDOW;
513}
514}
515
516//------------------------------------------------------------
517void ofAppGlutWindow::enableSetupScreen(){
518bEnableSetupScreen = true;
519}
520
521//------------------------------------------------------------
522void ofAppGlutWindow::disableSetupScreen(){
523bEnableSetupScreen = false;
524}
525
526//------------------------------------------------------------
527void ofAppGlutWindow::setVerticalSync(bool bSync){
528//----------------------------
529#ifdef TARGET_WIN32
530//----------------------------
531if (bSync) {
532if (WGL_EXT_swap_control) {
533wglSwapIntervalEXT (1);
534}
535} else {
536if (WGL_EXT_swap_control) {
537wglSwapIntervalEXT (0);
538}
539}
540//----------------------------
541#endif
542//----------------------------
543
544//--------------------------------------
545#ifdef TARGET_OSX
546//--------------------------------------
547GLint sync = bSync == true ? 1 : 0;
548CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &sync);
549//--------------------------------------
550#endif
551//--------------------------------------
552
553//--------------------------------------
554#ifdef TARGET_LINUX
555//--------------------------------------
556void (*swapIntervalExt)(Display *,GLXDrawable, int) = (void (*)(Display *,GLXDrawable, int)) glXGetProcAddress((const GLubyte*) "glXSwapIntervalEXT");
557if(swapIntervalExt){
558Display *dpy = glXGetCurrentDisplay();
559GLXDrawable drawable = glXGetCurrentDrawable();
560if (drawable) {
561swapIntervalExt(dpy, drawable, bSync ? 1 : 0);
562return;
563}
564}
565void (*swapInterval)(int) = (void (*)(int)) glXGetProcAddress((const GLubyte*) "glXSwapIntervalSGI");
566if(!swapInterval) {
567swapInterval = (void (*)(int)) glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA");
568}
569if(swapInterval) {
570swapInterval(bSync ? 1 : 0);
571}
572//--------------------------------------
573#endif
574//--------------------------------------
575}
576
577//------------------------------------------------------------
578ofCoreEvents & ofAppGlutWindow::events(){
579return coreEvents;
580}
581
582//------------------------------------------------------------
583std::shared_ptr<ofBaseRenderer> & ofAppGlutWindow::renderer(){
584return currentRenderer;
585}
586
587//------------------------------------------------------------
588void ofAppGlutWindow::display(void){
589
590//--------------------------------
591// when I had "glutFullScreen()"
592// in the initOpenGl, I was gettings a "heap" allocation error
593// when debugging via visual studio. putting it here, changes that.
594// maybe it's voodoo, or I am getting rid of the problem
595// by removing something unrelated, but everything seems
596// to work if I put fullscreen on the first frame of display.
597
598if (windowMode != OF_GAME_MODE){
599if ( bNewScreenMode ){
600if( windowMode == OF_FULLSCREEN){
601
602//----------------------------------------------------
603// before we go fullscreen, take a snapshot of where we are:
604nonFullScreenX = glutGet(GLUT_WINDOW_X);
605nonFullScreenY = glutGet(GLUT_WINDOW_Y);
606//----------------------------------------------------
607
608glutFullScreen();
609
610#ifdef TARGET_OSX
611[NSApp setPresentationOptions:NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock];
612#ifdef MAC_OS_X_VERSION_10_7 //needed for Lion as when the machine reboots the app is not at front level
613if( instance->events().getFrameNum() <= 10 ){ //is this long enough? too long?
614[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
615}
616#endif
617#endif
618
619}else if( windowMode == OF_WINDOW ){
620
621glutReshapeWindow(requestedWidth, requestedHeight);
622
623//----------------------------------------------------
624// if we have recorded the screen posion, put it there
625// if not, better to let the system do it (and put it where it wants)
626if (instance->events().getFrameNum() > 0){
627glutPositionWindow(nonFullScreenX,nonFullScreenY);
628}
629//----------------------------------------------------
630
631#ifdef TARGET_OSX
632[NSApp setPresentationOptions:NSApplicationPresentationDefault];
633#endif
634}
635bNewScreenMode = false;
636}
637}
638
639instance->currentRenderer->startRender();
640
641if( bEnableSetupScreen ) instance->currentRenderer->setupScreen();
642
643instance->events().notifyDraw();
644
645#ifdef TARGET_WIN32
646if (instance->currentRenderer->getBackgroundAuto() == false){
647// on a PC resizing a window with this method of accumulation (essentially single buffering)
648// is BAD, so we clear on resize events.
649if (nFramesSinceWindowResized < 3){
650instance->currentRenderer->clear();
651} else {
652if ( (instance->events().getFrameNum() < 3 || nFramesSinceWindowResized < 3) && bDoubleBuffered) glutSwapBuffers();
653else glFlush();
654}
655} else {
656if(bDoubleBuffered){
657glutSwapBuffers();
658} else{
659glFlush();
660}
661}
662#else
663if (instance->currentRenderer->getBackgroundAuto() == false){
664// in accum mode resizing a window is BAD, so we clear on resize events.
665if (nFramesSinceWindowResized < 3){
666instance->currentRenderer->clear();
667}
668}
669if(bDoubleBuffered){
670glutSwapBuffers();
671} else{
672glFlush();
673}
674#endif
675
676instance->currentRenderer->finishRender();
677
678nFramesSinceWindowResized++;
679
680}
681
682//------------------------------------------------------------
683void ofAppGlutWindow::swapBuffers() {
684glutSwapBuffers();
685}
686
687//--------------------------------------------
688void ofAppGlutWindow::startRender() {
689renderer()->startRender();
690}
691
692//--------------------------------------------
693void ofAppGlutWindow::finishRender() {
694renderer()->finishRender();
695}
696
697//------------------------------------------------------------
698static void rotateMouseXY(ofOrientation orientation, int w, int h, int &x, int &y) {
699int savedY;
700switch(orientation) {
701case OF_ORIENTATION_180:
702x = w - x;
703y = h - y;
704break;
705
706case OF_ORIENTATION_90_RIGHT:
707savedY = y;
708y = x;
709x = w-savedY;
710break;
711
712case OF_ORIENTATION_90_LEFT:
713savedY = y;
714y = h - x;
715x = savedY;
716break;
717
718case OF_ORIENTATION_DEFAULT:
719default:
720break;
721}
722}
723
724//------------------------------------------------------------
725void ofAppGlutWindow::mouse_cb(int button, int state, int x, int y) {
726rotateMouseXY(orientation, instance->getWidth(), instance->getHeight(), x, y);
727
728
729switch(button){
730case GLUT_LEFT_BUTTON:
731button = OF_MOUSE_BUTTON_LEFT;
732break;
733case GLUT_RIGHT_BUTTON:
734button = OF_MOUSE_BUTTON_RIGHT;
735break;
736case GLUT_MIDDLE_BUTTON:
737button = OF_MOUSE_BUTTON_MIDDLE;
738break;
739}
740
741if (instance->events().getFrameNum() > 0){
742if (state == GLUT_DOWN) {
743instance->events().notifyMousePressed(x, y, button);
744} else if (state == GLUT_UP) {
745instance->events().notifyMouseReleased(x, y, button);
746}
747
748buttonInUse = button;
749}
750}
751
752//------------------------------------------------------------
753void ofAppGlutWindow::motion_cb(int x, int y) {
754rotateMouseXY(orientation, instance->getWidth(), instance->getHeight(), x, y);
755
756if (instance->events().getFrameNum() > 0){
757instance->events().notifyMouseDragged(x, y, buttonInUse);
758}
759
760}
761
762//------------------------------------------------------------
763void ofAppGlutWindow::passive_motion_cb(int x, int y) {
764rotateMouseXY(orientation, instance->getWidth(), instance->getHeight(), x, y);
765
766if (instance->events().getFrameNum() > 0){
767instance->events().notifyMouseMoved(x, y);
768}
769}
770
771//------------------------------------------------------------
772void ofAppGlutWindow::dragEvent(char ** names, int howManyFiles, int dragX, int dragY){
773
774// TODO: we need position info on mac passed through
775ofDragInfo info;
776info.position.x = dragX;
777info.position.y = instance->getHeight()-dragY;
778
779for (int i = 0; i < howManyFiles; i++){
780std::string temp = std::string(names[i]);
781info.files.push_back(temp);
782}
783
784instance->events().notifyDragEvent(info);
785}
786
787
788//------------------------------------------------------------
789void ofAppGlutWindow::idle_cb(void) {
790instance->events().notifyUpdate();
791
792glutPostRedisplay();
793}
794
795
796//------------------------------------------------------------
797void ofAppGlutWindow::keyboard_cb(unsigned char key, int x, int y) {
798instance->events().notifyKeyPressed(key);
799}
800
801//------------------------------------------------------------
802void ofAppGlutWindow::keyboard_up_cb(unsigned char key, int x, int y){
803instance->events().notifyKeyReleased(key);
804}
805
806//------------------------------------------------------
807void ofAppGlutWindow::special_key_cb(int key, int x, int y) {
808instance->events().notifyKeyPressed(special_key_to_of(key));
809}
810
811//------------------------------------------------------------
812void ofAppGlutWindow::special_key_up_cb(int key, int x, int y) {
813instance->events().notifyKeyReleased(special_key_to_of(key));
814}
815
816//------------------------------------------------------------
817int ofAppGlutWindow::special_key_to_of(int key) {
818switch (key) {
819case GLUT_KEY_F1:
820return OF_KEY_F1;
821
822case GLUT_KEY_F2:
823return OF_KEY_F2;
824
825case GLUT_KEY_F3:
826return OF_KEY_F3;
827
828case GLUT_KEY_F4:
829return OF_KEY_F4;
830
831case GLUT_KEY_F5:
832return OF_KEY_F5;
833
834case GLUT_KEY_F6:
835return OF_KEY_F6;
836
837case GLUT_KEY_F7:
838return OF_KEY_F7;
839
840case GLUT_KEY_F8:
841return OF_KEY_F8;
842
843case GLUT_KEY_F9:
844return OF_KEY_F9;
845
846case GLUT_KEY_F10:
847return OF_KEY_F10;
848
849case GLUT_KEY_F11:
850return OF_KEY_F11;
851
852case GLUT_KEY_F12:
853return OF_KEY_F12;
854
855case GLUT_KEY_LEFT:
856return OF_KEY_LEFT;
857
858case GLUT_KEY_UP:
859return OF_KEY_UP;
860
861case GLUT_KEY_RIGHT:
862return OF_KEY_RIGHT;
863
864case GLUT_KEY_DOWN:
865return OF_KEY_DOWN;
866
867case GLUT_KEY_PAGE_UP:
868return OF_KEY_PAGE_UP;
869
870case GLUT_KEY_PAGE_DOWN:
871return OF_KEY_PAGE_DOWN;
872
873case GLUT_KEY_HOME:
874return OF_KEY_HOME;
875
876case GLUT_KEY_END:
877return OF_KEY_END;
878
879case GLUT_KEY_INSERT:
880return OF_KEY_INSERT;
881
882default:
883return 0;
884}
885}
886
887//------------------------------------------------------------
888void ofAppGlutWindow::resize_cb(int w, int h) {
889windowW = w;
890windowH = h;
891
892instance->events().notifyWindowResized(w, h);
893
894nFramesSinceWindowResized = 0;
895}
896
897//------------------------------------------------------------
898void ofAppGlutWindow::entry_cb(int state) {
899if (state == GLUT_ENTERED){
900instance->events().notifyMouseEntered(instance->events().getMouseX(), instance->events().getMouseY());
901}else if (state == GLUT_LEFT){
902instance->events().notifyMouseExited(instance->events().getMouseX(), instance->events().getMouseY());
903}
904}
905
906//------------------------------------------------------------
907void ofAppGlutWindow::exit_cb() {
908instance->events().notifyExit();
909instance->events().disable();
910}
911