~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to api/graphics2_unix.cpp

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// This file is part of BOINC.
2
 
// http://boinc.berkeley.edu
3
 
// Copyright (C) 2008 University of California
4
 
//
5
 
// BOINC is free software; you can redistribute it and/or modify it
6
 
// under the terms of the GNU Lesser General Public License
7
 
// as published by the Free Software Foundation,
8
 
// either version 3 of the License, or (at your option) any later version.
9
 
//
10
 
// BOINC is distributed in the hope that it will be useful,
11
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 
// See the GNU Lesser General Public License for more details.
14
 
//
15
 
// You should have received a copy of the GNU Lesser General Public License
16
 
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
17
 
 
18
 
// unix-specific graphics stuff
19
 
//
20
 
#include "config.h"
21
 
#include <stdlib.h>
22
 
#include <stdio.h>    
23
 
#include <setjmp.h>    
24
 
#include <unistd.h> 
25
 
#include <pthread.h> 
26
 
#include <signal.h>
27
 
#include <cstring>
28
 
#include "x_opengl.h"
29
 
 
30
 
#include "app_ipc.h"
31
 
#include "util.h"
32
 
#include "filesys.h"
33
 
 
34
 
#include "boinc_gl.h"
35
 
#include "boinc_glut.h"
36
 
#include "boinc_api.h"
37
 
#include "graphics2.h"
38
 
#include "diagnostics.h"
39
 
 
40
 
#define TIMER_INTERVAL_MSEC 30
41
 
 
42
 
static int xpos = 100, ypos = 100, width = 600, height = 400;
43
 
static int clicked_button;
44
 
static int win=0;
45
 
static int checkparentcounter=0;
46
 
 
47
 
#ifdef __APPLE__
48
 
#include <sys/param.h>  // for MAXPATHLEN
49
 
 
50
 
static bool need_show = false;
51
 
#endif
52
 
 
53
 
bool fullscreen;
54
 
 
55
 
void boinc_close_window_and_quit(const char* p) {
56
 
    fprintf(stderr, "Quitting: %s\n", p);
57
 
    exit(0);
58
 
}
59
 
 
60
 
void boinc_close_window_and_quit_aux() {
61
 
    boinc_close_window_and_quit("GLUT close");
62
 
}
63
 
 
64
 
// This callback is invoked when a user presses a key.
65
 
//
66
 
void keyboardD(unsigned char key, int /*x*/, int /*y*/) {
67
 
    if (fullscreen) {
68
 
        boinc_close_window_and_quit("key down");
69
 
    } else {
70
 
        boinc_app_key_press((int) key, 0);
71
 
    }
72
 
}
73
 
 
74
 
void keyboardU(unsigned char key, int /*x*/, int /*y*/) {
75
 
    if (fullscreen) {
76
 
        boinc_close_window_and_quit("key up");
77
 
    } else {
78
 
        boinc_app_key_release((int) key, 0);
79
 
    }
80
 
}
81
 
 
82
 
void mouse_click(int button, int state, int x, int y){
83
 
    clicked_button = button;
84
 
    if (fullscreen) {
85
 
        boinc_close_window_and_quit("mouse click");
86
 
    } else {
87
 
        if (state) {
88
 
            boinc_app_mouse_button(x, y, button, false);
89
 
        } else {
90
 
            boinc_app_mouse_button(x, y, button, true);
91
 
        }
92
 
    }
93
 
}
94
 
 
95
 
void mouse_click_move(int x, int y){
96
 
    if (fullscreen) {
97
 
        boinc_close_window_and_quit("mouse move");
98
 
    } else if (clicked_button == 2){
99
 
        boinc_app_mouse_move(x, y, false, false, true);
100
 
    } else if (clicked_button == 1){
101
 
        boinc_app_mouse_move(x, y, false, true, false);
102
 
    } else if (clicked_button == 0){
103
 
        boinc_app_mouse_move(x, y, true, false, false);
104
 
    } else{
105
 
        boinc_app_mouse_move(x, y, false, false, false);
106
 
    }
107
 
}
108
 
 
109
 
