+static void zoom_in (double *fov)
+{
+ *fov = *fov / ZOOM_SPEED;
+ if (*fov < 10.5)
+ *fov = 10.5;
+} /* void zoom_in */
+
+static void zoom_out (double *fov)
+{
+ *fov = *fov * ZOOM_SPEED;
+ if (*fov > 165.0)
+ *fov = 165.0;
+} /* void zoom_out */
+
+int main( int argc, char** argv )
+{
+ unsigned long color_fg, color_bg;
+ int done;
+ static Atom proto_atom= None, delete_atom= None;
+
+ long event_mask;
+
+ double fov = 70.0;
+ double yaw = 0.0;
+ double pitch = 0.0;
+
+ /* Detect mouse movement direction */
+ unsigned int btn_current_pressed = 0;
+ int btn_reference_pos_x = 0;
+ int btn_reference_pos_y = 0;
+ int btn_current_pos_x = 0;
+ int btn_current_pos_y = 0;
+
+ ui_image_t *pano;
+ ui_image_t *view;
+
+
+ // Set up display
+ disp_g = XOpenDisplay("");
+ screen_g = DefaultScreen(disp_g);
+ depth_g = DefaultDepth(disp_g, screen_g);
+
+ color_bg = WhitePixel(disp_g,screen_g);
+ color_fg = BlackPixel(disp_g,screen_g);
+
+ // Load panoramic image
+ if( argc < 2 )
+ {
+ PrintError("No image file supplied");
+ exit(0);
+ }
+
+ if( strcmp( argv[1], "-h" ) == 0 ) /* FIXME: Use getopt */
+ {
+ PrintError( "%s\n %s\nUsage: PTViewer Imagefile", "PTViewer", LONGVERSION );
+ exit(0);
+ }
+
+ pano = ui_create_file (argv[1]);
+ if (pano == NULL)
+ {
+ PrintError ("Unable to read pano file.");
+ exit (0);
+ }
+
+ printf ("Panorama `%s', %ux%u pixels, loaded.\n",
+ argv[1], pano->width, pano->height);
+
+ view = ui_create (DEF_VIEW_WIDTH, DEF_VIEW_HEIGHT); /* FIXME: Possibly chose another size */
+ if (view == NULL)
+ {
+ PrintError ("Unable to create view.");
+ exit (0);
+ }
+
+ window_g = XCreateSimpleWindow(disp_g,
+ DefaultRootWindow(disp_g),
+ 0, 0, /* Position */
+ view->width, view->height,
+ 5,
+ color_fg, color_bg);
+
+ {
+ XSizeHints hint;
+
+ memset (&hint, '\0', sizeof (hint));
+ hint.width = view->width;
+ hint.height = view->height;
+ hint.flags = PSize;
+
+ XSetStandardProperties(disp_g,
+ window_g,
+ text,
+ text,
+ None,
+ argv,
+ argc,
+ &hint);
+ }
+
+ gc = XCreateGC(disp_g,window_g,0,0);
+ XSetBackground(disp_g,gc,color_bg);
+ XSetForeground(disp_g,gc,color_fg);
+
+ event_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
+ | KeyPressMask | KeyReleaseMask | StructureNotifyMask
+ | EnterWindowMask | LeaveWindowMask| ExposureMask;
+
+ XSelectInput(disp_g, window_g, event_mask);
+ XMapRaised(disp_g,window_g);
+
+ proto_atom = XInternAtom(disp_g, "WM_PROTOCOLS", False);
+ delete_atom = XInternAtom(disp_g, "WM_DELETE_WINDOW", False);
+ if ((proto_atom != None) && (delete_atom != None))
+ XChangeProperty(disp_g, window_g, proto_atom, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *)&delete_atom,
+ 1);
+ visual_g = DefaultVisual(disp_g, screen_g);
+
+ pl_extract_view (view, pano, pitch, yaw, fov);
+ draw_window (view);
+
+ done = 0;
+ while (done == 0)
+ {
+ int isChanged = 0;
+ XEvent event;
+
+ memset (&event, '\0', sizeof (event));
+
+ if (btn_current_pressed == 0)
+ {
+ /* No button is pressed -> block */
+ XMaskEvent (disp_g, event_mask, &event);
+ }
+ else
+ {
+ /* A button is pressed -> do not block */
+ XCheckMaskEvent (disp_g, event_mask, &event);
+ }
+
+ switch (event.type)
+ {
+ case 0: /* XCheckMaskEvent didn't return an event */
+ break;
+
+ case Expose:
+ {
+ XExposeEvent *eev = (XExposeEvent *) &event;
+
+ while (eev->count != 0)
+ {
+ if (!XCheckTypedEvent (disp_g, Expose, &event))
+ {
+ eev = NULL;
+ break;
+ }
+ /* do nothing */
+ }
+
+ if (eev != NULL)
+ isChanged = 1;