00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "jed_defs.h"
00023
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <stdlib.h>
00027 #include "jed_gl.h"
00028 #include "framework/gui/_glut.h"
00029 #include "lista.cc"
00030
00031 #ifdef GLUT_ENABLED
00032 #include <GL/glut.h>
00033 #endif
00034
00035
00036
00037
00038
00039 #ifndef GLUT_ENABLED
00040
00041 JED_GUI_CLASE_NULA(JED_GLUT_INTERFACE, "JED_GLUT_INTERFACE",
00042 "GLUT", "glut", "GLUT_ENABLED");
00043
00044 #endif
00045
00046 #ifdef GLUT_ENABLED
00047
00048
00049
00050
00051
00052 class VENTANA_GLUT {
00053 private:
00054 int id;
00055 int status;
00056 BOOLEAN por_pintar;
00057 public:
00058 VENTANA_GLUT();
00059
00060 friend class JED_GLUT_INTERFACE;
00061 friend void glut_draw_callback(void);
00062 friend void glut_wstatus_callback(int wstatus);
00063 };
00064
00065 static BOOLEAN CON_glide = FALSE;
00066
00067 VENTANA_GLUT::VENTANA_GLUT()
00068 {
00069 status = -1;
00070 id = -1;
00071 por_pintar = FALSE;
00072 }
00073
00074
00075
00076
00077
00078 static EVENTO_GUI EVENTO_glut;
00079 static int PETICIONES_pendientes = 0;
00080 static BOOLEAN GUI_creada = FALSE;
00081 static int QUIERO_pintarme = 0;
00082 static LISTA<VENTANA_GLUT *> LAS_ventanas;
00083 static int X_mouse = 320;
00084 static int Y_mouse = 240;
00085 static int X_tam = 320;
00086 static int Y_tam = 240;
00087
00088
00089 static int (*GLUTGUI_ejecutor_callback)(int idc, int context_id);
00090 static void (*GLUTGUI_draw_callback)(int);
00091 static int (*GLUTGUI_tick_callback)(int);
00092 static void (*GLUTGUI_resize_callback)(int x_tam, int y_tam, int);
00093 static int (*GLUTGUI_keyboard_callback)(EVENTO_GUI *e, int);
00094 static int (*GLUTGUI_mouse_callback)(EVENTO_GUI *e, int);
00095 static void (*GLUTGUI_multiview_callback)(int operacion, int id_vista,
00096 char *detalles, char *menu, char *botonera);
00097
00098
00099
00100
00101
00102
00103 static void glut_idle_callback(void);
00104 static void glut_menu_callback(int param);
00105 static void glut_resize_callback(int x, int y);
00106 static void glut_mouseentry_callback(int estado);
00107 static void glut_mousestate_callback(int button, int state, int x, int y);
00108 static void glut_mousemove_callback(int x, int y);
00109 static void
00110 glut_keyboard1_callback(unsigned char tecla, int , int );
00111 static void
00112 glut_keyboard2_callback(int tecla, int , int );
00113 void glut_draw_callback(void);
00114 void glut_wstatus_callback(int wstatus);
00115
00116
00117
00118
00119
00120 #define MANEJO_DE_MOUSE_GLUT() \
00121 EVNT_EVENTO_GUI->mouse_old_x = EVNT_EVENTO_GUI->mouse_x;\
00122 EVNT_EVENTO_GUI->mouse_old_y = EVNT_EVENTO_GUI->mouse_y;\
00123 EVNT_EVENTO_GUI->mouse_x = X_mouse = x;\
00124 EVNT_EVENTO_GUI->mouse_y = Y_mouse = y;\
00125 EVNT_EVENTO_GUI->mouse_delta_x=x-EVNT_EVENTO_GUI->mouse_old_x;\
00126 EVNT_EVENTO_GUI->mouse_delta_y=y-EVNT_EVENTO_GUI->mouse_old_y;\
00127 int cod=GLUTGUI_mouse_callback(EVNT_EVENTO_GUI, glutGetWindow());\
00128 if ( CON_glide && \
00129 (EVNT_EVENTO_GUI->mouse_delta_x || \
00130 EVNT_EVENTO_GUI->mouse_delta_y) ) QUIERO_pintarme = 1; \
00131 if ( cod != 0 ) {\
00132 QUIERO_pintarme = cod; \
00133 }
00134
00135 #define VERIFICAR(o) \
00136 if ( !(o) ) { \
00137 fprintf(stderr, "<GLUT> - ERROR FATAL: No hay memoria!\n"); \
00138 fflush(stderr); \
00139 exit(-1); \
00140 }
00141
00142
00143
00144
00145
00146 static void quit_callback(int ) { exit(1); }
00147 static void pintar_nulo(int ) { ; }
00148 static void resize_nulo(int , int , int ) { ; }
00149 static void idle_nulo(void) {
00150 if (QUIERO_pintarme!=0 && !CON_glide) glut_draw_callback(); }
00151 static int evento_nulo(EVENTO_GUI * , int ) { return 0; }
00152
00153
00154
00155
00156
00157 static void
00158 glut_keyboard1_callback(unsigned char tecla, int , int )
00171 {
00172 EVNT_EVENTO_GUI->tipo_de_evento = ETYPE_KEY_DOWN;
00173 GLUTkeycode2JEDkeycode(EVNT_EVENTO_GUI, (int)tecla);
00174 EVNT_EVENTO_GUI->key_mask = 0x00;
00175
00176
00177
00178
00179 int cod=GLUTGUI_keyboard_callback(EVNT_EVENTO_GUI, glutGetWindow());
00180 if ( cod != 0 ) {
00181 QUIERO_pintarme = cod;
00182 return;
00183 }
00184 return;
00185 }
00186
00187 static void
00188 glut_keyboard2_callback(int tecla, int , int )
00201 {
00202 EVNT_EVENTO_GUI->tipo_de_evento = ETYPE_KEY_DOWN;
00203 GLUTkeycode2JEDkeycodeB(EVNT_EVENTO_GUI, tecla);
00204 EVNT_EVENTO_GUI->key_mask = 0x00;
00205
00206
00207
00208
00209
00210
00211 int cod=GLUTGUI_keyboard_callback(EVNT_EVENTO_GUI, glutGetWindow());
00212 if ( cod != 0 ) {
00213 QUIERO_pintarme = cod;
00214 return;
00215 }
00216 return;
00217 }
00218
00219 static void
00220 glut_mouseentry_callback(int )
00225 {
00226 ;
00227 }
00228
00229 static void
00230 glut_mousestate_callback(int button, int state, int x, int y)
00231 {
00232 if ( state ) {
00233 EVNT_EVENTO_GUI->tipo_de_evento = ETYPE_BUTTON_UP;
00234 EVNT_EVENTO_GUI->mouse_button_mask &= ~(0x01 << button);
00235 }
00236 else {
00237 EVNT_EVENTO_GUI->tipo_de_evento = ETYPE_BUTTON_DOWN;
00238 EVNT_EVENTO_GUI->mouse_button_mask |= 0x01 << button;
00239 }
00240 MANEJO_DE_MOUSE_GLUT();
00241 }
00242
00243 static void
00244 glut_mousemove_callback(int x, int y)
00245 {
00246 EVNT_EVENTO_GUI->tipo_de_evento = ETYPE_MOUSE_MOVE;
00247 MANEJO_DE_MOUSE_GLUT();
00248 }
00249
00250 static void
00251 glut_idle_callback(void)
00252 {
00253 int cod = GLUTGUI_tick_callback(glutGetWindow());
00254 if ( cod != 0 ) { QUIERO_pintarme = cod; }
00255
00256 if ( QUIERO_pintarme != 0 && !CON_glide ) glut_draw_callback();
00257 }
00258
00259 static void
00260 glut_resize_callback(int x, int y)
00261 {
00262 X_tam = x;
00263 Y_tam = y;
00264 GLUTGUI_resize_callback(x, y, glutGetWindow());
00265 QUIERO_pintarme = 1;
00266 }
00267
00268 static void
00269 glut_menu_callback(int param)
00270 {
00271 if ( !GLUTGUI_ejecutor_callback ) return;
00272 int cod = GLUTGUI_ejecutor_callback(param, glutGetWindow());
00273 if ( cod != 0 ) QUIERO_pintarme = cod;
00274 }
00275
00276 static void
00277 extra_cursor(void)
00278 {
00279 if ( !CON_glide ) return;
00280
00281 glViewport(0, 0, X_tam, Y_tam);
00282
00283 float x, y;
00284
00285 x = 2*(float)X_mouse/(float)X_tam - 1;
00286 y = 2*(float)(Y_tam - Y_mouse)/(float)Y_tam - 1;
00287
00288 glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();
00289 glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity();
00290 glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST);
00291 glDisable(GL_TEXTURE_2D); glDisable(GL_FOG);
00292 glDisable(GL_ALPHA_TEST);
00293
00294 glColor4d(0, 1, 0, 0.4);
00295 glEnable(GL_BLEND);
00296 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00297 glTranslated(x, y, 0);
00298 glScaled(0.04, 0.04, 0.04);
00299 glTranslated(1, -1, 0);
00300 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00301 glBegin(GL_TRIANGLES);
00302 glVertex2d(1, 0.5);
00303 glVertex2d(-1, 1);
00304 glVertex2d(0, 0.2);
00305
00306 glVertex2d(0, 0.2);
00307 glVertex2d(-1, 1);
00308 glVertex2d(0, -1);
00309 glEnd();
00310 glEnable(GL_LIGHTING);
00311 glEnable(GL_DEPTH_TEST);
00312 glPopMatrix();
00313 glMatrixMode(GL_PROJECTION); glPopMatrix();
00314 glMatrixMode(GL_MODELVIEW);
00315 glDisable(GL_BLEND);
00316 }
00317
00318 void
00319 glut_draw_callback(void)
00328 {
00329 int i, b;
00330
00331 b = glutGetWindow();
00332 switch ( QUIERO_pintarme ) {
00333 case -1:
00334 for ( i = 0; i < LAS_ventanas.tam(); i++ ) {
00335 glutSetWindow(LAS_ventanas[i]->id);
00336 GLUTGUI_draw_callback(LAS_ventanas[i]->id);
00337 glFlush(); glFinish();
00338 }
00339 for ( i = 0; BUFFER_doble && i < LAS_ventanas.tam(); i++ ) {
00340 glutSetWindow(LAS_ventanas[i]->id);
00341 extra_cursor();
00342 glutSwapBuffers();
00343 }
00344 glutSetWindow(b);
00345 break;
00346 case 1:
00347 for ( i = 0; i < LAS_ventanas.tam(); i++ ) {
00348 if ( LAS_ventanas[i]->por_pintar ||
00349 LAS_ventanas[i]->id == b ) {
00350 glutSetWindow(LAS_ventanas[i]->id);
00351 GLUTGUI_draw_callback(LAS_ventanas[i]->id);
00352 glFlush(); glFinish();
00353 }
00354 }
00355 for ( i = 0; BUFFER_doble && i < LAS_ventanas.tam(); i++ ) {
00356 if ( LAS_ventanas[i]->por_pintar ||
00357 LAS_ventanas[i]->id == b ) {
00358 glutSetWindow(LAS_ventanas[i]->id);
00359 extra_cursor();
00360 glutSwapBuffers();
00361 LAS_ventanas[i]->por_pintar = FALSE;
00362 }
00363 }
00364 glutSetWindow(b);
00365 break;
00366 case 0: default:
00367 break;
00368 }
00369
00370 QUIERO_pintarme = 0;
00371 }
00372
00373
00374
00375
00376
00377 JED_GLUT_INTERFACE::JED_GLUT_INTERFACE()
00378 {
00379 BUFFER_doble = TRUE;
00380
00381 GLUTGUI_draw_callback = pintar_nulo;
00382 GLUTGUI_tick_callback = NULL;
00383 GLUTGUI_mouse_callback = evento_nulo;
00384 GLUTGUI_keyboard_callback = evento_nulo;
00385 GLUTGUI_resize_callback = resize_nulo;
00386 GLUTGUI_multiview_callback = NULL;
00387 GLUTGUI_ejecutor_callback = NULL;
00388
00389 _xtam = 320;
00390 _ytam = 240;
00391 _nombre = NULL;
00392 }
00393
00394 JED_GLUT_INTERFACE::~JED_GLUT_INTERFACE()
00395 {
00396 ;
00397 }
00398
00399 void JED_GLUT_INTERFACE::solicitar_repintado(void){;}
00400
00401 void JED_GLUT_INTERFACE::set_draw_callback( void (*p)(int context_id) )
00402 { GLUTGUI_draw_callback = p; }
00403
00404 void JED_GLUT_INTERFACE::set_tick_callback( int (*p)(int context_id) )
00405 { GLUTGUI_tick_callback = p; }
00406
00407 void JED_GLUT_INTERFACE::set_keyboard_callback(
00408 int (*p)(EVENTO_GUI *e, int context_id) )
00409 { GLUTGUI_keyboard_callback = p; }
00410
00411 void JED_GLUT_INTERFACE::set_mouse_callback(
00412 int (*p)(EVENTO_GUI *e, int context_id) )
00413 { GLUTGUI_mouse_callback = p; }
00414
00415 void JED_GLUT_INTERFACE::set_resize_callback(
00416 void (*p)(int x_tam, int y_tam, int context_id) )
00417 { GLUTGUI_resize_callback = p; }
00418
00419 void JED_GLUT_INTERFACE::set_ejecutor( int (*p)(int idc, int context_id) )
00420 { GLUTGUI_ejecutor_callback = p; }
00421
00422 void JED_GLUT_INTERFACE::set_multiview_callback(void (*p)(int operacion,
00423 int id_vista, char *detalles, char *menu, char *botonera) )
00424 { GLUTGUI_multiview_callback = p; }
00425
00426 BOOLEAN
00427 JED_GLUT_INTERFACE::crear(int * Argc, char *argv[], int x_tam, int y_tam, char *nombre)
00428 {
00429 EVNT_EVENTO_GUI = &EVENTO_glut;
00430
00431 if ( getenv("MESA_GLX_FX") ) CON_glide = TRUE;
00432
00433
00434 glutInit(Argc, argv);
00435 _xtam = x_tam;
00436 _ytam = y_tam;
00437 _nombre = new char [strlen(nombre) + 1];
00438 strcpy(_nombre, nombre);
00439
00440
00441 leer_gui("etc/spanish.gui");
00442
00443 return TRUE;
00444 }
00445
00446 #ifdef NONONO
00447 void
00448 tmp_visibility_callback(int i)
00449 {
00450 printf("<GLUT/VISIBILITY>[%d] = %d\n", glutGetWindow(), i);
00451 fflush(stdout);
00452 }
00453 #endif
00454
00455 void
00456 glut_wstatus_callback(int wstatus)
00457 {
00458 int i, id;
00459 VENTANA_GLUT *V = NULL;
00460
00461
00462 id = glutGetWindow();
00463 for ( i = 0; i < LAS_ventanas.tam(); i++ ) {
00464 if ( LAS_ventanas[i]->id == id ) {
00465 V = LAS_ventanas[i];
00466 break;
00467 }
00468 }
00469 if ( !V ) return;
00470
00471
00472 if ( V->status >= 0 && wstatus != V->status && wstatus > 0 ) {
00473 if ( !QUIERO_pintarme ) QUIERO_pintarme = 1;
00474 V->por_pintar = TRUE;
00475 }
00476 else QUIERO_pintarme = 0;
00477 V->status = wstatus;
00478 }
00479
00480 void
00481 glut_draw1_callback(void)
00482 {
00483 GLUTGUI_draw_callback(1);
00484 extra_cursor();
00485 glFlush(); glFinish();
00486 glutSwapBuffers();
00487 glutPostRedisplay();
00488 }
00489
00490 void
00491 JED_GLUT_INTERFACE::crear_ventana_glut(void)
00492 {
00493
00494 VENTANA_GLUT *Nueva_ventana;
00495 int tipo;
00496
00497 Nueva_ventana = new VENTANA_GLUT();
00498 VERIFICAR(Nueva_ventana);
00499
00500 tipo = GLUT_DEPTH | GLUT_RGBA;
00501 tipo |= (BUFFER_doble) ? GLUT_DOUBLE : GLUT_SINGLE;
00502 glutInitWindowSize(_xtam, _ytam);
00503 glutInitDisplayMode((GLenum)tipo);
00504 Nueva_ventana->id = glutCreateWindow(_nombre);
00505 if ( Nueva_ventana->id < 1 ) {
00506 delete Nueva_ventana;
00507 return;
00508 }
00509
00510
00511 glutReshapeFunc(glut_resize_callback);
00512
00513 glutKeyboardFunc(glut_keyboard1_callback);
00514 glutSpecialFunc(glut_keyboard2_callback);
00515 glutEntryFunc(glut_mouseentry_callback);
00516 glutMouseFunc(glut_mousestate_callback);
00517 glutMotionFunc(glut_mousemove_callback);
00518 glutPassiveMotionFunc(glut_mousemove_callback);
00519
00520
00521
00522 if ( CON_glide ) glutDisplayFunc(glut_draw1_callback);
00523 else glutDisplayFunc(glut_draw_callback);
00524
00525
00526
00527 char menu[1024];
00528 char botonera[1024];
00529
00530 if ( GLUTGUI_multiview_callback ) {
00531 GLUTGUI_multiview_callback(GUI_CREAR_VISTA, Nueva_ventana->id,
00532 "default", menu, botonera);
00533
00534 GLUTGUI_resize_callback(_xtam, _ytam, Nueva_ventana->id);
00535 }
00536 if ( LAS_ventanas.tam() < 1 ) strcpy(menu, "GLOBAL");
00537
00538
00539 GUI_MENU *Global = resolver_menu(menu);
00540 int menu_glut;
00541
00542 if ( lista_menus.tam() > 0 && Global ) {
00543 menu_glut = Global->crear_glut(glut_menu_callback);
00544 }
00545 else {
00546 menu_glut = glutCreateMenu(quit_callback);
00547 glutSetMenu(menu_glut);
00548 glutAddMenuEntry("Salir", 666);
00549 }
00550
00551 glutSetMenu(menu_glut);
00552 glutSetWindow(Nueva_ventana->id);
00553 glutAttachMenu(GLUT_RIGHT_BUTTON);
00554
00555
00556 LAS_ventanas.anx(Nueva_ventana);
00557 glutSetWindow(Nueva_ventana->id);
00558 }
00559
00560 void
00561 JED_GLUT_INTERFACE::ejecutar(void)
00562 {
00563 if ( GLUTGUI_tick_callback ) glutIdleFunc(glut_idle_callback);
00564 else glutIdleFunc(idle_nulo);
00565
00566
00567 for ( ; PETICIONES_pendientes > 0; PETICIONES_pendientes-- ) {
00568 crear_ventana_glut();
00569 }
00570 GUI_creada = TRUE;
00571
00572
00573 glutMainLoop();
00574 }
00575
00576 void
00577 JED_GLUT_INTERFACE::finalizar(void)
00578 {
00579 int i;
00580
00581 for ( i = 0; i < LAS_ventanas.tam(); i++ ) {
00582 glutSetWindow(LAS_ventanas[i]->id);
00583 glutIdleFunc(NULL);
00584 glutDestroyWindow(LAS_ventanas[i]->id);
00585 delete LAS_ventanas[i];
00586 }
00587 LAS_ventanas.elim();
00588
00589
00590
00591
00592 exit(1);
00593 }
00594
00595 void
00596 JED_GLUT_INTERFACE::solicitar_nueva_ventana(void)
00599 {
00600 if ( GUI_creada ) {
00601 crear_ventana_glut();
00602 }
00603 else {
00604 PETICIONES_pendientes++;
00605 }
00606 }
00607
00608 BOOLEAN
00609 JED_GLUT_INTERFACE::anexar_controles(LISTA <CONTROL_GUI *> * ,
00610 REPOSITORIO_DE_ENTIDADES * )
00611 {
00612 fprintf(stderr, "<JED_INTERFACE> ERROR: Los controles GUI no estan\n"
00613 " implemetados en la interface actual. Intente Motif.\n");
00614 fflush(stderr);
00615 return FALSE;
00616 }
00617
00618 #endif // GLUT_ENABLED
00619
00620
00621
00622
00623