Browse Source

Add pause and resume (with space)

Olivier Marty 9 years ago
parent
commit
a71a759a20
6 changed files with 94 additions and 11 deletions
  1. 2 2
      README.md
  2. 20 0
      main.c
  3. 39 9
      printer.c
  4. 4 0
      printer.h
  5. 26 0
      time.c
  6. 3 0
      time.h

+ 2 - 2
README.md

@@ -26,6 +26,7 @@ subtitlesPrinter file.srt
 ```
 
 To quit, press CTRL+C in the terminal.
+To pause and resume, press space anywhere (this does not work with all windows).
 
 ### Optional arguments
 
@@ -36,9 +37,8 @@ subtitlesPrinter -h
 
 ## TODO
 
-* Manage some evenements, like pause, shift...
+* Manage other evenements, like shift...
 * Support more type of file (with an extern library ?)
-* Use a larger, customizable font
 
 Every improvement is welcome !
 

+ 20 - 0
main.c

@@ -40,6 +40,25 @@ void displayUsage(char *name)
   printf("  -h\t\t: display this help and exit\n");
 }
 
+void callbackEvent(struct printerEnv* env, int key, void* a) {
+  if(key == ' ') {
+    // display a message
+    if(!timeIsPaused())
+      printerShow(env, "(paused - press space to resume)", 0);
+    else
+      printerClean(*env);
+    
+    // toggle pause
+    timePause(!timeIsPaused());
+    // if paused, wait for an event
+    while(timeIsPaused())
+    {
+      waitEvent(env);
+      manageEvent(env, callbackEvent, a);
+    }
+  }
+}
+
 int main(int argc, char **argv)
 {
   int i, shift = 0, delay = 5, margin_bottom = 50, padding = 5, gap = 5;
@@ -148,6 +167,7 @@ int main(int argc, char **argv)
       // TODO manage when the next subtitle appear before
       printf("\n");
       printerClean(penv);
+      manageEvent(&penv, callbackEvent, NULL);
     }
     else
     {

+ 39 - 9
printer.c

@@ -22,6 +22,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/keysym.h>
+#include <X11/XKBlib.h>
 #include <string.h>
 
 char *strnstr(const char *s, const char *find, size_t slen)
@@ -136,16 +137,12 @@ struct printerEnv printerOpenWindow(char *font, char *font_i, char *font_b,
   gr_values.background = XBlackPixel(env.d, env.s);
   env.gc = XCreateGC(env.d, env.w, GCFont | GCForeground, &gr_values);
   
+  // focused window (for keyboard)
+  int revert;
+  XGetInputFocus(env.d, &env.w_focused, &revert);
+  
   // event to be listened
-  //XSelectInput(env.d, env.w, ExposureMask | KeyPressMask);
-  /*
-  XEvent e;
-  while(XCheckWindowEvent(env.d, env.w, KeyPressMask, &e))
-  {
-    if(e.type == KeyPress && XLookupKeysym(&(e.xkey), 0) == XK_space)
-      printf("PAUSE\n");
-  }
-  */
+  XSelectInput(env.d, env.w_focused, KeyPressMask|FocusChangeMask);
   
   return env;
 }
@@ -349,3 +346,36 @@ void printerClean(struct printerEnv env)
   XFlush(env.d);
 }
 
+void manageEvent(struct printerEnv *env, void callback(struct printerEnv*,int,void*), void* callback_arg)
+{
+  XEvent event;
+  int r;
+  XComposeStatus comp;
+
+  while(XPending(env->d))
+  {
+    XNextEvent(env->d, &event);
+    switch(event.type)
+    {
+      case FocusOut:
+        XGetInputFocus(env->d, &env->w_focused, &r);
+        if(env->w_focused == PointerRoot)
+          env->w_focused = RootWindow(env->d, env->s); // TODO why ?
+        XSelectInput(env->d, env->w_focused, KeyPressMask|FocusChangeMask);
+        break;
+      
+      case KeyPress:
+        callback(env, (int)XkbKeycodeToKeysym(env->d, event.xkey.keycode, 0, event.xkey.state & ShiftMask ? 1 : 0), callback_arg);
+        break;
+      
+      default:
+        break;
+    }
+  }
+}
+
+void waitEvent(struct printerEnv *env)
+{
+  XEvent event;
+  XPeekEvent(env->d, &event);
+}

+ 4 - 0
printer.h

@@ -26,6 +26,7 @@ struct printerEnv
   Display *d;
   int s;
   Window w;
+  Window w_focused;
   GC gc;
   XFontStruct *fontinfo;    // regular
   XFontStruct *fontinfo_i;  // italic
@@ -48,5 +49,8 @@ void printerCloseWindow(struct printerEnv env);
 void printerShow(struct printerEnv *env, char* text, enum t_type font);
 void printerClean(struct printerEnv env);
 
+void manageEvent(struct printerEnv *env, void callback(struct printerEnv*,int,void*), void* callback_arg);
+void waitEvent(struct printerEnv *env); // TODO plutot un arguement dans manageEvent qui déclenche une lecture bloquante
+
 #endif
 

+ 26 - 0
time.c

@@ -61,8 +61,11 @@ struct timespec timeFactor(struct timespec a, double f)
 }
 
 struct timespec begin;
+struct timespec tPause; // beginning of the pause
+int pause;
 void timeInitialize(int rel)
 {
+  pause = 0;
   if(clock_gettime(CLOCK_REALTIME, &begin) < 0)
   {
     perror("clock_gettime()");
@@ -73,6 +76,11 @@ void timeInitialize(int rel)
 
 struct timespec timeGetRelative()
 {
+  if(pause) {
+    printf("paused !\n");
+    return tPause;
+  }
+
   struct timespec r;
   if(clock_gettime(CLOCK_REALTIME, &r) < 0)
   {
@@ -103,3 +111,21 @@ int timeInFuture(struct timespec t)
   return tmp.tv_sec >= 0;
 }
 
+void timePause(int b)
+{
+  if(b)
+  {
+    tPause = timeGetRelative();
+    pause = 1;
+  }
+  else
+  {
+    pause = 0;
+    begin = timeDiff(begin, timeDiff(tPause, timeGetRelative()));
+  }
+}
+
+int timeIsPaused()
+{
+  return pause;
+}

+ 3 - 0
time.h

@@ -37,5 +37,8 @@ mytime timeDiff(mytime a, mytime b);
 // f should be >= 0
 mytime timeFactor(mytime a, double f);
 
+void timePause(int pause); // pause and resume the clock
+int timeIsPaused();
+
 #endif