static void maybe_render() {
110
 
    int new_xpos, new_ypos, new_width, new_height;
111
 
    static int size_changed = 0;
112
 
    
113
 
    new_xpos = glutGet(GLUT_WINDOW_X);
114
 
    new_ypos = glutGet(GLUT_WINDOW_Y);
115
 
    new_width = glutGet(GLUT_WINDOW_WIDTH);
116
 
    new_height = glutGet(GLUT_WINDOW_HEIGHT);
117
 
    
118
 
    
119
 
    if (throttled_app_render(new_width, new_height, dtime())) {
120
 
        glutSwapBuffers();
121
 
        if (! fullscreen) {
122
 
            // If user has changed window size, wait until it stops 
123
 
            // changing and then write the new dimensions to file
124
 
            if ((new_xpos != xpos) || (new_ypos != ypos) || 
125
 
                (new_width != width) || (new_height != height)
126
 
                ) {
127
 
                    size_changed = 1;
128
 
                    xpos = new_xpos;
129
 
                    ypos = new_ypos;
130
 
                    width = new_width;
131
 
                    height = new_height;
132
 
                } else {
133
 
                    if (size_changed && (++size_changed > 10)) {
134
 
                        size_changed = 0;
135
 
                        FILE *f = boinc_fopen("gfx_info", "w");
136
 
                        if (f) {
137
 
                            // ToDo: change this to XML
138
 
                            fprintf(f, "%d %d %d %d\n", xpos, ypos, width, height);
139
 
                            fclose(f);
140
 
                        }
141
 
                    }
142
 
                }               // End if (new size != previous size) else 
143
 
            }                   // End if (! fullscreen)
144
 
#ifdef __APPLE__
145
 
        MacGLUTFix(fullscreen);
146
 
        if (need_show) {
147
 
            glutShowWindow();
148
 
            need_show = false;
149
 
        }
150
 
#endif
151
 
    }
152
 
}
153
 
 
154
 
static void make_window() {
155
 
    char window_title[256];
156
 
    get_window_title(window_title, 256);
157
 
 
158
 
    win = glutCreateWindow(window_title); 
159
 
    glutReshapeFunc(app_graphics_resize);
160
 
    glutKeyboardFunc(keyboardD);
161
 
    glutKeyboardUpFunc(keyboardU);
162
 
    glutMouseFunc(mouse_click);
163
 
    glutMotionFunc(mouse_click_move);
164
 
    glutDisplayFunc(maybe_render); 
165
 
    glEnable(GL_DEPTH_TEST);
166
 
 
167
 
    app_graphics_init();
168
 
  
169
 
#ifdef __APPLE__
170
 
    glutWMCloseFunc(boinc_close_window_and_quit_aux);   // Enable the window's close box
171
 
    BringAppToFront();
172
 
    // Show window only after a successful call to throttled_app_render(); 
173
 
    // this avoids momentary display of old image when screensaver restarts 
174
 
    // which made image appear to "jump."
175
 
    need_show = true;
176
 
#endif
177
 
 
178
 
    if (fullscreen)  {
179
 
        glutFullScreen();
180
 
    }
181
 
}
182
 
 
183
 
static void boinc_glut_init(int *argc, char** argv) {
184
 
    win = 0;
185
 
 
186
 
    FILE *f = boinc_fopen("gfx_info", "r");
187
 
    if (f) {
188
 
        // ToDo: change this to XML parsing
189
 
        fscanf(f, "%d %d %d %d\n", &xpos, &ypos, &width, &height);
190
 
        fclose(f);
191
 
    }
192
 
 
193
 
    glutInit (argc, argv);
194
 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ALPHA); 
195
 
    glutInitWindowPosition(xpos, ypos);
196
 
    glutInitWindowSize(width, height); 
197
 
}
198
 
 
199
 
