/****************************************************************************** * Copyright (C) 1999 Chris Abernethy * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * * USA. * * * ****************************************************************************** * * This is a short, heavily commented demo program designed to help * get you started using the GtkGLArea widget in your gtk programs. * * The program creates a window with a GtkGLArea widget and a quit button. * Some commonly used callbacks are registered, but nothing is drawn into * the window. * * Please email me with any corrections, additions, or clarifications! * * Created 11.14.1999 * Modified 11.14.1999 * * Compile command: * * gcc gtkglarea_demo.c `gtk-config --libs --cflags` -lMesaGL -lMesaGLU -lgtkgl * *****************************************************************************/ /* --------------------------------------------------------------------------- * This file has been modified by H. James Parker during * October 2000 - January 2002 for educational purposes while learning OpenGL * programing. * * Please compare with original file for diffrences. * ------------------------------------------------------------------------- */ /* Change Log: * * 12/17/01 - Added 3 button mouse support; Updated copyright notice and added * change log; * * 01/01/02 - Modified Initiailization and resize functions; */ #include #include #include #include #include #include #include #include /* Define a constant for the value of PI */ #define GL_PI 3.1415f #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* * --- Data structures */ typedef struct { GtkWidget *notebook_page; GtkWidget *glarea; gint page_number; GLfloat xRot; GLfloat yRot; GLfloat zRot; GLfloat zoom; gint current; } typDrawingArea; /* * --- Function Prototypes */ GtkWidget *create_glarea (void); gint glarea_button_release (GtkWidget*, GdkEventButton*); gint glarea_button_press (GtkWidget*, GdkEventButton*); gint glarea_motion_notify (GtkWidget*, GdkEventMotion*); gint glarea_draw (GtkWidget*, GdkEventExpose*); gint glarea_reshape (GtkWidget*, GdkEventConfigure*); gint glarea_init (GtkWidget*); gint glarea_destroy (GtkWidget*); /* --- This has been modified and simplfied --- */ int main (int argc, char *argv[]); /* --- Added Functions --- */ gint glarea_keyboard_press (GtkWidget *widget, GdkEventKey *event); static void CreateMainWindow (void); gint EndProgram (void); static gint PrintDebugInfo (gchar *szMessage); /* --- custom functions added here --- */ void RenderScene (void); void PageSwitch (GtkWidget *widget, GtkNotebookPage *page, gint page_num); GtkWidget *add_notebook_page (GtkWidget *notebook, char *szName); GtkWidget *create_notebook (GtkWidget *dialog_window, GtkPositionType pos); int create_glarea_page ( GtkWidget *notebook_page, GtkWidget *draw_area ); GSList *insert_notebook_page(GSList *list, typDrawingArea *page); typDrawingArea *find_notebook_page(GSList *list, gint page_number); void ZoomIn (GtkWidget *widget, gpointer data); void ZoomOut (GtkWidget *widget, gpointer data); /* * --- Global data variables */ GtkWidget *debug_label; GSList *page_list = NULL; typDrawingArea *current; /****************************************************************************** * Main Program * * --- This is where it all begins ... *****************************************************************************/ int main (int argc, char *argv[]) { /* --- Initialize GTK --- */ gtk_init (&argc, &argv); /* --- Initialize tooltips --- */ /* tooltips = gtk_tooltips_new( ); */ /* --- Create the frontend to the application --- */ CreateMainWindow ( ); /* --- Let GTK do its stuff --- */ gtk_main ( ); return 0; } /****************************************************************************** * EndProgram ( ) * * --- This is where it all ends ... *****************************************************************************/ gint EndProgram ( ) { gtk_main_quit ( ); return FALSE; } /****************************************************************************** * PrintDebugInfo ( ) * * Prints debug information to a label on bottom of window *****************************************************************************/ static gint PrintDebugInfo (gchar *szMessage) { gchar buffer[50]; sprintf (buffer, "%s", szMessage); gtk_label_set (GTK_LABEL (debug_label), buffer); return TRUE; } /*****************************************************************************/ /* */ /* Function: create_glarea (void) */ /* */ /* This function performs the necessary operations to construct a GtkGlarea */ /* widget. These operations include creating the widget, setting the size */ /* of the widget, and registering callbacks for the widget. */ /* */ /* This is a good place to add function calls for any GtkGlarea */ /* initialization that you need to do. */ /* */ /*****************************************************************************/ GtkWidget *create_glarea (void) { GtkWidget *glarea; /* Choose the attributes that we would like for our visual. */ /* These attributes are passed to glXChooseVisual by the */ /* gdk (see gdk_gl_choose_visual in gdkgl.c from the */ /* GtkGlarea distro). */ /* */ /* */ /* From the glXChooseVisual manpage: */ /* */ /* glXChooseVisual returns a pointer to an XVisualInfo */ /* structure describing the visual that best meets a */ /* minimum specification. */ /* */ /* Check out the manpage for a complete list of attributes */ /* and their descriptions. */ int attrlist[] = { GDK_GL_RGBA, GDK_GL_DOUBLEBUFFER, GDK_GL_DEPTH_SIZE, 1, GDK_GL_NONE }; /* First things first! Make sure that OpenGL is supported */ /* before trying to do OpenGL stuff! */ if(gdk_gl_query() == FALSE) { g_print("OpenGL not supported!\n"); return NULL; } /* Now, create the GtkGLArea using the attribute list that */ /* we defined above. */ if ((glarea = GTK_WIDGET(gtk_gl_area_new(attrlist))) == NULL) { g_print("Error creating GtkGLArea!\n"); return NULL; } /* Indicate which events we are interested in receiving in */ /* in the window allocated to our glarea widget. */ /* */ /* Check out gdk/gdktypes.h in your include directory for a */ /* complete list of event masks that you can use. */ gtk_widget_set_events(GTK_WIDGET(glarea), GDK_EXPOSURE_MASK| GDK_BUTTON_PRESS_MASK| GDK_BUTTON_RELEASE_MASK| GDK_POINTER_MOTION_MASK| GDK_POINTER_MOTION_HINT_MASK| GDK_KEY_PRESS_MASK); /* Here we register the callbacks for the specific events */ /* we are interested in handling. Event handling is beyond */ /* the scope of this demo, but a good place to start for */ /* learning about this is the gtk web pages at www.gtk.org */ /* */ /* The following callback registration code registers */ /* callbacks for some of the more common things that you */ /* might want to do with an OpenGL window. */ /* button_release_event - The user has released one of the */ /* mouse buttons in the window. */ gtk_signal_connect (GTK_OBJECT(glarea), "button_release_event", GTK_SIGNAL_FUNC(glarea_button_release), NULL); /* button_press_event - The user has pressed one of the */ /* mouse buttons in the window. */ gtk_signal_connect (GTK_OBJECT(glarea), "button_press_event", GTK_SIGNAL_FUNC(glarea_button_press), NULL); /* motion_notify_event - The mouse is moving in the window. */ gtk_signal_connect (GTK_OBJECT(glarea), "motion_notify_event", GTK_SIGNAL_FUNC(glarea_motion_notify), NULL); /* For compatibilty with the examples in the "OpenGL Super Bible" * I'm adding the abilty to rotate the drawn objects via the keyboard * press on the arrow keys ... */ gtk_signal_connect (GTK_OBJECT(glarea), "key_press_event", GTK_SIGNAL_FUNC (glarea_keyboard_press), NULL); /* expose_event - The window was exposed and the contents */ /* need to be redrawn. */ gtk_signal_connect (GTK_OBJECT(glarea), "expose_event", GTK_SIGNAL_FUNC(glarea_draw), NULL); /* configure_event - The window has been resized. You will */ /* probably want to call your reshape */ /* function here. */ gtk_signal_connect (GTK_OBJECT(glarea), "configure_event", GTK_SIGNAL_FUNC(glarea_reshape), NULL); /* realize - The window has been created, this is where you */ /* can hook up your initialization routines. */ gtk_signal_connect (GTK_OBJECT(glarea), "realize", GTK_SIGNAL_FUNC(glarea_init), NULL); /* destroy - The window has received a destroy event, this */ /* is where you should do any cleanup that needs */ /* to happen, such as de-allocating data objects */ /* that you have added to your GtkGLArea. */ gtk_signal_connect (GTK_OBJECT(glarea), "destroy", GTK_SIGNAL_FUNC (glarea_destroy), NULL); gtk_widget_set_usize(GTK_WIDGET(glarea), 256, 256); GTK_WIDGET_SET_FLAGS(glarea, GTK_CAN_FOCUS); return (glarea); } /*****************************************************************************/ /* */ /* Function: glarea_button_release (GtkWidget*, GdkEventButton*) */ /* */ /* This function handles button-release events for the GtkGLArea into which */ /* we are drawing. */ /* */ /*****************************************************************************/ gint glarea_button_release (GtkWidget *widget, GdkEventButton *event) { int x = event->x; int y = event->y; gchar buffer[50]; if (event->button == 1) { /* Mouse button 1 was released */ sprintf(buffer, "Button 1 Release at x = %d, y = %d\n", x, y ); PrintDebugInfo ( buffer ); /* PrintDebugInfo ("Button 1 Release at x = %d, y = %d\n", x, y); */ return TRUE; } if (event->button == 2) { /* Mouse button 2 was released */ sprintf(buffer, "Button 2 Release at x = %d, y = %d\n", x, y ); PrintDebugInfo ( buffer ); /* PrintDebugInfo ("Button 2 Release at x = %d, y = %d\n", x, y); */ return TRUE; } if (event->button == 3) { /* Mouse button 3 was released */ sprintf(buffer, "Button 3 Release at x = %d, y = %d\n", x, y ); PrintDebugInfo ( buffer ); /* PrintDebugInfo ("Button 3 Release at x = %d, y = %d\n", x, y); */ return TRUE; } return FALSE; } /*****************************************************************************/ /* */ /* Function: glarea_button_press (GtkWidget*, GdkEventButton*) */ /* */ /* This function handles button-press events for the GtkGLArea into which we */ /* are drawing. */ /* */ /*****************************************************************************/ gint glarea_button_press (GtkWidget *widget, GdkEventButton *event) { int x = event->x; int y = event->y; gchar buffer[50]; if (event->button == 1) { /* Mouse button 1 was engaged */ sprintf(buffer, "Button 1 Press at x = %d, y = %d\n", x, y ); PrintDebugInfo ( buffer ); /* PrintDebugInfo ("Button 1 Press at x = %d, y = %d\n", x, y); */ return TRUE; } if (event->button == 2) { /* Mouse button 2 was engaged */ sprintf(buffer, "Button 2 Press at x = %d, y = %d\n", x, y ); PrintDebugInfo ( buffer ); /* PrintDebugInfo ("Button 2 Press at x = %d, y = %d\n", x, y); */ return TRUE; } if (event->button == 3) { /* Mouse button 3 was engaged */ sprintf(buffer, "Button 3 Press at x = %d, y = %d\n", x, y ); PrintDebugInfo ( buffer ); /* PrintDebugInfo ("Button 3 Press at x = %d, y = %d\n", x, y); */ return TRUE; } return FALSE; } /*****************************************************************************/ /* */ /* Function: glarea_motion_notify (GtkWidget*, GdkEventMotion*) */ /* */ /* This function handles motion events for the GtkGLArea into which we are */ /* drawing */ /* */ /*****************************************************************************/ gint glarea_motion_notify (GtkWidget *widget, GdkEventMotion *event) { int x; int y; GdkModifierType state; if (event->is_hint) { gdk_window_get_pointer(event->window, &x, &y, &state); } else { x = event->x; y = event->y; state = event->state; } if (state & GDK_BUTTON1_MASK) { /* Mouse button 1 is engaged */ PrintDebugInfo ("Button 1 Drag\n"); } if (state & GDK_BUTTON2_MASK) { /* Mouse button 2 is engaged */ PrintDebugInfo ("Button 2 Drag\n"); } if (state & GDK_BUTTON3_MASK) { /* Mouse button 3 is engaged */ PrintDebugInfo ("Button 3 Drag\n"); } return TRUE; } /*****************************************************************************/ /* */ /* Function: glarea_keyboard_press (GtkWidget*, GdkEventButton*) */ /* */ /* This function handles keyboard-press events for the GtkGLArea into which */ /* we are drawing. */ /* */ /*****************************************************************************/ gint glarea_keyboard_press (GtkWidget *widget, GdkEventKey *event) { switch (event->keyval) { /* --- Left arrow --- */ case GDK_Left: current->yRot -= 5.0f; if (current->yRot < -1.0f) current->yRot = 355.0f; gtk_widget_draw(GTK_WIDGET(widget), NULL); PrintDebugInfo ("Left arrow key pressed"); return TRUE; break; /* --- Right arrow --- */ case GDK_Right: current->yRot += 5.0f; if (current->yRot > 356.0f) current->yRot = 0.0f; gtk_widget_draw (GTK_WIDGET(widget), NULL); PrintDebugInfo ("Right arrow key pressed"); return TRUE; break; /* --- Up arrow --- */ case GDK_Up: current->xRot -= 5.0f; if (current->xRot < -1.0f) current->xRot = 355.0f; gtk_widget_draw (GTK_WIDGET(widget), NULL); PrintDebugInfo ("Up arrow key pressed"); return TRUE; break; /* --- Down arrow --- */ case GDK_Down: current->xRot += 5.0f; if (current->xRot > 356.0f) current->xRot = 0.0f; gtk_widget_draw (GTK_WIDGET(widget), NULL); PrintDebugInfo ("Down arrow key pressed"); return TRUE; break; /* --- Plus (+) key --- */ case GDK_plus: current->zoom += 0.1f; gtk_widget_draw(GTK_WIDGET(widget), NULL); PrintDebugInfo ("Plus (+) key pressed"); /* return TRUE; */ break; /* --- Minus (-) key --- */ case GDK_minus: current->zoom -= 0.1f; if (current->zoom == 0.0f) current->zoom = 1.0f; gtk_widget_draw(GTK_WIDGET(widget), NULL); PrintDebugInfo ("Minus (-) key pressed"); /* return TRUE; */ break; /* --- Ignore the rest --- */ default: gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),"key_release_event"); break; } return FALSE; } /*****************************************************************************/ /* */ /* Function: glarea_draw (GtkWidget*, GdkEventExpose*) */ /* */ /* This is the function that should render your scene to the GtkGLArea. It */ /* can be used as a callback to the 'Expose' event. */ /* */ /*****************************************************************************/ gint glarea_draw (GtkWidget *widget, GdkEventExpose *event) { /* Draw only on the last expose event. */ if (event->count > 0) { return(TRUE); } PrintDebugInfo ("Expose Event\n"); /* gtk_gl_area_make_current MUST be called before rendering */ /* into the GtkGLArea. */ if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) { /* Clear the drawing color buffer and depth buffers */ /* before drawing. */ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* * --- Begin insert your OpenGL drawing code here. */ RenderScene(); /* * --- End insert of your OpenGL drawing code */ /* Swap the back and front buffers. Using doublebuffers */ /* is definitely recommended! Take a look at the red */ /* book if you don't already have an understanding of */ /* single vs. double buffered windows. */ gtk_gl_area_swapbuffers (GTK_GL_AREA(widget)); } return (TRUE); } /*****************************************************************************/ /* */ /* Function: glarea_reshape (GtkWidget*, GdkEventConfigure*) */ /* */ /* This function performs the operations needed to maintain the viewing area */ /* of the GtkGLArea. This should be called whenever the size of the area */ /* is changed. */ /* */ /*****************************************************************************/ /* * --- This is called ChangeSize( ) in the "OpenGL Super Bible" * ... It's a GLUT thing :-) */ gint glarea_reshape (GtkWidget *widget, GdkEventConfigure *event) { int w = widget->allocation.width; int h = widget->allocation.height; /* PrintDebugInfo ("Reshape Event (ie ChangeSize)"); */ /* gtk_gl_area_make_current MUST be called before rendering */ /* into the GtkGLArea. */ if (gtk_gl_area_make_current (GTK_GL_AREA(widget))) { /* * --- Begin insert of OpenGL resize code here */ /* Prevent a divide by zero */ if(h == 0) h = 1; /* Set Viewport to window dimensions */ glViewport(0, 0, w, h); /* Reset coordinate system */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-w/2, w/2, -h/2, h/2, -100, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* * --- End insert of OpenGL resize code here */ } return (TRUE); } /*****************************************************************************/ /* */ /* Function: glarea_init (GtkWidget*) */ /* */ /* This function is a callback for the realization of the GtkGLArea widtget. */ /* You should do any OpenGL initialization here. */ /* */ /*****************************************************************************/ gint glarea_init (GtkWidget *widget) { PrintDebugInfo ("Realize Event\n"); /* gtk_gl_area_make_current MUST be called before rendering * into the GtkGLArea. */ if (gtk_gl_area_make_current (GTK_GL_AREA(widget))) { /* * --- Begin insert your OpenGL initialization code here */ /* Black background */ glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); /* Set drawing color to green */ /* glColor3f(0.0f, 1.0f, 0.0f); */ /* Display smooth points of a reasonable size */ glPointSize(2); glEnable(GL_POINT_SMOOTH); glEnable(GL_BLEND); /* * --- End insert your OpenGL initialization code here */ } return TRUE; } /*****************************************************************************/ /* */ /* Function: glarea_destroy (GtkWidget*) */ /* */ /* This function is a callback for the main GtkGLArea. It deletes should */ /* delete any data structures stored in the GtkGLArea. */ /* */ /*****************************************************************************/ gint glarea_destroy (GtkWidget *widget) { PrintDebugInfo ("GTK GL Area Destroy Event\n"); /* * --- Begin insert of any required cleanup code here. */ /* * --- End insert of any required cleanup code here. */ return TRUE; } /*****************************************************************************/ /* */ /* Function: CreateMainWindow () */ /* */ /* The main function sets up our GUI and calls the functions needed to */ /* create our GtkGLArea. */ /* */ /*****************************************************************************/ static void CreateMainWindow ( ) { gint i,j; gchar buffer[10]; GtkWidget *window; GtkWidget *button_quit; GtkWidget *box_main; GtkWidget *hbox; GtkWidget *button_zoomin; GtkWidget *button_zoomout; GtkWidget *notebook; typDrawingArea drawing_area; /* --- Main window --- */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE); gtk_widget_set_usize (window, 400, 450); gtk_window_set_title (GTK_WINDOW(window), "GtkGLArea Demo"); gtk_container_set_border_width (GTK_CONTAINER(window), 10); /* --- Top level window should listen for the delete_event --- */ gtk_signal_connect_object (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (EndProgram), NULL); gtk_quit_add_destroy (1, GTK_OBJECT(window)); /* --- Main widget container --- */ box_main = gtk_vbox_new (FALSE, 10); gtk_container_add (GTK_CONTAINER(window), box_main); /* * --- Create notebook and add to action v-box --- */ /* --- Create the notebook --- */ notebook = gtk_notebook_new (); /* --- Listen for the switch page event --- */ gtk_signal_connect (GTK_OBJECT (notebook), "switch_page", GTK_SIGNAL_FUNC (PageSwitch), NULL); /* --- Make sure tabs are set on correct side --- */ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM); /* --- Add notebook to vbox --- */ gtk_box_pack_start (GTK_BOX (box_main), notebook, TRUE, TRUE, 0); /* --- Give notebook a border --- */ gtk_container_border_width (GTK_CONTAINER (notebook), 5); /* --- Add pages to the notebook --- */ for ( i=0, j=2; i<(3); i++, j-- ) { drawing_area.notebook_page = NULL; sprintf(buffer,"view %d", i); drawing_area.notebook_page = add_notebook_page (notebook, buffer); create_glarea_page ( drawing_area.notebook_page, drawing_area.glarea ); drawing_area.page_number = j; drawing_area.xRot = (45 * j); drawing_area.yRot = 0.0; drawing_area.zRot = 0.0; drawing_area.zoom = 1.0; page_list = insert_notebook_page ( page_list, &drawing_area ); current = &drawing_area; } gtk_notebook_set_page( GTK_NOTEBOOK(notebook), 0 ); gtk_widget_show (notebook); /* --- Zoom In/Out Buttons --- */ hbox = gtk_hbox_new (FALSE, 10); gtk_box_pack_start (GTK_BOX(box_main), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); button_zoomin = gtk_button_new_with_label ("Zoom In"); gtk_signal_connect (GTK_OBJECT(button_zoomin), "clicked", GTK_SIGNAL_FUNC(ZoomIn), NULL); gtk_box_pack_start (GTK_BOX(hbox), button_zoomin, TRUE, TRUE, 0); gtk_widget_show (button_zoomin); button_zoomout = gtk_button_new_with_label ("Zoom Out"); gtk_signal_connect (GTK_OBJECT(button_zoomout), "clicked", GTK_SIGNAL_FUNC(ZoomOut), NULL); gtk_box_pack_start (GTK_BOX(hbox), button_zoomout, TRUE, TRUE, 0); gtk_widget_show (button_zoomout); /* --- Quit button --- */ button_quit = gtk_button_new_with_label ("Quit"); gtk_signal_connect (GTK_OBJECT(button_quit), "clicked", GTK_SIGNAL_FUNC(EndProgram), NULL); gtk_box_pack_start (GTK_BOX(box_main), button_quit, FALSE, TRUE, 0); /* --- Information label --- */ debug_label = gtk_label_new ("OpenGL Test Suite\n"); gtk_box_pack_start (GTK_BOX(box_main), debug_label, FALSE, TRUE, 0); /* --- Show the widgets you just created --- */ gtk_widget_show_all (window); /* gtk_widget_grab_focus(GTK_WIDGET(current->glarea)); */ } /****************************************************************************** * * Add additional functions here ... * *****************************************************************************/ void RenderScene (void) { /* --- Storage for coordinates and angles --- */ GLfloat x,y,z,angle; /* Save matrix state and do the rotation */ glPushMatrix(); glRotatef(current->xRot, 1.0f, 0.0f, 0.0f); glRotatef(current->yRot, 0.0f, 1.0f, 0.0f); /* Call only once for all remaining points */ glBegin(GL_LINE_STRIP); z = -50.0f; for(angle = 0.0f; angle <= (2.0f*3.1415f)*3.0f; angle += 0.1f) { x = 50.0f*sin(angle); y = 50.0f*cos(angle); /* Specify the point and move the Z value up a little */ glVertex3f(x, y, z); z += 0.5f; } /* Done drawing points */ glEnd(); /* Restore transformations */ glPopMatrix(); } /* * --- Notebook specific functions --- */ /* Function: PageSwitch ( ) * * Event that occurs when a different page is now * the focus. */ void PageSwitch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) { fprintf( stderr, "page switch to %d\n", page_num); if ( (current = find_notebook_page(page_list, page_num)) != NULL ) { fprintf(stderr,"Function: PageSwitch(), Page %d found.\n", current->page_number); } } /* Function: AddPage ( ) * * Add a page to the notebook * * Inputs: * notebook - existing notebook * szName - name to give to the new page */ GtkWidget * add_notebook_page (GtkWidget *notebook, char *szName) { GtkWidget *label; GtkWidget *frame; /* --- Create a label from the name. --- */ label = gtk_label_new (szName); gtk_widget_show (label); /* --- Create a frame for the page --- */ frame = gtk_frame_new (szName); gtk_widget_show (frame); /* --- Add a page with the frame and label --- */ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label); return (frame); } /* * Function: create_glarea_page ( ); * * Routine used to create a notebook page with a gtkglarea inside of it */ int create_glarea_page ( GtkWidget *notebook_page, GtkWidget *draw_area ) { GtkWidget *hbox; /* * --- Verify OpenGL is supported --- */ if (gdk_gl_query ( ) == FALSE) { g_print("OpenGL is not supported\n"); return(EXIT_FAILURE); } /* * --- Add a horizontal packing box to hold packing boxes for widgets --- */ hbox = gtk_hbox_new (FALSE, 0); gtk_container_add( GTK_CONTAINER (notebook_page), hbox ); gtk_widget_show (hbox); /* --- gtk_gl_area related code --- */ draw_area = create_glarea ( ); gtk_box_pack_start (GTK_BOX (hbox), draw_area, TRUE, TRUE,0); gtk_widget_show (draw_area); return (EXIT_SUCCESS); } /* Function: insert_notebook_page_data( ) * * Routine used to insert notebook page struct into a linked list. */ GSList * insert_notebook_page(GSList *list, typDrawingArea *page) { typDrawingArea *temp; temp = g_new (typDrawingArea, 1); temp->notebook_page = page->notebook_page; temp->glarea = page->glarea; temp->page_number = page->page_number; temp->xRot = page->xRot; temp->yRot = page->yRot; temp->zRot = page->zRot; temp->zoom = page->zoom; temp->current = FALSE; list = g_slist_append (list, temp); return (list); } /* Function: find_notebook_page_data ( ) * * Routine used to find specific waterplane data from a linked list. */ typDrawingArea * find_notebook_page(GSList *list, gint page_number) { int i; GSList *node; typDrawingArea *item; for (i = 0; (node = g_slist_nth (list, i)); i++) { item = node->data; if (item->page_number == page_number) { fprintf(stderr,"Page number %d found!\n", item->page_number); return (item); } } fprintf(stderr,"Page number %d not found !\n", page_number); return (NULL); } void ZoomIn (GtkWidget *widget, gpointer data) { fprintf(stderr, "%s\n", (char *)data ); current->zoom += 1.0; /* gtk_widget_draw (gl_drawing_area, NULL); */ /* gtk_widget_draw(GTK_WIDGET(current_drawing->glarea), NULL); */ gtk_widget_queue_draw (current->glarea); } void ZoomOut (GtkWidget *widget, gpointer data) { fprintf(stderr, "%s\n", (char *)data ); current->zoom += 1.0; /* gtk_widget_draw (gl_drawing_area, NULL); */ /* gtk_widget_draw(GTK_WIDGET(current_drawing->glarea), NULL); */ gtk_widget_queue_draw (current->glarea); }