From 35be190a96f0063d70b7fe1ae6cb85c30ed972a3 Mon Sep 17 00:00:00 2001
From: iovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a>
Date: Thu, 15 Nov 2007 11:29:15 +0000
Subject: Makefile.am: added poll_events.c(removed poll_damage.c) parseargs.c:
 added parsing for pause and stop shortcut recordmydesktop.c : shortcuts
 related code changes rmdthreads.c: added a hack to end the poll_events
 thread, since it now runs regardless of whether full-shots is specified.
 shortcuts.c: new method RegisterShortcuts.

git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@435 f606c939-3180-4ac9-a4b8-4b8779d57d0a
---
 recordmydesktop/src/Makefile.am       |   2 +-
 recordmydesktop/src/parseargs.c       |  29 +++++++
 recordmydesktop/src/recordmydesktop.c |  24 ++++++
 recordmydesktop/src/rmdthreads.c      |  39 ++++++---
 recordmydesktop/src/shortcuts.c       | 153 ++++++++++++++++++++++++++++++++++
 5 files changed, 236 insertions(+), 11 deletions(-)

(limited to 'recordmydesktop/src')

diff --git a/recordmydesktop/src/Makefile.am b/recordmydesktop/src/Makefile.am
index f9ad6bd..576cd97 100644
--- a/recordmydesktop/src/Makefile.am
+++ b/recordmydesktop/src/Makefile.am
@@ -11,7 +11,7 @@ recordmydesktop_SOURCES=	recordmydesktop.c\
 							register_callbacks.c\
 							get_frame.c\
 							update_image.c\
-							poll_damage.c\
+							poll_events.c\
 							encode_image_buffer.c\
 							bgr_to_yuv.c\
 							flush_to_ogg.c\
diff --git a/recordmydesktop/src/parseargs.c b/recordmydesktop/src/parseargs.c
index a540610..1ed0cc1 100644
--- a/recordmydesktop/src/parseargs.c
+++ b/recordmydesktop/src/parseargs.c
@@ -104,6 +104,11 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){
     "\t--no-wm-check\t\tDo not try to detect"
     " the window manager(and set options according to it)\n"
 
+    "\t-pause-shortcut MOD+KEY\tShortcut that will be used for (un)pausing" 
+    "(default Control+Mod1+p).\n"
+    "\t-stop-shortcut MOD+KEY\tShortcut that will be used to stop the "
+    "recording (default Control+Mod1+s).\n" 
+
     "\t--compress-cache\tImage data are cached with light compression.\n"
     "\t-workdir DIR\t\tLocation where a temporary directory"
     " will be created to hold project files(default $HOME).\n"
@@ -414,6 +419,30 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){
             }
             i++;
         }