static void timer_handler(int) {
200
 
    maybe_render();
201
 
    // When running under a V5 client, the worker app launches the graphics app
202
 
    // so this code kills the graphics when the worker application exits.
203
 
    // Under a V6 client, the Manager or Screensaver launched the graphics app
204
 
    // so this code kills the graphics when the Manager or Screensaver exits.
205
 
    if (--checkparentcounter < 0) {
206
 
        // Check approximately twice per second if parent process still running
207
 
        checkparentcounter = 500 / TIMER_INTERVAL_MSEC;
208
 
        if (getppid() == 1) {
209
 
            // Quit graphics application if parent process no longer running
210
 
            boinc_close_window_and_quit("parent dead");
211
 
        }
212
 
    }
213
 
    glutTimerFunc(TIMER_INTERVAL_MSEC, timer_handler, 0);
214
 
}
215
 
 
216
 
void boinc_graphics_loop(int argc, char** argv) {
217
 
    if (!diagnostics_is_initialized()) {
218
 
        boinc_init_graphics_diagnostics(BOINC_DIAG_DEFAULTS);
219
 
    }
220
 
 
221
 
#ifdef __APPLE__
222
 
    char dir [MAXPATHLEN];
223
 
    getcwd(dir, MAXPATHLEN);
224
 
#endif
225
 
    for (int i=1; i<argc; i++) {
226
 
        if (!strcmp(argv[i], "--fullscreen")) {
227
 
            fullscreen = true;
228
 
        }
229
 
    }
230
 
    boinc_glut_init(&argc, argv);
231
 
    make_window();
232
 
    glutTimerFunc(TIMER_INTERVAL_MSEC, timer_handler, 0);      
233
 
#ifdef __APPLE__
234
 
    // Apparently glut changed our working directory in OS 10.3.9
235
 
    chdir(dir);
236
 
#endif
237
 
    glutMainLoop();
238
 
}
 
1
// This file is part of BOINC.
 
2
// http://boinc.berkeley.edu
 
3
// Copyright (C) 2008 University of California
 
4
//
 
5
// BOINC is free software; you can redistribute it and/or modify it
 
6
// under the terms of the GNU Lesser General Public License
 
7
// as published by the Free Software Foundation,
 
8
// either version 3 of the License, or (at your option) any later version.
 
9
//
 
10
// BOINC is distributed in the hope that it will be useful,
 
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
13
// See the GNU Lesser General Public License for more details.
 
14
//
 
15
// You should have received a copy of the GNU Lesser General Public License
 
16
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
 
17
 
 
18
// unix-specific graphics stuff
 
19
//
 
20
#include "config.h"
 
21
#include <cstdlib>
 
22
#include <cstdio>    
 
23
#include <csetjmp>    
 
24
#include <unistd.h> 
 
25
#include <pthread.h> 
 
26
#include <csignal>
 
27
#include <cstring>
 
28
#include "x_opengl.h"
 
29
 
 
30
#include "app_ipc.h"
 
31
#include "util.h"
 
32
#include "filesys.h"
 
33
 
 
34
#include "boinc_gl.h"
 
35
#include "boinc_glut.h"
 
36
#include "boinc_api.h"
 
37
#include "graphics2.h"
 
38
#include "diagnostics.h"
 
39
 
 
40
#define TIMER_INTERVAL_MSEC 30
 
41
 
 
42
static int xpos = 100, ypos = 100, width = 600, height = 400;
 
43
static int clicked_button;
 
44
static int win=0;
 
45
static int checkparentcounter=0;
 
46
 
 
47
#ifdef __APPLE__
 
48
#include <sys/param.h>  // for MAXPATHLEN
 
49
 
 
50
static bool need_show = false;
 
51
#endif
 
52
 
 
53
bool fullscreen;
 
54
 
 
55
void boinc_close_window_and_quit(const char* p) {
 
56
    char buf[256];
 
57
    fprintf(stderr, "%s Quitting: %s\n", boinc_msg_prefix(buf, sizeof(buf)), p);
 
58
    exit(0);
 
59
}
 
