📄 ctrlbar.c
字号:
/* * Copyright (c) 1995 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. contributed by (but no rights held by): Michael J. Donahue National Institute of Standards and Technology Gaithersburg MD USA donahue@ulexite.nist.gov *//* * Portions of this software Copyright (c) 1995 Brown University. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement * is hereby granted, provided that the above copyright notice and the * following two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. *//* Changes to make the code reentrant: If using ANSI C, do prototyping for static functions display not a global, must be passed to functions display window now not a global, must be passed to functions via xinfo struct FILMState removed - now uses vid_stream->film_has_ended instead use totNumFrames from vid_stream, not global must pass vid_stream (EOF_flag, seekValue, etc. no longer global) CONTROLS version now can deal with >1 movie Additional changes: Do prototyping for static functions - lsh@cs.brown.edu (Loring Holden) */#ifndef NOCONTROLS#include <stdio.h>#include <stdlib.h>#include <string.h>#include "dither.h"#include "video.h"#include "ctrlbar.h"#include "proto.h"#ifndef MIPS#include <sys/time.h>#else#include <sys/types.h>#include <sys/system.h>#endif/* Default is to play asap. If you want it to start paused, change to CTRL_PAUSE */#define INITIAL_STATE CTRL_PLAY/* Global variable definitions */int ControlShow = CTRLBAR_ON; /* ON => Show (display) control bar */int ControlState = CTRL_UNDEFINED; /* Current control state */int ControlMotion = CTRLMOTION_OFF; /* Pause mode */long TotalFrameCount= 0; /* Total number of frames processed, including loops *//* File statics */static int CtrlBarWidth;static int CtrlBarHeight = 31;static int CtrlBarBorder = 4;static int ChildBorder = 2;static int ChildMargin = 6;static Window ctrlwindow = 0;static int screen = -1;static XFontStruct* ctrlfont = NULL;static int fontheight, fontwidth;static unsigned long fgcolor, bgcolor;static int ctrl_init = 0; /* 1 => Control windows have been initialized *//* Support for WM_DELETE_WINDOW */static Atom protocol_atom = (Atom)None;static Atom delete_atom = (Atom)None;/* Child windows */static int ChildCount = 7;static Window frametotalwin;static int ftw_width, ftw_height;static Window rewindwin;static int rww_width, rww_height;static Window pausewin;static int psw_width, psw_height;static Window playwin;static int plw_width, plw_height;static Window stepwin;static int stw_width, stw_height;static Window exitwin;static int exw_width, exw_height;static Window loopwin;static int lpw_width, lpw_height;/* *-------------------------------------------------------------- * * StopWatch -- * * On/off timing routine (in real elapsed time). * * Results: * If import is: * STOPWATCH_START ---- Starts timing, returns 0.0. * STOPWATCH_STOP ---- Stops timing, returns elapsed * time in seconds. * STOPWATCH_RESET ---- Resets timing, returns 0.0. * STOPWATCH_READ ---- Returns elapsed time in seconds. * * Side effects: * None. * *-------------------------------------------------------------- */doubleStopWatch(action)int action;{ static struct timeval start,current; /* Working times */ static struct timeval elapsed; /* Previously accumulated time */ static int state = STOPWATCH_STOP; double dtemp = 0.0; long ltemp; if (action == state) { if (state == STOPWATCH_START) { return 0.0; } else return elapsed.tv_sec + elapsed.tv_usec/1000000.0; } switch(action) { case STOPWATCH_START: state = STOPWATCH_START; gettimeofday(&start, (struct timezone *)NULL); break; case STOPWATCH_STOP: gettimeofday(¤t, (struct timezone *)NULL); state = STOPWATCH_STOP; ltemp = elapsed.tv_usec + current.tv_usec - start.tv_usec; elapsed.tv_sec += current.tv_sec-start.tv_sec + ltemp/1000000; elapsed.tv_usec = ltemp % 1000000; /* And fall through to STOPWATCH_READ */ case STOPWATCH_READ: if (state == STOPWATCH_START) { /* Stopwatch is running */ gettimeofday(¤t,(struct timezone *)NULL); dtemp = (current.tv_sec-start.tv_sec + elapsed.tv_sec) + (current.tv_usec-start.tv_usec + elapsed.tv_usec) / 1000000.0; } else dtemp = elapsed.tv_sec + elapsed.tv_usec/1000000.0; break; case STOPWATCH_RESET: state = STOPWATCH_STOP; elapsed.tv_sec = elapsed.tv_usec = 0; break; default: fprintf(stderr,"Illegal action (%d) requested of StopWatch()",action); exit(1); } return dtemp;}/* *-------------------------------------------------------------- * * GetWindowOrigins -- * * Determines window coordinates with respect to root window. * * Results: * Sets (xwhole,ywhole) to root coordinates of upper lefthand corner * of the specified window (including decorations), and (xclient,yclient) * to the root coordinates of the client region. * * Side effects: * None. * *-------------------------------------------------------------- */#ifdef __STDC__static void GetWindowOrigins(XInfo *xinfo, int *xclient, int *yclient, int *xwhole, int *ywhole)#elsestatic void GetWindowOrigins(xinfo,xclient,yclient,xwhole,ywhole)XInfo *xinfo;int *xclient;int *yclient;int *xwhole;int *ywhole;#endif{ Window dummy_window; Window win=xinfo->window; Display *display=xinfo->display; /* First get coordinates for client "sub"-window */ XTranslateCoordinates(display,win,DefaultRootWindow(display), 0,0,xclient,yclient,&dummy_window); if (dummy_window == None) { /* Shouldn't happen, but if so, then punt */ *xwhole = *xclient; *ywhole = *yclient; return; } /* Now dummy_window should be a direct child of root, so find */ /* its base coordinates. */ XTranslateCoordinates(display,dummy_window,DefaultRootWindow(display), 0,0,xwhole,ywhole,&dummy_window); /* And finally, subtract 1 for good luck ;-) */ if ((*xwhole) > 0) { (*xwhole)--; } if ((*ywhole) > 0) { (*ywhole)--; }}/* *-------------------------------------------------------------- * * WindowMapped -- * * Check event to see if window is mapped. A procedure * intended to be passed to XIfEvent(). * * Results: * Read the code. * * Side effects: * None. * *-------------------------------------------------------------- */Bool WindowMapped(dsp,xev,window)Display *dsp;XEvent *xev;char *window;{ if (xev->type == MapNotify && xev->xmap.event == *((Window *)window)) return TRUE; return FALSE;}/* *-------------------------------------------------------------- * * IfEventType -- * * Check event type. A procedure intended to be passed to XIfEvent(). * * Results: * Read the code. * * Side effects: * None. * *-------------------------------------------------------------- */Bool IfEventType(dsp,xev,type)Display *dsp;XEvent *xev;char *type;{ if (xev->type == *((int *)type)) { return TRUE; } return FALSE;}/* *-------------------------------------------------------------- * ShowHideControls--- * * Maps or unmaps control bar as dictated by the value of the * global variable ControlShow. * * Results: * None. * * Side effects: * None. * *-------------------------------------------------------------- */#ifdef __STDC__static void ShowHideControls(XInfo *xinfo)#elsestatic void ShowHideControls(xinfo)XInfo *xinfo;#endif{ if (ControlShow == CTRLBAR_ON) { XEvent event; XMapRaised(xinfo->display, ctrlwindow); XIfEvent(xinfo->display, &event, WindowMapped, (char *)(&ctrlwindow)); /* Wait for map. */ } else { XUnmapWindow(xinfo->display, ctrlwindow); }}/* *-------------------------------------------------------------- * * MakeControlBar -- * * Creates and (possibly) displays Control Bar in root window * at position (x,y) relative to video output window. * * Results: * Sets ctrlwindow. * * Side effects: * Sets ctrl_init to 1 if successful. * *-------------------------------------------------------------- */void MakeControlBar(xinfo) XInfo *xinfo;{ char *ctrlname = "MPEG Player Controls"; XSizeHints hint; int xpos, ypos; Display *display=xinfo->display; if (ctrl_init) { fprintf(stderr, "Warning from MakeControlBar(): Controls already initialized\n"); return; } if (xinfo->ditherType == NO_DITHER) return; if (display == (Display*)NULL) { fprintf(stderr, "Fatal error in MakeControlBar(): Display pointer not initialized\n"); exit(1); } /* Get font (used in window sizing) */ if ((ctrlfont = XLoadQueryFont(display, "fixed")) == NULL) { fprintf(stderr,"Error: Unable to load font \"fixed\" for Control Bar\n"); exit(1); } fontheight = ctrlfont->ascent + ctrlfont->descent; fontwidth = ctrlfont->max_bounds.width; if (fontheight < 4 || fontheight > 75 || fontwidth < 2 || fontwidth > 30) { fprintf(stderr,"Warning: Font size seems suspect...guessing\n"); fontheight = 20; fontwidth = 10; /* Maybe 13 and 6 are better */ } /* Set window sizes */ ftw_height = CtrlBarHeight-2*(ChildBorder+ChildMargin); ftw_width = fontwidth * 21; rww_height = ftw_height; rww_width = fontwidth * 8; psw_height = rww_height; psw_width = fontwidth * 7; stw_height = psw_height; stw_width = fontwidth * 6; plw_height = stw_height; plw_width = fontwidth * 6; lpw_height = plw_height; lpw_width = fontwidth * 10; exw_height = lpw_height; exw_width = fontwidth * 6; CtrlBarWidth = rww_width + psw_width + stw_width + plw_width + lpw_width + exw_width + ftw_width + ChildMargin + ChildCount*(ChildMargin + 2*ChildBorder); /* Figure out how to place control bar just above display window */ GetWindowOrigins(xinfo,&xpos,&ypos,&hint.x,&hint.y); /* Leave room for title bar decorations. Note this assumes */ /* control bar dec. same height as for display window */ hint.y = 2*hint.y - ypos; hint.y -= (CtrlBarHeight + 2*CtrlBarBorder + 1); /* +1 for luck ;-) */ if (hint.y < 0) { hint.y = 0; } hint.max_width = hint.base_width = hint.width = CtrlBarWidth; hint.max_height = hint.base_height = hint.height = CtrlBarHeight; hint.min_width = hint.min_height = 0; hint.flags = PMinSize | PMaxSize | PBaseSize | PPosition | PSize | USPosition; screen = DefaultScreen (display); fgcolor = BlackPixel(display, screen); bgcolor = WhitePixel(display, screen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -