Página principal | Jerarquía de la clase | Lista alfabética | Lista de componentes | Lista de archivos | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

_motifcb.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= _motifcb.cc                                       Desde octubre de 1998 =
00003 //=-------------------------------------------------------------------------=
00004 //= Definicion de las funciones CALLBACK para el uso del API Motif en       =
00005 //= AQUYNZA.  Las cosas aqui definidas solo se usan en _motif.cc.           =
00006 //=-------------------------------------------------------------------------=
00007 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO   =
00008 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN   =
00009 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES,     = 
00010 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO,        =
00011 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO,  =
00012 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA   =
00013 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES       =
00014 //= ("ACTIVIDADES DE ALGO RIESGO").                                         =
00015 //=-------------------------------------------------------------------------=
00016 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00017 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00018 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00019 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00020 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00021 //===========================================================================
00022 
00023 #include "jed_defs.h"  // Incluir antes que nada, en ese modulo se definen 
00024                        // aspectos importantes para la portabilidad del sistema
00025 
00026 #include "jed_gl.h"
00027 #include "framework/gui/_motifcb.h"
00028 #include "framework/gui/jed_menu.h"
00029 
00030 #ifdef MOTIF_ENABLED
00031 
00032 #include "lista.cc"
00033 
00034 #ifdef GL_ENABLED
00035   #ifdef SUN4SOL2_ENABLED
00036     #include <X11/GLw/GLwDrawA.h>      // Encabezados OpenGL + Motif + GLx
00037   #endif
00038   #ifndef SUN4SOL2_ENABLED
00039     #include <GL/GLwDrawA.h>      // Encabezados OpenGL + Motif + GLx
00040   #endif
00041 #endif
00042 
00043 #include <Xm/RowColumn.h>
00044 
00045 #include <stdio.h>
00046 
00047 //#define DEBUG_VISTAS 1
00048 
00049 //===========================================================================
00050 //= VARIABLES GLOBALES                                                      =
00051 //===========================================================================
00052 
00053 //- Apuntadores a funcion con los callbacks del framework AQUYNZA GUI -------
00054 void (*MOTIFGUI_draw_callback)(int);
00055 int  (*MOTIFGUI_tick_callback)(int);
00056 void (*MOTIFGUI_resize_callback)(int x_tam, int y_tam, int context_id);
00057 int  (*MOTIFGUI_mouse_callback)(EVENTO_GUI *e, int context_id) = NULL;
00058 int  (*MOTIFGUI_keyboard_callback)(EVENTO_GUI *e, int context_id);
00059 int  (*MOTIFGUI_ejecutor)(int idc, int context_id);
00060 void (*MOTIFGUI_multiview_callback)
00061         (int operacion, int id_vista, char *detalles,
00062          char *menu, char *botonera);
00063 
00064 //- Otras vainas ------------------------------------------------------------
00065 int QUIERO_pintarme_motif = 0;
00066 VENTANA_GUI_MOTIF LA_ventana; // OJO: Deberia estar en _motif.cc?
00067 
00068 #ifdef GL_ENABLED
00069 extern GLXContext glx_context;    // Esto no deberia estar en un .h?
00070 #endif
00071 
00072 extern BOOLEAN SUICIDIO_del_logo;
00073 extern Widget gl_draw;
00074 extern Widget toplevel;
00075 
00076 static int CONTEXTO_pintado = -1;     // Usados por la clase CONTEXTO_GLX
00077 static int CONTEXTO_seleccionado = -1;
00078 static int CONTEXTO_anterior = -1;
00079 
00089 static unsigned long ESPERA_entre_cuadros = 1000/24;
00090 
00091 //===========================================================================
00092 //= Constantes y macros                                                     =
00093 //===========================================================================
00094 
00095 #define MANEJE_MOUSE_X()                                                 \
00096         evento.mouse_old_x = evento.mouse_x;                             \
00097         evento.mouse_old_y = evento.mouse_y;                             \
00098         evento.mouse_delta_x = bevent->x - evento.mouse_old_x;           \
00099         evento.mouse_delta_y = bevent->y - evento.mouse_old_y;           \
00100         evento.mouse_x = bevent->x;                                      \
00101         evento.mouse_y = bevent->y;                                      \
00102                                                                          \
00103         if ( MOTIFGUI_mouse_callback ) {                                 \
00104            cod = MOTIFGUI_mouse_callback(&evento, CONTEXTO_seleccionado);\
00105            if ( cod != 0 ) {                                             \
00106             QUIERO_pintarme_motif = cod;                                 \
00107             LA_ventana.activacion(CONTEXTO_seleccionado, cod);           \
00108            }                                                             \
00109         }
00110 
00111 //===========================================================================
00112 //= CLASE CONTEXTO_GLX                                                      =
00113 //===========================================================================
00114 
00115 CONTEXTO_GLX::CONTEXTO_GLX(int _id, Widget w)
00116 {
00117     id = _id;
00118     gl_draw = w;
00119     activo = FALSE;
00120 
00121     Dimension xtam, ytam;
00122 
00123     XtVaGetValues(w, XmNwidth, &xtam, XmNheight, &ytam, NULL);
00124     x_tam = xtam;    y_tam = ytam;
00125   #ifdef DEBUG_VISTAS
00126     printf("<CONTEXTO %d>: Inicio de tamanno <%d, %d>\n", id, x_tam, y_tam);
00127   #endif
00128 }
00129 
00130 void
00131 CONTEXTO_GLX::activar(void)
00137 {
00138     activo = TRUE;
00139 }
00140 
00141 void
00142 CONTEXTO_GLX::desactivar(void)
00148 {
00149     activo = FALSE;
00150 }
00151 
00152 void
00153 CONTEXTO_GLX::resize(int xtam, int ytam)
00158 {
00159   #ifdef DEBUG_VISTAS
00160     printf("<CONTEXTO %d> Resize a (%d,%d)\n", id, x_tam, y_tam);
00161     fflush(stdout);
00162   #endif
00163     x_tam = xtam;
00164     y_tam = ytam;
00165     CONTEXTO_pintado = -1;
00166 }
00167 
00168 void
00169 CONTEXTO_GLX::pintar(void)
00198 {
00199     //- Solo se pinta si es necesario ---------------------------------------
00200     if ( !activo ) return;
00201 
00202 #ifdef GL_ENABLED
00203 
00204   #ifdef DEBUG_VISTAS
00205     printf("<CONTEXTO %d>: draw\n", id);  fflush(stdout);
00206   #endif
00207 
00208     //- PINTADO DE LA VISTA -------------------------------------------------
00209     // 1. Active la ventana apropiada
00210     glXMakeCurrent(XtDisplay(gl_draw), XtWindow(gl_draw), glx_context);
00211 
00212     // 2. Reconfigure OpenGL si es necesario
00213     if ( CONTEXTO_pintado != id ) {
00214         MOTIFGUI_resize_callback(x_tam, y_tam, id);
00215     }
00216 
00217     // 3. Notifique a la VISTA que debe pintarse
00218     MOTIFGUI_draw_callback(id);
00219 
00220     // 4. Administre la tecnica de animacion de buffer doble
00221     glFlush();    glFinish ();
00222     // OJO: Diferencia entre MesaGL y OpenGL (?)
00223     /*  XMesaSwapBuffers ();*/
00224     GLwDrawingAreaSwapBuffers(gl_draw);
00225     //
00226 
00227     //- Ya que se pinto, se marca para que no vuelva a pintarse por ahora ---
00228     CONTEXTO_pintado = id;  // Marca de reconfiguracion OpenGL
00229     desactivar();           // Marca de dibujado
00230 
00231     // OJO: Esto es un machete para que si hay un LOGO, se borre apenas se 
00232     //      pintar alguna vista... pero conceptualmente, esto no hace parte
00233     //      de este metodo.
00234     SUICIDIO_del_logo = TRUE;
00235 #endif
00236 }
00237 
00238 //===========================================================================
00239 //= CLASE VENTANA_GUI_MOTIF                                                 =
00240 //===========================================================================
00241 
00242 VENTANA_GUI_MOTIF::VENTANA_GUI_MOTIF()
00243 {
00244     ;
00245 }
00246 
00247 VENTANA_GUI_MOTIF::~VENTANA_GUI_MOTIF()
00248 {
00249     int i;
00250 
00251     for ( i = 0; i < lista_contextos.tam(); i++ ) {
00252         delete lista_contextos[i];
00253     }
00254     lista_contextos.elim();
00255 }
00256 
00257 void
00258 VENTANA_GUI_MOTIF::pintar(void)
00259 {
00260     int i;
00261 
00262   #ifdef DEBUG_VISTAS
00263     printf("<DRAW> ALL!\n");
00264   #endif
00265     for ( i = 0; i < lista_contextos.tam(); i++ ) {
00266         lista_contextos[i]->pintar();
00267     }
00268 }
00269 
00270 int
00271 VENTANA_GUI_MOTIF::busque_id(Widget w)
00272 {
00273     int i;
00274 
00275     for ( i = 0; i < lista_contextos.tam(); i++ ) {
00276         if ( lista_contextos[i]->gl_draw == w ) {
00277             return lista_contextos[i]->id;
00278         }
00279     }
00280 
00281     return -1;
00282 }
00283 
00284 void
00285 VENTANA_GUI_MOTIF::activacion(int id_contexto, int code)
00295 {
00296     int i;
00297 
00298     if ( code < 0 ) {
00299         for ( i = 0; i < lista_contextos.tam(); i++ ) {
00300             lista_contextos[i]->activar();
00301         }
00302       }
00303       else if ( code ) {
00304         for ( i = 0; i < lista_contextos.tam(); i++ ) {
00305             if ( lista_contextos[i]->id == id_contexto ) {
00306                 lista_contextos[i]->activar();
00307                 return;
00308             }
00309         }
00310     }
00311 }
00312 
00313 //===========================================================================
00314 //= FUNCIONES CALLBACK MOTIF                                                =
00315 //===========================================================================
00316 
00317 void
00318 motif_starttimer_callback(Widget w)
00321 {
00322     XtAppAddTimeOut(XtWidgetToApplicationContext(w),
00323         ESPERA_entre_cuadros, motif_tick_callback,
00324         (XtPointer)w);
00325 }
00326 
00327 void
00328 motif_tick_callback(XtPointer client_data, XtIntervalId * /*id*/)
00331 {
00332     //- Administra la funcion tick de AQUYNZA ------------------------------
00333     int i, code;
00334 
00335     code = MOTIFGUI_tick_callback(1);
00336     if ( code ) {
00337         for ( i = 0; i < LA_ventana.lista_contextos.tam(); i++ ) {
00338             LA_ventana.lista_contextos[i]->activar();
00339         }
00340         QUIERO_pintarme_motif = -1;
00341     }
00342 
00343     //- Administra el esquema general de pintado de vistas -----------------
00344     if ( QUIERO_pintarme_motif != 0 ) LA_ventana.pintar();
00345     QUIERO_pintarme_motif = 0;
00346     
00347     //- Reactiva este tick -------------------------------------------------
00348     Widget w = (Widget)client_data;
00349 
00350     motif_starttimer_callback(w); 
00351 }
00352 
00353 void
00354 motif_draw_specific(Widget /*w*/, XtPointer ptr)
00360 {
00361     CONTEXTO_GLX *Contexto_glx = (CONTEXTO_GLX*)ptr;
00362 
00363     Contexto_glx->activar();
00364     Contexto_glx->pintar();
00365 }
00366 
00367 void
00368 motif_resize(Widget w, XtPointer data, XtPointer /*callData*/)
00371 {
00372     Dimension x_tam, y_tam;
00373     CONTEXTO_GLX *Contexto_glx = (CONTEXTO_GLX*)data;
00374 
00375     XtVaGetValues(w, XmNwidth, &x_tam, XmNheight, &y_tam, NULL);
00376     Contexto_glx->resize((int)x_tam, (int)y_tam);
00377 }
00378 
00379 void 
00380 motif_button(Widget /*w*/, XtPointer client_data,  XEvent *e, Boolean * /*cont*/)
00386 {
00387     XButtonEvent *be = (XButtonEvent*)e;
00388     Widget menu = (Widget)client_data;
00389 
00390     if ( be->button == 3 ) {
00391         XmMenuPosition(menu, be);
00392         XtManageChild(menu);
00393     }
00394 }
00395 
00396 void
00397 motif_ejecutor(Widget /*widget*/, XtPointer elemento, XtPointer /*contexto*/)
00405 {
00406     int *idc = (int *)elemento;
00407     int cod = MOTIFGUI_ejecutor((*idc), CONTEXTO_anterior);
00408 
00409     if ( cod != 0 ) {
00410         LA_ventana.activacion(CONTEXTO_anterior, cod);
00411         QUIERO_pintarme_motif = cod;
00412     }
00413 }
00414 
00415 void
00416 motif_gl_input(Widget w, XEvent *event, String * /*args*/,
00417                unsigned int * /*num_args*/)
00423 {
00424     static EVENTO_GUI evento;
00425     int cod;
00426     XButtonEvent *bevent = (XButtonEvent *)event;
00427 
00428 #ifdef GL_ENABLED
00429     glXMakeCurrent(XtDisplay(w), XtWindow(w), glx_context);
00430 #endif
00431 
00432     if ( event->type == EnterNotify ) {
00433         XtSetKeyboardFocus(toplevel, w);
00434         CONTEXTO_anterior = CONTEXTO_seleccionado;
00435         CONTEXTO_seleccionado = LA_ventana.busque_id(w);
00436       }
00437       else if ( event->type == LeaveNotify ) {
00438         XtSetKeyboardFocus(toplevel, toplevel);
00439         CONTEXTO_anterior = CONTEXTO_seleccionado;
00440         CONTEXTO_seleccionado = -1;
00441       }
00442       else if( event->type == KeyPress ) {
00443         XKeyEvent *ke = (XKeyEvent*)event;
00444         KeySym codigo;
00445         char buf[1];
00446 
00447         evento.tipo_de_evento = ETYPE_KEY_DOWN;
00448         if ( XLookupString(ke, buf, 1, &codigo, NULL) ) {
00449             Xkeycode2JEDkeycode(&evento, codigo);
00450           }
00451           else {
00452             codigo = XLookupKeysym(ke, 0);
00453             Xkeycode2JEDkeycode(&evento, codigo);
00454         }
00455 
00456         cod = MOTIFGUI_keyboard_callback(&evento, CONTEXTO_seleccionado);
00457         if ( cod != 0 ) {
00458             QUIERO_pintarme_motif = cod;
00459             LA_ventana.activacion(CONTEXTO_seleccionado, cod);
00460         }
00461       }
00462       else if( event->type == KeyRelease ) {
00463         XKeyEvent *ke = (XKeyEvent*)event;
00464         KeySym codigo;
00465         char buf[1];
00466 
00467         evento.tipo_de_evento = ETYPE_KEY_UP;
00468         if ( XLookupString(ke, buf, 1, &codigo, NULL) ) {
00469             Xkeycode2JEDkeycode(&evento, codigo);
00470           }
00471           else {
00472             codigo = XLookupKeysym(ke, 0);
00473             Xkeycode2JEDkeycode(&evento, codigo);
00474         }
00475 
00476         //- OJO: QUE SERA MEJOR HACER AQUI? ----------------------------------
00477         /*
00478         cod = MOTIFGUI_keyboard_callback(&evento, CONTEXTO_seleccionado);
00479         if ( cod != 0 ) {
00480             QUIERO_pintarme_motif = cod;
00481             LA_ventana.activacion(CONTEXTO_seleccionado, cod);
00482         }*/
00483       }
00484       else if ( event->type == ButtonPress ) {
00485         evento.tipo_de_evento = ETYPE_BUTTON_DOWN;
00486         if ( bevent->button == 1 ) {                                     
00487             evento.mouse_button_mask |= 0x01;                            
00488         }                                                                
00489         if ( bevent->button == 2 ) {                                     
00490             evento.mouse_button_mask |= 0x02;                            
00491         }                                                                
00492         if ( bevent->button == 3 ) {                                     
00493             evento.mouse_button_mask |= 0x04;                            
00494         }                                                                
00495         MANEJE_MOUSE_X();
00496       }
00497       else if ( event->type == ButtonRelease ) {
00498         evento.tipo_de_evento = ETYPE_BUTTON_UP;
00499         if ( bevent->button == 1 ) {                                     
00500             evento.mouse_button_mask &= ~(0x01);                            
00501         }                                                                
00502         if ( bevent->button == 2 ) {                                     
00503             evento.mouse_button_mask &= ~(0x02);                            
00504         }                                                                
00505         if ( bevent->button == 3 ) {                                     
00506             evento.mouse_button_mask &= ~(0x04);                            
00507         }                                                                
00508         MANEJE_MOUSE_X();
00509       }
00510       else if ( event->type == MotionNotify ) {
00511         evento.tipo_de_evento = ETYPE_MOUSE_MOVE;
00512         MANEJE_MOUSE_X();
00513       }
00514     ;
00515 }
00516 
00517 #endif // MOTIF_ENABLED
00518 
00519 //===========================================================================
00520 //= EOF                                                                     =
00521 //===========================================================================
00522 

Este archivo HTML ha sido generado automáticamente a partir del código fuente AQUYNZA. NO LO EDITE. Para mayor información contacte al autor.