60
 
 
61
void boinc_close_window_and_quit_aux() {
 
62
    boinc_close_window_and_quit("GLUT close");
 
63
}
 
64
 
 
65
// This callback is invoked when a user presses a key.
 
66
//
 
67
void keyboardD(unsigned char key, int /*x*/, int /*y*/) {
 
68
    if (fullscreen) {
 
69
        boinc_close_window_and_quit("key down");
 
70
    } else {
 
71
        boinc_app_key_press((int) key, 0);
 
72
    }
 
73
}
 
74
 
 
75
void keyboardU(unsigned char key, int /*x*/, int /*y*/) {
 
76
    if (fullscreen) {
 
77
        boinc_close_window_and_quit("key up");
 
78
    } else {
 
79
        boinc_app_key_release((int) key, 0);
 
80
    }
 
81
}
 
82
 
 
83
void mouse_click(int button, int state, int x, int y){
 
84
    clicked_button = button;
 
85
    if (fullscreen) {
 
86
        boinc_close_window_and_quit("mouse click");
 
87
    } else {
 
88
        if (state) {
 
89
            boinc_app_mouse_button(x, y, button, false);
 
90
        } else {
 
91
            boinc_app_mouse_button(x, y, button, true);
 
92
        }
 
93
    }
 
94
}
 
95
 
 
96
void mouse_click_move(int x, int y){
 
97
    if (fullscreen) {
 
98
        boinc_close_window_and_quit("mouse move");
 
99
    } else if (clicked_button == 2){
 
100
        boinc_app_mouse_move(x, y, false, false, true);
 
101
    } else if (clicked_button == 1){
 
102
        boinc_app_mouse_move(x, y, false, true, false);
 
103
    } else if (clicked_button == 0){
 
104
        boinc_app_mouse_move(x, y, true, false, false);
 
105
    } else{
 
106
        boinc_app_mouse_move(x, y, false, false, false);
 
107
    }
 
108
}
 
109
 
 
110
static void maybe_render() {
 
111
    int new_xpos, new_ypos, new_width, new_height;
 
112
    static int size_changed = 0;
 
113
    
 
114
    new_xpos = glutGet(GLUT_WINDOW_X);
 
115
    new_ypos = glutGet(GLUT_WINDOW_Y);
 
116
    new_width = glutGet(GLUT_WINDOW_WIDTH);
 
117
    new_height = glutGet(GLUT_WINDOW_HEIGHT);
 
118
    
 
119
    
 
120
    if (throttled_app_render(new_width, new_height, dtime())) {
 
121
        glutSwapBuffers();
 
122
        if (! fullscreen) {
 
123
            // If user has changed window size, wait until it stops 
 
124
            // changing and then write the new dimensions to file
 
125
            if ((new_xpos != xpos) || (new_ypos != ypos) || 
 
126
                (new_width != width) || (new_height != height)
 
127
                ) {
 
128
                    size_changed = 1;
 
129
                    xpos = new_xpos;
 
130
                    ypos = new_ypos;
 
131
                    width = new_width;
 
132
                    height = new_height;
 
133
                } else {
 
134
                    if (size_changed && (++size_changed > 10)) {
 
135
                        size_changed = 0;
 
136
                        FILE *f = boinc_fopen("gfx_info", "w");
 
137
                        if (f) {
 
138
                            // ToDo: change this to XML
 
139
                            fprintf(f, "%d %d %d %d\n", xpos, ypos, width, height);
 
140
                            fclose(f);
 
141
                        }
 
142
                    }
 
143
                }               // End if (new size != previous size) else 
 
144
            }                   // End if (! fullscreen)
 
145
#ifdef __APPLE__
 
146
        MacGLUTFix(fullscreen);
 
147
        if (need_show) {
 
148
            glutShowWindow();
 
149
            need_show = false;
 
150
        }
 
151
#endif
 
152
    }
 
153
}
 
