+static int mouse_x = 0, mouse_y = 0 ;
+static int button_down = GLUT_DOWN ;
+
+static void
+Mouse ( int button, int updown, int x, int y )
+{
+ button_down = updown ;
+
+ if ( updown == GLUT_DOWN )
+ {
+ mouse_x = x ;
+ mouse_y = y ;
+ }
+}
+
+static void
+MouseMotion ( int x, int y )
+{
+ int window_width = glutGet ( GLUT_WINDOW_WIDTH ) ;
+ int window_height = glutGet ( GLUT_WINDOW_HEIGHT ) ;
+ int window_size = ( window_width < window_height ) ? window_width : window_height ;
+
+ double delta_x = 5.0 * (double)(x - mouse_x) / (double)(window_size) ;
+ double delta_y = 5.0 * (double)(y - mouse_y) / (double)(window_size) ;
+
+ xwin += delta_x * scale_factor ;
+ ywin -= delta_y * scale_factor ;
+ glMatrixMode ( GL_MODELVIEW ) ;
+ glTranslated ( delta_x * scale_factor, -delta_y * scale_factor, 0.0 ) ;
+
+ needClear = GL_TRUE;
+ glutPostRedisplay();
+
+ mouse_x = x ;
+ mouse_y = y ;
+}
+
+static void
+MouseWheel ( int wheel_number, int direction, int x, int y )
+{
+ double scale = ( direction > 0 ) ? 1.25 : 0.8 ;
+
+ glMatrixMode ( GL_MODELVIEW ) ;
+ glTranslated ( -xwin, -ywin, 0.0 ) ;
+ glScaled ( scale, scale, scale ) ;
+ glTranslated ( xwin, ywin, 0.0 ) ;
+ scale_factor /= scale ;
+
+ needClear = GL_TRUE;
+ glutPostRedisplay();
+}
+
+
+static void
+checkedFGets ( char *s, int size, FILE *stream )
+{
+ if ( fgets ( s, size, stream ) == NULL ) {
+ fprintf ( stderr, "fgets failed\n");
+ exit ( EXIT_FAILURE );
+ }
+}
+
+