+        else if(!strcmp(argv[i],"-pause-shortcut")){
+            if(i+1<argc){
+                free(arg_return->pause_shortcut);
+                arg_return->pause_shortcut=malloc(strlen(argv[i+1])+1);
+                strcpy(arg_return->pause_shortcut,argv[i+1]);
+            }
+            else{
+                fprintf(stderr,"Argument Usage: -pause-shortcut MOD+KEY\n");
+                return 1;
+            }
+            i++;
+        }
+        else if(!strcmp(argv[i],"-stop-shortcut")){
+            if(i+1<argc){
+                free(arg_return->stop_shortcut);
+                arg_return->stop_shortcut=malloc(strlen(argv[i+1])+1);
+                strcpy(arg_return->stop_shortcut,argv[i+1]);
+            }
+            else{
+                fprintf(stderr,"Argument Usage: -stop-shortcut MOD+KEY\n");
+                return 1;
+            }
+            i++;
+        }
         else if(!strcmp(argv[i],"-buffer-size")){
             if(i+1<argc){
                 int num=atoi(argv[i+1]);
diff --git a/recordmydesktop/src/recordmydesktop.c b/recordmydesktop/src/recordmydesktop.c
index b3ba150..56d821a 100644
--- a/recordmydesktop/src/recordmydesktop.c
+++ b/recordmydesktop/src/recordmydesktop.c
@@ -100,6 +100,30 @@ int main(int argc,char **argv){
 
 
         if((exit_status=InitializeData(&pdata,&enc_data,&cache_data))==0){
+            if(!strcmp(pdata.args.pause_shortcut,
+                      pdata.args.stop_shortcut)||
+                RegisterShortcut(pdata.dpy,
+                                 pdata.specs.root,
+                                 pdata.args.pause_shortcut,
+                                 &(pdata.pause_key)) ||
+                RegisterShortcut(pdata.dpy,
+                                 pdata.specs.root,
+                                 pdata.args.stop_shortcut,
+                                 &(pdata.stop_key))){
+
+                fprintf(stderr,"Invalid shortcut,"
+                               " or shortcuts are the same!\n\n"
+                               "Using defaults.\n");
+
+                RegisterShortcut(pdata.dpy,
+                                 pdata.specs.root,
+                                 "Control+Mod1+p",
+                                 &(pdata.pause_key));
+                RegisterShortcut(pdata.dpy,
+                                 pdata.specs.root,
+                                 "Control+Mod1+s",
+                                 &(pdata.stop_key));
+            }
 
             //this is where the capturing happens.
             rmdThreads(&pdata);
diff --git a/recordmydesktop/src/rmdthreads.c b/recordmydesktop/src/rmdthreads.c
index 6e4bf34..f8e9ef4 100644
--- a/recordmydesktop/src/rmdthreads.c
+++ b/recordmydesktop/src/rmdthreads.c
@@ -39,7 +39,7 @@
 
 
 void rmdThreads(ProgData *pdata){
-    pthread_t   poll_damage_t,
+    pthread_t   poll_events_t,
                 image_capture_t,
                 image_encode_t,
                 image_cache_t,
@@ -47,7 +47,7 @@ void rmdThreads(ProgData *pdata){
                 sound_encode_t,
                 sound_cache_t,
                 flush_to_ogg_t;
-
+    Window dummy_w;
 
     if(pdata->args.delay>0){
         fprintf(stderr,"Will sleep for %d seconds now.\n",pdata->args.delay);
@@ -55,11 +55,10 @@ void rmdThreads(ProgData *pdata){
     }
 
     /*start threads*/
-    if(!pdata->args.full_shots)
-        pthread_create(&poll_damage_t,
-                       NULL,
-                       (void *)PollDamage,
-                       (void *)pdata);
+    pthread_create(&poll_events_t,
+                   NULL,
+                   (void *)PollEvents,
+                   (void *)pdata);
     pthread_create(&image_capture_t,
                    NULL,
                    (void *)GetFrame,
@@ -152,9 +151,29 @@ void rmdThreads(ProgData *pdata){
         pthread_join(flush_to_ogg_t,NULL);
     fprintf(stderr,".");
 
-
-    if(!pdata->args.full_shots)
-        pthread_join(poll_damage_t,NULL);
+    /* 
+     * HACK ALERT
+     * This window (dummy_w) is created
+     * only so that we will receive a final
+     * create notify event. This is needed 
+     * especially for the full_shots mode were
+     * there are no damage events and the 
+     * poll_events thread might get stuck indefinatelly.
+     * XFlush is also needed in order to get the event
+     * before the current thread gets stuck at the join call.
+     * The second XFlush should be unnecesary.
+     */
+     
+    dummy_w=XCreateSimpleWindow(pdata->dpy,
+                                pdata->specs.root,
+                                1,1,1,1,0,
+                                pdata->specs.bpixel,
+                                pdata->specs.wpixel);
+    XFlush(pdata->dpy);
+    XDestroyWindow(pdata->dpy,dummy_w);
+    XFlush(pdata->dpy);
+
+    pthread_join(poll_events_t,NULL);
 
     //Now that we are done with recording we cancel the timer
     CancelTimer();
diff --git a/recordmydesktop/src/shortcuts.c b/recordmydesktop/src/shortcuts.c
index e69de29..f86fa1a 100644
--- a/recordmydesktop/src/shortcuts.c
+++ b/recordmydesktop/src/shortcuts.c
@@ -0,0 +1,153 @@
+/******************************************************************************
+*                            recordMyDesktop                                  *
+*******************************************************************************
+*                                                                             *
+*            Copyright (C) 2006,2007 John Varouhakis                          *
+*                                                                             *
+*                                                                             *
+*   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  *
+*                                                                             *
+*                                                                             *
+*                                                                             *
+*   For further information contact me at johnvarouhakis@gmail.com            *
+******************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/keysym.h> 
+#include <rmdtypes.h>
+
+int RegisterShortcut(Display *dpy,
+                     Window root,
+                     const char *shortcut,
+                     HotKey *hotkey){
+
+    int keycode=0, 
+        i, j ;
+    KeySym key=0;
+    unsigned int modifier_mask=0,
+                 numlock_mask=0;
+    char *keystr=NULL;
+    XModifierKeymap *modmap;
+
+    if(strstr(shortcut,"Shift"))
+        modifier_mask = modifier_mask|ShiftMask;
+    if(strstr(shortcut,"Control"))
+        modifier_mask = modifier_mask|ControlMask;
+    if(strstr(shortcut,"Mod1"))
+        modifier_mask = modifier_mask|Mod1Mask;
+    if(strstr(shortcut,"Mod2"))
+        modifier_mask = modifier_mask|Mod2Mask;
+    if(strstr(shortcut,"Mod3"))
+        modifier_mask = modifier_mask|Mod3Mask;
+    if(strstr(shortcut,"Mod4"))
+        modifier_mask = modifier_mask|Mod4Mask;
+    if(strstr(shortcut,"Mod5"))
+        modifier_mask = modifier_mask|Mod5Mask;
+    
+    //we register the shortcut on the root
+    //window, which means on every keypress event,
+    //so I think it's neccessary to have at least one 
+    //modifier.
+    if(modifier_mask == 0)
+        return 1;
+    if((keystr=rindex(shortcut,'+'))!=NULL){
+        keystr++;
+        if((key=XStringToKeysym(keystr))==NoSymbol)
+            return 1;
+        else
+            keycode=XKeysymToKeycode(dpy,key);
+    }
+    else
+        return 1;
+
+
+    /* Key grabbing stuff taken from tilda who took it from yeahconsole 
+     * who took it from evilwm */
+
+    modmap = XGetModifierMapping(dpy);
+    for(i=0;i<8;i++){
+        for(j=0;j<modmap->max_keypermod;j++){
+            if(modmap->modifiermap[i*modmap->max_keypermod+j]==
+               XKeysymToKeycode(dpy,XK_Num_Lock))
+                numlock_mask=(1<<i);
+        }
+    }
+    XFreeModifiermap(modmap);
+
+    hotkey->modnum=0;
+    hotkey->key=keycode;
+
+    XGrabKey(dpy,
+             keycode,
+             modifier_mask,
+             root,
+             True,
+             GrabModeAsync,
+             GrabModeAsync);
+    hotkey->mask[0]=modifier_mask;
+    hotkey->modnum++;
+
+    XGrabKey(dpy,
+             keycode,
+             LockMask | modifier_mask,
+             root,
+             True,
+             GrabModeAsync,
+             GrabModeAsync);
+    hotkey->mask[1]=LockMask | modifier_mask;
+    hotkey->modnum++;
+
+    if(numlock_mask){
+
+        XGrabKey(dpy,
+                 keycode,
+                 numlock_mask | modifier_mask,
+                 root,
+                 True,
+                 GrabModeAsync,
+                 GrabModeAsync);
+        hotkey->mask[2]=numlock_mask | modifier_mask;
+        hotkey->modnum++;
+
+        XGrabKey(dpy,
+                 keycode,
+                 numlock_mask | LockMask | modifier_mask,
+                 root,
+                 True,
+                 GrabModeAsync,
+                 GrabModeAsync);
+        hotkey->mask[3]=numlock_mask | LockMask | modifier_mask;
+        hotkey->modnum++;
+
+    }
+
+    return 0;
+
+}
+
+
+
+
+
+
-- 
cgit v1.2.3