154
 
 
155
static void make_window(const char* title) {
 
156
    char window_title[256];
 
157
    if (title) {
 
158
        strcpy(window_title, title);
 
159
    } else {
 
160
        get_window_title(window_title, 256);
 
161
    }
 
162
 
 
163
    win = glutCreateWindow(window_title); 
 
164
    glutReshapeFunc(app_graphics_resize);
 
165
    glutKeyboardFunc(keyboardD);
 
166
    glutKeyboardUpFunc(keyboardU);
 
167
    glutMouseFunc(mouse_click);
 
168
    glutMotionFunc(mouse_click_move);
 
169
    glutDisplayFunc(maybe_render); 
 
170
    glEnable(GL_DEPTH_TEST);
 
171
 
 
172
    app_graphics_init();
 
173
  
 
174
#ifdef __APPLE__
 
175
    glutWMCloseFunc(boinc_close_window_and_quit_aux);   // Enable the window's close box
 
176
    BringAppToFront();
 
177
    // Show window only after a successful call to throttled_app_render(); 
 
178
    // this avoids momentary display of old image when screensaver restarts 
 
179
    // which made image appear to "jump."
 
180
    need_show = true;
 
181
#endif
 
182
 
 
183
    if (fullscreen)  {
 
184
        glutFullScreen();
 
185
    }
 
186
}
 
187
 
 
188
static void boinc_glut_init(int *argc, char** argv) {
 
189
    win = 0;
 
190
 
 
191
    FILE *f = boinc_fopen("gfx_info", "r");
 
192
    if (f) {
 
193
        // ToDo: change this to XML parsing
 
194
        fscanf(f, "%d %d %d %d\n", &xpos, &ypos, &width, &height);
 
195
        fclose(f);
 
196
    }
 
197
 
 
198
    glutInit (argc, argv);
 
199
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ALPHA); 
 
200
    glutInitWindowPosition(xpos, ypos);
 
201
    glutInitWindowSize(width, height); 
 
202
}
 
203
 
 
204
static void timer_handler(int) {
 
205
    maybe_render();
 
206
    // When running under a V5 client, the worker app launches the graphics app
 
207
    // so this code kills the graphics when the worker application exits.
 
208
    // Under a V6 client, the Manager or Screensaver launched the graphics app
 
209
    // so this code kills the graphics when the Manager or Screensaver exits.
 
210
    if (--checkparentcounter < 0) {
 
211
        // Check approximately twice per second if parent process still running
 
212
        checkparentcounter = 500 / TIMER_INTERVAL_MSEC;
 
213
        if (getppid() == 1) {
 
214
            // Quit graphics application if parent process no longer running
 
215
            boinc_close_window_and_quit("parent dead");
 
216
        }
 
217
    }
 
218
    glutTimerFunc(TIMER_INTERVAL_MSEC, timer_handler, 0);
 
219
}
 
220
 
 
221
void boinc_graphics_loop(int argc, char** argv, const char* title) {
 
222
    if (!diagnostics_is_initialized()) {
 
223
        boinc_init_graphics_diagnostics(BOINC_DIAG_DEFAULTS);
 
224
    }
 
225
 
 
226
#ifdef __APPLE__
 
227
    char dir [MAXPATHLEN];
 
228
    getcwd(dir, MAXPATHLEN);
 
229
#endif
 
230
    for (int i=1; i<argc; i++) {
 
231
        if (!strcmp(argv[i], "--fullscreen")) {
 
232
            fullscreen = true;
 
233
        }
 
234
    }
 
235
    boinc_glut_init(&argc, argv);
 
236
    make_window(title);
 
237
    glutTimerFunc(TIMER_INTERVAL_MSEC, timer_handler, 0);      
 
238
#ifdef __APPLE__
 
239
    // Apparently glut changed our working directory in OS 10.3.9
 
240
    chdir(dir);
 
241
#endif
 
242
    glutMainLoop();
 
243
}