1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

another GLUT problem On MAC ( different with WINDOWS)

Discussion in 'Mac Programming' started by ccjimmy, Apr 29, 2011.

  1. macrumors newbie

    #1
    My program create a window using GLUT,
    when this program running on WINDOWS XP, the "glutEntryFunc" works well, which means when I leave the window I created by "glutCreateWindow" and click other windows by mouse_L button, the window will loss focus,when I enter the window I created and click by hit mouse_L button, the Window will retrieve the Focus.

    but on MAC OS, when my mouse leave the Window without mouse click, it will lose Focus, why?

    how can I make it works well as in WINDOWS XP on MAC OS?

    below is the sample code, it will works both on MAC OS and WINDOWS XP.


    #include <stdio.h>
    #include "GLUT.h"
    #include <stdlib.h>

    void Update(int para)
    {
    glutPostRedisplay();
    glutTimerFunc(17,Update,0);
    }

    void exitfunc(int para)
    {
    exit(0);
    }
    void key_process(unsigned char key,int x,int y)
    {
    if(key == '\033')//ESC
    {
    exit(0);
    }
    }

    void display()
    {
    glClear(GL_COLOR_BUFFER_BIT);
    glutSwapBuffers();
    }

    void focus_lost(int bAct)
    {
    if(bAct == GLUT_ENTERED)
    {
    printf("get focus \n");
    }
    else
    {
    printf("lose focus\n");
    }
    }

    int main(int argc, char ** argv)
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    {
    glutInitWindowSize(1024,768);
    }
    glutCreateWindow("Xcode Glut Demo");
    glutTimerFunc(17, Update,0);
    glutDisplayFunc(display);
    glutKeyboardFunc(key_process);
    glutEntryFunc(focus_lost);
    glutMainLoop();
    }
     
  2. macrumors 65816

    jiminaus

    #2
    You're mistaken about the behaviour of the entry callback. It's an entry callback, not a focus callback. It is meant to be called when the mouse enters or leaves the window, not just when window gains or looses focus. The Windows behaviour is wrong here. See the GLUT3 spec: http://www.opengl.org/resources/libraries/glut/spec3/node53.html

    AFAIK you can't get notifications for when the window gains or loses focus using just GLUT.
     
  3. macrumors newbie

    #3
    yes, I was mistaken...

    besides GLUT, any idear for me to handle gain/loss focus of my program?
     
  4. macrumors 65816

    jiminaus

    #4
    It involves some Objective-C, but I've coded a solution which gets your focus_lost function called when the application itself loses focus. This is the same as the window losing focus, assuming you only ever have one window open at a time.

    If you use XCode, just add focuslistener.h and focuslistener.m to your project. You might also need to add the Cocoa framework to your target.

    If you're compiling from Terminal, put focuslistener.h and focuslistener.m next to main.c and the compile with:
    Code:
    gcc -framework GLUT -framework OpenGL -framework Cocoa -o gluttest main.c focuslistener.m
    
    Change gluttest to whatever you want the executable to be called.

    main.c
    Code:
    #include <stdio.h>
    #include <GLUT/GLUT.h>
    #include <stdlib.h>
    
    [color=blue]#ifdef __APPLE__
    #include "focuslistener.h"
    #endif[/color]
    
    void Update(int para)
    {
        glutPostRedisplay();
        glutTimerFunc(17,Update,0);
    }
    
    void exitfunc(int para)
    {
        exit(0);
    }
    
    void key_process(unsigned char key,int x,int y)
    {	
        if(key == '\033')//ESC
        {	
            exit(0);
        }
    }
    
    void display() 
    { 
        glClear(GL_COLOR_BUFFER_BIT);
        glutSwapBuffers();
    }
    
    void focus_lost(int bAct)
    {
        if(bAct == GLUT_ENTERED)
        {
            printf("get focus \n");
        }
        else
        {
            printf("lose focus\n");
        }
    }
    
    [color=blue]void myEntryFunc(void (*callback)(int))
    {
    #ifdef __APPLE__
        setupFocusListener(callback);
    #else
        glutEntryFunc(callback);
    #endif
    }[/color]
    
    int main(int argc, char ** argv) 
    { 
        glutInit(&argc, argv); 
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
        {
            glutInitWindowSize(1024,768);	
        }
        glutCreateWindow("Xcode Glut Demo"); 
        glutTimerFunc(17, Update,0);
        glutDisplayFunc(display);
        glutKeyboardFunc(key_process);
        [color=blue]myEntryFunc(focus_lost);[/color]
        glutMainLoop(); 
    }
    
    focuslistener.h
    Code:
    #ifdef __OBJC__
    
    #import <Foundation/Foundation.h>
    
    @interface FocusListener : NSObject {
    @private
        void (*callback)(int);
    }
    
    @property (assign, nonatomic) void (*callback)(int);
    
    - (void)applicationDidBecomeActiveNotification:(NSNotification *)aNotification;
    - (void)applicationDidResignActiveNotification:(NSNotification *)aNotification;
    
    @end
    
    #endif
    
    void setupFocusListener(void (*callback)(int));
    
    focustlistener.m
    Code:
    #import "focuslistener.h"
    #import <Cocoa/Cocoa.h>
    #import <GLUT/GLUT.h>
    
    @implementation FocusListener
    
    @synthesize callback;
    
    - (id)init
    {
        self = [super init];
        if (self) {
            callback = NULL;
        }
        return self;
    }
    
    - (void)applicationDidBecomeActiveNotification:(NSNotification *)aNotification
    {
        if (callback) {
            callback(GLUT_ENTERED);
        }
    }
    
    - (void)applicationDidResignActiveNotification:(NSNotification *)aNotification
    {
        if (callback) {
            callback(GLUT_LEFT);
        }
    }
    
    @end
    
    void setupFocusListener(void (*callback)(int))
    {
        static FocusListener *listener = nil;
        
        if (!listener) {
            listener = [[FocusListener alloc] init];
            NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
            [center addObserver:listener selector:@selector(applicationDidBecomeActiveNotification:) name:NSApplicationDidBecomeActiveNotification object:nil];
            [center addObserver:listener selector:@selector(applicationDidResignActiveNotification:) name:NSApplicationDidResignActiveNotification object:nil];
        }
        
        listener.callback = callback;    
    }
    
     

Share This Page