diff options
Diffstat (limited to 'recordmydesktop/src')
78 files changed, 0 insertions, 10311 deletions
diff --git a/recordmydesktop/src/Makefile.am b/recordmydesktop/src/Makefile.am deleted file mode 100644 index a63c3c4..0000000 --- a/recordmydesktop/src/Makefile.am +++ /dev/null @@ -1,94 +0,0 @@ -bin_PROGRAMS = recordmydesktop - -recordmydesktop_SOURCES = \ - rmd.c \ - rmd_cache.c \ - rmd_cache.h \ - rmd_cache_audio.c \ - rmd_cache_audio.h \ - rmd_cache_frame.c \ - rmd_cache_frame.h \ - rmd_capture_sound.c \ - rmd_capture_sound.h \ - rmd_encode_cache.c \ - rmd_encode_cache.h \ - rmd_encode_image_buffer.c \ - rmd_encode_image_buffer.h \ - rmd_encode_sound_buffer.c \ - rmd_encode_sound_buffer.h \ - rmd_error.c \ - rmd_error.h \ - rmd_flush_to_ogg.c \ - rmd_flush_to_ogg.h \ - rmd_frame.c \ - rmd_frame.h \ - rmd_get_frame.c \ - rmd_get_frame.h \ - rmd_getzpixmap.c \ - rmd_getzpixmap.h \ - rmd_init_encoder.c \ - rmd_init_encoder.h \ - rmd_initialize_data.c \ - rmd_initialize_data.h \ - rmd_jack.c \ - rmd_jack.h \ - rmd_load_cache.c \ - rmd_load_cache.h \ - rmd_macro.h \ - rmd_make_dummy_pointer.c \ - rmd_make_dummy_pointer.h \ - rmd_math.c \ - rmd_math.h \ - rmd_opendev.c \ - rmd_opendev.h \ - rmd_parseargs.c \ - rmd_parseargs.h \ - rmd_poll_events.c \ - rmd_poll_events.h \ - rmd_queryextensions.c \ - rmd_queryextensions.h \ - rmd_rectinsert.c \ - rmd_rectinsert.h \ - rmd_register_callbacks.c \ - rmd_register_callbacks.h \ - rmd_rescue.c \ - rmd_rescue.h \ - rmd_setbrwindow.c \ - rmd_setbrwindow.h \ - rmd_shortcuts.c \ - rmd_shortcuts.h \ - rmd_specsfile.c \ - rmd_specsfile.h \ - rmd_threads.c \ - rmd_threads.h \ - rmd_timer.c \ - rmd_timer.h \ - rmd_types.h \ - rmd_update_image.c \ - rmd_update_image.h \ - rmd_wm_check.c \ - rmd_wm_check.h \ - rmd_wm_is_compositing.c \ - rmd_wm_is_compositing.h \ - rmd_yuv_utils.c \ - rmd_yuv_utils.h \ - skeleton.c \ - skeleton.h - -recordmydesktop_CPPFLAGS = -D_THREAD_SAFE -pthread -Wall -recordmydesktop_LDFLAGS = @X_LIBS@ @X_EXTRA_LIBS@ @X_PRE_LIBS@ - - -# RectInsert test -TESTS = test-rectinsert -EXTRA_PROGRAMS = test-rectinsert -CLEANFILES = $(EXTRA_PROGRAMS) - -test_rectinsert_SOURCES = \ - test-rectinsert.c \ - test-rectinsert-data.c \ - test-rectinsert-data.h \ - test-rectinsert-types.h \ - rmd_rectinsert.c - -test_rectinsert_CFLAGS = -Wall diff --git a/recordmydesktop/src/rmd.c b/recordmydesktop/src/rmd.c deleted file mode 100644 index 5a93e79..0000000 --- a/recordmydesktop/src/rmd.c +++ /dev/null @@ -1,184 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" - -#include "rmd_cache.h" -#include "rmd_encode_cache.h" -#include "rmd_error.h" -#include "rmd_initialize_data.h" -#include "rmd_parseargs.h" -#include "rmd_queryextensions.h" -#include "rmd_rescue.h" -#include "rmd_setbrwindow.h" -#include "rmd_shortcuts.h" -#include "rmd_threads.h" -#include "rmd_wm_is_compositing.h" -#include "rmd_types.h" - -#include <X11/Xlib.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -int main(int argc, char **argv){ - ProgData pdata = {}; - EncData enc_data = {}; - CacheData cache_data = {}; - int exit_status = 0; - -#ifdef HAVE_LIBJACK - JackData jdata; - - // Give jack access to program data, mainly for program state - jdata.pdata = &pdata; - pdata.jdata = &jdata; -#endif - - rmdSetupDefaultArgs(&pdata.args); - - if (!rmdParseArgs(argc, argv, &pdata.args)) - exit(1); - - if (pdata.args.rescue_path != NULL) - exit(rmdRescue(pdata.args.rescue_path)); - - if (XInitThreads() == 0) { - fprintf(stderr, "Couldn't initialize thread support!\n"); - exit(7); - } - - if (pdata.args.display != NULL) { - pdata.dpy = XOpenDisplay(pdata.args.display); - XSetErrorHandler(rmdErrorHandler); - } else { - fprintf(stderr, "No display specified for connection!\n"); - exit(8); - } - - if (pdata.dpy == NULL) { - fprintf(stderr, "Cannot connect to X server %s\n", pdata.args.display); - exit(9); - } - - // Query display specs - pdata.specs.screen = DefaultScreen(pdata.dpy); - pdata.specs.width = DisplayWidth(pdata.dpy, pdata.specs.screen); - pdata.specs.height = DisplayHeight(pdata.dpy, pdata.specs.screen); - pdata.specs.root = RootWindow(pdata.dpy, pdata.specs.screen); - pdata.specs.visual = DefaultVisual(pdata.dpy, pdata.specs.screen); - pdata.specs.gc = DefaultGC(pdata.dpy, pdata.specs.screen); - pdata.specs.depth = DefaultDepth(pdata.dpy, pdata.specs.screen); - - if (pdata.specs.depth != 32 && pdata.specs.depth != 24 && pdata.specs.depth != 16) { - fprintf(stderr, - "Only 32bpp, 24bpp, and 16bpp" - " color depth modes are currently supported.\n"); - exit(10); - } - - if (!rmdSetBRWindow(pdata.dpy, &pdata.brwin, &pdata.specs, &pdata.args)) - exit(11); - - if (!pdata.args.nowmcheck && rmdWMIsCompositing( pdata.dpy, pdata.specs.screen ) ) { - - fprintf(stderr, "\nDetected compositing window manager.\n" - "Reverting to full screen capture at every frame.\n" - "To disable this check run with --no-wm-check\n" - "(though that is not advised, since it will " - "probably produce faulty results).\n\n"); - pdata.args.full_shots = 1; - pdata.args.noshared = 0; - } - - rmdQueryExtensions( pdata.dpy, - &pdata.args, - &pdata.damage_event, - &pdata.damage_error, - &pdata.shm_opcode); - - exit_status = rmdInitializeData(&pdata, &enc_data, &cache_data); - if (exit_status) - exit(exit_status); - - if ( !strcmp(pdata.args.pause_shortcut, pdata.args.stop_shortcut) || - rmdRegisterShortcut( pdata.dpy, pdata.specs.root, - pdata.args.pause_shortcut, - &(pdata.pause_key)) || - rmdRegisterShortcut( pdata.dpy, - pdata.specs.root, - pdata.args.stop_shortcut, - &(pdata.stop_key))) { - - fprintf(stderr, "Invalid shortcut, or shortcuts are the same!\n\nUsing defaults.\n"); - - rmdRegisterShortcut( pdata.dpy, - pdata.specs.root, - "Control+Mod1+p", - &(pdata.pause_key)); - - rmdRegisterShortcut( pdata.dpy, - pdata.specs.root, - "Control+Mod1+s", - &(pdata.stop_key)); - } - - //this is where the capturing happens. - rmdThreads(&pdata); - - XCloseDisplay(pdata.dpy); - fprintf(stderr, ".\n"); - - //encode and then cleanup cache - if (!pdata.args.encOnTheFly && !pdata.args.no_encode) { - if (!pdata.aborted) - rmdEncodeCache(&pdata); - - fprintf(stderr, "Cleanning up cache...\n"); - if (rmdPurgeCache(pdata.cache_data, !pdata.args.nosound)) - fprintf(stderr, "Some error occured while cleaning up cache!\n"); - - fprintf(stderr, "Done!!!\n"); - } - - if (pdata.aborted && pdata.args.encOnTheFly) { - if (remove(pdata.args.filename)) { - perror("Error while removing file:\n"); - return 1; - } else { - fprintf(stderr, "SIGABRT received, file %s removed\n", - pdata.args.filename); - return 0; - } - } else - fprintf(stderr, "Goodbye!\n"); - - rmdCleanUp(); - - return exit_status; -} diff --git a/recordmydesktop/src/rmd_cache.c b/recordmydesktop/src/rmd_cache.c deleted file mode 100644 index 1353bc2..0000000 --- a/recordmydesktop/src/rmd_cache.c +++ /dev/null @@ -1,218 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_cache.h" - -#include "rmd_specsfile.h" -#include "rmd_types.h" - -#include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/stat.h> - - -/** -*Construct an number postfixed name -* -* \param name base name -* -* \param newname modified name -* -* \n number to be used as a postfix -* -*/ -static void rmdCacheFileN(char *name, char **newname, int n) { // Nth cache file - char numbuf[8]; - - strcpy(*newname, name); - strcat(*newname, "."); - snprintf(numbuf, 8, "%d", n); - strcat(*newname, numbuf); -} - -int rmdSwapCacheFilesWrite(char *name, int n, gzFile *fp, FILE **ucfp) { - char *newname = malloc(strlen(name) + 10); - - rmdCacheFileN(name, &newname, n); - if (*fp == NULL) { - fflush(*ucfp); - fclose(*ucfp); - *ucfp = fopen(newname, "wb"); - } else { - gzflush(*fp, Z_FINISH); - gzclose(*fp); - *fp = gzopen(newname, "wb0f"); - } - free(newname); - - return ((*fp == NULL) && (*ucfp == NULL)); -} - -int rmdSwapCacheFilesRead(char *name, int n, gzFile *fp, FILE **ucfp) { - char *newname = malloc(strlen(name) + 10); - - rmdCacheFileN(name, &newname, n); - if (*fp == NULL) { - fclose(*ucfp); - *ucfp = fopen(newname, "rb"); - } else { - gzclose(*fp); - *fp = gzopen(newname, "rb"); - } - free(newname); - - return ((*fp == NULL) && (*ucfp == NULL)); -} - -int rmdPurgeCache(CacheData *cache_data_t, int sound) { - struct stat buff; - char *fname; - int exit_value = 0; - int nth_cache = 1; - - fname = malloc(strlen(cache_data_t->imgdata) + 10); - strcpy(fname, cache_data_t->imgdata); - - while (stat(fname, &buff) == 0) { - if (remove(fname)) { - fprintf(stderr, "Couldn't remove temporary file %s", cache_data_t->imgdata); - exit_value = 1; - } - rmdCacheFileN(cache_data_t->imgdata, &fname, nth_cache); - nth_cache++; - } - - free(fname); - - if (sound) { - if (remove(cache_data_t->audiodata)) { - fprintf(stderr, "Couldn't remove temporary file %s", cache_data_t->audiodata); - exit_value = 1; - } - } - - if (remove(cache_data_t->specsfile)) { - fprintf(stderr, "Couldn't remove temporary file %s", cache_data_t->specsfile); - exit_value = 1; - } - - if (remove(cache_data_t->projname)) { - fprintf(stderr, "Couldn't remove temporary directory %s", cache_data_t->projname); - exit_value = 1; - } - - return exit_value; -} - -void rmdInitCacheData(ProgData *pdata, EncData *enc_data_t, CacheData *cache_data_t) { - int width, height, pid; - char pidbuf[8]; - - //we set the buffer only since there's - //no need to initialize the encoder from now. - width = ((pdata->brwin.rrect.width + 15) >> 4) << 4; - height = ((pdata->brwin.rrect.height + 15) >> 4) << 4; - - (pdata)->enc_data = enc_data_t; - - enc_data_t->yuv.y = (unsigned char *)malloc(height * width); - enc_data_t->yuv.u = (unsigned char *)malloc(height * width / 4); - enc_data_t->yuv.v = (unsigned char *)malloc(height * width / 4); - enc_data_t->yuv.y_width = width; - enc_data_t->yuv.y_height = height; - enc_data_t->yuv.y_stride = width; - - enc_data_t->yuv.uv_width = width / 2; - enc_data_t->yuv.uv_height = height / 2; - enc_data_t->yuv.uv_stride = width / 2; - - //now we set the cache files - (pdata)->cache_data = cache_data_t; - - cache_data_t->workdir = (pdata->args).workdir; - pid = getpid(); - - snprintf( pidbuf, 8, "%d", pid ); - //names are stored relatively to current dir(i.e. no chdir) - cache_data_t->projname = malloc(strlen(cache_data_t->workdir) + 12 + strlen(pidbuf) + 3); - //projname - strcpy(cache_data_t->projname, cache_data_t->workdir); - strcat(cache_data_t->projname, "/"); - strcat(cache_data_t->projname, "rMD-session-"); - strcat(cache_data_t->projname, pidbuf); - strcat(cache_data_t->projname, "/"); - //image data - cache_data_t->imgdata = malloc(strlen(cache_data_t->projname) + 11); - strcpy(cache_data_t->imgdata, cache_data_t->projname); - strcat(cache_data_t->imgdata, "img.out"); - //audio data - cache_data_t->audiodata = malloc(strlen(cache_data_t->projname) + 10); - strcpy(cache_data_t->audiodata, cache_data_t->projname); - strcat(cache_data_t->audiodata, "audio.pcm"); - //specsfile - cache_data_t->specsfile = malloc(strlen(cache_data_t->projname) + 10); - strcpy(cache_data_t->specsfile, cache_data_t->projname); - strcat(cache_data_t->specsfile, "specs.txt"); - - //now that've got out buffers and our filenames we start - //creating the needed files - - if (mkdir(cache_data_t->projname, 0777)) { - fprintf(stderr, "Could not create temporary directory %s !!!\n", cache_data_t->projname); - exit(13); - } - - if (!pdata->args.zerocompression) { - cache_data_t->ifp = gzopen(cache_data_t->imgdata, "wb0f"); - if (cache_data_t->ifp == NULL) { - fprintf(stderr, "Could not create temporary file %s !!!\n", cache_data_t->imgdata); - exit(13); - } - } else { - cache_data_t->uncifp = fopen(cache_data_t->imgdata, "wb0f"); - if (cache_data_t->uncifp == NULL) { - fprintf(stderr, "Could not create temporary file %s !!!\n", cache_data_t->imgdata); - exit(13); - } - } - - if (!pdata->args.nosound) { - cache_data_t->afp = fopen(cache_data_t->audiodata, "wb"); - if (cache_data_t->afp == NULL) { - fprintf(stderr, "Could not create temporary file %s !!!\n", cache_data_t->audiodata); - exit(13); - } - } - - if (rmdWriteSpecsFile(pdata)) { - fprintf(stderr, "Could not write specsfile %s !!!\n", cache_data_t->specsfile); - exit(13); - } -} diff --git a/recordmydesktop/src/rmd_cache.h b/recordmydesktop/src/rmd_cache.h deleted file mode 100644 index 9f4acce..0000000 --- a/recordmydesktop/src/rmd_cache.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMD_CACHE_H -#define RMD_CACHE_H 1 - -#include "rmd_types.h" - -#include <zlib.h> - -#include <stdio.h> - - - -/** -* Change file pointer to a new file while writting -* (file name is incremented with CacheFileN) -* -* \param name base file name -* -* \param n number to be used as a postfix -* -* \param fp File pointer if compression is used(must be NULL otherwise) -* -* \param ucfp File pointer if compression is NOT used(must be NULL otherwise) -* -* \returns 0 on Success 1 on Failure -*/ -int rmdSwapCacheFilesWrite(char *name,int n,gzFile *fp,FILE **ucfp); - -/** -* Change file pointer to a new file while reading -* (file name is incremented with CacheFileN) -* -* \param name base file name -* -* \param n number to be used as a postfix -* -* \param fp File pointer if compression is used(must be NULL otherwise) -* -* \param ucfp File pointer if compression is NOT used(must be NULL otherwise) -* -* \returns 0 on Success 1 on Failure -*/ -int rmdSwapCacheFilesRead(char *name,int n,gzFile *fp,FILE **ucfp); - -/** -* Delete all cache files -* -* \param cache_data_t Caching options(file names etc.) -* -* \returns 0 if all files and folders where deleted, 1 otherwise -*/ -int rmdPurgeCache(CacheData *cache_data_t,int sound); - -/** -* Initializes paths and everything else needed to start caching -* -* \param pdata ProgData struct containing all program data -* -* \param enc_data_t Encoding options -* -* \param cache_data_t Caching options -* -*/ -void rmdInitCacheData(ProgData *pdata, - EncData *enc_data_t, - CacheData *cache_data_t); - - -#endif diff --git a/recordmydesktop/src/rmd_cache_audio.c b/recordmydesktop/src/rmd_cache_audio.c deleted file mode 100644 index fabcb39..0000000 --- a/recordmydesktop/src/rmd_cache_audio.c +++ /dev/null @@ -1,104 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_cache_audio.h" - -#include "rmd_jack.h" -#include "rmd_types.h" - -#include <pthread.h> - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - - - -void *rmdCacheSoundBuffer(ProgData *pdata) { - size_t write_size = pdata->periodsize * pdata->sound_framesize; - -#ifdef HAVE_LIBJACK - void *jackbuf = NULL; - - if (pdata->args.use_jack) { - write_size = pdata->sound_framesize * pdata->jdata->buffersize; - jackbuf = malloc(pdata->sound_framesize * pdata->jdata->buffersize); - } -#endif - -//We are simply going to throw sound on the disk. -//It's sound is tiny compared to that of image, so -//compressing would reducethe overall size by only an -//insignificant fraction. - - while (pdata->running) { - SndBuffer *buff = NULL; - - pthread_mutex_lock(&pdata->pause_mutex); - while (pdata->paused) - pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex); - pthread_mutex_unlock(&pdata->pause_mutex); - - if (!pdata->args.use_jack) { - pthread_mutex_lock(&pdata->sound_buffer_mutex); - while (!pdata->sound_buffer && pdata->running) - pthread_cond_wait(&pdata->sound_data_read, &pdata->sound_buffer_mutex); - - buff = pdata->sound_buffer; - if (buff) - pdata->sound_buffer = buff->next; - pthread_mutex_unlock(&pdata->sound_buffer_mutex); - - if (!pdata->running) - break; - - fwrite(buff->data, 1, write_size, pdata->cache_data->afp); - free(buff->data); - free(buff); - } else { -#ifdef HAVE_LIBJACK - pthread_mutex_lock(&pdata->sound_buffer_mutex); - while ( pdata->running && - jack_ringbuffer_read_space(pdata->jdata->sound_buffer) < write_size) - pthread_cond_wait(&pdata->sound_data_read, &pdata->sound_buffer_mutex); - - if (pdata->running) - jack_ringbuffer_read(pdata->jdata->sound_buffer, jackbuf, write_size); - pthread_mutex_unlock(&pdata->sound_buffer_mutex); - - if (!pdata->running) - break; - - fwrite(jackbuf, 1, write_size, pdata->cache_data->afp); -#endif - } - pdata->avd -= pdata->periodtime; - } - - fclose(pdata->cache_data->afp); - pthread_exit(&errno); -} diff --git a/recordmydesktop/src/rmd_cache_audio.h b/recordmydesktop/src/rmd_cache_audio.h deleted file mode 100644 index 1ba3221..0000000 --- a/recordmydesktop/src/rmd_cache_audio.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef CACHE_AUDIO_H -#define CACHE_AUDIO_H 1 - -#include "rmd_types.h" - - -/** -* Sound caching thread. Simply writes the pcm buffers on disk -* -* \param pdata ProgData struct containing all program data -* -*/ -void *rmdCacheSoundBuffer(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_cache_frame.c b/recordmydesktop/src/rmd_cache_frame.c deleted file mode 100644 index 7b8a2f3..0000000 --- a/recordmydesktop/src/rmd_cache_frame.c +++ /dev/null @@ -1,319 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_cache_frame.h" - -#include "rmd_yuv_utils.h" -#include "rmd_cache.h" -#include "rmd_types.h" - -#include <signal.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <math.h> - - -#define BYTES_PER_MB (1024 * 1024) -#define CACHE_OUT_BUFFER_SIZE (4 * 1024) -#define CACHE_FILE_SIZE_LIMIT (500 * 1024 * 1024) - - -static int rmdFlushBlock( - unsigned char *buf, - int blockno, - int width, - int height, - int blockwidth, - gzFile fp, - FILE *ucfp, - int flush) { - - int bytes_written = 0, - block_i = (!blockwidth) ? 0 : (blockno / (width / blockwidth)),//place on the grid - block_k = (!blockwidth) ? 0 : (blockno % (width / blockwidth)); - register unsigned char *buf_reg = (&buf[(block_i * width + block_k) * blockwidth]); - static unsigned char out_buffer[CACHE_OUT_BUFFER_SIZE]; - static unsigned int out_buffer_bytes = 0; - - if (out_buffer_bytes + pow(blockwidth, 2) >= CACHE_OUT_BUFFER_SIZE || (flush && out_buffer_bytes)) { - if (ucfp == NULL) - gzwrite(fp, (void *)out_buffer, out_buffer_bytes); - else - fwrite((void *)out_buffer, 1, out_buffer_bytes, ucfp); - - bytes_written = out_buffer_bytes; - out_buffer_bytes = 0; - } - - if (!flush) { - register unsigned char *out_buf_reg = &out_buffer[out_buffer_bytes]; - - for (int j = 0;j < blockwidth; j++) { - - for(int i = 0;i < blockwidth; i++) - (*out_buf_reg++) = (*buf_reg++); - - out_buffer_bytes += blockwidth; - buf_reg += width - blockwidth; - } - } - - return bytes_written; -} - -void *rmdCacheImageBuffer(ProgData *pdata) { - - gzFile fp = NULL; - FILE *ucfp = NULL; - int index_entry_size = sizeof(u_int32_t), - blocknum_x = pdata->enc_data->yuv.y_width / Y_UNIT_WIDTH, - blocknum_y = pdata->enc_data->yuv.y_height / Y_UNIT_WIDTH, - firstrun = 1, - frameno = 0, - nbytes = 0, - nth_cache = 1; - u_int32_t ynum, unum, vnum, - y_short_blocks[blocknum_x * blocknum_y], - u_short_blocks[blocknum_x * blocknum_y], - v_short_blocks[blocknum_x * blocknum_y]; - unsigned long long int total_bytes = 0; - unsigned long long int total_received_bytes = 0; - unsigned int capture_frameno = 0; - - if (!pdata->args.zerocompression) { - fp = pdata->cache_data->ifp; - - if (fp == NULL) - exit(13); - } else { - ucfp = pdata->cache_data->uncifp; - - if (ucfp == NULL) - exit(13); - } - - while (pdata->running) { - FrameHeader fheader; - - ynum = unum = vnum = 0; - - pthread_mutex_lock(&pdata->img_buff_ready_mutex); - while (pdata->running && capture_frameno >= pdata->capture_frameno) - pthread_cond_wait(&pdata->image_buffer_ready, &pdata->img_buff_ready_mutex); - - capture_frameno = pdata->capture_frameno; - pthread_mutex_unlock(&pdata->img_buff_ready_mutex); - - pthread_mutex_lock(&pdata->pause_mutex); - while (pdata->paused) - pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex); - pthread_mutex_unlock(&pdata->pause_mutex); - - pthread_mutex_lock(&pdata->yuv_mutex); - - //find and flush different blocks - if (firstrun) { - firstrun = 0; - for(int j = 0; j < blocknum_x * blocknum_y; j++) { - yblocks[ynum] = 1; - y_short_blocks[ynum] = j; - ynum++; - ublocks[unum] = 1; - u_short_blocks[unum] = j; - unum++; - vblocks[vnum] = 1; - v_short_blocks[vnum] = j; - vnum++; - } - } else { - /**COMPRESS ARRAYS*/ - for(int j = 0; j < blocknum_x * blocknum_y; j++) { - if (yblocks[j]) { - y_short_blocks[ynum] = j; - ynum++; - } - if (ublocks[j]) { - u_short_blocks[unum] = j; - unum++; - } - if (vblocks[j]) { - v_short_blocks[vnum] = j; - vnum++; - } - } - } - - /**WRITE FRAME TO DISK*/ - if (!pdata->args.zerocompression) { - if (ynum * 4 + unum + vnum > (blocknum_x * blocknum_y * 6) / 10) - gzsetparams(fp, 1, Z_FILTERED); - else - gzsetparams(fp, 0, Z_FILTERED); - } - - strncpy(fheader.frame_prefix, "FRAM", 4); - fheader.frameno = ++frameno; - fheader.current_total = pdata->frames_total; - - fheader.Ynum = ynum; - fheader.Unum = unum; - fheader.Vnum = vnum; - - if (!pdata->args.zerocompression) { - nbytes += gzwrite(fp, (void*)&fheader, sizeof(FrameHeader)); - //flush indexes - if (ynum) - nbytes += gzwrite(fp, (void*)y_short_blocks, ynum * index_entry_size); - - if (unum) - nbytes += gzwrite(fp, (void*)u_short_blocks, unum * index_entry_size); - - if (vnum) - nbytes += gzwrite(fp, (void*)v_short_blocks, vnum * index_entry_size); - } else { - nbytes += sizeof(FrameHeader)* - fwrite((void*)&fheader, sizeof(FrameHeader), 1, ucfp); - //flush indexes - if (ynum) - nbytes += index_entry_size * fwrite(y_short_blocks, index_entry_size, ynum, ucfp); - - if (unum) - nbytes += index_entry_size * fwrite(u_short_blocks, index_entry_size, unum, ucfp); - - if (vnum) - nbytes += index_entry_size * fwrite(v_short_blocks, index_entry_size, vnum, ucfp); - } - - //flush the blocks for each buffer - if (ynum) { - for(int j = 0; j < ynum; j++) - nbytes += rmdFlushBlock(pdata->enc_data->yuv.y, - y_short_blocks[j], - pdata->enc_data->yuv.y_width, - pdata->enc_data->yuv.y_height, - Y_UNIT_WIDTH, - fp, - ucfp, - 0); - } - - if (unum) { - for(int j = 0; j < unum; j++) - nbytes += rmdFlushBlock(pdata->enc_data->yuv.u, - u_short_blocks[j], - pdata->enc_data->yuv.uv_width, - pdata->enc_data->yuv.uv_height, - UV_UNIT_WIDTH, - fp, - ucfp, - 0); - } - - if (vnum) { - for(int j = 0; j < vnum; j++) - nbytes += rmdFlushBlock(pdata->enc_data->yuv.v, - v_short_blocks[j], - pdata->enc_data->yuv.uv_width, - pdata->enc_data->yuv.uv_height, - UV_UNIT_WIDTH, - fp, - ucfp, - 0); - } - - //release main buffer - pthread_mutex_unlock(&pdata->yuv_mutex); - - nbytes += rmdFlushBlock(NULL, 0, 0, 0, 0, fp, ucfp, 1); - /**@________________@**/ - pdata->avd += pdata->frametime; - - if (nbytes > CACHE_FILE_SIZE_LIMIT) { - if (rmdSwapCacheFilesWrite(pdata->cache_data->imgdata, nth_cache, &fp, &ucfp)) { - fprintf(stderr, "New cache file could not be created.\n" - "Ending recording...\n"); - fflush(stderr); - raise(SIGINT); //if for some reason we cannot make a new file - //we have to stop. If we are out of space, - //which means - //that encoding cannot happen either, - //InitEncoder will cause an abrupt end with an - //error code and the cache will remain intact. - //If we've chosen separate two-stages, - //the program will make a - //clean exit. - //In either case data will be preserved so if - //space is freed the recording - //can be proccessed later. - } - total_bytes += nbytes; - nth_cache++; - nbytes = 0; - } - } - total_bytes += nbytes; - - { - unsigned int bytes_per_pixel = pdata->specs.depth >= 24 ? 4 : 2; - unsigned int pixels_per_frame = pdata->enc_data->yuv.y_width * pdata->enc_data->yuv.y_height; - - total_received_bytes = ((unsigned long long int)frameno) * bytes_per_pixel * pixels_per_frame; - } - - if (total_received_bytes) { - double percent_of_data_left = (total_bytes / (double)total_received_bytes) * 100; - - fprintf(stderr, "\n" - "*********************************************\n" - "\n" - "Cached %llu MB, from %llu MB that were received.\n" - "Average cache compression ratio: %.1f %%\n" - "\n" - "*********************************************\n", - total_bytes / BYTES_PER_MB, - total_received_bytes / BYTES_PER_MB, - 100 - percent_of_data_left); - - } - - fprintf(stderr, "Saved %d frames in a total of %d requests\n", - frameno, - pdata->frames_total); - fflush(stderr); - - if (!pdata->args.zerocompression) { - gzflush(fp, Z_FINISH); - gzclose(fp); - } else { - fflush(ucfp); - fclose(ucfp); - } - - pthread_exit(&errno); -} diff --git a/recordmydesktop/src/rmd_cache_frame.h b/recordmydesktop/src/rmd_cache_frame.h deleted file mode 100644 index 9361e35..0000000 --- a/recordmydesktop/src/rmd_cache_frame.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef CACHE_FRAME_H -#define CACHE_FRAME_H 1 - -#include "rmd_types.h" - - -/** -* Image caching thread. Copies the yuv buffer, compares with the last one and -* caches the result. -* -* \param pdata ProgData struct containing all program data -* -*/ -void *rmdCacheImageBuffer(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_capture_sound.c b/recordmydesktop/src/rmd_capture_sound.c deleted file mode 100644 index 2719c60..0000000 --- a/recordmydesktop/src/rmd_capture_sound.c +++ /dev/null @@ -1,165 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_capture_sound.h" - -#include "rmd_jack.h" -#include "rmd_opendev.h" -#include "rmd_types.h" - -#include <pthread.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/uio.h> -#include <unistd.h> -#include <stdlib.h> - - -void *rmdCaptureSound(ProgData *pdata) { - -#ifdef HAVE_LIBASOUND - int frames = pdata->periodsize; -#endif - //start capturing only after first frame is taken - usleep(pdata->frametime); - - while (pdata->running) { - int sret = 0; - SndBuffer *newbuf, *tmp; - - if (pdata->paused) { -#ifdef HAVE_LIBASOUND - if (!pdata->hard_pause) { - snd_pcm_pause(pdata->sound_handle, 1); - pthread_mutex_lock(&pdata->pause_mutex); - pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex); - pthread_mutex_unlock(&pdata->pause_mutex); - snd_pcm_pause(pdata->sound_handle, 0); - } else {//device doesn't support pause(is this the norm?mine doesn't) - snd_pcm_close(pdata->sound_handle); - pthread_mutex_lock(&pdata->pause_mutex); - pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex); - pthread_mutex_unlock(&pdata->pause_mutex); - pdata->sound_handle = - rmdOpenDev(pdata->args.device, - &pdata->args.channels, - &pdata->args.frequency, - &pdata->args.buffsize, - NULL, - NULL, - NULL//let's hope that the device capabilities - //didn't magically change - ); - if (pdata->sound_handle == NULL) { - fprintf(stderr, "Couldn't reopen sound device.Exiting\n"); - pdata->running = FALSE; - errno = 3; - pthread_exit(&errno); - } - } -#else - close(pdata->sound_handle); - pthread_mutex_lock(&pdata->pause_mutex); - pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex); - pthread_mutex_unlock(&pdata->pause_mutex); - pdata->sound_handle = rmdOpenDev( pdata->args.device, - pdata->args.channels, - pdata->args.frequency); - if (pdata->sound_handle < 0) { - fprintf(stderr, "Couldn't reopen sound device. Exiting\n"); - pdata->running = FALSE; - errno = 3; - pthread_exit(&errno); - } -#endif - } - - //create new buffer - newbuf = (SndBuffer *)malloc(sizeof(SndBuffer)); -#ifdef HAVE_LIBASOUND - newbuf->data = (signed char *)malloc(frames * pdata->sound_framesize); -#else - newbuf->data = (signed char *)malloc((pdata->args.buffsize << 1) * pdata->args.channels); -#endif - newbuf->next = NULL; - - //read data into new buffer -#ifdef HAVE_LIBASOUND - while (sret<frames) { - int temp_sret = snd_pcm_readi( pdata->sound_handle, - newbuf->data + pdata->sound_framesize * sret, - frames-sret); - if (temp_sret == -EPIPE) { - fprintf(stderr, "%s: Overrun occurred.\n", - snd_strerror(temp_sret)); - snd_pcm_prepare(pdata->sound_handle); - } else if (temp_sret < 0) { - fprintf(stderr, "An error occured while reading sound data:\n" - " %s\n", - snd_strerror(temp_sret)); - snd_pcm_prepare(pdata->sound_handle); - } else - sret += temp_sret; - } -#else - sret = 0; - //oss recording loop - do { - int temp_sret = read( pdata->sound_handle, - &newbuf->data[sret], - (pdata->args.buffsize << 1) * - pdata->args.channels)-sret; - if (temp_sret < 0) { - fprintf(stderr, "An error occured while reading from soundcard" - "%s\nError description:\n%s\n", - pdata->args.device, strerror(errno)); - } else - sret += temp_sret; - } while (sret < (pdata->args.buffsize << 1) * pdata->args.channels); -#endif - //queue the new buffer - pthread_mutex_lock(&pdata->sound_buffer_mutex); - tmp = pdata->sound_buffer; - if (!tmp) - pdata->sound_buffer = newbuf; - else { - while (tmp->next != NULL) - tmp = tmp->next; - - tmp->next = newbuf; - } - pthread_cond_signal(&pdata->sound_data_read); - pthread_mutex_unlock(&pdata->sound_buffer_mutex); - } -#ifdef HAVE_LIBASOUND - snd_pcm_close(pdata->sound_handle); -#else - close(pdata->sound_handle); -#endif - pthread_exit(&errno); -} diff --git a/recordmydesktop/src/rmd_capture_sound.h b/recordmydesktop/src/rmd_capture_sound.h deleted file mode 100644 index b403fa8..0000000 --- a/recordmydesktop/src/rmd_capture_sound.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef CAPTURE_SOUND_H -#define CAPTURE_SOUND_H 1 - -#include "rmd_types.h" - - -/** -* Sound capturing thread. Data are placed on a -* list to be picked up by other threads. -* -* \param pdata ProgData struct containing all program data -*/ -void *rmdCaptureSound(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_encode_cache.c b/recordmydesktop/src/rmd_encode_cache.c deleted file mode 100644 index 1e0727c..0000000 --- a/recordmydesktop/src/rmd_encode_cache.c +++ /dev/null @@ -1,72 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_encode_cache.h" - -#include "rmd_flush_to_ogg.h" -#include "rmd_init_encoder.h" -#include "rmd_load_cache.h" -#include "rmd_types.h" - -#include <pthread.h> - -#include <stdio.h> -#include <stdlib.h> - - - -void rmdEncodeCache(ProgData *pdata){ - pthread_t flush_to_ogg_t, load_cache_t; - - fprintf(stderr, "STATE:ENCODING\n"); - fprintf(stderr, "Encoding started!\nThis may take several minutes.\n" - "Pressing Ctrl-C will cancel the procedure" - " (resuming will not be possible, but\n" - "any portion of the video, which is already encoded won't be deleted).\n" - "Please wait...\n"); - - pdata->running = TRUE; - rmdInitEncoder(pdata, pdata->enc_data, 1); - //load encoding and flushing threads - if (!pdata->args.nosound) { - //before we start loading again - //we need to free any left-overs - while (pdata->sound_buffer != NULL) { - free(pdata->sound_buffer->data); - pdata->sound_buffer = pdata->sound_buffer->next; - } - } - pthread_create(&flush_to_ogg_t, NULL, (void *)rmdFlushToOgg, (void *)pdata); - - //start loading image and audio - pthread_create(&load_cache_t, NULL, (void *)rmdLoadCache, (void *)pdata); - - //join and finish - pthread_join(load_cache_t, NULL); - fprintf(stderr, "Encoding finished!\nWait a moment please...\n"); - pthread_join(flush_to_ogg_t, NULL); -} diff --git a/recordmydesktop/src/rmd_encode_cache.h b/recordmydesktop/src/rmd_encode_cache.h deleted file mode 100644 index 4c37f97..0000000 --- a/recordmydesktop/src/rmd_encode_cache.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef ENCODE_CACHE_H -#define ENCODE_CACHE_H 1 - -#include "rmd_types.h" - - -/** -* Encode cache into an -* ogg stream. -* \param pdata ProgData struct containing all program data -*/ -void rmdEncodeCache(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_encode_image_buffer.c b/recordmydesktop/src/rmd_encode_image_buffer.c deleted file mode 100644 index c234aa4..0000000 --- a/recordmydesktop/src/rmd_encode_image_buffer.c +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_encode_image_buffer.h" - -#include "rmd_types.h" - -#include <errno.h> - - -void *rmdEncodeImageBuffer(ProgData *pdata) { - unsigned int encode_frameno = 0; - - pdata->th_encoding_clean = 0; - - while (pdata->running) { - EncData *enc_data = pdata->enc_data; - - pthread_mutex_lock(&pdata->img_buff_ready_mutex); - while (pdata->running && encode_frameno >= pdata->capture_frameno) - pthread_cond_wait(&pdata->image_buffer_ready, &pdata->img_buff_ready_mutex); - encode_frameno = pdata->capture_frameno; - pthread_mutex_unlock(&pdata->img_buff_ready_mutex); - - pthread_mutex_lock(&pdata->pause_mutex); - while (pdata->paused) - pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex); - pthread_mutex_unlock(&pdata->pause_mutex); - - pthread_mutex_lock(&pdata->yuv_mutex); - if (theora_encode_YUVin(&enc_data->m_th_st, &enc_data->yuv)) { - fprintf(stderr, "Encoder not ready!\n"); - pthread_mutex_unlock(&pdata->yuv_mutex); - } else { - pthread_mutex_unlock(&pdata->yuv_mutex); - - if (theora_encode_packetout(&enc_data->m_th_st, 0, &enc_data->m_ogg_pckt1) == 1) { - pthread_mutex_lock(&pdata->libogg_mutex); - ogg_stream_packetin(&enc_data->m_ogg_ts, &enc_data->m_ogg_pckt1); - pdata->avd += pdata->frametime; - pthread_mutex_unlock(&pdata->libogg_mutex); - } - } - } - - //last packet - pthread_mutex_lock(&pdata->theora_lib_mutex); - pdata->th_encoding_clean = 1; - pthread_cond_signal(&pdata->theora_lib_clean); - pthread_mutex_unlock(&pdata->theora_lib_mutex); - - pthread_exit(&errno); -} - -//this function is meant to be called normally -//not through a thread of it's own -void rmdSyncEncodeImageBuffer(ProgData *pdata) { - EncData *enc_data = pdata->enc_data; - - if (theora_encode_YUVin(&enc_data->m_th_st, &enc_data->yuv)) { - fprintf(stderr, "Encoder not ready!\n"); - return; - } - - if (theora_encode_packetout(&enc_data->m_th_st, !pdata->running, &enc_data->m_ogg_pckt1) == 1) { - pthread_mutex_lock(&pdata->libogg_mutex); - ogg_stream_packetin(&enc_data->m_ogg_ts, &enc_data->m_ogg_pckt1); - - if (!pdata->running) - enc_data->m_ogg_ts.e_o_s = 1; - - pdata->avd += pdata->frametime; - pthread_mutex_unlock(&pdata->libogg_mutex); - } -} diff --git a/recordmydesktop/src/rmd_encode_image_buffer.h b/recordmydesktop/src/rmd_encode_image_buffer.h deleted file mode 100644 index e5ca3db..0000000 --- a/recordmydesktop/src/rmd_encode_image_buffer.h +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef ENCODE_IMAGE_BUFFER_H -#define ENCODE_IMAGE_BUFFER_H 1 - -#include "rmd_types.h" - - -/** -* feed a yuv buffer to the theora encoder and submit outcome to -* the ogg stream. -* \param pdata ProgData struct containing all program data -*/ -void *rmdEncodeImageBuffer(ProgData *pdata); - -/** -* As rmdEncodeImageBuffer, only with the assumption that -* this is not a thread on it's own -* -* \param pdata ProgData struct containing all program data -* -*/ -void rmdSyncEncodeImageBuffer(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_encode_sound_buffer.c b/recordmydesktop/src/rmd_encode_sound_buffer.c deleted file mode 100644 index 5fa1dc6..0000000 --- a/recordmydesktop/src/rmd_encode_sound_buffer.c +++ /dev/null @@ -1,178 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_encode_sound_buffer.h" - -#include "rmd_jack.h" -#include "rmd_types.h" - -#include <pthread.h> - -#include <stdlib.h> -#include <errno.h> - - -void *rmdEncodeSoundBuffer(ProgData *pdata) { - int sampread = pdata->periodsize; -#ifdef HAVE_LIBJACK - void *jackbuf = NULL; - - if (pdata->args.use_jack) - jackbuf = malloc(pdata->sound_framesize * pdata->jdata->buffersize); -#endif - - pdata->v_encoding_clean = 0; - while (pdata->running) { - float **vorbis_buffer; - SndBuffer *buff = NULL; - - pthread_mutex_lock(&pdata->pause_mutex); - while (pdata->paused) - pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex); - pthread_mutex_unlock(&pdata->pause_mutex); - - if (!pdata->args.use_jack) { - pthread_mutex_lock(&pdata->sound_buffer_mutex); - while (!pdata->sound_buffer && pdata->running) - pthread_cond_wait(&pdata->sound_data_read, &pdata->sound_buffer_mutex); - - buff = pdata->sound_buffer; - if (buff) - pdata->sound_buffer = buff->next; - pthread_mutex_unlock(&pdata->sound_buffer_mutex); - - if (!pdata->running) - break; - - vorbis_buffer = vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp, sampread); - - for (int i = 0, count = 0; i < sampread; i++) { - for (int j = 0; j < pdata->args.channels; j++) { - vorbis_buffer[j][i] = ((buff->data[count + 1] << 8) | - (0x00ff & (int)buff->data[count])) / - 32768.f; - count += 2; - } - } - free(buff->data); - free(buff); - } else { -#ifdef HAVE_LIBJACK - - pthread_mutex_lock(&pdata->sound_buffer_mutex); - while ( pdata->running && - jack_ringbuffer_read_space(pdata->jdata->sound_buffer) < - pdata->sound_framesize * pdata->jdata->buffersize) - pthread_cond_wait(&pdata->sound_data_read, &pdata->sound_buffer_mutex); - - if (pdata->running) - jack_ringbuffer_read( pdata->jdata->sound_buffer, - jackbuf, - (pdata->sound_framesize * - pdata->jdata->buffersize) - ); - - pthread_mutex_unlock(&pdata->sound_buffer_mutex); - - if (!pdata->running) - break; - - vorbis_buffer = vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp, sampread); - - for (int j = 0, count = 0; j < pdata->args.channels; j++) { - for (int i = 0; i < sampread; i++) { - vorbis_buffer[j][i] = ((float*)jackbuf)[count]; - count++; - } - } -#endif - } - vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp, sampread); - - pthread_mutex_lock(&pdata->libogg_mutex); - while (vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_vo_block) == 1) { - - vorbis_analysis(&pdata->enc_data->m_vo_block, NULL); - vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block); - - while (vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_ogg_pckt2)) { - ogg_stream_packetin(&pdata->enc_data->m_ogg_vs, &pdata->enc_data->m_ogg_pckt2); - } - } - pthread_mutex_unlock(&pdata->libogg_mutex); - - /* this needs synchronizing */ - pdata->avd -= pdata->periodtime; - } - - pthread_mutex_lock(&pdata->vorbis_lib_mutex); - pdata->v_encoding_clean = 1; - pthread_cond_signal(&pdata->vorbis_lib_clean); - pthread_mutex_unlock(&pdata->vorbis_lib_mutex); - pthread_exit(&errno); -} - -void rmdSyncEncodeSoundBuffer(ProgData *pdata, signed char *buff) { - int sampread = (buff != NULL) ? pdata->periodsize : 0; - float **vorbis_buffer = vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp, sampread); - - if (!pdata->args.use_jack) { - for (int i = 0, count = 0; i < sampread; i++) { - for (int j = 0; j < pdata->args.channels; j++) { - vorbis_buffer[j][i] = ((buff[count + 1] << 8) | - (0x00ff & (int)buff[count])) - / 32768.f; - count += 2; - } - } - } else { - for (int j = 0, count = 0; j < pdata->args.channels; j++) { - for (int i = 0; i < sampread; i++) { - vorbis_buffer[j][i] = ((float *)buff)[count]; - count++; - } - } - } - - vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp, sampread); - - pthread_mutex_lock(&pdata->libogg_mutex); - while (vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_vo_block) == 1) { - - vorbis_analysis(&pdata->enc_data->m_vo_block, NULL); - vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block); - - while (vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_ogg_pckt2)) - ogg_stream_packetin(&pdata->enc_data->m_ogg_vs, &pdata->enc_data->m_ogg_pckt2); - } - pthread_mutex_unlock(&pdata->libogg_mutex); - - if (!pdata->running) - pdata->enc_data->m_ogg_vs.e_o_s = 1; - - pdata->avd -= pdata->periodtime; -} diff --git a/recordmydesktop/src/rmd_encode_sound_buffer.h b/recordmydesktop/src/rmd_encode_sound_buffer.h deleted file mode 100644 index 7d5c312..0000000 --- a/recordmydesktop/src/rmd_encode_sound_buffer.h +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef ENCODE_SOUND_BUFFER_H -#define ENCODE_SOUND_BUFFER_H 1 - -#include "rmd_types.h" - - -/** -* Sound encoding thread. Picks up data from the buffer queue , -* encodes and places them on the vorbis stream. -* -* \param pdata ProgData struct containing all program data -*/ -void *rmdEncodeSoundBuffer(ProgData *pdata); - -/** -* As rmdEncodeSoundBuffer, only with the assumption that -* this is not a thread on it's own -* -* \param pdata ProgData struct containing all program data -* -*/ -void rmdSyncEncodeSoundBuffer(ProgData *pdata,signed char *buff); - - -#endif diff --git a/recordmydesktop/src/rmd_error.c b/recordmydesktop/src/rmd_error.c deleted file mode 100644 index ba95198..0000000 --- a/recordmydesktop/src/rmd_error.c +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_error.h" - -#include <X11/Xlib.h> -#include <X11/Xlibint.h> - -#include <stdio.h> -#include <stdlib.h> - - - -int rmdErrorHandler(Display *dpy, XErrorEvent *e) -{ - char error_desc[1024]; - - XGetErrorText(dpy, e->error_code, error_desc, sizeof(error_desc)); - fprintf(stderr, "X Error: %s\n", error_desc); - fflush(stderr); - - if ((e->error_code==BadWindow)&&(e->request_code==X_GetWindowAttributes)) { - fprintf(stderr, "BadWindow on XGetWindowAttributes.\nIgnoring...\n"); - fflush(stderr); - return 0; - } - - if ((e->error_code==BadAccess)&&(e->request_code==X_GrabKey)) { - fprintf(stderr, "Bad Access on XGrabKey.\n" "Shortcut already assigned.\n"); - fflush(stderr); - return 0; - } - - exit(1); -} diff --git a/recordmydesktop/src/rmd_error.h b/recordmydesktop/src/rmd_error.h deleted file mode 100644 index 4d27264..0000000 --- a/recordmydesktop/src/rmd_error.h +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMD_ERROR_H -#define RMD_ERROR_H 1 - -#include "rmd_types.h" - - -/* - * Handling of X errors. - * Ignores, bad access when registering shortcuts - * and BadWindow on XQueryTree - * - * \param dpy Connection to the X Server - * - * \param e XErrorEvent struct containing error info - * - * \returns 0 on the two ignored cases, calls exit(1) - * otherwise. - * - */ -int rmdErrorHandler(Display *dpy,XErrorEvent *e); - - -#endif diff --git a/recordmydesktop/src/rmd_flush_to_ogg.c b/recordmydesktop/src/rmd_flush_to_ogg.c deleted file mode 100644 index 87308a6..0000000 --- a/recordmydesktop/src/rmd_flush_to_ogg.c +++ /dev/null @@ -1,235 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_flush_to_ogg.h" - -#include "rmd_encode_image_buffer.h" -#include "rmd_encode_sound_buffer.h" -#include "rmd_types.h" - -#include <pthread.h> - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> - - - -//we copy the page because the next call to ogg_stream_pageout -//will invalidate it. But we must have pages from -//both streams at every time in -//order to do correct multiplexing -static void page_copy(ogg_page *new, ogg_page *old) { - - new->header_len = old->header_len; - new->header = malloc(new->header_len); - new->body_len = old->body_len; - new->body = malloc(new->body_len); - - memcpy(new->header, old->header, new->header_len); - memcpy(new->body, old->body, new->body_len); -} - -//free our copy -static void page_free(ogg_page *pg) { - pg->header_len = pg->body_len = 0; - free(pg->header); - free(pg->body); -} - -void *rmdFlushToOgg(ProgData *pdata) { - int videoflag = 0, audioflag = 0; - double video_bytesout = 0, audio_bytesout = 0; - ogg_page videopage, //owned by libogg - videopage_copy, //owned by the application - audiopage, //owned by libogg - audiopage_copy; //owned by the application - - double audiotime = 0; - double videotime = 0; - int th_st_fin = 0, - v_st_fin = (pdata->args.nosound); - - while (!(th_st_fin && v_st_fin)) { - int audio_or_video = 0; - - if (pdata->running) { - pthread_mutex_lock(&pdata->libogg_mutex); - if (!videoflag) { - videoflag = ogg_stream_pageout(&pdata->enc_data->m_ogg_ts, &videopage); - videotime = videoflag ? theora_granule_time( - &pdata->enc_data->m_th_st, - ogg_page_granulepos(&videopage) - ) : -1; - - if (videoflag) - page_copy(&videopage_copy, &videopage); - } - - if (!pdata->args.nosound && !audioflag) { - audioflag = ogg_stream_pageout(&pdata->enc_data->m_ogg_vs, &audiopage); - audiotime = audioflag ? vorbis_granule_time( - &pdata->enc_data->m_vo_dsp, - ogg_page_granulepos(&audiopage) - ) : -1; - - if (audioflag) - page_copy(&audiopage_copy, &audiopage); - } - pthread_mutex_unlock(&pdata->libogg_mutex); - } else { - if (!th_st_fin && !videoflag) { - pthread_mutex_lock(&pdata->libogg_mutex); - videoflag = ogg_stream_flush(&pdata->enc_data->m_ogg_ts, &videopage); - videotime = videoflag ? theora_granule_time( - &pdata->enc_data->m_th_st, - ogg_page_granulepos(&videopage) - ) : -1; - - if (videoflag) - page_copy(&videopage_copy, &videopage); - pthread_mutex_unlock(&pdata->libogg_mutex); - - //we need the last page to properly close the stream - if (!videoflag) { - pthread_mutex_lock(&pdata->theora_lib_mutex); - while (!pdata->th_encoding_clean) - pthread_cond_wait(&pdata->theora_lib_clean, &pdata->theora_lib_mutex); - pthread_mutex_unlock(&pdata->theora_lib_mutex); - rmdSyncEncodeImageBuffer(pdata); - } - } - - if (!pdata->args.nosound && !v_st_fin && !audioflag) { - pthread_mutex_lock(&pdata->libogg_mutex); - audioflag = ogg_stream_flush(&pdata->enc_data->m_ogg_vs, &audiopage); - audiotime = audioflag ? vorbis_granule_time( - &pdata->enc_data->m_vo_dsp, - ogg_page_granulepos(&audiopage) - ) : -1; - - if (audioflag) - page_copy(&audiopage_copy, &audiopage); - pthread_mutex_unlock(&pdata->libogg_mutex); - - //we need the last page to properly close the stream - if (!audioflag) { - pthread_mutex_lock(&pdata->vorbis_lib_mutex); - while (!pdata->v_encoding_clean) - pthread_cond_wait(&pdata->vorbis_lib_clean, &pdata->vorbis_lib_mutex); - pthread_mutex_unlock(&pdata->vorbis_lib_mutex); - rmdSyncEncodeSoundBuffer(pdata, NULL); - } - } - } - -#if 0 - /* I don't understand what this is about, if these are finished we want to lose - * their pages? - */ - if (th_st_fin) - videoflag=0; - - if (v_st_fin) - audioflag=0; -#endif - if ((!audioflag && !v_st_fin && !pdata->args.nosound) || (!videoflag && !th_st_fin)) { - usleep(10000); - continue; - } - - if (!audioflag) { - audio_or_video = 1; - } else if (!videoflag) { - audio_or_video = 0; - } else { - if (audiotime < videotime) - audio_or_video = 0; - else - audio_or_video = 1; - } - - if (audio_or_video == 1) { - video_bytesout += fwrite( videopage_copy.header, 1, - videopage_copy.header_len, - pdata->enc_data->fp); - - video_bytesout += fwrite( videopage_copy.body, 1, - videopage_copy.body_len, - pdata->enc_data->fp); - videoflag = 0; - - if (!pdata->running) { - pthread_mutex_lock(&pdata->libogg_mutex); - if (ogg_page_eos(&videopage_copy)) - th_st_fin = 1; - pthread_mutex_unlock(&pdata->libogg_mutex); - } - - page_free(&videopage_copy); - } else { - audio_bytesout += fwrite( audiopage_copy.header, 1, - audiopage_copy.header_len, - pdata->enc_data->fp); - - audio_bytesout += fwrite( audiopage_copy.body, 1, - audiopage_copy.body_len, - pdata->enc_data->fp); - audioflag = 0; - - if (!pdata->running) { - pthread_mutex_lock(&pdata->libogg_mutex); - if (ogg_page_eos(&audiopage_copy)) - v_st_fin = 1; - pthread_mutex_unlock(&pdata->libogg_mutex); - } - - page_free(&audiopage_copy); - } - } - - pthread_mutex_lock(&pdata->libogg_mutex); - ogg_stream_clear(&pdata->enc_data->m_ogg_ts); - - if (!pdata->args.nosound) - ogg_stream_clear(&pdata->enc_data->m_ogg_vs); - - pthread_mutex_unlock(&pdata->libogg_mutex); - - theora_clear(&pdata->enc_data->m_th_st); - - if (pdata->enc_data->fp) - fclose(pdata->enc_data->fp); - - fprintf(stderr, "\r \nDone.\nWritten %.0f bytes\n" - "(%.0f of which were video data and %.0f audio data)\n\n", - video_bytesout + audio_bytesout, - video_bytesout, audio_bytesout); - - pthread_exit(&errno); -} diff --git a/recordmydesktop/src/rmd_flush_to_ogg.h b/recordmydesktop/src/rmd_flush_to_ogg.h deleted file mode 100644 index 64094a8..0000000 --- a/recordmydesktop/src/rmd_flush_to_ogg.h +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef FLUSH_TO_OGG_H -#define FLUSH_TO_OGG_H 1 - -#include "rmd_types.h" - - -/** -* Query theora and vorbis streams for ready packages and -* flush them on the disk -* \param pdata ProgData struct containing all program data -*/ -void *rmdFlushToOgg(ProgData *pdata); - -#endif diff --git a/recordmydesktop/src/rmd_frame.c b/recordmydesktop/src/rmd_frame.c deleted file mode 100644 index ee5c4d8..0000000 --- a/recordmydesktop/src/rmd_frame.c +++ /dev/null @@ -1,142 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_frame.h" - -#include <X11/Xlib.h> -#include <X11/extensions/shape.h> - -#include <stdio.h> -#include <stdlib.h> - - -#define BORDER_WIDTH 6 -#define OUTLINE_WIDTH 1 - - -void rmdDrawFrame( Display *dpy, - int screen, - Window win, - int width, - int height) { - - GC gc; - XGCValues gcv; - XColor white, white_e, black, black_e; - unsigned long gcmask = GCForeground; - - XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "white", &white, &white_e); - XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &black_e); - - gcv.foreground = black.pixel; - gc = XCreateGC(dpy, win, gcmask, &gcv); - XFillRectangle( dpy, - win, - gc, - OUTLINE_WIDTH, - OUTLINE_WIDTH, - width + (BORDER_WIDTH-OUTLINE_WIDTH) * 2, - height + (BORDER_WIDTH-OUTLINE_WIDTH) * 2); - gcv.foreground = white.pixel; - XChangeGC(dpy, gc, gcmask, &gcv); - XFillRectangle( dpy, - win, - gc, - BORDER_WIDTH-OUTLINE_WIDTH, - BORDER_WIDTH-OUTLINE_WIDTH, - width + OUTLINE_WIDTH * 2, - height + OUTLINE_WIDTH * 2); - - XFreeGC(dpy, gc); - -} - -void rmdMoveFrame( Display *dpy, - Window win, - int x, - int y) { - - XMoveWindow(dpy, win, x-BORDER_WIDTH, y-BORDER_WIDTH); -// XSync(pdata->dpy, False); -} - -Window rmdFrameInit( Display *dpy, - int screen, - Window root, - int x, - int y, - int width, - int height) { - - XSetWindowAttributes attribs; - XColor white, white_e; - Window win; - unsigned long valuemask = CWBackPixmap|CWBackPixel| - CWSaveUnder|CWOverrideRedirect|CWColormap; - - XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "white", &white, &white_e); - - attribs.background_pixmap = None; - attribs.background_pixel = white.pixel; - attribs.save_under = True; - attribs.override_redirect = True; - attribs.colormap = DefaultColormap(dpy, screen); - - win = XCreateWindow( dpy, - root, - x - BORDER_WIDTH, - y - BORDER_WIDTH, - width + BORDER_WIDTH * 2, - height + BORDER_WIDTH * 2, - 0, - CopyFromParent, - InputOutput, - CopyFromParent, - valuemask, - &attribs); - - XRectangle rect; - rect.x = rect.y = BORDER_WIDTH; - rect.width = width; - rect.height = height; - - XShapeCombineRectangles( dpy, - win, - ShapeBounding, - 0, - 0, - &rect, - 1, - ShapeSubtract, - 0); - - XMapWindow(dpy, win); - - rmdDrawFrame(dpy, screen, win, width, height); - - return win; -} diff --git a/recordmydesktop/src/rmd_frame.h b/recordmydesktop/src/rmd_frame.h deleted file mode 100644 index c3969f8..0000000 --- a/recordmydesktop/src/rmd_frame.h +++ /dev/null @@ -1,101 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMD_FRAME_H -#define RMD_FRAME_H 1 - -#include "rmd_types.h" - - -/* - * Create a frame that marks the recording area. - * - * \param dpy Connection to the X Server - * - * \param screen Recorded screen - * - * \param root Root window of the display - * - * \param x X pos of the recorded area - * - * \param y Y pos of the recorded area - * - * \param width Width of the recorded area - * - * \param height Height of the recorded area - * - * \returns The WindowID of the frame - * - */ -Window rmdFrameInit(Display *dpy, - int screen, - Window root, - int x, - int y, - int width, - int height); - - -/* - * Move the frame (subtracts the borderwidth) - * - * \param dpy Connection to the X Server - * - * \param win WindowId of the frame - * - * \param x New X pos of the recorded area - * - * \param y New Y pos of the recorded area - * - */ -void rmdMoveFrame(Display *dpy, - Window win, - int x, - int y); - - -/* - * Redraw the frame that marks the recording area. - * - * \param dpy Connection to the X Server - * - * \param screen Recorded screen - * - * \param win WindoID of the frame - * - * \param width Width of the recorded area - * - * \param height Height of the recorded area - * - */ -void rmdDrawFrame(Display *dpy, - int screen, - Window win, - int width, - int height); - - -#endif diff --git a/recordmydesktop/src/rmd_get_frame.c b/recordmydesktop/src/rmd_get_frame.c deleted file mode 100644 index a9e4daa..0000000 --- a/recordmydesktop/src/rmd_get_frame.c +++ /dev/null @@ -1,593 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_get_frame.h" - -#include "rmd_cache.h" -#include "rmd_frame.h" -#include "rmd_getzpixmap.h" -#include "rmd_poll_events.h" -#include "rmd_rectinsert.h" -#include "rmd_update_image.h" -#include "rmd_yuv_utils.h" -#include "rmd_types.h" - -#include <X11/extensions/Xfixes.h> -#include <X11/extensions/XShm.h> - -#include <limits.h> -#include <pthread.h> -#include <sys/shm.h> -#include <errno.h> -#include <stdlib.h> - - -/* clip_event_area dejavu */ -static void clip_dummy_pointer_area(XRectangle *area, XRectangle *clip, XRectangle *res) -{ - res->x = (((area->x + area->width >= clip->x) && - (area->x <= clip->x + clip->width)) ? - ((area->x <= clip->x) ? clip->x : area->x) : -1); - - res->y = (((area->y + area->height >= clip->y) && - (area->y <= clip->y + clip->height)) ? - ((area->y <= clip->y) ? clip->y : area->y) : -1); - - res->width = (area->x <= clip->x) ? area->width - (clip->x - area->x) : - (area->x <= clip->x + clip->width) ? - (clip->width - area->x + clip->x < area->width) ? - clip->width - area->x + clip->x : area->width : 0; - - res->height = (area->y <= clip->y) ? area->height - (clip->y - area->y) : - (area->y <= clip->y + clip->height) ? - (clip->height - area->y + clip->y < area->height) ? - clip->height - area->y + clip->y : area->height : 0; - - if (res->x + res->width > clip->x + clip->width) - res->width = clip->x + clip->width - res->x; - - if (res->y + res->height > clip->y + clip->height) - res->height = clip->y + clip->height - res->y; -} - -#define MARK_BUFFER_AREA_C( data, \ - x_tm, \ - y_tm, \ - width_tm, \ - height_tm, \ - buffer_width, \ - __depth__) { \ - \ - register u_int##__depth__##_t *datapi = \ - ((u_int##__depth__##_t *)data) + y_tm * buffer_width + x_tm; \ - \ - for(int k = 0; k < height_tm; k++) { \ - for(int i = 0; i < width_tm; i++) { \ - *datapi += 1; \ - datapi++; \ - } \ - datapi += buffer_width - width_tm; \ - } \ -} - -static void mark_buffer_area( unsigned char *data, - int x_tm, int y_tm, - int width_tm, int height_tm, - int buffer_width, int depth) { - - if ((depth == 24) || (depth == 32)) { - MARK_BUFFER_AREA_C( data, - x_tm, - y_tm, - width_tm, - height_tm, - buffer_width, - 32); - } else { - MARK_BUFFER_AREA_C( data, - x_tm, - y_tm, - width_tm, - height_tm, - buffer_width, - 16); - } -} - -//besides taking the first screenshot, this functions primary purpose is to -//initialize the structures and memory. -static int rmdFirstFrame(ProgData *pdata, Image *image) { - const XRectangle *rrect = &pdata->brwin.rrect; - - if (pdata->args.noshared) { - image->ximage = XGetImage( pdata->dpy, - pdata->specs.root, - rrect->x, - rrect->y, - rrect->width, - rrect->height, - AllPlanes, - ZPixmap); - } else { - image->ximage = XShmCreateImage(pdata->dpy, - pdata->specs.visual, - pdata->specs.depth, - ZPixmap, - NULL, - &image->shm_info, - rrect->width, - rrect->height); - - image->shm_info.shmid = shmget( IPC_PRIVATE, - image->ximage->bytes_per_line * - image->ximage->height, - IPC_CREAT|0777); - - if (image->shm_info.shmid == -1) { - fprintf(stderr, "Failed to obtain Shared Memory segment!\n"); - return 12; - } - - image->shm_info.shmaddr = image->ximage->data = shmat(image->shm_info.shmid, NULL, 0); - image->shm_info.readOnly = False; - shmctl(image->shm_info.shmid, IPC_RMID, NULL); - - if (!XShmAttach(pdata->dpy, &image->shm_info)) { - fprintf(stderr, "Failed to attach shared memory to proccess.\n"); - return 12; - } - - XShmGetImage( pdata->dpy, - pdata->specs.root, - image->ximage, - rrect->x, - rrect->y, - AllPlanes); - } - - rmdUpdateYuvBuffer( &pdata->enc_data->yuv, - (unsigned char *)image->ximage->data, - NULL, - 0, - 0, - rrect->width, - rrect->height, - pdata->args.no_quick_subsample, - pdata->specs.depth); - - return 0; -} - -//make a deep copy -static void rmdBRWinCpy(BRWindow *target, BRWindow *source) { - target->winrect = source->winrect; - target->rrect = source->rrect; - target->windowid = source->windowid; -} - -//recenters the capture area to the mouse -//without exiting the display bounding box -static void rmdMoveCaptureArea( XRectangle *rect, - int cursor_x, - int cursor_y, - int width, - int height) { - int t_x = 0, t_y = 0; - - t_x = cursor_x - rect->width / 2; - t_x = (t_x >> 1) << 1; - rect->x = (t_x < 0) ? 0 : ((t_x + rect->width > width) ? width - rect->width : t_x); - t_y = cursor_y - rect->height / 2; - t_y = (t_y >> 1) << 1; - rect->y = (t_y < 0 ) ? 0 : ((t_y + rect->height > height) ? height - rect->height : t_y); -} - - -static void rmdBlocksReset(unsigned int blocks_w, unsigned int blocks_h) { - memset(yblocks, 0, blocks_w * blocks_h * sizeof(*yblocks)); - memset(ublocks, 0, blocks_w * blocks_h * sizeof(*ublocks)); - memset(vblocks, 0, blocks_w * blocks_h * sizeof(*vblocks)); -} - - -/** -* Extract cache blocks from damage list -* -* \param root Root entry of the list with damaged areas -* -* \param x_offset left x of the recording area -* -* \param y_offset upper y of the recording area -* -* \param blocks_w Width of image in blocks -* -* \param blocks_h Height of image in blocks -*/ -static void rmdBlocksFromList( RectArea **root, - unsigned int x_offset, - unsigned int y_offset, - unsigned int blocks_w, - unsigned int blocks_h) { - - rmdBlocksReset(blocks_w, blocks_h); - - for (RectArea *temp = *root; temp; temp = temp->next) { - int row_start, row_end, column_start, column_end; - - column_start = ((int)(temp->rect.x - x_offset)) / Y_UNIT_WIDTH; - column_end = ((int)(temp->rect.x + (temp->rect.width - 1) - x_offset)) / Y_UNIT_WIDTH; - row_start = ((int)(temp->rect.y - y_offset)) / Y_UNIT_WIDTH; - row_end = ((int)(temp->rect.y + (temp->rect.height - 1) - y_offset)) / Y_UNIT_WIDTH; - - for (int i = row_start; i < row_end + 1; i++) { - for (int j = column_start; j < column_end + 1; j++) { - - int blockno = i * blocks_w + j; - - yblocks[blockno] = 1; - ublocks[blockno] = 1; - vblocks[blockno] = 1; - } - } - } -} - -void *rmdGetFrame(ProgData *pdata) { - int blocks_w = pdata->enc_data->yuv.y_width / Y_UNIT_WIDTH, - blocks_h = pdata->enc_data->yuv.y_height / Y_UNIT_WIDTH; - unsigned int msk_ret; - XRectangle mouse_pos_abs, mouse_pos_rel, mouse_pos_temp; - BRWindow temp_brwin; - Window root_ret, child_ret; //Frame - XFixesCursorImage *xcim = NULL; - Image image = {}, image_back = {}; //the image that holds - //the current full screenshot - int init_img1 = 0, init_img2 = 0, img_sel, d_buff; - - img_sel = d_buff = pdata->args.full_shots; - - if ((init_img1 = rmdFirstFrame(pdata, &image) != 0)) { - if (pdata->args.encOnTheFly) { - if (remove(pdata->args.filename)) { - perror("Error while removing file:\n"); - } else { - fprintf(stderr, "SIGABRT received, file %s removed\n", - pdata->args.filename); - } - } else { - rmdPurgeCache(pdata->cache_data, !pdata->args.nosound); - } - - exit(init_img1); - } - - if (d_buff) { - if ((init_img2 = rmdFirstFrame(pdata, &image_back) != 0)) { - if (pdata->args.encOnTheFly) { - if (remove(pdata->args.filename)) { - perror("Error while removing file:\n"); - } else{ - fprintf(stderr, "SIGABRT received, file %s removed\n", - pdata->args.filename); - } - } else { - rmdPurgeCache(pdata->cache_data, !pdata->args.nosound); - } - - exit(init_img2); - } - } - - if (!pdata->args.noframe) { - pdata->shaped_w = rmdFrameInit( pdata->dpy, - pdata->specs.screen, - pdata->specs.root, - pdata->brwin.rrect.x, - pdata->brwin.rrect.y, - pdata->brwin.rrect.width, - pdata->brwin.rrect.height); - - XSelectInput(pdata->dpy, pdata->shaped_w, ExposureMask); - } - - mouse_pos_abs.x = mouse_pos_temp.x = 0; - mouse_pos_abs.y = mouse_pos_temp.y = 0; - mouse_pos_abs.width = mouse_pos_temp.width = pdata->dummy_p_size; - mouse_pos_abs.height = mouse_pos_temp.height = pdata->dummy_p_size; - - //This is the the place where we call XSelectInput - //and arrange so that we listen for damage on all - //windows - rmdInitEventsPolling(pdata); - - while (pdata->running) { - unsigned time_frameno; - - //if we are left behind we must not wait. - //also before actually pausing we must make sure the streams - //are synced. sound stops so this should only happen quickly. - pthread_mutex_lock(&pdata->time_mutex); - while ( (pdata->avd > 0 || pdata->args.nosound) && - pdata->capture_frameno >= pdata->time_frameno) - pthread_cond_wait(&pdata->time_cond, &pdata->time_mutex); - - time_frameno = pdata->time_frameno; - pthread_mutex_unlock(&pdata->time_mutex); - - //read all events and construct list with damage - //events (if not full_shots) - rmdEventLoop(pdata); - - if (pdata->paused) - continue; - - //switch back and front buffers (full_shots only) - if (d_buff) - img_sel = img_sel ? 0 : 1; - - rmdBRWinCpy(&temp_brwin, &pdata->brwin); - - - if ( pdata->args.xfixes_cursor || - pdata->args.have_dummy_cursor || - pdata->args.follow_mouse) { - - - // Pointer sequence: - // * Mark previous position as dirty with rmdRectInsert() - // * Update to new position - // * Mark new position as dirty with rmdRectInsert() - if ( !pdata->args.full_shots && - mouse_pos_temp.x >= 0 && - mouse_pos_temp.y >= 0 && - mouse_pos_temp.width > 0 && - mouse_pos_temp.height > 0) { - rmdRectInsert(&pdata->rect_root, &mouse_pos_temp); - } - - if (pdata->args.xfixes_cursor) { - xcim = XFixesGetCursorImage(pdata->dpy); - mouse_pos_abs.x = xcim->x - xcim->xhot; - mouse_pos_abs.y = xcim->y - xcim->yhot; - mouse_pos_abs.width = xcim->width; - mouse_pos_abs.height = xcim->height; - } else { - XQueryPointer( pdata->dpy, - pdata->specs.root, - &root_ret, &child_ret, - (int *)&mouse_pos_abs.x, - (int *)&mouse_pos_abs.y, - (int *)&mouse_pos_rel.x, - (int *)&mouse_pos_rel.y, - &msk_ret); - } - - clip_dummy_pointer_area(&mouse_pos_abs, &temp_brwin.rrect, &mouse_pos_temp); - if ( mouse_pos_temp.x >= 0 && - mouse_pos_temp.y >= 0 && - mouse_pos_temp.width > 0 && - mouse_pos_temp.height > 0) { - - //there are 3 capture scenarios: - // * Xdamage - // * full-shots with double buffering - // * full-shots on a single buffer - //The last one cannot be reached through - //this code (see above how the d_buf variable is set), but - //even if it could, it would not be of interest regarding the - //marking of the cursor area. Single buffer means full repaint - //on every frame so there is no need for marking at all. - - if (!pdata->args.full_shots) { - rmdRectInsert(&pdata->rect_root, &mouse_pos_temp); - } else if (d_buff) { - unsigned char *back_buff= img_sel ? - ((unsigned char*)image.ximage->data) : - ((unsigned char*)image_back.ximage->data); - - mark_buffer_area( - back_buff, - mouse_pos_temp.x - temp_brwin.rrect.x, - mouse_pos_temp.y - temp_brwin.rrect.y, - mouse_pos_temp.width, mouse_pos_temp.height, temp_brwin.rrect.width, - pdata->specs.depth - ); - } - } - } - - if (pdata->args.follow_mouse) { - rmdMoveCaptureArea( &pdata->brwin.rrect, - mouse_pos_abs.x + pdata->args.xfixes_cursor ? xcim->xhot : 0, - mouse_pos_abs.y + pdata->args.xfixes_cursor ? xcim->yhot : 0, - pdata->specs.width, - pdata->specs.height); - - if (!pdata->args.noframe) - rmdMoveFrame( pdata->dpy, - pdata->shaped_w, - temp_brwin.rrect.x, - temp_brwin.rrect.y); - } - - if (!pdata->args.full_shots) { - pthread_mutex_lock(&pdata->yuv_mutex); - rmdUpdateImage( pdata->dpy, - &pdata->enc_data->yuv, - &pdata->specs, - &pdata->rect_root, - &temp_brwin, - pdata->enc_data, - &image, - pdata->args.noshared, - pdata->shm_opcode, - pdata->args.no_quick_subsample); - - rmdBlocksFromList( &pdata->rect_root, - temp_brwin.rrect.x, - temp_brwin.rrect.y, - blocks_w, - blocks_h); - - pthread_mutex_unlock(&pdata->yuv_mutex); - } else { - unsigned char *front_buff = !img_sel ? ((unsigned char*)image.ximage->data): - ((unsigned char*)image_back.ximage->data); - unsigned char *back_buff = !d_buff ? NULL : (img_sel ? - ((unsigned char*)image.ximage->data): - ((unsigned char*)image_back.ximage->data)); - - if (pdata->args.noshared) { - rmdGetZPixmap( pdata->dpy, - pdata->specs.root, - image.ximage->data, - temp_brwin.rrect.x, - temp_brwin.rrect.y, - temp_brwin.rrect.width, - temp_brwin.rrect.height); - } else { - XShmGetImage( pdata->dpy, - pdata->specs.root, - ((!img_sel) ? image.ximage : image_back.ximage), - temp_brwin.rrect.x, - temp_brwin.rrect.y, - AllPlanes); - } - - pthread_mutex_lock(&pdata->yuv_mutex); - rmdBlocksReset(blocks_w, blocks_h); - rmdUpdateYuvBuffer( &pdata->enc_data->yuv, - front_buff, - back_buff, - 0, - 0, - temp_brwin.rrect.width, - temp_brwin.rrect.height, - pdata->args.no_quick_subsample, - pdata->specs.depth); - - pthread_mutex_unlock(&pdata->yuv_mutex); - } - - if (pdata->args.xfixes_cursor || pdata->args.have_dummy_cursor) { - int mouse_xoffset, mouse_yoffset; - - //avoid segfaults - clip_dummy_pointer_area(&mouse_pos_abs, &temp_brwin.rrect, &mouse_pos_temp); - mouse_xoffset = mouse_pos_temp.x - mouse_pos_abs.x; - mouse_yoffset = mouse_pos_temp.y - mouse_pos_abs.y; - - if ((mouse_xoffset < 0) || (mouse_xoffset > mouse_pos_abs.width)) - mouse_xoffset = 0; - - if ((mouse_yoffset < 0) || (mouse_yoffset > mouse_pos_abs.height)) - mouse_yoffset = 0; - - //draw the cursor - if ( (mouse_pos_temp.x >= 0) && - (mouse_pos_temp.y >= 0) && - (mouse_pos_temp.width > 0) && - (mouse_pos_temp.height > 0)) { - - if (pdata->args.xfixes_cursor) { - rmdXFixesPointerToYuv( - &pdata->enc_data->yuv, - ((unsigned char*)xcim->pixels), - mouse_pos_temp.x - temp_brwin.rrect.x, - mouse_pos_temp.y - temp_brwin.rrect.y, - mouse_pos_temp.width, - mouse_pos_temp.height, - mouse_xoffset, - mouse_yoffset, - xcim->width-mouse_pos_temp.width - ); - } else { - rmdDummyPointerToYuv( - &pdata->enc_data->yuv, - pdata->dummy_pointer, - mouse_pos_temp.x - temp_brwin.rrect.x, - mouse_pos_temp.y - temp_brwin.rrect.y, - mouse_pos_temp.width, - mouse_pos_temp.height, - mouse_xoffset, - mouse_yoffset, - pdata->npxl - ); - } - - if (d_buff) { - //make previous cursor position dirty - //on the currently front buffer (which - //will be the back buffer next time it's - //used) - unsigned char *front_buff = !img_sel ? - ((unsigned char*)image.ximage->data) : - ((unsigned char*)image_back.ximage->data); - - mark_buffer_area( - front_buff, - mouse_pos_temp.x - temp_brwin.rrect.x, - mouse_pos_temp.y - temp_brwin.rrect.y, - mouse_pos_temp.width, - mouse_pos_temp.height, - temp_brwin.rrect.width, - pdata->specs.depth - ); - } - - } - - if (pdata->args.xfixes_cursor) { - XFree(xcim); - xcim = NULL; - } - } - - if (!pdata->args.full_shots) - rmdClearList(&pdata->rect_root); - - /* notify the encoder of the new frame */ - pthread_mutex_lock(&pdata->img_buff_ready_mutex); - pdata->capture_frameno = time_frameno; - pthread_cond_broadcast(&pdata->image_buffer_ready); - pthread_mutex_unlock(&pdata->img_buff_ready_mutex); - } - - if (!pdata->args.noframe) - XDestroyWindow(pdata->dpy, pdata->shaped_w); - - if (!pdata->args.noshared) { - XShmDetach(pdata->dpy, &image.shm_info); - shmdt(image.shm_info.shmaddr); - if (d_buff) { - XShmDetach(pdata->dpy, &image_back.shm_info); - shmdt(image_back.shm_info.shmaddr); - } - } - - pthread_exit(&errno); -} diff --git a/recordmydesktop/src/rmd_get_frame.h b/recordmydesktop/src/rmd_get_frame.h deleted file mode 100644 index 162c05e..0000000 --- a/recordmydesktop/src/rmd_get_frame.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef GET_FRAME_H -#define GET_FRAME_H 1 - -#include "rmd_types.h" - - -/** -* Retrieve frame form xserver, and transform to a yuv buffer, -* either directly(full shots) or by calling UpdateImage. -* \param pdata ProgData struct containing all program data -*/ -void *rmdGetFrame(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_getzpixmap.c b/recordmydesktop/src/rmd_getzpixmap.c deleted file mode 100644 index 43465c8..0000000 --- a/recordmydesktop/src/rmd_getzpixmap.c +++ /dev/null @@ -1,117 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_getzpixmap.h" - -#include "rmd_types.h" - - -#include <X11/Xlib.h> -#include <X11/Xlibint.h> -#include <X11/extensions/shmproto.h> -#include <X11/extensions/XShm.h> - - - -int rmdGetZPixmap( Display *dpy, - Window root, - char *data, - int x, - int y, - int width, - int height) { - - xGetImageReply reply; - xGetImageReq *request; - long nbytes; - - LockDisplay(dpy); - GetReq(GetImage, request); - request->drawable = root; - request->x = x; - request->y = y; - request->width = width; - request->height = height; - request->planeMask = AllPlanes; - request->format = ZPixmap; - - if (!_XReply(dpy, (xReply *)&reply, 0, xFalse) || !reply.length) { - UnlockDisplay(dpy); - SyncHandle(); - - return 1; - } - - nbytes = (long)reply.length << 2; - _XReadPad(dpy, data, nbytes); - UnlockDisplay(dpy); - SyncHandle(); - - return 0; -} - -int rmdGetZPixmapSHM( Display *dpy, - Window root, - XShmSegmentInfo *shminfo, - int shm_opcode, - char *data, - int x, - int y, - int width, - int height) { - - xShmGetImageReply reply; - xShmGetImageReq *request = NULL; - - LockDisplay(dpy); - GetReq(ShmGetImage, request); - - request->reqType = shm_opcode; - request->shmReqType = X_ShmGetImage; - request->shmseg = shminfo->shmseg; - - request->drawable = root; - request->x = x; - request->y = y; - request->width = width; - request->height = height; - request->planeMask = AllPlanes; - request->format = ZPixmap; - request->offset = data - shminfo->shmaddr; - - if ((!_XReply(dpy, (xReply *)&reply, 0, xFalse)) || !reply.length) { - UnlockDisplay(dpy); - SyncHandle(); - - return 1; - } - - UnlockDisplay(dpy); - SyncHandle(); - - return 0; -} diff --git a/recordmydesktop/src/rmd_getzpixmap.h b/recordmydesktop/src/rmd_getzpixmap.h deleted file mode 100644 index 87ad7bb..0000000 --- a/recordmydesktop/src/rmd_getzpixmap.h +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef GETZPIXMAP_H -#define GETZPIXMAP_H 1 - -#include "rmd_types.h" - -#include <X11/extensions/XShm.h> - -/** -* Rerieve pixmap data from xserver -* -* \param dpy Connection to the server -* -* \param root root window of the display -* -* \param data (preallocated)buffer to place the data -* -* \param x x position of the screenshot -* -* \param y y position of the screenshot -* -* \param x x position of the screenshot -* -* \param width width of the screenshot -* -* \param height height position of the screenshot -* -* \returns 0 on Success 1 on Failure -*/ -int rmdGetZPixmap(Display *dpy, - Window root, - char *data, - int x, - int y, - int width, - int height); - -/** -* Rerieve pixmap data from xserver through the MIT-Shm extension -* -* \param dpy Connection to the server -* -* \param root root window of the display -* -* \param shminfo Info for the shared memory segment -* -* \param shm_opcode Opcode of Shm extension -* -* \param data (preallocated)buffer to place the data -* -* \param x x position of the screenshot -* -* \param y y position of the screenshot -* -* \param x x position of the screenshot -* -* \param width width of the screenshot -* -* \param height height position of the screenshot -* -* \returns 0 on Success 1 on Failure -*/ -int rmdGetZPixmapSHM(Display *dpy, - Window root, - XShmSegmentInfo *shminfo, - int shm_opcode, - char *data, - int x, - int y, - int width, - int height); - - -#endif diff --git a/recordmydesktop/src/rmd_init_encoder.c b/recordmydesktop/src/rmd_init_encoder.c deleted file mode 100644 index a0d81e6..0000000 --- a/recordmydesktop/src/rmd_init_encoder.c +++ /dev/null @@ -1,346 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_init_encoder.h" - -#include "rmd_types.h" - -#include "skeleton.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> - - - -static void m_add_fishead_packet(ogg_stream_state *m_ogg_state) { - fishead_packet skel_fp; - - skel_fp.ptime_n = skel_fp.btime_n = 0; - skel_fp.ptime_d = skel_fp.btime_d = 1000; - - add_fishead_to_stream(m_ogg_state, &skel_fp); -} - - -static int rmdIncrementalNaming(char **name) { - struct stat buff; - char *base_name__; - int i = 0, fname_length = strlen(*name)-4; - - base_name__ = malloc(fname_length+1); - strncpy(base_name__, *name, fname_length); - base_name__[fname_length] = '\0'; - - //this will go on an endless loop if you have 65536? - //files with the same name - //or it will crash and die.anyone interested in trying ? - while (stat(*name, &buff)==0) { - //create new name - char *tname = malloc(strlen(*name)+10); - char numbuf[8]; - - strcpy(tname, base_name__); - strcat(tname, "-"); - i++; - snprintf( numbuf, 8, "%d", i ); - strcat(tname, numbuf); - strcat(tname, ".ogv"); - //save new name - - free(*name); - *name = malloc(strlen(tname)+1); - strcpy(*name, tname); - free(tname); - } - - free(base_name__); - return 0; -} - -void rmdInitEncoder(ProgData *pdata, EncData *enc_data_t, int buffer_ready) { - int y0, y1, y2, fname_length; - ogg_stream_state m_ogg_skel; - ogg_page skel_og_pg; - fisbone_packet skel_fbv, //video fisbone packet - skel_fba; //audio fisbone packet - const char *fname; - - pdata->enc_data = enc_data_t; - - fname = pdata->args.filename; - fname_length = strlen(fname); - if (!(fname_length>4 && !strcasecmp(&fname[fname_length-3], "ogv"))) { - - char *new_name = malloc(fname_length + 5); - strcpy(new_name, fname); - strcat(new_name, ".ogv"); - - free(pdata->args.filename); - pdata->args.filename = new_name; - } - - if (!pdata->args.overwrite) { - rmdIncrementalNaming(&(pdata)->args.filename); - fprintf(stderr, "Output file: %s\n", pdata->args.filename); - } - - enc_data_t->fp = fopen((pdata)->args.filename, "w"); - if (enc_data_t->fp == NULL) { - fprintf(stderr, "Cannot open file %s for writting!\n", (pdata)->args.filename); - exit(13); - } - - //each stream must have a unique - srand(time(NULL)); - y0 = rand() + 1; - y1 = rand() + 1; - y2 = rand() + 1; - y2 += (y1 == y2); - y0 = (((y0 == y1) || (y0 == y2)) ? (y1 + y2) : y0); - - //init ogg streams - //skeleton first - ogg_stream_init(&m_ogg_skel, y0); - m_add_fishead_packet(&m_ogg_skel); - if (ogg_stream_pageout(&m_ogg_skel, &skel_og_pg) != 1) { - fprintf (stderr, "Internal Ogg library error.\n"); - exit (2); - } - fwrite(skel_og_pg.header, 1, skel_og_pg.header_len, enc_data_t->fp); - fwrite(skel_og_pg.body, 1, skel_og_pg.body_len, enc_data_t->fp); - - ogg_stream_init(&enc_data_t->m_ogg_ts, y1); - if (!pdata->args.nosound) - ogg_stream_init(&enc_data_t->m_ogg_vs, y2); - - theora_info_init(&enc_data_t->m_th_inf); - enc_data_t->m_th_inf.frame_width = pdata->brwin.rrect.width; - enc_data_t->m_th_inf.frame_height = pdata->brwin.rrect.height; - enc_data_t->m_th_inf.width = ((enc_data_t->m_th_inf.frame_width + 15) >> 4) << 4; - enc_data_t->m_th_inf.height = ((enc_data_t->m_th_inf.frame_height + 15) >> 4) << 4; - enc_data_t->m_th_inf.offset_x = 0; - enc_data_t->m_th_inf.offset_y = 0; - - enc_data_t->m_th_inf.fps_numerator = pdata->args.fps * 100.0; - enc_data_t->m_th_inf.fps_denominator = 100; - enc_data_t->m_th_inf.aspect_numerator = 1; - enc_data_t->m_th_inf.aspect_denominator = 1; - - enc_data_t->m_th_inf.colorspace = OC_CS_UNSPECIFIED; - enc_data_t->m_th_inf.pixelformat = OC_PF_420; - - enc_data_t->m_th_inf.target_bitrate = pdata->args.v_bitrate; - enc_data_t->m_th_inf.quality = pdata->args.v_quality; - enc_data_t->m_th_inf.dropframes_p = 0; - enc_data_t->m_th_inf.quick_p = 1; - enc_data_t->m_th_inf.keyframe_auto_p = 1; - enc_data_t->m_th_inf.keyframe_frequency = 64; - enc_data_t->m_th_inf.keyframe_frequency_force = 64; - enc_data_t->m_th_inf.keyframe_data_target_bitrate = enc_data_t->m_th_inf.quality * 1.5; - enc_data_t->m_th_inf.keyframe_auto_threshold = 80; - enc_data_t->m_th_inf.keyframe_mindistance = 8; - enc_data_t->m_th_inf.noise_sensitivity = 1; - enc_data_t->m_th_inf.sharpness = 2; - - if (!pdata->args.nosound) { - int ret; - vorbis_info_init(&enc_data_t->m_vo_inf); - ret = vorbis_encode_init_vbr( &enc_data_t->m_vo_inf, - pdata->args.channels, - pdata->args.frequency, - (float)pdata->args.s_quality*0.1); - if (ret) { - fprintf(stderr, "Error while setting up vorbis stream quality!\n"); - exit(2); - } - vorbis_comment_init(&enc_data_t->m_vo_cmmnt); - vorbis_analysis_init(&enc_data_t->m_vo_dsp, &enc_data_t->m_vo_inf); - vorbis_block_init(&enc_data_t->m_vo_dsp, &enc_data_t->m_vo_block); - } - - if (theora_encode_init(&enc_data_t->m_th_st, &enc_data_t->m_th_inf)) { - fprintf(stderr, "Theora encoder initialization failure.\n"); - exit(2); - } - - if (theora_encode_header(&enc_data_t->m_th_st, &enc_data_t->m_ogg_pckt1)) { - fprintf(stderr, "Theora enocde header failure.\n"); - exit(2); - } - - ogg_stream_packetin(&enc_data_t->m_ogg_ts, &enc_data_t->m_ogg_pckt1); - if (ogg_stream_pageout(&enc_data_t->m_ogg_ts, &enc_data_t->m_ogg_pg) != 1) { - fprintf(stderr, "Internal Ogg library error.\n"); - exit(2); - } - fwrite(enc_data_t->m_ogg_pg.header, 1, - enc_data_t->m_ogg_pg.header_len, - enc_data_t->fp); - fwrite(enc_data_t->m_ogg_pg.body, 1, - enc_data_t->m_ogg_pg.body_len, - enc_data_t->fp); - - theora_comment_init(&enc_data_t->m_th_cmmnt); - theora_comment_add_tag(&enc_data_t->m_th_cmmnt, "recordMyDesktop", VERSION); - theora_encode_comment(&enc_data_t->m_th_cmmnt, &enc_data_t->m_ogg_pckt1); - ogg_stream_packetin(&enc_data_t->m_ogg_ts, &enc_data_t->m_ogg_pckt1); - theora_encode_tables(&enc_data_t->m_th_st, &enc_data_t->m_ogg_pckt1); - ogg_stream_packetin(&enc_data_t->m_ogg_ts, &enc_data_t->m_ogg_pckt1); - - if (!pdata->args.nosound) { - ogg_packet header; - ogg_packet header_comm; - ogg_packet header_code; - - vorbis_analysis_headerout( &enc_data_t->m_vo_dsp, - &enc_data_t->m_vo_cmmnt, - &header, &header_comm, - &header_code); - ogg_stream_packetin(&enc_data_t->m_ogg_vs, &header); - if (ogg_stream_pageout(&enc_data_t->m_ogg_vs, &enc_data_t->m_ogg_pg) != 1) { - fprintf(stderr, "Internal Ogg library error.\n"); - exit(2); - } - - fwrite(enc_data_t->m_ogg_pg.header, 1, - enc_data_t->m_ogg_pg.header_len, - enc_data_t->fp); - - fwrite(enc_data_t->m_ogg_pg.body, 1, - enc_data_t->m_ogg_pg.body_len, - enc_data_t->fp); - - ogg_stream_packetin(&enc_data_t->m_ogg_vs, &header_comm); - ogg_stream_packetin(&enc_data_t->m_ogg_vs, &header_code); - } - - //fishbone packets go here - memset(&skel_fbv, 0, sizeof(skel_fbv)); - skel_fbv.serial_no = enc_data_t->m_ogg_ts.serialno; - skel_fbv.nr_header_packet = 3; - skel_fbv.granule_rate_n = enc_data_t->m_th_inf.fps_numerator; - skel_fbv.granule_rate_d = enc_data_t->m_th_inf.fps_denominator; - skel_fbv.start_granule = 0; - skel_fbv.preroll = 0; - skel_fbv.granule_shift = theora_granule_shift(&enc_data_t->m_th_inf); - add_message_header_field(&skel_fbv, "Content-Type", "video/theora"); - - add_fisbone_to_stream(&m_ogg_skel, &skel_fbv); - - if (!pdata->args.nosound) { - - memset(&skel_fba, 0, sizeof(skel_fba)); - skel_fba.serial_no = enc_data_t->m_ogg_vs.serialno; - skel_fba.nr_header_packet = 3; - skel_fba.granule_rate_n = pdata->args.frequency; - skel_fba.granule_rate_d = (ogg_int64_t)1; - skel_fba.start_granule = 0; - skel_fba.preroll = 2; - skel_fba.granule_shift = 0; - add_message_header_field(&skel_fba, "Content-Type", "audio/vorbis"); - - add_fisbone_to_stream(&m_ogg_skel, &skel_fba); - } - - while (1) { - int result = ogg_stream_flush(&m_ogg_skel, &skel_og_pg); - if (result < 0) { - fprintf (stderr, "Internal Ogg library error.\n"); - exit(2); - } - - if (result == 0) - break; - - fwrite(skel_og_pg.header, 1, skel_og_pg.header_len, enc_data_t->fp); - fwrite(skel_og_pg.body, 1, skel_og_pg.body_len, enc_data_t->fp); - } - - while (1) { - int result = ogg_stream_flush(&enc_data_t->m_ogg_ts, &enc_data_t->m_ogg_pg); - if (result < 0) { - fprintf(stderr, "Internal Ogg library error.\n"); - exit(2); - } - - if (result == 0) - break; - - fwrite( enc_data_t->m_ogg_pg.header, 1, - enc_data_t->m_ogg_pg.header_len, - enc_data_t->fp); - fwrite( enc_data_t->m_ogg_pg.body, 1, - enc_data_t->m_ogg_pg.body_len, - enc_data_t->fp); - } - - if (!pdata->args.nosound) { - while (1) { - int result = ogg_stream_flush(&enc_data_t->m_ogg_vs, &enc_data_t->m_ogg_pg); - if (result < 0) { - fprintf(stderr, "Internal Ogg library error.\n"); - exit(2); - } - - if (result == 0) - break; - - fwrite( enc_data_t->m_ogg_pg.header, 1, - enc_data_t->m_ogg_pg.header_len, - enc_data_t->fp); - fwrite( enc_data_t->m_ogg_pg.body, 1, - enc_data_t->m_ogg_pg.body_len, - enc_data_t->fp); - } - } - - //skeleton eos - add_eos_packet_to_stream(&m_ogg_skel); - if (ogg_stream_flush(&m_ogg_skel, &skel_og_pg) < 0) { - fprintf(stderr, "Internal Ogg library error.\n"); - exit(2); - } - fwrite(skel_og_pg.header, 1, skel_og_pg.header_len, enc_data_t->fp); - - //theora buffer allocation, if any - if (!buffer_ready) { - enc_data_t->yuv.y = malloc(enc_data_t->m_th_inf.height * enc_data_t->m_th_inf.width); - enc_data_t->yuv.u = malloc(enc_data_t->m_th_inf.height * enc_data_t->m_th_inf.width / 4); - enc_data_t->yuv.v = malloc(enc_data_t->m_th_inf.height * enc_data_t->m_th_inf.width / 4); - enc_data_t->yuv.y_width = enc_data_t->m_th_inf.width; - enc_data_t->yuv.y_height = enc_data_t->m_th_inf.height; - enc_data_t->yuv.y_stride = enc_data_t->m_th_inf.width; - - enc_data_t->yuv.uv_width = enc_data_t->m_th_inf.width / 2; - enc_data_t->yuv.uv_height = enc_data_t->m_th_inf.height / 2; - enc_data_t->yuv.uv_stride = enc_data_t->m_th_inf.width / 2; - } - - theora_info_clear(&enc_data_t->m_th_inf); -} diff --git a/recordmydesktop/src/rmd_init_encoder.h b/recordmydesktop/src/rmd_init_encoder.h deleted file mode 100644 index bbf73c7..0000000 --- a/recordmydesktop/src/rmd_init_encoder.h +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef INIT_ENCODER_H -#define INIT_ENCODER_H 1 - -#include "rmd_types.h" - - -/** -* Initialize theora,vorbis encoders, and their respective ogg streams. -* -* \param pdata ProgData struct containing all program data -* -* \param enc_data_t Encoding options -* -* \param buffer_ready when 1, the yuv buffer must be preallocated -* when 0 rmdInitEncoder will alocate a new one -* -*/ -void rmdInitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready); - - -#endif diff --git a/recordmydesktop/src/rmd_initialize_data.c b/recordmydesktop/src/rmd_initialize_data.c deleted file mode 100644 index 0f0a073..0000000 --- a/recordmydesktop/src/rmd_initialize_data.c +++ /dev/null @@ -1,252 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_initialize_data.h" - -#include "rmd_cache.h" -#include "rmd_init_encoder.h" -#include "rmd_jack.h" -#include "rmd_make_dummy_pointer.h" -#include "rmd_opendev.h" -#include "rmd_yuv_utils.h" -#include "rmd_types.h" - -#include <pthread.h> - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef HAVE_LIBASOUND -static void rmdFixBufferSize(snd_pcm_uframes_t *buffsize) { - snd_pcm_uframes_t buffsize_t = *buffsize, -#else -static void rmdFixBufferSize(u_int32_t *buffsize) { - u_int32_t buffsize_t = *buffsize, -#endif - buffsize_ret = 1; - - while (buffsize_t > 1) { - buffsize_t >>= 1; - buffsize_ret <<= 1; - } - fprintf(stderr, "Buffer size adjusted to %d from %d frames.\n", - (int)buffsize_ret, (int)*buffsize); -} - -int rmdInitializeData(ProgData *pdata, EncData *enc_data, CacheData *cache_data) { - fprintf(stderr, "Initializing...\n"); - - rmdMakeMatrices(); - if (pdata->args.have_dummy_cursor) { - pdata->dummy_pointer = rmdMakeDummyPointer( pdata->dpy, - &pdata->specs, - 16, - pdata->args.cursor_color, - 0, - &pdata->npxl); - pdata->dummy_p_size = 16; - } else - pdata->dummy_p_size = 0; - - pthread_mutex_init(&pdata->sound_buffer_mutex, NULL); - pthread_mutex_init(&pdata->img_buff_ready_mutex, NULL); - pthread_mutex_init(&pdata->theora_lib_mutex, NULL); - pthread_mutex_init(&pdata->vorbis_lib_mutex, NULL); - pthread_mutex_init(&pdata->libogg_mutex, NULL); - pthread_mutex_init(&pdata->yuv_mutex, NULL); - pthread_mutex_init(&pdata->pause_mutex, NULL); - pthread_mutex_init(&pdata->time_mutex, NULL); - pthread_cond_init(&pdata->time_cond, NULL); - pthread_cond_init(&pdata->pause_cond, NULL); - pthread_cond_init(&pdata->image_buffer_ready, NULL); - pthread_cond_init(&pdata->sound_data_read, NULL); - pthread_cond_init(&pdata->theora_lib_clean, NULL); - pthread_cond_init(&pdata->vorbis_lib_clean, NULL); - - pdata->th_encoding_clean = pdata->v_encoding_clean = 1; - pdata->rect_root = NULL; - pdata->avd = 0; - pdata->sound_buffer = NULL; - pdata->running = TRUE; - pdata->paused = FALSE; - pdata->aborted = FALSE; - pdata->pause_state_changed = FALSE; - pdata->frames_total = 0; - pdata->frames_lost = 0; - pdata->capture_frameno = 0; - pdata->time_frameno = 0; - - if (!pdata->args.nosound) { - if (!pdata->args.use_jack) { - rmdFixBufferSize(&pdata->args.buffsize); -#ifdef HAVE_LIBASOUND - pdata->sound_handle=rmdOpenDev( pdata->args.device, - &pdata->args.channels, - &pdata->args.frequency, - &pdata->args.buffsize, - &pdata->periodsize, - &pdata->periodtime, - &pdata->hard_pause); - - pdata->sound_framesize=(snd_pcm_format_width(SND_PCM_FORMAT_S16_LE) / 8 * - pdata->args.channels); - - if (pdata->sound_handle == NULL) { -#else - pdata->sound_handle = rmdOpenDev( pdata->args.device, - pdata->args.channels, - pdata->args.frequency); - - pdata->periodtime = (1000000 * pdata->args.buffsize) / - ((pdata->args.channels<<1) * pdata->args.frequency); - //when using OSS periodsize serves as an alias of buffsize - pdata->periodsize = pdata->args.buffsize; - pdata->sound_framesize = pdata->args.channels<<1; - if (pdata->sound_handle<0) { -#endif - fprintf(stderr, "Error while opening/configuring soundcard %s\n" - "Try running with the --no-sound or specify a " - "correct device.\n", - pdata->args.device); - return 3; - } - } else { -#ifdef HAVE_LIBJACK - int jack_error = 0; - pdata->jdata->port_names = pdata->args.jack_port_names; - pdata->jdata->nports = pdata->args.jack_nports; - pdata->jdata->ringbuffer_secs = pdata->args.jack_ringbuffer_secs; - pdata->jdata->sound_buffer_mutex = &pdata->sound_buffer_mutex; - pdata->jdata->sound_data_read = &pdata->sound_data_read; - pdata->jdata->capture_started = 0; - - if ((jack_error = rmdStartJackClient(pdata->jdata))!=0) - return jack_error; - - pdata->args.buffsize = pdata->jdata->buffersize; - pdata->periodsize = pdata->args.buffsize; - pdata->args.frequency = pdata->jdata->frequency; - pdata->args.channels = pdata->jdata->nports; - pdata->periodtime = 1000000 * pdata->args.buffsize / - pdata->args.frequency; - pdata->sound_framesize = sizeof(jack_default_audio_sample_t) * - pdata->jdata->nports; -#else - fprintf(stderr, "Should not be here!\n"); - exit(-1); -#endif - } - } - - if (pdata->args.encOnTheFly) - rmdInitEncoder(pdata, enc_data, 0); - else - rmdInitCacheData(pdata, enc_data, cache_data); - - for (int i = 0; i < pdata->enc_data->yuv.y_width * pdata->enc_data->yuv.y_height; i++) - pdata->enc_data->yuv.y[i] = 0; - - for (int i = 0; i < pdata->enc_data->yuv.uv_width * pdata->enc_data->yuv.uv_height; i++) - pdata->enc_data->yuv.v[i] = pdata->enc_data->yuv.u[i] = 127; - - yblocks = malloc((pdata->enc_data->yuv.y_width / Y_UNIT_WIDTH) * - (pdata->enc_data->yuv.y_height / Y_UNIT_WIDTH)); - ublocks = malloc((pdata->enc_data->yuv.y_width / Y_UNIT_WIDTH) * - (pdata->enc_data->yuv.y_height / Y_UNIT_WIDTH)); - vblocks = malloc((pdata->enc_data->yuv.y_width / Y_UNIT_WIDTH) * - (pdata->enc_data->yuv.y_height / Y_UNIT_WIDTH)); - - pdata->frametime = 1000000 / pdata->args.fps; - - return 0; - -} - -void rmdSetupDefaultArgs(ProgArgs *args) { - args->delay = 0; - args->windowid = 0; - args->x = 0; - args->y = 0; - args->width = 0; - args->height = 0; - args->rescue_path = NULL; - args->nosound = 0; - args->full_shots = 0; - args->follow_mouse = 0; - args->encOnTheFly = 0; - args->nowmcheck = 0; - args->overwrite = 0; - args->use_jack = 0; - args->noshared = 0; - args->no_encode = 0; - args->noframe = 0; - args->jack_nports = 0; - args->jack_ringbuffer_secs = 3.0; - args->zerocompression = 1; - args->no_quick_subsample = 1; - args->cursor_color = 1; - args->have_dummy_cursor = 0; - args->xfixes_cursor = 1; - args->fps = 15; - args->channels = 1; - args->frequency = 22050; - args->buffsize = 4096; - args->v_bitrate = 0; - args->v_quality = 63; - args->s_quality = 10; - - if (getenv("DISPLAY") != NULL) { - args->display = malloc(strlen(getenv("DISPLAY")) + 1); - strcpy(args->display, getenv("DISPLAY")); - } else { - args->display = NULL; - } - - memset(args->jack_port_names, 0, sizeof(args->jack_port_names)); - - args->device = malloc(strlen(DEFAULT_AUDIO_DEVICE) + 1); - strcpy(args->device, DEFAULT_AUDIO_DEVICE); - - args->workdir = malloc(5); - strcpy(args->workdir, "/tmp"); - - args->pause_shortcut = malloc(15); - strcpy(args->pause_shortcut, "Control+Mod1+p"); - - args->stop_shortcut = malloc(15); - strcpy(args->stop_shortcut, "Control+Mod1+s"); - - args->filename = malloc(8); - strcpy(args->filename, "out.ogv"); -} - -void rmdCleanUp(void) { - free(yblocks); - free(ublocks); - free(vblocks); -} diff --git a/recordmydesktop/src/rmd_initialize_data.h b/recordmydesktop/src/rmd_initialize_data.h deleted file mode 100644 index a5e43dd..0000000 --- a/recordmydesktop/src/rmd_initialize_data.h +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef INITIALIZE_DATA_H -#define INITIALIZE_DATA_H 1 - -#include "rmd_types.h" - - -/** -* initialize lists,mutexes,image buffers, take first screenshot, -* and anything else needed before launching the capture threads. -* -* \param pdata ProgData struct containing all program data -* -* \param enc_data reference to enc_data structure -* -* \param cache_data reference to cache_data structure -* -* \returns 0 on success, other values must cause the program to exit -*/ -int rmdInitializeData(ProgData *pdata, - EncData *enc_data, - CacheData *cache_data); - -/** -* Sets up the ProgArgs structure to default values. -*/ -void rmdSetupDefaultArgs(ProgArgs *args); - -/** -* Currently only frees some memory -* (y,u,v blocks) -* -*/ -void rmdCleanUp(void); - - -#endif diff --git a/recordmydesktop/src/rmd_jack.c b/recordmydesktop/src/rmd_jack.c deleted file mode 100644 index 841017f..0000000 --- a/recordmydesktop/src/rmd_jack.c +++ /dev/null @@ -1,209 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_jack.h" - -#include "rmd_types.h" - -#include <pthread.h> - -#include <string.h> - -#ifdef HAVE_LIBJACK - - -/** -* Callback for capture through jack -* -* \param nframes Number of frames captured -* -* \param jdata_t Pointer to JackData struct containing port -* and client information -* -* \returns Zero always -*/ -static int rmdJackCapture(jack_nframes_t nframes, void *jdata_t) { - JackData *jdata = (JackData *)jdata_t; - - if (!jdata->pdata->running || jdata->pdata->paused || !jdata->capture_started) - return 0; - - for(int i = 0; i < jdata->nports; i++) - jdata->portbuf[i] = jack_port_get_buffer(jdata->ports[i], nframes); - - - pthread_mutex_lock(jdata->sound_buffer_mutex); -//vorbis analysis buffer wants uninterleaved data -//so we are simply placing the buffers for every channel -//sequentially on the ringbuffer - for(int i = 0; i < jdata->nports; i++) - jack_ringbuffer_write( jdata->sound_buffer, - (void *)(jdata->portbuf[i]), - nframes * - sizeof(jack_default_audio_sample_t)); - - pthread_cond_signal(jdata->sound_data_read); - pthread_mutex_unlock(jdata->sound_buffer_mutex); - - return 0; -} - -/** -* Register and Activate specified ports -* -* \param jdata_t Pointer to JackData struct containing port -* and client information -* -* \returns 0 on Success, 1 on failure -*/ -static int rmdSetupPorts(JackData *jdata) { - jdata->ports = malloc(sizeof(jack_port_t *) * jdata->nports); - jdata->portbuf = malloc(sizeof(jack_default_audio_sample_t *) * jdata->nports); - memset(jdata->portbuf, 0, sizeof(jack_default_audio_sample_t *) * jdata->nports); - - for(int i = 0; i < jdata->nports; i++) { - char name[64];//recordMyDesktop:input_n<64 is enough for full name - char num[8]; - strcpy(name, "input_"); - snprintf(num, 8, "%d", i + 1); - strcat(name, num); - - jdata->ports[i] = jack_port_register( jdata->client, - name, - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, - 0); - - if (!jdata->ports[i]) { - fprintf(stderr, "Cannot register input port \"%s\"!\n", name); - return 1; - } - - if (jack_connect(jdata->client, jdata->port_names[i], jack_port_name(jdata->ports[i]))) { - - fprintf(stderr, "Cannot connect input port %s to %s\n", - jack_port_name(jdata->ports[i]), - jdata->port_names[i]); - return 1; - } - } - return 0; -} - -//in case the jack server shuts down -//the program should stop recording, -//encode the result(if not on the fly) -//an exit cleanly. -static void rmdJackShutdown(void *jdata_t) { - JackData *jdata = (JackData *)jdata_t; - - jdata->pdata->running = FALSE; - - fprintf (stderr, "JACK shutdown\n"); -} - -int rmdStartJackClient(JackData *jdata) { - float ring_buffer_size = 0.0; - int pid; - char pidbuf[8]; - char rmd_client_name[32]; - - //construct the jack client name - //which is recordMyDesktop-pid - //in order to allow multiple - //instances of recordMyDesktop - //to connetc to a Jack Server - strcpy(rmd_client_name, "recordMyDesktop-"); - pid = getpid(); - snprintf( pidbuf, 8, "%d", pid ); - strcat(rmd_client_name, pidbuf); - - if ((jdata->client = jack_client_new(rmd_client_name)) == 0) { - fprintf(stderr, "Could not create new client!\n" - "Make sure that Jack server is running!\n"); - return 15; - } -//in contrast to ALSA and OSS, Jack dictates frequency -//and buffersize to the values it was launched with. -//Supposedly jack_set_buffer_size can set the buffersize -//but that causes some kind of halt and keeps giving me -//zero buffers. -//recordMyDesktop cannot handle buffer size changes. -//FIXME -//There is a callback for buffer size changes that I should use. -//It will provide clean exits, instead of ?segfaults? . -//Continuing though is not possible, with the current layout -//(it might be in some cases, but it will certainly be the cause -//of unpredicted problems). A clean exit is preferable -//and any recording up to that point will be encoded and saved. - jdata->frequency = jack_get_sample_rate(jdata->client); - jdata->buffersize = jack_get_buffer_size(jdata->client); - ring_buffer_size = ( jdata->ringbuffer_secs* - jdata->frequency* - sizeof(jack_default_audio_sample_t)* - jdata->nports); - jdata->sound_buffer = jack_ringbuffer_create((int)(ring_buffer_size+0.5));//round up - jack_set_process_callback(jdata->client, rmdJackCapture, jdata); - jack_on_shutdown(jdata->client, rmdJackShutdown, jdata); - - if (jack_activate(jdata->client)) { - fprintf(stderr, "cannot activate client!\n"); - return 16; - } - - if (rmdSetupPorts(jdata)) { - jack_client_close(jdata->client); - return 17; - } - - return 0; -} - -int rmdStopJackClient(JackData *jdata) { - int ret = 0; - - jack_ringbuffer_free(jdata->sound_buffer); - if (jack_client_close(jdata->client)) { - fprintf(stderr, "Cannot close Jack client!\n"); - ret = 1; - } - -/*TODO*/ -//I need to make some kind of program/thread -//flow diagram to see where it's safe to dlclose -//because here it causes a segfault. - -// if (dlclose(jdata->jack_lib_handle)) { -// fprintf(stderr, "Cannot unload Jack library!\n"); -// ret=1; -// } -// else fprintf(stderr, "Unloaded Jack library.\n"); - - return ret; -} - -#endif diff --git a/recordmydesktop/src/rmd_jack.h b/recordmydesktop/src/rmd_jack.h deleted file mode 100644 index a216c1b..0000000 --- a/recordmydesktop/src/rmd_jack.h +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMD_JACK_H -#define RMD_JACK_H 1 - -#include "rmd_types.h" - - -#ifdef HAVE_LIBJACK - -/** -* create and activate client,register ports -* -* \param jdata_t Pointer to JackData struct containing port -* and client information -* -* \returns 0 on Success, error code on failure -* (depending on where the error occured) -*/ -int rmdStartJackClient(JackData *jdata); - -/** -* Close Jack Client -* -* \param jdata_t Pointer to JackData struct containing port -* and client information -* -* \returns 0 on Success, 1 on failure -*/ -int rmdStopJackClient(JackData *jdata); - -#endif - - -#endif diff --git a/recordmydesktop/src/rmd_load_cache.c b/recordmydesktop/src/rmd_load_cache.c deleted file mode 100644 index 8ca37f6..0000000 --- a/recordmydesktop/src/rmd_load_cache.c +++ /dev/null @@ -1,336 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_load_cache.h" - -#include "rmd_cache.h" -#include "rmd_encode_image_buffer.h" -#include "rmd_encode_sound_buffer.h" -#include "rmd_macro.h" -#include "rmd_types.h" - -#include <pthread.h> -#include <signal.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - -//The number of bytes for every -//sub-block of the y,u and v planes. -//Since the blocks are square -//these are obviously the squares -//of the widths(specified above), -//but the definitions bellow are only -//for convenience anyway. -#define Y_UNIT_BYTES 0x0100 -#define UV_UNIT_BYTES 0x0040 - - -//The frame after retrieval. -//Based on the Header information -//we can read the correct amount of bytes. -typedef struct _CachedFrame{ - FrameHeader *header; - u_int32_t *YBlocks, //identifying number on the grid, - *UBlocks, //starting at top left - *VBlocks; // >> >> - unsigned char *YData, //pointer to data for the blocks that have changed, - *UData, //which have to be remapped - *VData; //on the buffer when reading -}CachedFrame; - - -static void rmdLoadBlock( - unsigned char *dest, - unsigned char *source, - int blockno, - int width, - int height, - int blockwidth) { - - int block_i = blockno / (width / blockwidth),//place on the grid - block_k = blockno % (width / blockwidth); - - for (int j = 0; j < blockwidth; j++)//we copy rows - memcpy( &dest[(block_i * width + block_k) * blockwidth + j * width], - &source[j * blockwidth], - blockwidth); -} - -//returns number of bytes -static int rmdReadZF(void * buffer, size_t size, size_t nmemb, FILE *ucfp, gzFile ifp) { - if ((ifp != NULL && ucfp != NULL) || - (ifp == NULL && ucfp == NULL)) - return -1; - else if (ucfp != NULL) { - return size * fread(buffer, size, nmemb, ucfp); - } else - return gzread(ifp, buffer, size * nmemb); -} - -static int rmdReadFrame(CachedFrame *frame, FILE *ucfp, gzFile ifp) { - int index_entry_size = sizeof(u_int32_t); - - if (frame->header->Ynum > 0) { - if (rmdReadZF( frame->YBlocks, - index_entry_size, - frame->header->Ynum, - ucfp, - ifp) != index_entry_size * frame->header->Ynum) { - return -1; - } - } - - if (frame->header->Unum > 0) { - if (rmdReadZF( frame->UBlocks, - index_entry_size, - frame->header->Unum, - ucfp, - ifp) != index_entry_size * frame->header->Unum) { - return -1; - } - } - - if (frame->header->Vnum > 0) { - if (rmdReadZF( frame->VBlocks, - index_entry_size, - frame->header->Vnum, - ucfp, - ifp) != index_entry_size * frame->header->Vnum) { - return -1; - } - } - - if (frame->header->Ynum > 0) { - if (rmdReadZF( frame->YData, - Y_UNIT_BYTES, - frame->header->Ynum, - ucfp, - ifp) != Y_UNIT_BYTES * frame->header->Ynum) { - return -2; - } - } - - if (frame->header->Unum > 0) { - if (rmdReadZF( frame->UData, - UV_UNIT_BYTES, - frame->header->Unum, - ucfp, - ifp) != UV_UNIT_BYTES * frame->header->Unum) { - return -2; - } - } - - if (frame->header->Vnum > 0) { - if (rmdReadZF( frame->VData, - UV_UNIT_BYTES, - frame->header->Vnum, - ucfp, - ifp) != UV_UNIT_BYTES * frame->header->Vnum) { - return -2; - } - } - - return 0; -} - -void *rmdLoadCache(ProgData *pdata) { - - yuv_buffer *yuv = &pdata->enc_data->yuv; - gzFile ifp = NULL; - FILE *ucfp = NULL; - FILE *afp = pdata->cache_data->afp; - FrameHeader fheader; - CachedFrame frame; - int nth_cache = 1, - audio_end = 0, - extra_frames = 0, //total number of duplicated frames - missing_frames = 0, //if this is found >0 current run will not load - //a frame but it will proccess the previous - thread_exit = 0, //0 success, -1 couldn't find files,1 couldn't remove - blocknum_x = pdata->enc_data->yuv.y_width / Y_UNIT_WIDTH, - blocknum_y = pdata->enc_data->yuv.y_height / Y_UNIT_WIDTH, - blockszy = Y_UNIT_BYTES,//size of y plane block in bytes - blockszuv = UV_UNIT_BYTES;//size of u,v plane blocks in bytes - signed char *sound_data = (signed char *)malloc(pdata->periodsize * pdata->sound_framesize); - - u_int32_t YBlocks[(yuv->y_width * yuv->y_height) / Y_UNIT_BYTES], - UBlocks[(yuv->uv_width * yuv->uv_height) / UV_UNIT_BYTES], - VBlocks[(yuv->uv_width * yuv->uv_height) / UV_UNIT_BYTES]; - - // We allocate the frame that we will use - frame.header = &fheader; - frame.YBlocks = YBlocks; - frame.UBlocks = UBlocks; - frame.VBlocks = VBlocks; - frame.YData = malloc(yuv->y_width * yuv->y_height); - frame.UData = malloc(yuv->uv_width * yuv->uv_height); - frame.VData = malloc(yuv->uv_width * yuv->uv_height); - - //and the we open our files - if (!pdata->args.zerocompression) { - ifp = gzopen(pdata->cache_data->imgdata, "rb"); - if (ifp == NULL) { - thread_exit = -1; - pthread_exit(&thread_exit); - } - } else { - ucfp = fopen(pdata->cache_data->imgdata, "rb"); - if (ucfp == NULL) { - thread_exit = -1; - pthread_exit(&thread_exit); - } - } - - if (!pdata->args.nosound) { - afp = fopen(pdata->cache_data->audiodata, "rb"); - if (afp == NULL) { - thread_exit = -1; - pthread_exit(&thread_exit); - } - } - - //this will be used now to define if we proccess audio or video - //on any given loop. - pdata->avd = 0; - //If sound finishes first,we go on with the video. - //If video ends we will do one more run to flush audio in the ogg file - while (pdata->running) { - //video load and encoding - if (pdata->avd <= 0 || pdata->args.nosound || audio_end) { - if (missing_frames > 0) { - extra_frames++; - missing_frames--; - rmdSyncEncodeImageBuffer(pdata); - } else if (((!pdata->args.zerocompression) && - (gzread(ifp, frame.header, sizeof(FrameHeader)) == - sizeof(FrameHeader) )) || - ((pdata->args.zerocompression) && - (fread(frame.header, sizeof(FrameHeader), 1, ucfp) == 1))) { - //sync - missing_frames += frame.header->current_total - - (extra_frames + frame.header->frameno); - if (pdata->frames_total) { - fprintf(stdout, "\r[%d%%] ", - ((frame.header->frameno + extra_frames) * 100) / pdata->frames_total); - } else - fprintf(stdout, "\r[%d frames rendered] ", - (frame.header->frameno + extra_frames)); - fflush(stdout); - if ( (frame.header->Ynum <= blocknum_x * blocknum_y) && - (frame.header->Unum <= blocknum_x * blocknum_y) && - (frame.header->Vnum <= blocknum_x * blocknum_y) && - !rmdReadFrame( &frame, - (pdata->args.zerocompression ? ucfp : NULL), - (pdata->args.zerocompression ? NULL : ifp)) - ) { - - //load the blocks for each buffer - if (frame.header->Ynum) - for (int j = 0; j < frame.header->Ynum; j++) - rmdLoadBlock( yuv->y, - &frame.YData[j * blockszy], - frame.YBlocks[j], - yuv->y_width, - yuv->y_height, - Y_UNIT_WIDTH); - if (frame.header->Unum) - for (int j = 0; j < frame.header->Unum; j++) - rmdLoadBlock( yuv->u, - &frame.UData[j * blockszuv], - frame.UBlocks[j], - yuv->uv_width, - yuv->uv_height, - UV_UNIT_WIDTH); - if (frame.header->Vnum) - for (int j = 0; j < frame.header->Vnum; j++) - rmdLoadBlock( yuv->v, - &frame.VData[j * blockszuv], - frame.VBlocks[j], - yuv->uv_width, - yuv->uv_height, - UV_UNIT_WIDTH); - - //encode. This is not made in a thread since - //now blocking is not a problem - //and this way sync problems - //can be avoided more easily. - rmdSyncEncodeImageBuffer(pdata); - } else { - raise(SIGINT); - continue; - } - } else { - if (rmdSwapCacheFilesRead( pdata->cache_data->imgdata, - nth_cache, - &ifp, - &ucfp)) { - raise(SIGINT); - } else { - fprintf(stderr, "\t[Cache File %d]", nth_cache); - nth_cache++; - } - continue; - } - //audio load and encoding - } else { - if (!audio_end) { - int nbytes = fread(sound_data, 1, pdata->periodsize* - pdata->sound_framesize, afp); - if (nbytes <= 0) - audio_end = 1; - else - rmdSyncEncodeSoundBuffer(pdata, sound_data); - } - } - } - - pthread_mutex_lock(&pdata->theora_lib_mutex); - pdata->th_encoding_clean = 1; - pthread_cond_signal(&pdata->theora_lib_clean); - pthread_mutex_unlock(&pdata->theora_lib_mutex); - - pthread_mutex_lock(&pdata->vorbis_lib_mutex); - pdata->v_encoding_clean = 1; - pthread_cond_signal(&pdata->vorbis_lib_clean); - pthread_mutex_unlock(&pdata->vorbis_lib_mutex); - fprintf(stdout, "\n"); - - // Clear frame - free(frame.YData); - free(frame.UData); - free(frame.VData); - - free(sound_data); - - if (!pdata->args.nosound) - fclose(afp); - - pthread_exit(&thread_exit); -} diff --git a/recordmydesktop/src/rmd_load_cache.h b/recordmydesktop/src/rmd_load_cache.h deleted file mode 100644 index 917f31f..0000000 --- a/recordmydesktop/src/rmd_load_cache.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef LOAD_CACHE -#define LOAD_CACHE 1 - -#include "rmd_types.h" - - -/** -* Cache loading and processing thread -* -* \param pdata ProgData struct containing all program data -* -*/ -void *rmdLoadCache(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_macro.h b/recordmydesktop/src/rmd_macro.h deleted file mode 100644 index 2f1ac88..0000000 --- a/recordmydesktop/src/rmd_macro.h +++ /dev/null @@ -1,83 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMDMACRO_H -#define RMDMACRO_H 1 - -#include "config.h" - -#include "rmd_types.h" - -#include <limits.h> - - -//define which way we are reading a pixmap -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define __ABYTE 3 -#define __RBYTE 2 -#define __GBYTE 1 -#define __BBYTE 0 - -#elif __BYTE_ORDER == __BIG_ENDIAN - -#define __ABYTE 0 -#define __RBYTE 1 -#define __GBYTE 2 -#define __BBYTE 3 - -#else -#error Only little-endian and big-endian systems are supported -#endif - -#define __RVALUE_32(tmp_val) (((tmp_val)&0x00ff0000)>>16) -#define __GVALUE_32(tmp_val) (((tmp_val)&0x0000ff00)>>8) -#define __BVALUE_32(tmp_val) (((tmp_val)&0x000000ff)) - -#define __R16_MASK 0xf800 -#define __G16_MASK 0x7e0 -#define __B16_MASK 0x1f - -#define __RVALUE_16(tmp_val) ((((tmp_val)&__R16_MASK)>>11)*8) -#define __GVALUE_16(tmp_val) ((((tmp_val)&__G16_MASK)>>5)*4) -#define __BVALUE_16(tmp_val) ((((tmp_val)&__B16_MASK))*8) - -//xfixes pointer data are written as unsigned long -//(even though the server returns CARD32) -//so we need to set the step accordingly to -//avoid problems (amd64 has 8byte ulong) -#define RMD_ULONG_SIZE_T (sizeof(unsigned long)) - -//The width, in bytes, of the blocks -//on which the y,u and v planes are broken. -//These blocks are square. -#define Y_UNIT_WIDTH 0x0010 -#define UV_UNIT_WIDTH 0x0008 - -#define MAX(a, b) ((a) < (b)) ? (b) : (a) -#define MIN(a, b) ((a) > (b)) ? (b) : (a) - -#endif - diff --git a/recordmydesktop/src/rmd_make_dummy_pointer.c b/recordmydesktop/src/rmd_make_dummy_pointer.c deleted file mode 100644 index 25bb027..0000000 --- a/recordmydesktop/src/rmd_make_dummy_pointer.c +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_make_dummy_pointer.h" - -#include "rmd_macro.h" -#include "rmd_types.h" - -#include <X11/Xlib.h> -#include <stdlib.h> - -unsigned char *rmdMakeDummyPointer( Display *display, - DisplaySpecs *specs, - int size, - int color, - int type, - unsigned char *npxl) { - - unsigned long bpixel = XBlackPixel(display, specs->screen); - unsigned long wpixel = XWhitePixel(display, specs->screen); - int i, k, o = '.'; - unsigned long b = color ? 'w' : 'b', w = color ? 'b' : 'w'; - char pmask[1][16][16] = {{ - {w,w,o,o,o,o,o,o,o,o,o,o,o,o,o,o}, - {w,b,w,o,o,o,o,o,o,o,o,o,o,o,o,o}, - {w,b,b,w,o,o,o,o,o,o,o,o,o,o,o,o}, - {w,b,b,b,w,o,o,o,o,o,o,o,o,o,o,o}, - {w,b,b,b,b,w,o,o,o,o,o,o,o,o,o,o}, - {w,b,b,b,b,b,w,o,o,o,o,o,o,o,o,o}, - {w,b,b,b,b,b,b,w,o,o,o,o,o,o,o,o}, - {w,b,b,b,b,b,b,b,w,o,o,o,o,o,o,o}, - {w,b,b,b,b,b,b,b,b,w,o,o,o,o,o,o}, - {w,b,b,b,b,b,w,w,w,w,o,o,o,o,o,o}, - {w,b,b,b,b,b,w,o,o,o,o,o,o,o,o,o}, - {w,b,b,w,w,b,b,w,o,o,o,o,o,o,o,o}, - {w,b,w,o,w,b,b,w,o,o,o,o,o,o,o,o}, - {w,w,o,o,o,w,b,b,w,o,o,o,o,o,o,o}, - {o,o,o,o,o,w,b,b,w,o,o,o,o,o,o,o}, - {o,o,o,o,o,o,w,w,o,o,o,o,o,o,o,o}} - }; - unsigned char *ret = malloc(size * sizeof(char[size * 4])); - unsigned char wp[4] = { - (wpixel ^ 0xff000000) >> 24, - (wpixel ^ 0x00ff0000) >> 16, - (wpixel ^ 0x0000ff00) >> 8, - (wpixel ^ 0x000000ff) - }; - unsigned char bp[4] = { - (bpixel ^ 0xff000000) >> 24, - (bpixel ^ 0x00ff0000) >> 16, - (bpixel ^ 0x0000ff00) >> 8, - (bpixel ^ 0x000000ff) - }; - - *npxl = ((wp[0] - 1) != bp[0]) ? wp[0] - 100 : wp[0] - 102; - for (i = 0; i < size; i++) { - for (k = 0; k < size; k++) { - ret[(i * size + k) * 4 + __ABYTE] = (pmask[type][i][k] == 'w') ? - wp[0]:(pmask[type][i][k] == 'b') ? bp[0] : *npxl; - ret[(i * size + k) * 4 + __RBYTE] = (pmask[type][i][k] == 'w') ? - wp[1]:(pmask[type][i][k] == 'b') ? bp[1] : *npxl; - ret[(i * size + k) * 4 + __GBYTE] = (pmask[type][i][k] == 'w') ? - wp[2]:(pmask[type][i][k] == 'b') ? bp[2] : *npxl; - ret[(i * size + k) * 4 + __BBYTE] = (pmask[type][i][k] == 'w') ? - wp[3]:(pmask[type][i][k] == 'b') ? bp[3] : *npxl; - } - } - - return ret; -} diff --git a/recordmydesktop/src/rmd_make_dummy_pointer.h b/recordmydesktop/src/rmd_make_dummy_pointer.h deleted file mode 100644 index 3eccd42..0000000 --- a/recordmydesktop/src/rmd_make_dummy_pointer.h +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef MAKE_DUMMY_POINTER_H -#define MAKE_DUMMY_POINTER_H 1 - -#include "rmd_types.h" - - -/** -* Create an array containing the data for the dummy pointer -* -* \param specs DisplaySpecs struct with -* information about the display to be recorded -* -* \param size Pointer size, always square, always 16.(exists only -* for the possibility to create more dummy cursors) -* \param color 0 white, 1 black -* -* \param type Always 0.(exists only for the possibility to create -* more dummy cursors) -* -* \param npxl Return of pixel value that denotes non-drawing, while -* applying the cursor on the target image -* -* \returns Pointer to pixel data of the cursor -*/ -unsigned char *rmdMakeDummyPointer(Display *display, - DisplaySpecs *specs, - int size, - int color, - int type, - unsigned char *npxl); - - -#endif diff --git a/recordmydesktop/src/rmd_math.c b/recordmydesktop/src/rmd_math.c deleted file mode 100644 index 1cf3d29..0000000 --- a/recordmydesktop/src/rmd_math.c +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -* recordMyDesktop - rmd_math.c * -******************************************************************************* -* * -* Copyright (C) 2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_math.h" - -#include <math.h> - -double rmdRoundf(double val) { - return val < 0.0 ? ceilf(val - .5) : floorf(val + 0.5); -} diff --git a/recordmydesktop/src/rmd_math.h b/recordmydesktop/src/rmd_math.h deleted file mode 100644 index 87c6166..0000000 --- a/recordmydesktop/src/rmd_math.h +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** -* recordMyDesktop - rmd_math.h * -******************************************************************************* -* * -* Copyright (C) 2008 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 * -******************************************************************************/ - -#ifndef RMD_MATH_H -#define RMD_MATH_H 1 - -/* - * Since roundf depends on C99, using it might make - * the code non-portable. rmdRoundf solves this - * problem, by behaving identically with roundf - * and being portable (floorf and ceilf, that are - * used in the implementation, are defined in C89) - * - * \param val Number to be rounded - * - * \returns val rounded - * - */ -double rmdRoundf( double val ); - -#endif - diff --git a/recordmydesktop/src/rmd_opendev.c b/recordmydesktop/src/rmd_opendev.c deleted file mode 100644 index 37fb33c..0000000 --- a/recordmydesktop/src/rmd_opendev.c +++ /dev/null @@ -1,189 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_opendev.h" - -#ifdef HAVE_LIBASOUND - #include <alsa/asoundlib.h> -#else - #include <sys/ioctl.h> - #include <sys/soundcard.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> - - -#ifdef HAVE_LIBASOUND - -snd_pcm_t *rmdOpenDev( const char *pcm_dev, - unsigned int *channels, - unsigned int *frequency, - snd_pcm_uframes_t *buffsize, - snd_pcm_uframes_t *periodsize, - unsigned int *periodtime, - int *hard_pause) { - - snd_pcm_t *mhandle; - snd_pcm_hw_params_t *hwparams; - unsigned int periods = 2; - unsigned int exactrate = *frequency; - - // The compiler might warn us because the expansion starts with - // assert(&hwparams) - snd_pcm_hw_params_alloca(&hwparams); - - if (snd_pcm_open(&mhandle, pcm_dev, SND_PCM_STREAM_CAPTURE, SND_PCM_ASYNC) < 0) { - fprintf(stderr, "Couldn't open PCM device %s\n", pcm_dev); - return NULL; - } else - fprintf(stderr, "Opened PCM device %s\n", pcm_dev); - - if (snd_pcm_hw_params_any(mhandle, hwparams) < 0) { - fprintf(stderr, "Couldn't configure PCM device.\n"); - return NULL; - } - - if (snd_pcm_hw_params_set_access(mhandle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { - fprintf(stderr, "Couldn't set access.\n"); - return NULL; - } - - if (snd_pcm_hw_params_set_format(mhandle, hwparams, SND_PCM_FORMAT_S16_LE) < 0) { - fprintf(stderr, "Couldn't set format.\n"); - return NULL; - } - - if (snd_pcm_hw_params_set_rate_near(mhandle, hwparams, &exactrate, 0) < 0) { - fprintf(stderr, "Couldn't set frequency.\n"); - return NULL; - } - - if (*frequency != exactrate) { - fprintf(stderr, "Playback frequency %dHz is not available...\n" - "Using %dHz instead.\n", - *frequency, exactrate); - - *frequency = exactrate; - } - - if (snd_pcm_hw_params_set_channels_near(mhandle, hwparams, channels) < 0) { - fprintf(stderr, "Couldn't set channels number.\n"); - return NULL; - } - - if (*channels>2) { - fprintf(stderr, "Channels number should be 1(mono) or 2(stereo).\n"); - return NULL; - } - - if (snd_pcm_hw_params_set_periods_near(mhandle, hwparams, &periods, 0) < 0) { - fprintf(stderr, "Couldn't set periods.\n"); - return NULL; - } - - if (snd_pcm_hw_params_set_buffer_size_near(mhandle, hwparams, buffsize) < 0) { - fprintf(stderr, "Couldn't set buffer size.\n"); - return NULL; - } - - if (snd_pcm_hw_params(mhandle, hwparams) < 0) { - fprintf(stderr, "Couldn't set hardware parameters.\n"); - return NULL; - } - - if (hard_pause != NULL) { - if (!snd_pcm_hw_params_can_pause(hwparams)) - *hard_pause = 1; - } - - if (periodsize != NULL) - snd_pcm_hw_params_get_period_size(hwparams, periodsize, 0); - - if (periodtime != NULL) - snd_pcm_hw_params_get_period_time(hwparams, periodtime, 0); - - fprintf(stderr, - "Recording on device %s is set to:\n%d channels at %dHz\n", - pcm_dev, *channels, *frequency); - - snd_pcm_prepare(mhandle); - - return mhandle; -} - -#else - -int rmdOpenDev(const char *pcm_dev, unsigned int channels, unsigned int frequency) { - int fd ; - unsigned int value; - - fd = open(pcm_dev, O_RDONLY); - if (fd < 0) - return -1; - - if (ioctl(fd, SNDCTL_DSP_GETFMTS, &value) < 0) { - fprintf(stderr, "Couldn't get audio format list\n"); - return -1; - } - - if (value & AFMT_S16_LE) { - value = AFMT_S16_LE; - } else if (value & AFMT_S16_BE) { - value = AFMT_S16_BE; - } else { - fprintf(stderr, "Soundcard doesn't support signed 16-bit-data\n"); - return -1; - } - - if (ioctl(fd, SNDCTL_DSP_SETFMT, &value) < 0) { - fprintf(stderr, "Couldn't set audio format\n" ); - return -1; - } - - value = channels; - if (ioctl(fd, SNDCTL_DSP_CHANNELS, &value) < 0) { - fprintf(stderr, "Cannot set the number of channels\n" ); - return -1; - } - - value = frequency; - if (ioctl(fd, SNDCTL_DSP_SPEED, &value) < 0) { - fprintf(stderr, "Couldn't set audio frequency\n" ); - return -1; - } - - if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK) < 0) { - fprintf(stderr, "Couldn't set audio blocking mode\n" ); - return -1; - } - - return fd; -} -#endif diff --git a/recordmydesktop/src/rmd_opendev.h b/recordmydesktop/src/rmd_opendev.h deleted file mode 100644 index 06dfc64..0000000 --- a/recordmydesktop/src/rmd_opendev.h +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef OPENDEV_H -#define OPENDEV_H 1 - -#include "rmd_types.h" - - -#ifdef HAVE_LIBASOUND -/** -* Try to open (alsa) sound device, with the desired parameters, -* and place the obtained ones on their place -* -* \param pcm_dev name of the device -* -* \param channels desired number of channels -* (gets modified with the acieved value) -* -* \param frequency desired frequency(gets modified with the acieved value) -* -* \param buffsize Size of buffer -* -* \param periodsize Size of a period(can be NULL) -* -* \param periodtime Duration of a period(can be NULL) -* -* \param hardpause Set to 1 when the device has to be stopped during pause -* and to 0 when it supports pausing -* (can be NULL) -* -* \returns snd_pcm_t handle on success, NULL on failure -*/ -snd_pcm_t *rmdOpenDev(const char *pcm_dev, - unsigned int *channels, - unsigned int *frequency, - snd_pcm_uframes_t *buffsize, - snd_pcm_uframes_t *periodsize, - unsigned int *periodtime, - int *hardpause); -#else -/** -* Try to open (OSS) sound device, with the desired parameters. -* -* -* \param pcm_dev name of the device -* -* \param channels desired number of channels -* -* \param frequency desired frequency -* -* -* \returns file descriptor of open device,-1 on failure -*/ -int rmdOpenDev(const char *pcm_dev, - unsigned int channels, - unsigned int frequency); -#endif - - -#endif diff --git a/recordmydesktop/src/rmd_parseargs.c b/recordmydesktop/src/rmd_parseargs.c deleted file mode 100644 index 12d2cd4..0000000 --- a/recordmydesktop/src/rmd_parseargs.c +++ /dev/null @@ -1,511 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 John Varouhakis * -* Copyright (C) 2009 Martin Nordholts * -* * -* * -* 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_parseargs.h" - -#include "rmd_types.h" - -#include <popt.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - -#ifdef HAVE_LIBJACK -#define RMD_LIBJACK_STATUS "Enabled" -#define RMD_USE_JACK_EXTRA_FLAG 0 -#else -#define RMD_LIBJACK_STATUS "Disabled" -#define RMD_USE_JACK_EXTRA_FLAG POPT_ARGFLAG_DOC_HIDDEN -#endif - -#ifdef HAVE_LIBASOUND -#define RMD_LIBASOUND_STATUS "ALSA" -#else -#define RMD_LIBASOUND_STATUS "OSS" -#endif - -#define RMD_ARG_DELAY 1 -#define RMD_ARG_DUMMY_CURSOR 2 -#define RMD_ARG_USE_JACK 3 - -#define RMD_OPTION_TABLE(name, table) \ - { NULL, '\0', \ - POPT_ARG_INCLUDE_TABLE, (table), \ - 0, (name), NULL } - - -static void rmdPrintAndExit(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data); -static boolean rmdValidateArguments(const ProgArgs *args); - - -boolean rmdParseArgs(int argc, char **argv, ProgArgs *arg_return) { - poptContext popt_context = NULL; - boolean no_cursor = FALSE; - boolean quick_subsampling = FALSE; - boolean compress_cache = FALSE; - boolean success = TRUE; - int arg_id = 0; - - // Setup the option tables - struct poptOption generic_options[] = { - { NULL, '\0', - POPT_ARG_CALLBACK, (void *)rmdPrintAndExit, 0, - NULL, NULL }, - - { "help", 'h', - POPT_ARG_NONE, NULL, 0, - "Print this help and exit.", - NULL }, - - { "version", '\0', - POPT_ARG_NONE, NULL, 0, - "Print program version and exit.", - NULL }, - - { "print-config", '\0', - POPT_ARG_NONE, NULL, 0, - "Print info about options selected during compilation and exit.", - NULL }, - - POPT_TABLEEND }; - - struct poptOption image_options[] = { - { "windowid", '\0', - POPT_ARG_INT, &arg_return->windowid, 0, - "id of window to be recorded.", - "id_of_window" }, - - { "display", '\0', - POPT_ARG_STRING, &arg_return->display, 0, - "Display to connect to.", - "DISPLAY" }, - - { "x", 'x', - POPT_ARG_INT, &arg_return->x, 0, - "Offset in x direction.", - "N>=0" }, - - { "y", 'y', - POPT_ARG_INT, &arg_return->y, 0, - "Offset in y direction.", - "N>=0" }, - - { "width", '\0', - POPT_ARG_INT, &arg_return->width, 0, - "Width of recorded window.", - "N>0" }, - - { "height", '\0', - POPT_ARG_INT, &arg_return->height, 0, - "Height of recorded window.", - "N>0" }, - - { "dummy-cursor", '\0', - POPT_ARG_STRING, NULL, RMD_ARG_DUMMY_CURSOR, - "Color of the dummy cursor [black|white]", - "color" }, - - { "no-cursor", '\0', - POPT_ARG_NONE, &no_cursor, 0, - "Disable drawing of the cursor.", - NULL }, - - { "no-shared", '\0', - POPT_ARG_NONE, &arg_return->noshared, 0, - "Disable usage of MIT-shared memory extension(Not Recommended!).", - NULL }, - - { "full-shots", '\0', - POPT_ARG_NONE, &arg_return->full_shots, 0, - "Take full screenshot at every frame(Not recomended!).", - NULL }, - - { "follow-mouse", '\0', - POPT_ARG_NONE, &arg_return->follow_mouse, 0, - "Makes the capture area follow the mouse cursor. Autoenables --full-shots.", - NULL }, - - { "quick-subsampling", '\0', - POPT_ARG_NONE, &quick_subsampling, 0, - "Do subsampling of the chroma planes by discarding, not averaging.", - NULL }, - - { "fps", '\0', - POPT_ARG_FLOAT, &arg_return->fps, 0, - "A positive number denoting desired framerate.", - "N(number>0.0)" }, - - POPT_TABLEEND }; - - struct poptOption sound_options[] = { - { "channels", '\0', - POPT_ARG_INT, &arg_return->channels, 0, - "A positive number denoting desired sound channels in recording.", - "N" }, - - { "freq", '\0', - POPT_ARG_INT, &arg_return->frequency, 0, - "A positive number denoting desired sound frequency.", - "N" }, - - { "buffer-size", '\0', - POPT_ARG_INT, &arg_return->buffsize, 0, - "A positive number denoting the desired sound buffer size (in frames, when using ALSA or OSS)", - "N" }, - - { "ring-buffer-size", '\0', - POPT_ARG_FLOAT, &arg_return->jack_ringbuffer_secs, 0, - "A float number denoting the desired ring buffer size (in seconds, when using JACK only).", - "N" }, - - { "device", '\0', - POPT_ARG_STRING, &arg_return->device, 0, - "Sound device(default " DEFAULT_AUDIO_DEVICE ").", - "SOUND_DEVICE" }, - - { "use-jack", '\0', - POPT_ARG_STRING | RMD_USE_JACK_EXTRA_FLAG, &arg_return->x, RMD_ARG_USE_JACK, - "Record audio from the specified list of space-separated jack ports.", - "port1 port2... portn" }, - - { "no-sound", '\0', - POPT_ARG_NONE, &arg_return->nosound, 0, - "Do not record sound.", - NULL }, - - POPT_TABLEEND }; - - struct poptOption encoding_options[] = { - { "on-the-fly-encoding", '\0', - POPT_ARG_NONE, &arg_return->encOnTheFly, 0, - "Encode the audio-video data, while recording.", - NULL }, - - { "v_quality", '\0', - POPT_ARG_INT, &arg_return->v_quality, 0, - "A number from 0 to 63 for desired encoded video quality(default 63).", - "n" }, - - { "v_bitrate", '\0', - POPT_ARG_INT, &arg_return->v_bitrate, 0, - "A number from 0 to 2000000 for desired encoded video bitrate(default 0).", - "n" }, - - { "s_quality", '\0', - POPT_ARG_INT, &arg_return->s_quality, 0, - "Desired audio quality(-1 to 10).", - "n" }, - - POPT_TABLEEND }; - - struct poptOption misc_options[] = { - { "rescue", '\0', - POPT_ARG_STRING, &arg_return->rescue_path, 0, - "Encode data from a previous, crashed, session.", - "path_to_data" }, - - { "no-encode", '\0', - POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &arg_return->no_encode, 0, - "Do not encode any data after recording is complete. This is instead done manually afterwards with --rescue.", - NULL }, - - { "no-wm-check", '\0', - POPT_ARG_NONE, &arg_return->nowmcheck, 0, - "Do not try to detect the window manager(and set options according to it)", - NULL }, - - { "no-frame", '\0', - POPT_ARG_NONE, &arg_return->noframe, 0, - "Don not show the frame that visualizes the recorded area.", - NULL }, - - { "pause-shortcut", '\0', - POPT_ARG_STRING, &arg_return->pause_shortcut, 0, - "Shortcut that will be used for (un)pausing (default Control+Mod1+p).", - "MOD+KEY" }, - - { "stop-shortcut", '\0', - POPT_ARG_STRING, &arg_return->stop_shortcut, 0, - "Shortcut that will be used to stop the recording (default Control+Mod1+s).", - "MOD+KEY" }, - - { "compress-cache", '\0', - POPT_ARG_NONE, &compress_cache, 0, - "Image data are cached with light compression.", - NULL }, - - { "workdir", '\0', - POPT_ARG_STRING, &arg_return->workdir, 0, - "Location where a temporary directory will be created to hold project files(default $HOME).", - "DIR" }, - - { "delay", '\0', - POPT_ARG_STRING, &arg_return->delay, RMD_ARG_DELAY, - "Number of secs(default), minutes or hours before capture starts(number can be float)", - "n[H|h|M|m]" }, - - { "overwrite", '\0', - POPT_ARG_NONE, &arg_return->overwrite, 0, - "If there is already a file with the same name, delete it (default is to add a number postfix to the new one).", - NULL }, - - { "output", 'o', - POPT_ARG_STRING, &arg_return->filename, 0, - "Name of recorded video(default out.ogv).", - "filename" }, - - POPT_TABLEEND }; - - struct poptOption rmd_args[] = { - RMD_OPTION_TABLE("Generic Options", generic_options), - RMD_OPTION_TABLE("Image Options", image_options), - RMD_OPTION_TABLE("Sound Options", sound_options), - RMD_OPTION_TABLE("Encoding Options", encoding_options), - RMD_OPTION_TABLE("Misc Options", misc_options), - POPT_TABLEEND }; - - - // Some trivial setup - popt_context = poptGetContext(NULL, argc, (const char **)argv, rmd_args, 0); - poptSetOtherOptionHelp(popt_context, "[OPTIONS]^filename"); - - - // Parse the arguments - while ((arg_id = poptGetNextOpt(popt_context)) > 0) { - char *arg = poptGetOptArg(popt_context); - - // Most arguments are handled completely by libpopt but we - // handle some by ourself, namely those in this switch case - switch (arg_id) { - case RMD_ARG_DELAY: - { - float num = atof(arg); - - if (num > 0.0) { - int k; - for (k = 0; k < strlen(arg); k++) { - if ((arg[k] == 'M') || (arg[k] == 'm')) { - num *= 60.0; - break; - } - else if ((arg[k] == 'H') || (arg[k] == 'h')) { - num *= 3600.0; - break; - } - } - arg_return->delay = (int) num; - } else { - fprintf(stderr, - "Argument Usage: --delay n[H|h|M|m]\n" - "where n is a float number\n"); - success = FALSE; - } - } - break; - - case RMD_ARG_DUMMY_CURSOR: - { - if (!strcmp(arg, "white")) - arg_return->cursor_color = 0; - else if (!strcmp(arg, "black")) - arg_return->cursor_color = 1; - else { - fprintf(stderr, - "Argument Usage:\n" - " --dummy-cursor [black|white]\n"); - success = FALSE; - } - arg_return->have_dummy_cursor = TRUE; - arg_return->xfixes_cursor = FALSE; - } - break; - - case RMD_ARG_USE_JACK: - { - arg_return->jack_nports = 0; - - while (arg) { - - arg_return->jack_nports++; - - arg_return->jack_port_names[arg_return->jack_nports - 1] = malloc(strlen(arg) + 1); - strcpy(arg_return->jack_port_names[arg_return->jack_nports - 1], arg); - - arg = poptGetOptArg(popt_context); - } - - if (arg_return->jack_nports > 0) { - arg_return->use_jack = 1; - } else { - fprintf(stderr, - "Argument Usage: --use-jack port1 port2... portn\n"); - success = FALSE; - } - - if (RMD_USE_JACK_EXTRA_FLAG == POPT_ARGFLAG_DOC_HIDDEN) { - fprintf(stderr, - "Warning, will ignore --use-jack flags, no libjack support in build.\n"); - } - } - - default: - break; - } - } - - if (arg_id == -1) { - // Parsing is complete, perform final adjustments - if (no_cursor) - arg_return->xfixes_cursor = FALSE; - - if (quick_subsampling) - arg_return->no_quick_subsample = FALSE; - - if (compress_cache) - arg_return->zerocompression = FALSE; - - if (arg_return->follow_mouse) - arg_return->full_shots = TRUE; - - if (!arg_return->filename) - arg_return->filename = strdup(poptGetArg(popt_context)); - } else { - // Parsing error, say what went wrong - const char *str = poptBadOption(popt_context, 0); - - success = FALSE; - - fprintf(stderr, - "Error when parsing `%s': ", str); - - switch (arg_id) { - case POPT_ERROR_NOARG: - fprintf(stderr, "Missing argument\n"); - break; - - case POPT_ERROR_BADNUMBER: - fprintf(stderr, "Bad number\n"); - break; - - default: - fprintf(stderr, "libpopt error: %d\n", arg_id); - break; - } - } - - // Make sure argument ranges are valid - success = success && rmdValidateArguments(arg_return); - - // Clean up - poptFreeContext(popt_context); - - return success; -} - -static boolean rmdValidateArguments(const ProgArgs *args) -{ - boolean success = TRUE; - - if (args->x < 0) { - fprintf(stdout, "-x must not be less than 0.\n"); - success = FALSE; - } - if (args->y < 0) { - fprintf(stdout, "-y must not be less than 0.\n"); - success = FALSE; - } - if (args->width < 0) { - fprintf(stdout, "--width must be larger than 0.\n"); - success = FALSE; - } - if (args->height < 0) { - fprintf(stdout, "--height must be larger than 0.\n"); - success = FALSE; - } - if (args->fps <= 0) { - fprintf(stdout, "--fps must be larger than 0.\n"); - success = FALSE; - } - if (args->v_quality < 0 || args->v_quality > 63) { - fprintf(stdout, "--v_quality must be within the inclusive range [0-63].\n"); - success = FALSE; - } - if (args->v_bitrate < 0 || args->v_quality > 2000000) { - fprintf(stdout, "--v_bitrate must be within the inclusive range [0-2000000].\n"); - success = FALSE; - } - if (args->frequency <= 0) { - fprintf(stdout, "--frequency must be larger than 0.\n"); - success = FALSE; - } - if (args->channels <= 0) { - fprintf(stdout, "--channels must be larger than 0.\n"); - success = FALSE; - } - if (args->buffsize <= 0) { - fprintf(stdout, "--buffer-size must be larger than 0.\n"); - success = FALSE; - } - if (args->jack_ringbuffer_secs <= 0) { - fprintf(stdout, "--jack-buffer-size must be larger than 0.\n"); - success = FALSE; - } - - return success; -} - -static void rmdPrintAndExit( poptContext con, - enum poptCallbackReason reason, - const struct poptOption *opt, - const char *arg, - const void *data) -{ - if (strcmp(opt->longName, "version") == 0) { - fprintf(stderr, "recordMyDesktop v%s\n\n", VERSION); - } else if (strcmp(opt->longName, "help") == 0) { - poptPrintHelp(con, stdout, 0); - fprintf(stdout, - "\n" - "\tIf no other options are specified, filename can be given without the -o switch.\n" - "\n" - "\n"); - } else if (strcmp(opt->longName, "print-config") == 0) { - fprintf(stdout, - "\n" - "recordMyDesktop was compiled with the following options:\n" - "\n" - "Jack:\t\t\t" RMD_LIBJACK_STATUS "\n" - "Default Audio Backend:\t" RMD_LIBASOUND_STATUS "\n" - "\n" - "\n"); - } - - exit(0); -} diff --git a/recordmydesktop/src/rmd_parseargs.h b/recordmydesktop/src/rmd_parseargs.h deleted file mode 100644 index 42f2bac..0000000 --- a/recordmydesktop/src/rmd_parseargs.h +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef PARSEARGS_H -#define PARSEARGS_H 1 - -#include "rmd_types.h" - - -/** -* Fill ProgArgs struct with arguments entered at execution -* -* \param argc argc as entered from main -* -* \param argv argv as entered from main -* -* \param arg_return ProgArgs struct to be filled with the options -* -* \returns 0 on Success 1 on Failure -*/ -boolean rmdParseArgs(int argc, char **argv, ProgArgs *arg_return); - - -#endif diff --git a/recordmydesktop/src/rmd_poll_events.c b/recordmydesktop/src/rmd_poll_events.c deleted file mode 100644 index 49f2478..0000000 --- a/recordmydesktop/src/rmd_poll_events.c +++ /dev/null @@ -1,245 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_poll_events.h" - -#include "rmd_frame.h" -#include "rmd_macro.h" -#include "rmd_rectinsert.h" -#include "rmd_types.h" - -#include <X11/Xlib.h> -#include <X11/Xlibint.h> -#include <X11/extensions/Xdamage.h> - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <pthread.h> - - -static int clip_event_area(XDamageNotifyEvent *e, XRectangle *cliprect, XRectangle *res) -{ - -#if 0 - printf("got area %x,%x %x,%x\n", - e->area.x, - e->area.y, - e->area.width, - e->area.height); -#endif - - if ( e->area.x <= cliprect->x && - e->area.y <= cliprect->y && - e->area.width >= cliprect->width && - e->area.height >= cliprect->height) { - - /* area completely covers cliprect, cliprect becomes the area */ - res->x = cliprect->x; - res->y = cliprect->y; - res->width = cliprect->width; - res->height = cliprect->height; - - } else if ( e->area.x + e->area.width < cliprect->x || - e->area.x + e->area.width > cliprect->x + cliprect->width || - e->area.y + e->area.height < cliprect->y || - e->area.y + e->area.height > cliprect->y + cliprect->height) { - - /* area has at least one axis with zero overlap, so they can't overlap */ - return 0; - - } else { - - /* areas partially overlap */ - res->x = MAX(e->area.x, cliprect->x); - res->width = MIN(e->area.x + e->area.width, cliprect->x + cliprect->width) - res->x; - - res->y = MAX(e->area.y, cliprect->y); - res->height = MIN(e->area.y + e->area.height, cliprect->y + cliprect->height) - res->y; - - if (!res->width || !res->height) - return 0; - } - -#if 0 - printf("clipped to %x,%x %x,%x\n", - res->x, - res->y, - res->width, - res->height); -#endif - - return 1; -} - - -/* Try align xrect to even boundaries relative to cliprect, - * this is done for the UV routines which operate at 2x2 rgb pixel granularity. - */ -static void uv_align(XRectangle *cliprect, XRectangle *xrect) { - XRectangle rel; - - rel.x = xrect->x - cliprect->x; - rel.y = xrect->y - cliprect->y; - - if (rel.x % 2) { - rel.x -= 1; - rel.width = xrect->width + 1; - } else { - rel.width = xrect->width; - } - - if (rel.y % 2) { - rel.y -= 1; - rel.height = xrect->height + 1; - } else { - rel.height = xrect->height; - } - - /* XXX: note when cliprect prevents an even width, we can't do anything - * about it. rmd could force even-sized recording windows to prevent - * this, but that would be kind of annoying. For now it's assumed - * the UV routines will handle the exception - which might temporarily - * mean they just lop the odd row/column off the edge. - */ - if (rel.width % 2 && rel.width + rel.x < cliprect->x + cliprect->width) - rel.width++; - - if (rel.height % 2 && rel.height + rel.y < cliprect->y + cliprect->height) - rel.height++; -} - - -void rmdInitEventsPolling(ProgData *pdata) { - Window root_return, - parent_return, - *children; - unsigned int i, - nchildren; - - XSelectInput (pdata->dpy, pdata->specs.root, SubstructureNotifyMask); - - if (!pdata->args.full_shots) { - XQueryTree ( pdata->dpy, - pdata->specs.root, - &root_return, - &parent_return, - &children, - &nchildren); - - for (i = 0; i < nchildren; i++) { - XWindowAttributes attribs; - if (XGetWindowAttributes (pdata->dpy, children[i], &attribs)) { - if (!attribs.override_redirect && attribs.depth == pdata->specs.depth) - XDamageCreate( pdata->dpy, - children[i], - XDamageReportRawRectangles); - } - } - XFree(children); - XDamageCreate( pdata->dpy, - pdata->specs.root, - XDamageReportRawRectangles); - } -} - - -void rmdEventLoop(ProgData *pdata) { - int inserts = 0; - - XEvent event; - - while (XPending(pdata->dpy)) { - XNextEvent(pdata->dpy, &event); - if (event.type == KeyPress) { - XKeyEvent *e = (XKeyEvent *)(&event); - if (e->keycode == pdata->pause_key.key) { - int i = 0; - int found = 0; - for (i = 0; i < pdata->pause_key.modnum; i++) { - if (pdata->pause_key.mask[i] == e->state) { - found = 1; - break; - } - } - if (found) { - raise(SIGUSR1); - continue; - } - } - if (e->keycode == pdata->stop_key.key) { - int i = 0; - int found = 0; - for (i = 0; i < pdata->stop_key.modnum; i++) { - if (pdata->stop_key.mask[i] == e->state) { - found = 1; - break; - } - } - if (found) { - raise(SIGINT); - continue; - } - } - } else if (event.type == Expose) { - - if (event.xexpose.count != 0) - continue; - else if (!pdata->args.noframe) { - rmdDrawFrame( pdata->dpy, - pdata->specs.screen, - pdata->shaped_w, - pdata->brwin.rrect.width, - pdata->brwin.rrect.height); - } - - } else if (!pdata->args.full_shots) { - if (event.type == MapNotify ) { - XWindowAttributes attribs; - - if (!((XMapEvent *)(&event))->override_redirect&& - XGetWindowAttributes( pdata->dpy, - event.xcreatewindow.window, - &attribs)) { - - if (!attribs.override_redirect && attribs.depth == pdata->specs.depth) - XDamageCreate( pdata->dpy, - event.xcreatewindow.window, - XDamageReportRawRectangles); - } - } else if (event.type == pdata->damage_event + XDamageNotify ) { - XDamageNotifyEvent *e = (XDamageNotifyEvent *)&event; - XRectangle xrect; - - if (clip_event_area(e, &pdata->brwin.rrect, &xrect)) { - uv_align(&pdata->brwin.rrect, &xrect); - inserts += rmdRectInsert(&pdata->rect_root, &xrect); - } - } - } - } -} diff --git a/recordmydesktop/src/rmd_poll_events.h b/recordmydesktop/src/rmd_poll_events.h deleted file mode 100644 index a1902cb..0000000 --- a/recordmydesktop/src/rmd_poll_events.h +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef POLL_EVENTS_H -#define POLL_EVENTS_H 1 - -#include "rmd_types.h" - - -/** -* Start listening to damage and substructure notify events -* (needed before rmdEventLoop call) -* \param pdata ProgData struct containing all program data -*/ -void rmdInitEventsPolling(ProgData *pdata); - -/** -* Loop calling XNextEvent.Retrieve and place on -* list damage events that arive, create damage for new windows -* and pickup key events for shortcuts. -* \param pdata ProgData struct containing all program data -*/ -void rmdEventLoop(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_queryextensions.c b/recordmydesktop/src/rmd_queryextensions.c deleted file mode 100644 index 4484866..0000000 --- a/recordmydesktop/src/rmd_queryextensions.c +++ /dev/null @@ -1,88 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_queryextensions.h" - -#include "rmd_types.h" - -#include <X11/extensions/shape.h> -#include <X11/extensions/Xfixes.h> -#include <X11/extensions/Xdamage.h> -#include <stdlib.h> - - - -void rmdQueryExtensions( Display *dpy, - ProgArgs *args, - int *damage_event, - int *damage_error, - int *shm_opcode) { - int xf_event_basep, - xf_error_basep, - shm_event_base, - shm_error_base, - shape_event_base, - shape_error_base; - - if ( !args->full_shots && - !XDamageQueryExtension(dpy, damage_event, damage_error)) { - - fprintf(stderr, "XDamage extension not found!!!\n" - "Try again using the --full-shots option, though\n" - "enabling XDamage is highly recommended,\n" - "for performance reasons.\n"); - exit(4); - } - - if ( !args->noshared && - !XQueryExtension(dpy, "MIT-SHM", shm_opcode, &shm_event_base, &shm_error_base)) { - - args->noshared = 1; - fprintf(stderr, "Shared Memory extension not present!\n" - "Try again using the --no-shared option\n"); - exit(5); - } - - if ( args->xfixes_cursor && - XFixesQueryExtension(dpy, &xf_event_basep, &xf_error_basep) == False) { - - args->xfixes_cursor = 0; - fprintf(stderr, "Xfixes extension not present!\n" - "Please run with the -dummy-cursor or" - " --no-cursor option.\n"); - exit(6); - } - - if ( !args->noframe && - !XShapeQueryExtension(dpy, &shape_event_base, &shape_error_base)) { - - fprintf(stderr, "XShape Not Found!!!\n" - "Frame won't be available.\n"); - - args->noframe = 1; - } -} diff --git a/recordmydesktop/src/rmd_queryextensions.h b/recordmydesktop/src/rmd_queryextensions.h deleted file mode 100644 index 432fa6c..0000000 --- a/recordmydesktop/src/rmd_queryextensions.h +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef QUERYEXTENSIONS_H -#define QUERYEXTENSIONS_H 1 - -#include "rmd_types.h" - - -/** -* Check if needed extensions are present -* -* \param dpy Connection to the server -* -* \param args ProgArgs struct containing the user-set options -* -* \param damage_event gets filled with damage event number -* -* \param damage_error gets filled with damage error number -* -* \note Can be an exit point if extensions are not found -*/ -void rmdQueryExtensions(Display *dpy, - ProgArgs *args, - int *damage_event, - int *damage_error, - int *shm_opcode); - - -#endif diff --git a/recordmydesktop/src/rmd_rectinsert.c b/recordmydesktop/src/rmd_rectinsert.c deleted file mode 100644 index 2d2fd8c..0000000 --- a/recordmydesktop/src/rmd_rectinsert.c +++ /dev/null @@ -1,480 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_rectinsert.h" - -#include "rmd_types.h" - -#include <stdlib.h> - - -/** -* Collide two rectangles and dictate most sane action for insertion, -* as well as provide the updated rectangle(s) -* \param xrect1 resident rectangle -* -* \param xrect2 New rectangle -* -* \param xrect_return Pointer to rectangles to be inserted -* -* \param nrects number of entries in xrect_return -* -* \retval 0 No collision -* -* \retval 1 xrect1 is covered by xrect2 -* -* \retval 2 xrect2 is covered by xrect1 -* -* \retval -1 xrect1 was broken (new is picked up in xrect_return) -* -* \retval -2 xrect2 was broken (new is picked up in xrect_return) -* -* \retval -10 Grouping the two rects is possible -* -*/ -static int rmdCollideRects( const XRectangle *xrect1, - const XRectangle *xrect2, - XRectangle xrect_return[], - int *nrects) { - if ((xrect1->x>=xrect2->x)&& - (xrect1->x+xrect1->width<=xrect2->x+xrect2->width)&& - (xrect1->y>=xrect2->y)&& - (xrect1->y+xrect1->height<=xrect2->y+xrect2->height)) { - //1 fits in 2 - *nrects=0; - return 1; - } else if ((xrect2->x>=xrect1->x)&& - (xrect2->x+xrect2->width<=xrect1->x+xrect1->width)&& - (xrect2->y>=xrect1->y)&& - (xrect2->y+xrect2->height<=xrect1->y+xrect1->height)) { - //2 fits in 1 - *nrects=0; - return 2; - } else if ((xrect1->x+xrect1->width<xrect2->x)|| - (xrect2->x+xrect2->width<xrect1->x)|| - (xrect1->y+xrect1->height<xrect2->y)|| - (xrect2->y+xrect2->height<xrect1->y)) { - //no collision - *nrects=0; - return 0; - } else { -//overlapping points are considered enclosed -//this happens because libxdamage may generate many events for one change -//and some of them may be in the the exact same region -//so identical rects would be considered not colliding -//in order though to avoid endless recursion on the rmdRectInsert -//function should always start at the next element(which is logical since -//if any rect makes it to a points none of it's part collides with previous -//nodes on the list, too) - int x1[2]={xrect1->x,xrect1->x+xrect1->width}; - int y1[2]={xrect1->y,xrect1->y+xrect1->height}; - int x2[2]={xrect2->x,xrect2->x+xrect2->width}; - int y2[2]={xrect2->y,xrect2->y+xrect2->height}; - int enclosed[2][4],tot1,tot2; - enclosed[0][0]=(((x1[0]>=x2[0])&&(x1[0]<=x2[1])&& - (y1[0]>=y2[0])&&(y1[0]<=y2[1]))?1:0); - enclosed[0][1]=(((x1[1]>=x2[0])&&(x1[1]<=x2[1])&& - (y1[0]>=y2[0])&&(y1[0]<=y2[1]))?1:0); - enclosed[0][2]=(((x1[0]>=x2[0])&&(x1[0]<=x2[1])&& - (y1[1]>=y2[0])&&(y1[1]<=y2[1]))?1:0); - enclosed[0][3]=(((x1[1]>=x2[0])&&(x1[1]<=x2[1])&& - (y1[1]>=y2[0])&&(y1[1]<=y2[1]))?1:0); - enclosed[1][0]=(((x2[0]>=x1[0])&&(x2[0]<=x1[1])&& - (y2[0]>=y1[0])&&(y2[0]<=y1[1]))?1:0); - enclosed[1][1]=(((x2[1]>=x1[0])&&(x2[1]<=x1[1])&& - (y2[0]>=y1[0])&&(y2[0]<=y1[1]))?1:0); - enclosed[1][2]=(((x2[0]>=x1[0])&&(x2[0]<=x1[1])&& - (y2[1]>=y1[0])&&(y2[1]<=y1[1]))?1:0); - enclosed[1][3]=(((x2[1]>=x1[0])&&(x2[1]<=x1[1])&& - (y2[1]>=y1[0])&&(y2[1]<=y1[1]))?1:0); - tot1=enclosed[0][0]+enclosed[0][1]+enclosed[0][2]+enclosed[0][3]; - tot2=enclosed[1][0]+enclosed[1][1]+enclosed[1][2]+enclosed[1][3]; - if ((tot1==2)&&(tot2==2)) {//same width or height, which is the best case - //group - if ((enclosed[1][0]&&enclosed[1][1])&& - (xrect1->width==xrect2->width)) { - *nrects=1; - xrect_return[0].x = xrect1->x; - xrect_return[0].y = xrect1->y; - xrect_return[0].width = xrect1->width; - xrect_return[0].height = xrect2->height + xrect2->y - xrect1->y; - return -10; - } else if ((enclosed[1][0]&&enclosed[1][2])&& - (xrect1->height==xrect2->height)) { - *nrects=1; - xrect_return[0].x = xrect1->x; - xrect_return[0].y = xrect1->y; - xrect_return[0].width = xrect2->width + xrect2->x - xrect1->x; - xrect_return[0].height = xrect1->height; - return -10; - } else if ((enclosed[1][3]&&enclosed[1][1])&& - (xrect1->height==xrect2->height)) { - *nrects=1; - xrect_return[0].x = xrect2->x; - xrect_return[0].y = xrect2->y; - xrect_return[0].width = xrect1->width + xrect1->x - xrect2->x; - xrect_return[0].height = xrect2->height; - return -10; - } else if ((enclosed[1][3]&&enclosed[1][2])&& - (xrect1->width==xrect2->width)) { - *nrects=1; - xrect_return[0].x = xrect2->x; - xrect_return[0].y = xrect2->y; - xrect_return[0].width = xrect2->width; - xrect_return[0].height = xrect1->height + xrect1->y - xrect2->y; - return -10; - } - //if control reaches here therewasn't a group and we go on - } - - if (tot2==2) { - //break rect2 - xrect_return[0].x = xrect2->x; - xrect_return[0].y = xrect2->y; - xrect_return[0].width = xrect2->width; - xrect_return[0].height = xrect2->height; - *nrects=1; - if (enclosed[1][0]&&enclosed[1][1]) { - xrect_return[0].y = y1[1]; - xrect_return[0].height -= y1[1] - y2[0]; - } else if (enclosed[1][0]&&enclosed[1][2]) { - xrect_return[0].x = x1[1]; - xrect_return[0].width -= x1[1] - x2[0]; - } else if (enclosed[1][3]&&enclosed[1][1]) - xrect_return[0].width -= x2[1] - x1[0]; - else if (enclosed[1][3]&&enclosed[1][2]) - xrect_return[0].height -= y2[1] - y1[0]; - return -2; - } else if (tot1==2) { - //if the first one breaks(which is already inserted) - //then we reenter the part that was left and the one - //that was to be inserted - xrect_return[1].x = xrect2->x; - xrect_return[1].y = xrect2->y; - xrect_return[1].width = xrect2->width; - xrect_return[1].height = xrect2->height; - xrect_return[0].x = xrect1->x; - xrect_return[0].y = xrect1->y; - xrect_return[0].width = xrect1->width; - xrect_return[0].height = xrect1->height; - *nrects=1; - if (enclosed[0][0]&&enclosed[0][1]) { - xrect_return[0].y = y2[1]; - xrect_return[0].height -= y2[1] - y1[0]; - } else if (enclosed[0][0]&&enclosed[0][2]) { - xrect_return[0].x = x2[1]; - xrect_return[0].width -= x2[1] - x1[0]; - } else if (enclosed[0][3]&&enclosed[0][1]) - xrect_return[0].width -= x1[1] - x2[0]; - else if (enclosed[0][3]&&enclosed[0][2]) - xrect_return[0].height -= y1[1] - y2[0]; - return -1; - - } else if (tot2==1) { //in which case there is also tot1==1 - //but we rather not break that - //break rect2 in two - *nrects=2; - if (enclosed[1][0]) { -//first - xrect_return[0].x = x1[1]; - xrect_return[0].y = y2[0]; - xrect_return[0].width = xrect2->width - x1[1] + x2[0]; - xrect_return[0].height = xrect2->height; -//second - xrect_return[1].x = x2[0]; - xrect_return[1].y = y1[1]; - xrect_return[1].width = x1[1] - x2[0]; - xrect_return[1].height = xrect2->height - y1[1] + y2[0]; - } else if (enclosed[1][1]) { -//first - xrect_return[0].x = x2[0]; - xrect_return[0].y = y2[0]; - xrect_return[0].width = xrect2->width - x2[1] + x1[0]; - xrect_return[0].height = xrect2->height; -//second - xrect_return[1].x = x1[0]; - xrect_return[1].y = y1[1]; - xrect_return[1].width = x2[1] - x1[0]; - xrect_return[1].height = xrect2->height - y1[1] + y2[0]; - } else if (enclosed[1][2]) { -//first(same as [1][0]) - xrect_return[0].x = x1[1]; - xrect_return[0].y = y2[0]; - xrect_return[0].width = xrect2->width - x1[1] + x2[0]; - xrect_return[0].height = xrect2->height; -//second - xrect_return[1].x = x2[0]; - xrect_return[1].y = y2[0]; - xrect_return[1].width = x1[1] - x2[0]; - xrect_return[1].height = xrect2->height - y2[1] + y1[0]; - } else if (enclosed[1][3]) { -//first(same as [1][1]) - xrect_return[0].x = x2[0]; - xrect_return[0].y = y2[0]; - xrect_return[0].width = xrect2->width - x2[1] + x1[0]; - xrect_return[0].height = xrect2->height; -//second - xrect_return[1].x = x1[0]; - xrect_return[1].y = y2[0]; - xrect_return[1].width = x2[1] - x1[0]; - xrect_return[1].height = xrect2->height - y2[1] + y1[0]; - } - return -2; - } else {//polygons collide but no point of one is in the other - //so we just keep the two parts of rect2 that are outside rect1 - - //break rect2 in two - //two cases: - //rect2 crossing vertically rect1 - //and rect2 crossing horizontally rect1 - //The proper one can be found by simply checking x,y positions - *nrects=2; - if (xrect2->y<xrect1->y) { - //common - xrect_return[0].x = xrect_return[1].x = x2[0]; - xrect_return[0].width = xrect_return[1].width = xrect2->width; - - xrect_return[0].y = y2[0]; - xrect_return[0].height = xrect2->height - y2[1] + y1[0]; - xrect_return[1].y = y1[1]; - xrect_return[1].height = y2[1] - y1[1]; - } else { - //common - xrect_return[0].y = xrect_return[1].y = y2[0]; - xrect_return[0].height = xrect_return[1].height = xrect2->height; - - xrect_return[0].x = x2[0]; - xrect_return[0].width = xrect2->width - x2[1] + x1[0]; - xrect_return[1].x = x1[1]; - xrect_return[1].width = x2[1] - x1[1]; - } - return -2; - } - } -} - -int rmdRectInsert(RectArea **root, const XRectangle *xrect) { - - int total_insertions = 0; - RectArea *temp = NULL, *newnode = (RectArea *)malloc(sizeof(RectArea)); - - newnode->rect.x = xrect->x; - newnode->rect.y = xrect->y; - newnode->rect.width = xrect->width; - newnode->rect.height = xrect->height; - newnode->prev = newnode->next = NULL; - - if (*root == NULL) { - *root = newnode; - total_insertions = 1; - } else { - XRectangle xrect_return[2]; - int nrects = 0, insert_ok = 1, i = 0; - - temp = *root; - - while (insert_ok) { //if something is broken list does not procceed - //(except on -1 collres case) - - int collres = rmdCollideRects(&temp->rect, xrect, &xrect_return[0], &nrects); - if ((!collres)) - insert_ok = 1; - else { - insert_ok=0; - switch (collres) { - case 1://remove current node,reinsert new one - total_insertions--; - if (temp->prev!=NULL) {//no root - if (temp->next!=NULL) {// - RectArea *temp1=temp->next; - temp->prev->next=temp->next; - temp->next->prev=temp->prev; - free(temp); - if ((xrect->width>0)&&(xrect->height>0)) - total_insertions+=rmdRectInsert(&temp1,xrect); - } else { - temp->prev->next=newnode; - newnode->prev=temp->prev; - total_insertions++; - free(temp); - } - } else {//root - if ((*root)->next!=NULL) { - (*root)=(*root)->next; - (*root)->prev=NULL; - if ((xrect->width>0)&&(xrect->height>0)) - total_insertions+=rmdRectInsert(root,xrect); - } else if ((xrect->width>0)&&(xrect->height>0)) { - *root=newnode; - total_insertions++; - } else { - *root=NULL; - total_insertions++; - } - free(temp); - } - break; - case 2://done,area is already covered - free(newnode); - break; - case -1://current node is broken and reinserted - //(in same pos) - //newnode is also reinserted - if (xrect_return[0].width > 0 && - xrect_return[0].height > 0) { - temp->rect.x = xrect_return[0].x; - temp->rect.y = xrect_return[0].y; - temp->rect.width = xrect_return[0].width; - temp->rect.height = xrect_return[0].height; - if (temp->next==NULL) { - temp->next=newnode; - newnode->prev=temp; - total_insertions++; - } else { - insert_ok=1; - } - } else {//it might happen that the old and now broken node - //is of zero width or height - //(so it isn't reinserted) - if ((temp->prev==NULL)&&(temp->next!=NULL)) { - *root=(*root)->next; - (*root)->prev=NULL; - } else if ((temp->next==NULL)&&(temp->prev!=NULL)) { - temp->prev->next=newnode; - newnode->prev=temp->prev; - } else if ((temp->next==NULL)&&(temp->prev==NULL)) - (*root)=newnode; else { - total_insertions--; - temp->next->prev=temp->prev; - temp->prev->next=temp->next; - total_insertions+=rmdRectInsert(&temp->next, xrect); - } - free(temp); - } - break; - case -2://new is broken and reinserted - if (temp->next==NULL) { - total_insertions+=nrects; - newnode->rect.x = xrect_return[0].x; - newnode->rect.y = xrect_return[0].y; - newnode->rect.width = xrect_return[0].width; - newnode->rect.height = xrect_return[0].height; - temp->next=newnode; - newnode->prev=temp; - if (nrects>1) { - RectArea *newnode1= - (RectArea *)malloc(sizeof(RectArea)); - - newnode1->rect.x = xrect_return[1].x; - newnode1->rect.y = xrect_return[1].y; - newnode1->rect.width = xrect_return[1].width; - newnode1->rect.height = xrect_return[1].height; - newnode->next=newnode1; - newnode1->prev=newnode; - newnode1->next=NULL; - } - } else { - for(i=0;i<nrects;i++) { - if (xrect_return[i].width > 0 && - xrect_return[i].height > 0) - total_insertions+= - rmdRectInsert(&temp->next, &xrect_return[i]); - } - } - break; - case -10://grouped - if (temp->prev==NULL) { - if (temp->next==NULL) {//empty list - newnode->rect.x = xrect_return[0].x; - newnode->rect.y = xrect_return[0].y; - newnode->rect.width = xrect_return[0].width; - newnode->rect.height = xrect_return[0].height; - - *root=newnode; - free(temp); - } else { - total_insertions--; - *root=temp->next; - (*root)->prev=NULL; - free(temp); - if (xrect_return[0].width > 0 && - xrect_return[0].height > 0) - total_insertions+= - rmdRectInsert(root, &xrect_return[0]); - } - } else if (temp->next==NULL) {//last, enter anyway - newnode->rect.x = xrect_return[0].x; - newnode->rect.y = xrect_return[0].y; - newnode->rect.width = xrect_return[0].width; - newnode->rect.height = xrect_return[0].height; - temp->prev->next=newnode; - newnode->prev=temp->prev; - free(temp); - } else {//remove node and reinsert, starting where we were - total_insertions--; - RectArea *temp1=temp->next; - temp->prev->next=temp->next; - temp->next->prev=temp->prev; - free(temp); - if (xrect_return[0].width > 0 && - xrect_return[0].height > 0) - total_insertions+= - rmdRectInsert(&temp1, &xrect_return[0]); - } - break; - } - } - if (insert_ok) { - if (temp->next==NULL) { - temp->next=newnode; - newnode->prev=temp; - total_insertions++; - break; - } else { - temp=temp->next; - } - } else { - break; - } - }; - } - return total_insertions; -} - -void rmdClearList(RectArea **root) { - - RectArea *temp; - temp=*root; - if (temp!=NULL) { - while (temp->next!=NULL) { - temp=temp->next; - free(temp->prev); - } - free(temp); - *root=NULL; - } -} diff --git a/recordmydesktop/src/rmd_rectinsert.h b/recordmydesktop/src/rmd_rectinsert.h deleted file mode 100644 index d9d0a9c..0000000 --- a/recordmydesktop/src/rmd_rectinsert.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RECTINSERT_H -#define RECTINSERT_H 1 - - -#include "rmd_types.h" - - -/** -* Insert a new rectangle on the list, making sure it doesn't overlap -* with the existing ones -* \param root Root entry of the list -* -* \param xrect New area to be inserted -* -* \returns Number of insertions during operation -* -* \note This function is reentrant and recursive. The number -* of insertions takes this into account. -*/ -int rmdRectInsert(RectArea **root, const XRectangle *xrect); - -/** -* Clean up a list of areas marked for update. -* \param root Root entry of the list -*/ -void rmdClearList(RectArea **root); - - -#endif diff --git a/recordmydesktop/src/rmd_register_callbacks.c b/recordmydesktop/src/rmd_register_callbacks.c deleted file mode 100644 index 33e04dd..0000000 --- a/recordmydesktop/src/rmd_register_callbacks.c +++ /dev/null @@ -1,86 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_register_callbacks.h" - -#include "rmd_types.h" - -#include <signal.h> - - -// There seem to be no way of passing user data to the signal handler, -// so hack around not being able to pass ProgData to them -static int *pdata_running = NULL; -static int *pdata_paused = NULL; -static int *pdata_aborted = NULL; -static int *pdata_pause_state_changed = NULL; - - -static void rmdSetPaused(int signum) { - - *pdata_pause_state_changed = TRUE; -} - -static void rmdSetRunning(int signum) { - - if (!*pdata_paused) { - - *pdata_running = FALSE; - - if (signum == SIGABRT) { - *pdata_aborted = TRUE; - } - } -} - -void rmdRegisterCallbacks(ProgData *pdata) { - - struct sigaction pause_act; - struct sigaction end_act; - - // Is there some way to pass pdata to the signal handlers? - pdata_running = &pdata->running; - pdata_paused = &pdata->paused; - pdata_aborted = &pdata->aborted; - pdata_pause_state_changed = &pdata->pause_state_changed; - - // Setup pause_act - sigfillset(&pause_act.sa_mask); - pause_act.sa_flags = SA_RESTART; - pause_act.sa_handler = rmdSetPaused; - - sigaction(SIGUSR1, &pause_act, NULL); - - // Setup end_act - sigfillset(&end_act.sa_mask); - end_act.sa_flags = SA_RESTART; - end_act.sa_handler = rmdSetRunning; - - sigaction(SIGINT, &end_act, NULL); - sigaction(SIGTERM, &end_act, NULL); - sigaction(SIGABRT, &end_act, NULL); -} diff --git a/recordmydesktop/src/rmd_register_callbacks.h b/recordmydesktop/src/rmd_register_callbacks.h deleted file mode 100644 index abe8783..0000000 --- a/recordmydesktop/src/rmd_register_callbacks.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef REGISTER_CALLBACKS_H -#define REGISTER_CALLBACKS_H 1 - - -#include "rmd_types.h" - - -/** -* Set up all callbacks and signal handlers -* \param pdata ProgData struct containing all program data -*/ -void rmdRegisterCallbacks(ProgData *prog_data); - - -#endif diff --git a/recordmydesktop/src/rmd_rescue.c b/recordmydesktop/src/rmd_rescue.c deleted file mode 100644 index 84bcf4b..0000000 --- a/recordmydesktop/src/rmd_rescue.c +++ /dev/null @@ -1,124 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_rescue.h" - -#include "rmd_yuv_utils.h" -#include "rmd_encode_cache.h" -#include "rmd_initialize_data.h" -#include "rmd_register_callbacks.h" -#include "rmd_specsfile.h" -#include "rmd_types.h" - -#include <pthread.h> - -#include <string.h> -#include <stdlib.h> - - -int rmdRescue(const char *path) { - unsigned short width, height; - ProgData pdata; - EncData enc_data; - CacheData cache_data; - - rmdSetupDefaultArgs(&pdata.args); - - pdata.enc_data = &enc_data; - pdata.cache_data = &cache_data; - - //projname - cache_data.projname = malloc(strlen(path) + 2); - strcpy(cache_data.projname, path); - strcat(cache_data.projname, "/");//having two of these doesn't hurt... - //image data - cache_data.imgdata = malloc(strlen(cache_data.projname) + 11); - strcpy(cache_data.imgdata, cache_data.projname); - strcat(cache_data.imgdata, "img.out"); - //audio data - cache_data.audiodata = malloc(strlen(cache_data.projname) + 10); - strcpy(cache_data.audiodata, cache_data.projname); - strcat(cache_data.audiodata, "audio.pcm"); - //specsfile - cache_data.specsfile = malloc(strlen(cache_data.projname) + 10); - strcpy(cache_data.specsfile, cache_data.projname); - strcat(cache_data.specsfile, "specs.txt"); - - if (rmdReadSpecsFile(&pdata)) - return 1; - - width = ((pdata.brwin.rrect.width + 15) >> 4) << 4; - height = ((pdata.brwin.rrect.height + 15) >> 4) << 4; - - enc_data.yuv.y = malloc(height * width); - enc_data.yuv.u = malloc(height * width / 4); - enc_data.yuv.v = malloc(height * width / 4); - enc_data.yuv.y_width = width; - enc_data.yuv.y_height = height; - enc_data.yuv.y_stride = width; - - enc_data.yuv.uv_width = width / 2; - enc_data.yuv.uv_height = height / 2; - enc_data.yuv.uv_stride = width / 2; - - for (int i = 0; i < (enc_data.yuv.y_width * enc_data.yuv.y_height); i++) - enc_data.yuv.y[i] = 0; - - for (int i = 0; i < (enc_data.yuv.uv_width * enc_data.yuv.uv_height); i++) - enc_data.yuv.v[i] = enc_data.yuv.u[i] = 127; - - yblocks = malloc(sizeof(*yblocks) * (enc_data.yuv.y_width / Y_UNIT_WIDTH) * - (enc_data.yuv.y_height / Y_UNIT_WIDTH)); - ublocks = malloc(sizeof(*ublocks) * (enc_data.yuv.y_width / Y_UNIT_WIDTH) * - (enc_data.yuv.y_height / Y_UNIT_WIDTH)); - vblocks = malloc(sizeof(*vblocks) * (enc_data.yuv.y_width / Y_UNIT_WIDTH) * - (enc_data.yuv.y_height / Y_UNIT_WIDTH)); - - pdata.frametime = 1000000 / pdata.args.fps; - - pthread_mutex_init(&pdata.theora_lib_mutex, NULL); - pthread_mutex_init(&pdata.vorbis_lib_mutex, NULL); - pthread_mutex_init(&pdata.libogg_mutex, NULL); - pthread_cond_init(&pdata.theora_lib_clean, NULL); - pthread_cond_init(&pdata.vorbis_lib_clean, NULL); - pdata.th_encoding_clean = pdata.v_encoding_clean = 1; - pdata.avd = 0; - pdata.sound_buffer = NULL; - pdata.running = TRUE; - pdata.aborted = FALSE; - - rmdRegisterCallbacks(&pdata); - fprintf(stderr, "Restoring %s!!!\n", path); - - rmdEncodeCache(&pdata); - - fprintf(stderr, "Done!!!\n"); - fprintf(stderr, "Goodbye!\n"); - rmdCleanUp(); - - return 0; -} diff --git a/recordmydesktop/src/rmd_rescue.h b/recordmydesktop/src/rmd_rescue.h deleted file mode 100644 index 2fbf2da..0000000 --- a/recordmydesktop/src/rmd_rescue.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMD_RESCUE_H -#define RMD_RESCUE_H 1 - -/* - * Rescue a previous recording, found in - * the given path. - * - * \param path Path to the cache folder. - * - * \returns 0 on Success, 1 on failure - * - */ -int rmdRescue(const char *path); - - -#endif diff --git a/recordmydesktop/src/rmd_setbrwindow.c b/recordmydesktop/src/rmd_setbrwindow.c deleted file mode 100644 index 9ad30b8..0000000 --- a/recordmydesktop/src/rmd_setbrwindow.c +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_setbrwindow.h" - -#include "rmd_types.h" - - -boolean rmdSetBRWindow( Display *dpy, - BRWindow *brwin, - DisplaySpecs *specs, - ProgArgs *args) { - - //before we start recording we have to make sure the ranges are valid - if (args->windowid == 0) {//root window - //first set it up - brwin->windowid = specs->root; - brwin->winrect.x = 0; - brwin->winrect.y = 0; - brwin->winrect.width = specs->width; - brwin->winrect.height = specs->height; - - brwin->rrect.x = args->x; - brwin->rrect.y = args->y; - brwin->rrect.width = args->width ? args->width : brwin->winrect.width - args->x; - brwin->rrect.height = args->height ? args->height : brwin->winrect.height - args->y; - - //and then check validity - if ( brwin->rrect.x + brwin->rrect.width > specs->width || - brwin->rrect.y + brwin->rrect.height > specs->height) { - - fprintf(stderr, "Window size specification out of bounds!" - "(current resolution:%dx%d)\n", - specs->width, specs->height); - return FALSE; - } - } else { - int transl_x, transl_y; - Window wchid; - XWindowAttributes attribs; - - XGetWindowAttributes(dpy, args->windowid, &attribs); - - if (attribs.map_state == IsUnviewable || attribs.map_state == IsUnmapped) { - fprintf(stderr, "Window must be mapped and visible!\n"); - return FALSE; - } - - XTranslateCoordinates( dpy, - specs->root, - args->windowid, - attribs.x, - attribs.y, - &transl_x, - &transl_y, - &wchid); - - brwin->winrect.x = attribs.x - transl_x; - brwin->winrect.y = attribs.y - transl_y; - brwin->winrect.width = attribs.width; - brwin->winrect.height = attribs.height; - - /* XXX FIXME: this check is partial at best, surely windows can be off the low - * sides of the screen too... - */ - if ( brwin->winrect.x + brwin->winrect.width > specs->width || - brwin->winrect.y + brwin->winrect.height > specs->height) { - - fprintf(stderr,"Window must be on visible screen area!\n"); - return FALSE; - } - - brwin->rrect.x = brwin->winrect.x + args->x; - brwin->rrect.y = brwin->winrect.y + args->y; - brwin->rrect.width = args->width ? args->width : brwin->winrect.width - args->x; - brwin->rrect.height = args->height ? args->height : brwin->winrect.height - args->y; - - if ( args->x + brwin->rrect.width > brwin->winrect.width || - args->y + brwin->rrect.height > brwin->winrect.height) { - fprintf(stderr, "Specified Area is larger than window!\n"); - return FALSE; - } - } - - fprintf(stderr, "Initial recording window is set to:\n" - "X:%d Y:%d Width:%d Height:%d\n", - brwin->rrect.x, brwin->rrect.y, - brwin->rrect.width, brwin->rrect.height); - - return TRUE; -} diff --git a/recordmydesktop/src/rmd_setbrwindow.h b/recordmydesktop/src/rmd_setbrwindow.h deleted file mode 100644 index e036856..0000000 --- a/recordmydesktop/src/rmd_setbrwindow.h +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef SETBRWINDOW_H -#define SETBRWINDOW_H 1 - -#include "rmd_types.h" - - -/** -* Check and align window size -* -* \param dpy Connection to the server -* -* \param brwin BRWindow struct contaning the initial and final window -* -* \param specs DisplaySpecs struct with -* information about the display to be recorded -* -* \param args ProgArgs struct containing the user-set options -* -* \returns 0 on Success 1 on Failure -*/ -int rmdSetBRWindow(Display *dpy, - BRWindow *brwin, - DisplaySpecs *specs, - ProgArgs *args); - - -#endif diff --git a/recordmydesktop/src/rmd_shortcuts.c b/recordmydesktop/src/rmd_shortcuts.c deleted file mode 100644 index e1e07f5..0000000 --- a/recordmydesktop/src/rmd_shortcuts.c +++ /dev/null @@ -1,142 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_shortcuts.h" - -#include "rmd_types.h" - -#include <X11/Xlib.h> -#include <X11/Xlibint.h> -#include <X11/keysym.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -int rmdRegisterShortcut( 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; - - 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 */ - - { - KeyCode numlock = XKeysymToKeycode(dpy, XK_Num_Lock); - XModifierKeymap *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] == numlock) - 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; -} diff --git a/recordmydesktop/src/rmd_shortcuts.h b/recordmydesktop/src/rmd_shortcuts.h deleted file mode 100644 index a0dc2af..0000000 --- a/recordmydesktop/src/rmd_shortcuts.h +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef SHORTCUTS_H -#define CHORTCUTS_H 1 - -#include "rmd_types.h" - - -/* - * Check a shortcut combination and if valid, - * register it, on the root window. - * - * \param dpy Connection to the X Server - * - * \param root Root window id - * - * \param shortcut String represantation of the shortcut - * - * \param HotKey Pre-allocated struct that is filled with the - * modifiers and the keycode, for checks on incoming - * keypress events. Left untouched if the call fails. - * - * - * \returns 0 on Success, 1 on Failure. - * - */ -int rmdRegisterShortcut(Display *dpy, - Window root, - const char *shortcut, - HotKey *hotkey); - - -#endif diff --git a/recordmydesktop/src/rmd_specsfile.c b/recordmydesktop/src/rmd_specsfile.c deleted file mode 100644 index 50542a8..0000000 --- a/recordmydesktop/src/rmd_specsfile.c +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_specsfile.h" - -#include "rmd_types.h" - -#include <stdlib.h> -#include <stdio.h> - - -int rmdWriteSpecsFile(ProgData *pdata) { - - FILE *fp; - - fp=fopen(pdata->cache_data->specsfile,"wb"); - if (!fp) - return 1; - - fprintf(fp,"recordMyDesktop = %s\n",VERSION); - fprintf(fp,"Width = %hu\n",pdata->brwin.rrect.width); - fprintf(fp,"Height = %hu\n",pdata->brwin.rrect.height); - fprintf(fp,"Filename = %s\n",pdata->args.filename); - fprintf(fp,"FPS = %f\n",pdata->args.fps); - fprintf(fp,"NoSound = %d\n",pdata->args.nosound); - fprintf(fp,"Frequency = %d\n",pdata->args.frequency); - fprintf(fp,"Channels = %d\n",pdata->args.channels); - fprintf(fp,"BufferSize = %lu\n",(unsigned long)pdata->args.buffsize); - fprintf(fp,"SoundFrameSize = %d\n",pdata->sound_framesize); - fprintf(fp,"PeriodSize = %lu\n",(unsigned long)pdata->periodsize); - fprintf(fp,"UsedJack = %d\n",pdata->args.use_jack); - fprintf(fp,"v_bitrate = %d\n",pdata->args.v_bitrate); - fprintf(fp,"v_quality = %d\n",pdata->args.v_quality); - fprintf(fp,"s_quality = %d\n",pdata->args.s_quality); - fprintf(fp,"ZeroCompression = %d\n",pdata->args.zerocompression); - - fclose(fp); - - return 0; -} - -int rmdReadSpecsFile(ProgData *pdata) { - char Cached_Version[256]; - FILE *fp; - - fp=fopen(pdata->cache_data->specsfile,"rb"); - if (!fp) - return 1; - - free(pdata->args.filename); - pdata->args.filename=malloc(512); - - //Take that single-point-of-exit advocates !!! - //15 points of exit, just for your pleasure. - //Also, Vi(m) rules, emacs sucks. - - if (fscanf(fp,"recordMyDesktop = %s\n",Cached_Version)!=1) { - fprintf(stderr,"Error reading VERSION attribute!!!\n"); - return 1; - } - if (fscanf(fp,"Width = %hu\n",&pdata->brwin.rrect.width)!=1) { - fprintf(stderr,"Error reading Width attribute!!!\n"); - return 1; - } - if (fscanf(fp,"Height = %hu\n",&pdata->brwin.rrect.height)!=1) { - fprintf(stderr,"Error reading Height attribute!!!\n"); - return 1; - } - if (fscanf(fp,"Filename = %s\n",pdata->args.filename)!=1) { - fprintf(stderr,"Error reading Filename attribute!!!\n"); - return 1; - } - if (fscanf(fp,"FPS = %f\n",&pdata->args.fps)!=1) { - fprintf(stderr,"Error reading FPS attribute!!!\n"); - return 1; - } - if (fscanf(fp,"NoSound = %d\n",&pdata->args.nosound)!=1) { - fprintf(stderr,"Error reading NoSound attribute!!!\n"); - return 1; - } - if (fscanf(fp,"Frequency = %d\n",&pdata->args.frequency)!=1) { - fprintf(stderr,"Error reading Frequency attribute!!!\n"); - return 1; - } - if (fscanf(fp,"Channels = %d\n",&pdata->args.channels)!=1) { - fprintf(stderr,"Error reading Channels attribute!!!\n"); - return 1; - } - if (fscanf(fp,"BufferSize = %lu\n", - (unsigned long *)&pdata->args.buffsize)!=1) { - fprintf(stderr,"Error reading BufferSize attribute!!!\n"); - return 1; - } - if (fscanf(fp,"SoundFrameSize = %d\n",&pdata->sound_framesize)!=1) { - fprintf(stderr,"Error reading SoundFrameSize attribute!!!\n"); - return 1; - } - if (fscanf(fp,"PeriodSize = %lu\n", - (unsigned long *)&pdata->periodsize)!=1) { - fprintf(stderr,"Error reading PeriodSize attribute!!!\n"); - return 1; - } - if (fscanf(fp,"UsedJack = %u\n",&pdata->args.use_jack)!=1) { - fprintf(stderr,"Error reading UsedJack attribute!!!\n"); - return 1; - } - if (fscanf(fp,"v_bitrate = %d\n",&pdata->args.v_bitrate)!=1) { - fprintf(stderr,"Error reading v_bitrate attribute!!!\n"); - return 1; - } - if (fscanf(fp,"v_quality = %d\n",&pdata->args.v_quality)!=1) { - fprintf(stderr,"Error reading v_quality attribute!!!\n"); - return 1; - } - if (fscanf(fp,"s_quality = %d\n",&pdata->args.s_quality)!=1) { - fprintf(stderr,"Error reading s_quality attribute!!!\n"); - return 1; - } - if (fscanf(fp,"ZeroCompression = %d\n",&pdata->args.zerocompression)!=1) { - fprintf(stderr,"Error reading ZeroCompression attribute!!!\n"); - return 1; - } - - fclose(fp); - - return 0; -} diff --git a/recordmydesktop/src/rmd_specsfile.h b/recordmydesktop/src/rmd_specsfile.h deleted file mode 100644 index 67cbd46..0000000 --- a/recordmydesktop/src/rmd_specsfile.h +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef SPECSFILE_H -#define SPECSFILE_H 1 - -#include "rmd_types.h" - - -/* - * Create a text file that holds the required - * capture attributes, in the cache directory. - * - * \param pdata ProgData struct containing all program data - * - * \returns 0 on Success, 1 on failure - * - */ -int rmdWriteSpecsFile(ProgData *pdata); - - - -/* - * Read the text file that holds the required - * capture attributes, in the cache directory. - * - * \param pdata ProgData struct that will be fille - * with all program data - * - * \returns 0 on Success, 1 on failure - * - */ -int rmdReadSpecsFile(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_threads.c b/recordmydesktop/src/rmd_threads.c deleted file mode 100644 index cb81f84..0000000 --- a/recordmydesktop/src/rmd_threads.c +++ /dev/null @@ -1,169 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_threads.h" - -#include "rmd_cache_audio.h" -#include "rmd_cache_frame.h" -#include "rmd_capture_sound.h" -#include "rmd_encode_image_buffer.h" -#include "rmd_encode_sound_buffer.h" -#include "rmd_flush_to_ogg.h" -#include "rmd_get_frame.h" -#include "rmd_jack.h" -#include "rmd_register_callbacks.h" -#include "rmd_timer.h" -#include "rmd_types.h" - -#include <pthread.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -void rmdThreads(ProgData *pdata) { - pthread_t image_capture_t, - image_encode_t, - image_cache_t, - sound_capture_t, - sound_encode_t, - sound_cache_t, - flush_to_ogg_t, - timer_t; - - if (pdata->args.delay > 0) { - fprintf(stderr, "Will sleep for %d seconds now.\n", pdata->args.delay); - sleep(pdata->args.delay); - } - - /*start threads*/ - pthread_create( &image_capture_t, - NULL, - (void *)rmdGetFrame, - (void *)pdata); - - if (pdata->args.encOnTheFly) - pthread_create( &image_encode_t, - NULL, - (void *)rmdEncodeImageBuffer, - (void *)pdata); - else - pthread_create( &image_cache_t, - NULL, - (void *)rmdCacheImageBuffer, - (void *)pdata); - - if (!pdata->args.nosound) { - if (!pdata->args.use_jack) - pthread_create( &sound_capture_t, - NULL, - (void *)rmdCaptureSound, - (void *)pdata); - - if (pdata->args.encOnTheFly) - pthread_create( &sound_encode_t, - NULL, - (void *)rmdEncodeSoundBuffer, - (void *)pdata); - else - pthread_create( &sound_cache_t, - NULL, - (void *)rmdCacheSoundBuffer, - (void *)pdata); - } - - if (pdata->args.encOnTheFly) - pthread_create( &flush_to_ogg_t, - NULL, - (void *)rmdFlushToOgg, - (void *)pdata); - - rmdRegisterCallbacks(pdata); - pdata->timer_alive = 1; - pthread_create( &timer_t, - NULL, - (void *)rmdTimer, - (void *)pdata); - fprintf(stderr,"Capturing!\n"); - -#ifdef HAVE_LIBJACK - if (pdata->args.use_jack) - pdata->jdata->capture_started = 1; -#endif - //wait all threads to finish - - pthread_join(image_capture_t, NULL); - fprintf(stderr,"Shutting down."); - //if no damage events have been received the thread will get stuck - pthread_mutex_lock(&pdata->theora_lib_mutex); - while (!pdata->th_encoding_clean) { - puts("waiting for th_enc"); - pthread_cond_signal(&pdata->image_buffer_ready); - pthread_mutex_unlock(&pdata->theora_lib_mutex); - usleep(10000); - pthread_mutex_lock(&pdata->theora_lib_mutex); - } - pthread_mutex_unlock(&pdata->theora_lib_mutex); - - if (pdata->args.encOnTheFly) - pthread_join(image_encode_t, NULL); - else - pthread_join(image_cache_t, NULL); - fprintf(stderr,"."); - - if (!pdata->args.nosound) { -#ifdef HAVE_LIBJACK - if (pdata->args.use_jack) - rmdStopJackClient(pdata->jdata); -#endif - if (!pdata->args.use_jack) - pthread_join(sound_capture_t,NULL); - - fprintf(stderr,"."); - pthread_mutex_lock(&pdata->vorbis_lib_mutex); - while (!pdata->v_encoding_clean) { - puts("waiting for v_enc"); - pthread_cond_signal(&pdata->sound_data_read); - pthread_mutex_unlock(&pdata->vorbis_lib_mutex); - usleep(10000); - pthread_mutex_lock(&pdata->vorbis_lib_mutex); - } - pthread_mutex_unlock(&pdata->vorbis_lib_mutex); - - if (pdata->args.encOnTheFly) - pthread_join(sound_encode_t, NULL); - else - pthread_join(sound_cache_t, NULL); - } else - fprintf(stderr,".."); - - fprintf(stderr,"."); - - //Now that we are done with recording we cancel the timer - pdata->timer_alive = 0; - pthread_join(timer_t,NULL); -} diff --git a/recordmydesktop/src/rmd_threads.h b/recordmydesktop/src/rmd_threads.h deleted file mode 100644 index e2c103a..0000000 --- a/recordmydesktop/src/rmd_threads.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMDTHREADS_H -#define RMDTHREADS_H 1 - -#include "rmd_types.h" - - -/** -* Launch and wait capture threads. -* Also creates and waits the encoding threads when -* encode-on-the-fly is enabled. -* -* \param pdata ProgData struct containing all program data -*/ -void rmdThreads(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_timer.c b/recordmydesktop/src/rmd_timer.c deleted file mode 100644 index b8161ca..0000000 --- a/recordmydesktop/src/rmd_timer.c +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_timer.h" - -#include "rmd_types.h" - -#include <pthread.h> - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> - - -void *rmdTimer(ProgData *pdata){ - long unsigned int secs_tw=1/pdata->args.fps; - long unsigned int usecs_tw=(1000000)/pdata->args.fps- secs_tw*1000000; - - while (pdata->timer_alive) { - - pthread_mutex_lock(&pdata->pause_mutex); - if (pdata->pause_state_changed) { - pdata->pause_state_changed = FALSE; - - if (!pdata->paused) { - pdata->paused = TRUE; - fprintf(stderr,"STATE:PAUSED\n");fflush(stderr); - } else{ - pdata->paused = FALSE; - fprintf(stderr,"STATE:RECORDING\n");fflush(stderr); - pthread_cond_broadcast(&pdata->pause_cond); - } - } - - if (!pdata->paused) { - pthread_mutex_unlock(&pdata->pause_mutex); - - /* FIXME TODO: detect dropped frames by delta between {time,capture}_frameno */ - pdata->frames_total++; - } else - pthread_mutex_unlock(&pdata->pause_mutex); - - pthread_mutex_lock(&pdata->time_mutex); - pdata->time_frameno++; - pthread_mutex_unlock(&pdata->time_mutex); - pthread_cond_signal(&pdata->time_cond); - - /* FIXME use nanosleep */ - if (secs_tw) - sleep(secs_tw); - - usleep(usecs_tw); - } - - pthread_exit(&errno); -} diff --git a/recordmydesktop/src/rmd_timer.h b/recordmydesktop/src/rmd_timer.h deleted file mode 100644 index d9292d9..0000000 --- a/recordmydesktop/src/rmd_timer.h +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMD_TIMER_H -#define RMD_TIMER_H 1 - -#include "rmd_types.h" - - -/** -* Loop ,signal timer cond var,sleep-\ -* ^ | -* |________________________________/ -* -* -* \param pdata ProgData struct containing all program data -*/ -void *rmdTimer(ProgData *pdata); - - -#endif diff --git a/recordmydesktop/src/rmd_types.h b/recordmydesktop/src/rmd_types.h deleted file mode 100644 index 6018955..0000000 --- a/recordmydesktop/src/rmd_types.h +++ /dev/null @@ -1,366 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMDTYPES_H -#define RMDTYPES_H 1 - -#include "config.h" - -#include <stdio.h> -#include <pthread.h> -#include <zlib.h> -#include <X11/Xlib.h> -#include <X11/extensions/XShm.h> -#include <theora/theora.h> -#include <vorbis/codec.h> -#include <vorbis/vorbisenc.h> -#include <ogg/ogg.h> - -#ifdef HAVE_LIBASOUND - #include <alsa/asoundlib.h> - - #define DEFAULT_AUDIO_DEVICE "hw:0,0" -#else - #include <sys/ioctl.h> - #include <sys/soundcard.h> - - #define DEFAULT_AUDIO_DEVICE "/dev/dsp" -#endif - -#ifdef HAVE_LIBJACK - #include <jack/jack.h> - #include <jack/ringbuffer.h> -#endif - - -//this type exists only -//for comparing the planes at caching. -//u_int64_t mught not be available everywhere. -//The performance gain comes from casting the unsigned char -//buffers to this type before comparing the two blocks. -//This is made possible by the fact that blocks -//for the Y plane are 16 bytes in width and blocks -//for the U,V planes are 8 bytes in width -#ifdef HAVE_U_INT64_T -typedef u_int64_t cmp_int_t; -#else -typedef u_int32_t cmp_int_t; -#endif - -//type of pixel proccessing for the Cb,Cr planes -//when converting from full rgb to 4:2:2 Ycbcr -enum{ - __PXL_DISCARD, //only select 1 pixel in every block of four - __PXL_AVERAGE //calculate the average of all four pixels -}; - -// Boolean type -typedef int boolean; -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -#define RMD_MAX_JACK_PORTS (100) - -// Forward declarations -typedef struct _ProgData ProgData; - -typedef struct _Image { - XImage *ximage; - XShmSegmentInfo shm_info; -}Image; - -typedef struct _DisplaySpecs{ //this struct holds some basic information - int screen; //about the display,needed mostly for - unsigned int width, height; //validity checks at startup - Window root; - Visual *visual; - GC gc; - int depth; -}DisplaySpecs; - -typedef struct _RectArea{ //an area that has been damaged gets stored - XRectangle rect; //in a list comprised of structs of this type - struct _RectArea *prev,*next; -}RectArea; - -typedef struct _BRWindow{ //'basic recorded window' specs - XRectangle winrect; //window attributes - XRectangle rrect; //recorded window rect in screen space coordinates - Window windowid; //id -}BRWindow; - -//defaults in the following comment lines may be out of sync with reality -//check the SetupDefaultArgs() function further bellow -typedef struct _ProgArgs{ - int delay; //start up delay - Window windowid; //window to record(default root) - char *display; //display to connect(default :0) - int x,y; //x,y offset(default 0,0) - int width,height; //defaults to window width and height - char *filename; //output file(default out.[ogg|*]) - int cursor_color; //black or white=>1 or 0 - int have_dummy_cursor; //disable/enable drawing of the dummy cursor - int xfixes_cursor; //disable/enable drawing of a cursor obtained - //through the xfixes extension - float fps; //desired framerate(default 15) - unsigned int frequency; //desired frequency (default 22050) - unsigned int channels; //no of channels(default 2) - char *device; //default sound device -#ifdef HAVE_LIBASOUND - snd_pcm_uframes_t buffsize; //buffer size(in frames) for sound capturing -#else - u_int32_t buffsize; -#endif - const char* rescue_path; - int nosound; //do not record sound(default 0) - int noshared; //do not use shared memory extension(default 0) - int nowmcheck; //do not check if there's a 3d comp window manager - //(which changes full-shots and with-shared to 1) - int full_shots; //do not poll damage, take full screenshots - int follow_mouse; //capture area follows the mouse(fullshots auto enabled) - int no_encode; //do not encode or delete the temporary files(debug opt) - int no_quick_subsample; //average pixels in chroma planes - int v_bitrate,v_quality,s_quality; //video bitrate,video-sound quality - int encOnTheFly; //encode while recording, no caching(default 0) - char *workdir; //directory to be used for cache files(default $HOME) - char *pause_shortcut; //pause/unpause shortcut sequence(Control+Alt+p) - char *stop_shortcut; //stop shortcut sequence(Control+Alt+s) - int noframe; //don't draw a frame around the recording area - int zerocompression; //image data are always flushed uncompressed - int overwrite; //overwite a previously existing file - //(do not add a .number postfix) - int use_jack; //record audio with jack - unsigned int jack_nports; - char *jack_port_names[RMD_MAX_JACK_PORTS]; - float jack_ringbuffer_secs; -} ProgArgs; - -//this struct holds anything related to encoding AND -//writting out to file. -typedef struct _EncData{ - ogg_stream_state m_ogg_ts; //theora - ogg_stream_state m_ogg_vs; //vorbis - ogg_page m_ogg_pg; //this could be avoided since - // it is used only while initializing - ogg_packet m_ogg_pckt1; //theora stream - ogg_packet m_ogg_pckt2; //vorbis stream -//theora data - theora_state m_th_st; - theora_info m_th_inf; - theora_comment m_th_cmmnt; - yuv_buffer yuv; -//vorbis data - vorbis_info m_vo_inf; - vorbis_comment m_vo_cmmnt; - vorbis_dsp_state m_vo_dsp; - vorbis_block m_vo_block; -//our file - FILE *fp; -} EncData; - -//this struct will hold a few basic -//information, needed for caching the frames. -typedef struct _CacheData{ - char *workdir, //The directory were the project - //will be stored, while recording. - //Since this will take a lot of space, the user must be - //able to change the location. - *projname, //This is the name of the folder that - //will hold the project. - //It is rMD-session-%d where %d is the pid - //of the current proccess. - //This way, running two instances - //will not create problems - //and also, a frontend can identify - //leftovers from a possible crash - //and delete them - *specsfile, //workdir+projname+specs.txt - *imgdata, //workdir+projname+img.out.gz - *audiodata; //workdir+projname+audio.pcm - - gzFile ifp; //image data file pointer - FILE *uncifp; //uncompressed image data file pointer - - FILE *afp; //audio data file pointer - -}CacheData; - -//sound buffer -//sound keeps coming so we que it in this list -//which we then traverse -typedef struct _SndBuffer{ - signed char *data; - struct _SndBuffer *next; -}SndBuffer; - -#ifdef HAVE_LIBJACK -typedef struct _JackData{ - ProgData *pdata; //pointer to prog data - jack_client_t *client; - unsigned int buffersize, //buffer size for every port in frames. - frequency, //samplerate with which jack server was started. - nports; //number of ports. - float ringbuffer_secs; - char **port_names; //names of ports(as specified in args). - jack_port_t **ports; //connections to thes ports. - jack_default_audio_sample_t - **portbuf; //retrieval of audio buffers. - pthread_mutex_t *sound_buffer_mutex; //mutex and cond_var - pthread_cond_t *sound_data_read; //in the pdata struct - jack_ringbuffer_t *sound_buffer; //data exchange happens through this - int capture_started; //used to hold recording in the beginning -}JackData; -#endif - -typedef struct _HotKey{ //Hold info about the shortcuts - int modnum; //modnum is the number of modifier masks - unsigned int mask[4]; //that should be checked (the initial - int key; //user requested modifier plus it's -}HotKey; //combinations with LockMask and NumLockMask). - -//this structure holds any data related to the program -//It's usage is mostly to be given as an argument to the -//threads,so they will have access to the program data, avoiding -//at the same time usage of any globals. -struct _ProgData { -/**recordMyDesktop specific structs*/ - ProgArgs args; //the program arguments - DisplaySpecs specs; //Display specific information - BRWindow brwin; //recording window - RectArea *rect_root; //the interchanging list roots for storing - //the changed regions - SndBuffer *sound_buffer; - EncData *enc_data; - CacheData *cache_data; - HotKey pause_key, //Shortcuts - stop_key; -#ifdef HAVE_LIBJACK - JackData *jdata; -#endif -/**X related info*/ - Display *dpy; //curtrent display -/** Mutexes*/ - pthread_mutex_t sound_buffer_mutex, - img_buff_ready_mutex, - theora_lib_mutex, //serializes access to th_encoding_clean w/theora_lib_clean - vorbis_lib_mutex, //serializes acces to v_encoding_clean w/vorbis_lib_clean - libogg_mutex, //libogg is not thread safe, - yuv_mutex; //this might not be needed since we only have - //one read-only and one write-only thread - //also on previous versions, - //y component was looped separately - //and then u and v so this was needed - //to avoid wrong coloring to render - //Currently this mutex only prevents - //the cursor from flickering -/**Condition Variables*/ - pthread_cond_t time_cond, //this gets a signal by the handler - //whenever it's time to get a screenshot - pause_cond, //this is blocks execution, - //when program is paused - sound_data_read, //a buffer is ready for proccessing - image_buffer_ready, //image encoding finished - theora_lib_clean, //the flush_ogg thread cannot - //procceed to creating last - vorbis_lib_clean; //packages until these two libs - //are no longer used, by other threads -/**Buffers,Flags and other vars*/ - unsigned char *dummy_pointer, //a dummy pointer to be drawn - //in every frame - //data is casted to unsigned for - //later use in YUV buffer - npxl; //this is the no pixel convention - //when drawing the dummy pointer - unsigned int periodtime,//time that a sound buffer lasts (microsecs) - frametime; //time that a frame lasts (microsecs) - Window shaped_w; //frame - int damage_event, //damage event base code - damage_error, //damage error base code - shm_opcode, //MIT-Shm opcode - dummy_p_size, //dummy pointer size,initially 16x16,always square - th_encoding_clean, //thread exit inidcator - v_encoding_clean, // >> >> - timer_alive, //determines loop of timer thread - hard_pause, //if sound device doesn't support pause - //we have to close and reopen - avd, //syncronization among audio and video - sound_framesize; //size of each sound frame - - /** Progam state vars */ - boolean running; //1 while the program is capturing/paused/encoding - boolean paused; //1 while the program is paused - boolean aborted; //1 if we should abort - boolean pause_state_changed; //1 if pause state changed - - //the following values are of no effect - //but they might be usefull later for profiling - unsigned int frames_total, //frames calculated by total time expirations - frames_lost; //the value of shame - - /* timer advances time_frameno, getframe copies time_frameno to capture_frameno - * access to both is serialized by time_{mutex,cond} - */ - unsigned int time_frameno, capture_frameno; - - pthread_mutex_t pause_mutex; - pthread_mutex_t time_mutex; - -#ifdef HAVE_LIBASOUND - snd_pcm_t *sound_handle; - snd_pcm_uframes_t periodsize; -#else - int sound_handle; - u_int32_t periodsize; -#endif -}; - - -//This is the header of every frame. -//Reconstruction will be correct only if made on -//the same platform. - -//We need the total number of blocks -//for each plane. - -//The number of the frame compared to the -//number of time expirations at the time of -//caching, will enable us to make up for lost frames. - - -typedef struct _FrameHeader{ - char frame_prefix[4]; //always FRAM - u_int32_t frameno, //number of frame(cached frames) - current_total; //number of frames that should have been - //taken at time of caching this one - u_int32_t Ynum, //number of changed blocks in the Y plane - Unum, //number of changed blocks in the U plane - Vnum; //number of changed blocks in the V plane -}FrameHeader; - -#endif - diff --git a/recordmydesktop/src/rmd_update_image.c b/recordmydesktop/src/rmd_update_image.c deleted file mode 100644 index 343e1bb..0000000 --- a/recordmydesktop/src/rmd_update_image.c +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_update_image.h" - -#include "rmd_getzpixmap.h" -#include "rmd_yuv_utils.h" -#include "rmd_types.h" - -#include <X11/Xlibint.h> -#include <X11/extensions/shmproto.h> -#include <X11/extensions/XShm.h> - -#include <assert.h> - - -void rmdUpdateImage( Display * dpy, - yuv_buffer *yuv, - DisplaySpecs *specs, - RectArea **root, - BRWindow *brwin, - EncData *enc, - Image *image, - int noshmem, - int shm_opcode, - int no_quick_subsample){ - - RectArea *temp; - - for (temp = *root; temp; temp = temp->next) { - - /* sanity check the clipping, nothing on the reclist - * should go outside rrect - */ - assert(temp->rect.x >= brwin->rrect.x); - assert(temp->rect.y >= brwin->rrect.y); - assert(temp->rect.x + temp->rect.width <= brwin->rrect.x + brwin->rrect.width); - assert(temp->rect.y + temp->rect.height <= brwin->rrect.y + brwin->rrect.height); - - if (noshmem) { - rmdGetZPixmap( dpy, - specs->root, - image->ximage->data, - temp->rect.x, - temp->rect.y, - temp->rect.width, - temp->rect.height); - } else { - rmdGetZPixmapSHM( dpy, - specs->root, - &image->shm_info, - shm_opcode, - image->ximage->data, - temp->rect.x, - temp->rect.y, - temp->rect.width, - temp->rect.height); - } - rmdUpdateYuvBuffer( - yuv, - (unsigned char *)image->ximage->data, - NULL, - temp->rect.x - brwin->rrect.x, - temp->rect.y - brwin->rrect.y, - temp->rect.width, - temp->rect.height, - no_quick_subsample, - specs->depth - ); - } -} diff --git a/recordmydesktop/src/rmd_update_image.h b/recordmydesktop/src/rmd_update_image.h deleted file mode 100644 index 3057f18..0000000 --- a/recordmydesktop/src/rmd_update_image.h +++ /dev/null @@ -1,70 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef UPDATE_IMAGE_H -#define UPDATE_IMAGE_H 1 - -#include "rmd_types.h" - -#include <X11/extensions/XShm.h> - -/** -* Retrieve and apply all changes, if xdamage is used. -* -* \param dpy Connection to the server -* -* \param yuv yuv_buffer that is to be modified -* -* \param specs DisplaySpecs struct with -* information about the display to be recorded -* -* \param root Root entry of the list with damaged areas -* -* \param brwin BRWindow struct contaning the recording window specs -* -* \param enc Encoding options -* -* \param datatemp Buffer for pixel data to be -* retrieved before placed on the yuv buffer -* -* \param noshmem don't use MIT_Shm extension -* -* \param no_quick_subsample Don't do quick subsampling -* -*/ -void rmdUpdateImage(Display * dpy, - yuv_buffer *yuv, - DisplaySpecs *specs, - RectArea **root, - BRWindow *brwin, - EncData *enc, - Image *image, - int noshmem, - int shm_opcode, - int no_quick_subsample); - - -#endif diff --git a/recordmydesktop/src/rmd_wm_check.c b/recordmydesktop/src/rmd_wm_check.c deleted file mode 100644 index 4934425..0000000 --- a/recordmydesktop/src/rmd_wm_check.c +++ /dev/null @@ -1,76 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_wm_check.h" - -#include "rmd_types.h" - -#include <X11/Xatom.h> - - -char *rmdWMCheck(Display *dpy,Window root) { - Window *wm_child=NULL; - Atom nwm_atom, - utf8_string, - wm_name_atom, - rt; - unsigned long nbytes, nitems; - - char *wm_name_str=NULL; - int fmt; - - utf8_string = XInternAtom(dpy, "UTF8_STRING", False); - - nwm_atom =XInternAtom(dpy,"_NET_SUPPORTING_WM_CHECK",True); - wm_name_atom =XInternAtom(dpy,"_NET_WM_NAME",True); - - if (nwm_atom!=None && wm_name_atom!=None) { - - if (XGetWindowProperty( dpy,root,nwm_atom,0,100, - False,XA_WINDOW, - &rt,&fmt,&nitems, &nbytes, - (unsigned char **)((void*)&wm_child)) - != Success ) { - fprintf(stderr,"Error while trying to get a" - " window to identify the window manager.\n"); - } - - if ((wm_child == NULL)|| - (XGetWindowProperty(dpy,*wm_child,wm_name_atom,0,100, - False,utf8_string,&rt, - &fmt,&nitems, &nbytes, - (unsigned char **)((void*)&wm_name_str)) - !=Success)) { - fprintf(stderr,"Warning!!!\nYour window manager appears" - " to be non-compliant!\n"); - } - } - fprintf(stderr, "Your window manager appears to be %s\n\n", - ((wm_name_str!=NULL)?wm_name_str:"Unknown")); - - return wm_name_str; -} diff --git a/recordmydesktop/src/rmd_wm_check.h b/recordmydesktop/src/rmd_wm_check.h deleted file mode 100644 index 12f33dd..0000000 --- a/recordmydesktop/src/rmd_wm_check.h +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef WM_CHECK_H -#define WM_CHECK_H 1 - -#include "rmd_types.h" - - -/** -*Check current running window manager. -* -* \param dpy Connection to the server -* -* \param root root window of the display -* -* \returns Window manager name -*/ -char *rmdWMCheck(Display *dpy,Window root); - - -#endif diff --git a/recordmydesktop/src/rmd_wm_is_compositing.c b/recordmydesktop/src/rmd_wm_is_compositing.c deleted file mode 100644 index bc43282..0000000 --- a/recordmydesktop/src/rmd_wm_is_compositing.c +++ /dev/null @@ -1,61 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_wm_is_compositing.h" - -#include "rmd_wm_check.h" -#include "rmd_types.h" - -#include <X11/Xatom.h> - -#include <stdlib.h> - - -boolean rmdWMIsCompositing( Display *dpy, int screen ) { - Window win; - Atom atom; - char buf[32]; - char *window_manager=rmdWMCheck( dpy, RootWindow( dpy, screen ) ); - - //If the wm name is queried successfully the wm is compliant (source - //http://standards.freedesktop.org/wm-spec/1.4/ar01s03.html#id2568282 ) - //in which case we will also free() the allcoated string. - - if (window_manager == NULL) - return FALSE; - else - free(window_manager); - - snprintf( buf, sizeof(buf), "_NET_WM_CM_S%d", screen); - atom = XInternAtom(dpy, buf, True); - if (atom == None) - return FALSE; - - win = XGetSelectionOwner(dpy, atom); - - return win != None; -} diff --git a/recordmydesktop/src/rmd_wm_is_compositing.h b/recordmydesktop/src/rmd_wm_is_compositing.h deleted file mode 100644 index 7f152ac..0000000 --- a/recordmydesktop/src/rmd_wm_is_compositing.h +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef RMD_WM_IS_COMPOSITING_H -#define RMD_WM_IS_COMPOSITING_H 1 - -#include "rmd_types.h" - - -/** -*Check if the window manager is compositing (duh!). -* -* \param dpy Connection to the server -* -* \param screen screen number/id that the window manager runs on -* -* \returns TRUE if compositing, false otherwise or when -* the window manager doesn't support the required -* freedesktop.org hints for the test to be done -* succesfully. -*/ - -boolean rmdWMIsCompositing( Display *dpy, int screen) ; - -#endif diff --git a/recordmydesktop/src/rmd_yuv_utils.c b/recordmydesktop/src/rmd_yuv_utils.c deleted file mode 100644 index 1f163ae..0000000 --- a/recordmydesktop/src/rmd_yuv_utils.c +++ /dev/null @@ -1,517 +0,0 @@ -/****************************************************************************** -* recordMyDesktop - rmd_yuv_utils.c * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 John Varouhakis * -* Copyright (C) 2008 Luca Bonavita * -* * -* 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 * -******************************************************************************/ - -#include "config.h" -#include "rmd_yuv_utils.h" - -#include "rmd_math.h" - - -// Keep these global (for performance reasons I assume). -unsigned char Yr[256], Yg[256], Yb[256], - Ur[256], Ug[256], UbVr[256], - Vg[256], Vb[256]; - -// FIXME: These globals are modified in other source files! We keep -// thsee here for now. These are the cache blocks. They need to be -// accesible in the dbuf macros -unsigned char *yblocks, - *ublocks, - *vblocks; - -void rmdMakeMatrices (void) { - int i; - - /* assuming 8-bit precision */ - float Yscale = 219.0, Yoffset = 16.0; - float Cscale = 224.0, Coffset = 128.0; - float RGBscale = 255.0; - - float r, g, b; - float yr, yg, yb; - float ur, ug, ub; - float vg, vb; /* vr intentionally missing */ - - /* as for ITU-R BT-601-6 specifications: */ - r = 0.299; - b = 0.114; - g = 1.0 - r - b; - - /* as a note, here are the coefficients - as for ITU-R BT-709 specifications: - r=0.2126; b=0.0722; g=1.0-r-b; */ - - yr = r * Yscale / RGBscale; - yg = g * Yscale / RGBscale; - yb = b * Yscale / RGBscale; - ur = ( -0.5 * r / ( 1 - b ) ) * Cscale / RGBscale; - ug = ( -0.5 * g / ( 1 - b ) ) * Cscale / RGBscale; - ub = ( 0.5 * Cscale / RGBscale); - /* vr = ub so UbVr = ub*i = vr*i */ - vg = ( -0.5 * g / ( 1 - r ) ) * Cscale / RGBscale; - vb = ( -0.5 * b / ( 1 - r ) ) * Cscale / RGBscale; - - for (i = 0; i < 256; i++) { - Yr[i] = (unsigned char) rmdRoundf( Yoffset + yr * i ); - Yg[i] = (unsigned char) rmdRoundf( yg * i ); - Yb[i] = (unsigned char) rmdRoundf( yb * i ); - - Ur[i] = (unsigned char) rmdRoundf( Coffset + ur * i ); - Ug[i] = (unsigned char) rmdRoundf( ug * i ); - UbVr[i] = (unsigned char) rmdRoundf( ub * i ); - - Vg[i] = (unsigned char) rmdRoundf( vg * i ); - Vb[i] = (unsigned char) rmdRoundf( Coffset + vb * i ); - } -} - -static inline int blocknum(int xv, int yv, int widthv, int blocksize) -{ - return ((yv/blocksize) * (widthv/blocksize) + (xv/blocksize)); -} - -/* These at least make some sense as macros since they need duplication for - * the multiple depths, so I've just moved and reformatted them here for now. - */ - -#define UPDATE_Y_PLANE( data, \ - x_tm, \ - y_tm, \ - width_tm, \ - height_tm, \ - yuv, \ - __depth__) { \ - \ - register unsigned char *yuv_Y = (yuv)->y + x_tm + y_tm * (yuv)->y_stride, \ - *_yr = Yr, *_yg = Yg, *_yb = Yb; \ - register u_int##__depth__##_t *datapi = (u_int##__depth__##_t *)data; \ - \ - for (int k = 0; k < height_tm; k++) { \ - for (int i = 0; i < width_tm; i++) { \ - register u_int##__depth__##_t t_val = *datapi; \ - \ - *yuv_Y = _yr[__RVALUE_##__depth__(t_val)] + \ - _yg[__GVALUE_##__depth__(t_val)] + \ - _yb[__BVALUE_##__depth__(t_val)]; \ - datapi++; \ - yuv_Y++; \ - } \ - \ - yuv_Y += (yuv)->y_stride - width_tm; \ - } \ -} - -//when adding the r values, we go beyond -//the (16 bit)range of the t_val variable, but we are performing -//32 bit arithmetics, so there's no problem. -//(This note is useless, I'm just adding because -//the addition of the A components in CALC_TVAL_AVG_32, -//now removed as uneeded, produced an overflow which would have caused -//color distrtion, where it one of the R,G or B components) -#define CALC_TVAL_AVG_16(t_val, datapi, datapi_next) { \ - register u_int16_t t1, t2, t3, t4; \ - \ - t1 = *datapi; \ - t2 = *(datapi + 1); \ - t3 = *datapi_next; \ - t4 = *(datapi_next + 1); \ - \ - t_val = ((((t1 & __R16_MASK) + (t2 & __R16_MASK) + \ - (t3 & __R16_MASK) + (t4 & __R16_MASK)) / 4) & __R16_MASK) + \ - ((((t1 & __G16_MASK) + (t2 & __G16_MASK)+ \ - (t3 & __G16_MASK) + (t4 & __G16_MASK)) / 4) & __G16_MASK) + \ - ((((t1 & __B16_MASK) + (t2 & __B16_MASK) + \ - (t3 & __B16_MASK) + (t4 & __B16_MASK)) / 4) & __B16_MASK); \ -} - -//the 4 most significant bytes represent the A component which -//does not need to be added on t_val, as it is always unused -#define CALC_TVAL_AVG_32(t_val, datapi, datapi_next) { \ - register unsigned int t1, t2, t3, t4; \ - \ - t1 = *datapi; \ - t2 = *(datapi + 1); \ - t3 = *datapi_next; \ - t4 = *(datapi_next + 1); \ - \ - t_val = ((((t1 & 0x00ff0000) + (t2 & 0x00ff0000) + \ - (t3 & 0x00ff0000) + (t4 & 0x00ff0000)) / 4) & 0x00ff0000) + \ - ((((t1 & 0x0000ff00) + (t2 & 0x0000ff00) + \ - (t3 & 0x0000ff00) + (t4 & 0x0000ff00)) / 4) & 0x0000ff00) + \ - ((((t1 & 0x000000ff) + (t2 & 0x000000ff) + \ - (t3 & 0x000000ff) + (t4 & 0x000000ff)) / 4) & 0x000000ff); \ -} - -#define UPDATE_A_UV_PIXEL( yuv_U, \ - yuv_V, \ - t_val, \ - datapi, \ - datapi_next, \ - _ur,_ug,_ubvr,_vg,_vb, \ - sampling, \ - __depth__) \ - \ - if (sampling == __PXL_AVERAGE) { \ - CALC_TVAL_AVG_##__depth__(t_val, datapi, datapi_next) \ - } else \ - t_val = *(datapi); \ - \ - *(yuv_U) = _ur[__RVALUE_##__depth__(t_val)] + \ - _ug[__GVALUE_##__depth__(t_val)] + \ - _ubvr[__BVALUE_##__depth__(t_val)]; \ - \ - *(yuv_V) = _ubvr[__RVALUE_##__depth__(t_val)] + \ - _vg[__GVALUE_##__depth__(t_val)] + \ - _vb[__BVALUE_##__depth__(t_val)]; - -#define UPDATE_UV_PLANES( data, \ - x_tm, \ - y_tm, \ - width_tm, \ - height_tm, \ - yuv, \ - sampling, \ - __depth__) { \ - \ - register u_int##__depth__##_t t_val; \ - register unsigned char *yuv_U = (yuv)->u + x_tm / 2 + \ - (y_tm * (yuv)->uv_width) / 2, \ - *yuv_V = (yuv)->v + x_tm / 2 + \ - (y_tm * (yuv)->uv_width) / 2, \ - *_ur = Ur, *_ug = Ug, *_ubvr = UbVr, \ - *_vg = Vg, *_vb = Vb; \ - register u_int##__depth__##_t *datapi = (u_int##__depth__##_t *)data, \ - *datapi_next = NULL; \ - int w_odd = width_tm % 2, h_odd = height_tm % 2; \ - \ - if (sampling == __PXL_AVERAGE) \ - datapi_next = datapi + width_tm; \ - \ - for (int k = 0; k < height_tm - h_odd; k += 2) { \ - for (int i = 0; i < width_tm - w_odd; i += 2) { \ - UPDATE_A_UV_PIXEL( yuv_U, \ - yuv_V, \ - t_val, \ - datapi, \ - datapi_next, \ - _ur, _ug, _ubvr, _vg, _vb, \ - sampling, \ - __depth__); \ - \ - datapi += 2; \ - if (sampling == __PXL_AVERAGE) \ - datapi_next += 2; \ - yuv_U++; \ - yuv_V++; \ - } \ - \ - yuv_U += ((yuv)->y_stride - (width_tm - w_odd * 2)) >> 1; \ - yuv_V += ((yuv)->y_stride - (width_tm - w_odd * 2)) >> 1; \ - \ - datapi += width_tm + w_odd; \ - if (sampling == __PXL_AVERAGE) \ - datapi_next += width_tm + w_odd; \ - } \ -} - -#define UPDATE_Y_PLANE_DBUF( data, \ - data_back, \ - x_tm, \ - y_tm, \ - width_tm, \ - height_tm, \ - yuv, \ - __depth__) { \ - \ - register u_int##__depth__##_t t_val; \ - register unsigned char *yuv_Y = (yuv)->y + x_tm + y_tm * (yuv)->y_stride, \ - *_yr = Yr, *_yg = Yg, *_yb = Yb; \ - register u_int##__depth__##_t *datapi = (u_int##__depth__##_t *)data, \ - *datapi_back = (u_int##__depth__##_t *)data_back; \ - \ - for (int k = 0; k < height_tm; k++) { \ - for (int i = 0; i < width_tm; i++) { \ - if (*datapi != *datapi_back) { \ - t_val = *datapi; \ - *yuv_Y = _yr[__RVALUE_##__depth__(t_val)] + \ - _yg[__GVALUE_##__depth__(t_val)] + \ - _yb[__BVALUE_##__depth__(t_val)]; \ - yblocks[blocknum(x_tm + i, y_tm + k, (yuv)->y_width, Y_UNIT_WIDTH)] = 1;\ - } \ - datapi++; \ - datapi_back++; \ - yuv_Y++; \ - } \ - yuv_Y += (yuv)->y_stride - width_tm; \ - } \ -} - -#define UPDATE_UV_PLANES_DBUF( data, \ - data_back, \ - x_tm, \ - y_tm, \ - width_tm, \ - height_tm, \ - yuv, \ - sampling, \ - __depth__) { \ - \ - register u_int##__depth__##_t t_val; \ - register unsigned char *yuv_U = (yuv)->u + x_tm / 2 + \ - (y_tm * (yuv)->uv_width) / 2, \ - *yuv_V = (yuv)->v + x_tm / 2 + \ - (y_tm * (yuv)->uv_width) / 2, \ - *_ur = Ur, *_ug = Ug, *_ubvr = UbVr, \ - *_vg = Vg, *_vb = Vb; \ - \ - register u_int##__depth__##_t *datapi = (u_int##__depth__##_t *)data, \ - *datapi_next = NULL, \ - *datapi_back = (u_int##__depth__##_t *)data_back, \ - *datapi_back_next = NULL; \ - int w_odd = width_tm % 2, h_odd = height_tm % 2; \ - \ - if (sampling == __PXL_AVERAGE) { \ - datapi_next = datapi + width_tm; \ - datapi_back_next = datapi_back + width_tm; \ - \ - for (int k = 0; k < height_tm - h_odd; k += 2) { \ - for (int i = 0; i < width_tm - w_odd; i += 2) { \ - if ( (*datapi != *datapi_back || \ - (*(datapi + 1) != *(datapi_back + 1)) || \ - (*datapi_next != *datapi_back_next) || \ - (*(datapi_next + 1) != *(datapi_back_next + 1)))) { \ - \ - UPDATE_A_UV_PIXEL( yuv_U, \ - yuv_V, \ - t_val, \ - datapi, \ - datapi_next, \ - _ur,_ug,_ubvr,_vg,_vb, \ - sampling, \ - __depth__); \ - \ - ublocks[blocknum(x_tm + i, y_tm + k, (yuv)->y_width, Y_UNIT_WIDTH)] = 1; \ - vblocks[blocknum(x_tm + i, y_tm + k, (yuv)->y_width, Y_UNIT_WIDTH)] = 1; \ - } \ - \ - datapi += 2; \ - datapi_back += 2; \ - datapi_next += 2; \ - datapi_back_next += 2; \ - \ - yuv_U++; \ - yuv_V++; \ - } \ - \ - yuv_U += ((yuv)->y_stride - (width_tm - w_odd * 2)) >> 1; \ - yuv_V += ((yuv)->y_stride - (width_tm - w_odd * 2)) >> 1; \ - \ - datapi += width_tm + w_odd; \ - datapi_back += width_tm + w_odd; \ - datapi_next += width_tm + w_odd; \ - datapi_back_next += width_tm + w_odd; \ - } \ - } else { \ - for (int k = 0; k < height_tm - h_odd; k += 2) { \ - for (int i = 0; i < width_tm - w_odd; i += 2) { \ - if ((*datapi != *datapi_back)) { \ - UPDATE_A_UV_PIXEL( yuv_U, \ - yuv_V, \ - t_val, \ - datapi, \ - datapi_next, \ - _ur, _ug, _ubvr, _vg, _vb, \ - sampling, \ - __depth__); \ - \ - ublocks[blocknum(x_tm + i, y_tm + k, (yuv)->y_width, Y_UNIT_WIDTH)] = 1; \ - vblocks[blocknum(x_tm + i, y_tm + k, (yuv)->y_width, Y_UNIT_WIDTH)] = 1; \ - } \ - \ - datapi += 2; \ - datapi_back += 2; \ - \ - yuv_U++; \ - yuv_V++; \ - } \ - \ - yuv_U += ((yuv)->y_stride - (width_tm - w_odd * 2)) >> 1; \ - yuv_V += ((yuv)->y_stride - (width_tm - w_odd * 2)) >> 1; \ - \ - datapi += width_tm + w_odd; \ - datapi_back += width_tm + w_odd; \ - } \ - } \ -} - -void rmdUpdateYuvBuffer( yuv_buffer *yuv, - unsigned char *data, - unsigned char *data_back, - int x_tm, - int y_tm, - int width_tm, - int height_tm, - int sampling, - int depth) { - - if (data_back == NULL) { - switch (depth) { - case 24: - case 32: - UPDATE_Y_PLANE(data, x_tm, y_tm, width_tm, height_tm, yuv, 32); - UPDATE_UV_PLANES(data, x_tm, y_tm, width_tm, height_tm, yuv, sampling, 32); - break; - case 16: - UPDATE_Y_PLANE(data, x_tm, y_tm, width_tm, height_tm, yuv, 16); - UPDATE_UV_PLANES(data, x_tm, y_tm, width_tm, height_tm, yuv, sampling, 16); - break; - default: - assert(0); - } - } else { - switch (depth) { - case 24: - case 32: - UPDATE_Y_PLANE_DBUF(data, data_back, x_tm, y_tm, width_tm, height_tm, yuv, 32); - UPDATE_UV_PLANES_DBUF(data, data_back, x_tm, y_tm, width_tm, height_tm, yuv, sampling, 32); - break; - case 16: - UPDATE_Y_PLANE_DBUF(data, data_back, x_tm, y_tm, width_tm, height_tm, yuv, 16); - UPDATE_UV_PLANES_DBUF(data, data_back, x_tm, y_tm, width_tm, height_tm, yuv, sampling, 16); - break; - default: - assert(0); - } - } -} - -void rmdDummyPointerToYuv( yuv_buffer *yuv, - unsigned char *data_tm, - int x_tm, - int y_tm, - int width_tm, - int height_tm, - int x_offset, - int y_offset, - unsigned char no_pixel) { - - int i, k, j = 0; - int x_2 = x_tm / 2, y_2 = y_tm / 2, y_width_2 = yuv->y_width/2; - - for (k = y_offset; k < y_offset + height_tm; k++) { - for (i = x_offset; i < x_offset + width_tm; i++) { - j = k * 16 + i; - - if (data_tm[j * 4] != no_pixel) { - yuv->y[x_tm + (i - x_offset) + ((k - y_offset) + y_tm) * yuv->y_width] = - Yr[data_tm[j * 4 + __RBYTE]] + - Yg[data_tm[j * 4 + __GBYTE]] + - Yb[data_tm[j * 4 + __BBYTE]]; - - if ((k % 2) && (i % 2)) { - yuv->u[x_2 + (i - x_offset) / 2 + ((k - y_offset) / 2 + y_2) * y_width_2] = - Ur[data_tm[(k * width_tm + i) * 4 + __RBYTE]] + - Ug[data_tm[(k * width_tm + i) * 4 + __GBYTE]] + - UbVr[data_tm[(k * width_tm + i) * 4 + __BBYTE]]; - yuv->v[x_2 + (i - x_offset) / 2 + ((k - y_offset) / 2 + y_2) * y_width_2] = - UbVr[data_tm[(k * width_tm + i) * 4 + __RBYTE]] + - Vg[data_tm[(k * width_tm + i) * 4 + __GBYTE]] + - Vb[data_tm[(k * width_tm + i) * 4 + __BBYTE]] ; - } - } - } - } - -} - -static inline unsigned char avg_4_pixels( unsigned char *data_array, - int width_img, - int k_tm, - int i_tm, - int offset) -{ - - return ((data_array[(k_tm*width_img+i_tm)*RMD_ULONG_SIZE_T+offset]+ - data_array[((k_tm-1)*width_img+i_tm)*RMD_ULONG_SIZE_T+offset]+ - data_array[(k_tm*width_img+i_tm-1)*RMD_ULONG_SIZE_T+offset]+ - data_array[((k_tm-1)*width_img+i_tm-1)*RMD_ULONG_SIZE_T+offset])/4); -} - -void rmdXFixesPointerToYuv( yuv_buffer *yuv, - unsigned char *data_tm, - int x_tm, - int y_tm, - int width_tm, - int height_tm, - int x_offset, - int y_offset, - int column_discard_stride) { - - unsigned char avg0, avg1, avg2, avg3; - int x_2 = x_tm / 2, y_2 = y_tm / 2; - - for (int k = y_offset; k < y_offset + height_tm; k++) { - for (int i = x_offset;i < x_offset + width_tm; i++) { - int j = k * (width_tm + column_discard_stride) + i; - - yuv->y[x_tm + (i - x_offset) + (k + y_tm - y_offset) * yuv->y_width] = - (yuv->y[x_tm + (i - x_offset) + (k - y_offset + y_tm) * yuv->y_width] * - (UCHAR_MAX - data_tm[(j * RMD_ULONG_SIZE_T) + __ABYTE]) + - ( ( Yr[data_tm[(j * RMD_ULONG_SIZE_T) + __RBYTE]] + - Yg[data_tm[(j * RMD_ULONG_SIZE_T) + __GBYTE]] + - Yb[data_tm[(j * RMD_ULONG_SIZE_T) + __BBYTE]] ) % - ( UCHAR_MAX + 1 ) ) * - data_tm[(j * RMD_ULONG_SIZE_T) + __ABYTE]) / UCHAR_MAX; - - if ((k % 2) && (i % 2)) { - int idx = x_2 + (i - x_offset) / 2 + ((k - y_offset) / 2 + y_2) * yuv->uv_width; - - avg3 = avg_4_pixels( data_tm, - (width_tm + column_discard_stride), - k, i, __ABYTE); - avg2 = avg_4_pixels( data_tm, - (width_tm + column_discard_stride), - k, i, __RBYTE); - avg1 = avg_4_pixels( data_tm, - (width_tm + column_discard_stride), - k, i, __GBYTE); - avg0 = avg_4_pixels( data_tm, - (width_tm + column_discard_stride), - k, i, __BBYTE); - - yuv->u[idx] = - (yuv->u[idx] * (UCHAR_MAX - avg3) + - ((Ur[avg2] + Ug[avg1] + UbVr[avg0]) % (UCHAR_MAX + 1)) - * avg3) / UCHAR_MAX; - - yuv->v[idx]= - (yuv->u[idx] * (UCHAR_MAX - avg3) + - ((UbVr[avg2] + Vg[avg1] + Vb[avg0]) % (UCHAR_MAX + 1)) - * avg3) / UCHAR_MAX; - } - } - } -} diff --git a/recordmydesktop/src/rmd_yuv_utils.h b/recordmydesktop/src/rmd_yuv_utils.h deleted file mode 100644 index f92471a..0000000 --- a/recordmydesktop/src/rmd_yuv_utils.h +++ /dev/null @@ -1,83 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 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 * -******************************************************************************/ - -#ifndef YUV_UTILS_H -#define YUV_UTILS_H 1 - -#include "rmd_macro.h" -#include "rmd_types.h" - - -// The macros work directly on this data (for performance reasons I -// suppose) so we keep this global -extern unsigned char Yr[256], Yg[256], Yb[256], - Ur[256], Ug[256], UbVr[256], - Vg[256], Vb[256]; - - -// We keep these global for now. FIXME: Isolate them. -extern unsigned char *yblocks, - *ublocks, - *vblocks; - - -/** -* Fill Yr,Yg,Yb,Ur,Ug.Ub,Vr,Vg,Vb arrays(globals) with values. -*/ -void rmdMakeMatrices(void); - -/* update yuv from data and optionally data_back */ -void rmdUpdateYuvBuffer( yuv_buffer *yuv, - unsigned char *data, - unsigned char *data_back, - int x_tm, - int y_tm, - int width_tm, - int height_tm, - int sampling_type, - int color_depth); - -void rmdDummyPointerToYuv( yuv_buffer *yuv, - unsigned char *data_tm, - int x_tm, - int y_tm, - int width_tm, - int height_tm, - int x_offset, - int y_offset, - unsigned char no_pixel); - -void rmdXFixesPointerToYuv( yuv_buffer *yuv, - unsigned char *data_tm, - int x_tm, - int y_tm, - int width_tm, - int height_tm, - int x_offset, - int y_offset, - int column_discard_stride); - -#endif diff --git a/recordmydesktop/src/skeleton.c b/recordmydesktop/src/skeleton.c deleted file mode 100644 index 77567db..0000000 --- a/recordmydesktop/src/skeleton.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * skeleton.c - * author: Tahseen Mohammad - */ - -/* This file depends on WORDS_BIGENDIAN being defined to 1 if the host - * processor stores words with the most significant byte first (like Motorola - * and SPARC, unlike Intel and VAX). - * On little endian systems, WORDS_BIGENDIAN should be undefined. - * - * When using GNU Autotools, the correct value will be written into config.h - * if the autoconf macro AC_C_BIGENDIAN is called in configure.ac. - */ -#include "config.h" - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include <ogg/ogg.h> - -#include "skeleton.h" - -#ifdef WIN32 -#define snprintf _snprintf -#endif - -static unsigned short -_le_16 (unsigned short s) -{ - unsigned short ret=s; -#ifdef WORDS_BIGENDIAN - ret = (s>>8) & 0x00ffU; - ret += (s<<8) & 0xff00U; -#endif - return ret; -} - -static ogg_uint32_t -_le_32 (ogg_uint32_t i) -{ - ogg_uint32_t ret=i; -#ifdef WORDS_BIGENDIAN - ret = (i>>24); - ret += (i>>8) & 0x0000ff00; - ret += (i<<8) & 0x00ff0000; - ret += (i<<24); -#endif - return ret; -} - -static ogg_int64_t -_le_64 (ogg_int64_t l) -{ - ogg_int64_t ret=l; - unsigned char *ucptr = (unsigned char *)&ret; -#ifdef WORDS_BIGENDIAN - unsigned char temp; - - temp = ucptr [0] ; - ucptr [0] = ucptr [7] ; - ucptr [7] = temp ; - - temp = ucptr [1] ; - ucptr [1] = ucptr [6] ; - ucptr [6] = temp ; - - temp = ucptr [2] ; - ucptr [2] = ucptr [5] ; - ucptr [5] = temp ; - - temp = ucptr [3] ; - ucptr [3] = ucptr [4] ; - ucptr [4] = temp ; - -#endif - return (*(ogg_int64_t *)ucptr); -} - -/* write an ogg_page to a file pointer */ -int write_ogg_page_to_file(ogg_page *og, FILE *out) { - int written; - - written = fwrite(og->header,1, og->header_len, out); - if (written > 0) - written += fwrite(og->body,1, og->body_len, out); - - return written; -} - -int add_message_header_field(fisbone_packet *fp, - char *header_key, - char *header_value) { - - /* size of both key and value + ': ' + CRLF */ - int this_message_size = strlen(header_key) + strlen(header_value) + 4; - if (fp->message_header_fields == NULL) { - fp->message_header_fields = _ogg_calloc(this_message_size+1, sizeof(char)); - } else { - int new_size = (fp->current_header_size + this_message_size+1) * sizeof(char); - fp->message_header_fields = _ogg_realloc(fp->message_header_fields, new_size); - } - snprintf(fp->message_header_fields + fp->current_header_size, - this_message_size+1, - "%s: %s\r\n", - header_key, - header_value); - fp->current_header_size += this_message_size; - - return 0; -} - -/* create a ogg_packet from a fishead_packet structure */ -int ogg_from_fishead(fishead_packet *fp,ogg_packet *op) { - - if (!fp || !op) return -1; - - memset(op, 0, sizeof(*op)); - op->packet = _ogg_calloc(FISHEAD_SIZE, sizeof(unsigned char)); - if (!op->packet) return -1; - - memset(op->packet, 0, FISHEAD_SIZE); - - memcpy (op->packet, FISHEAD_IDENTIFIER, 8); /* identifier */ - *((ogg_uint16_t*)(op->packet+8)) = _le_16 (SKELETON_VERSION_MAJOR); /* version major */ - *((ogg_uint16_t*)(op->packet+10)) = _le_16 (SKELETON_VERSION_MINOR); /* version minor */ - *((ogg_int64_t*)(op->packet+12)) = _le_64 (fp->ptime_n); /* presentationtime numerator */ - *((ogg_int64_t*)(op->packet+20)) = _le_64 (fp->ptime_d); /* presentationtime denominator */ - *((ogg_int64_t*)(op->packet+28)) = _le_64 (fp->btime_n); /* basetime numerator */ - *((ogg_int64_t*)(op->packet+36)) = _le_64 (fp->btime_d); /* basetime denominator */ - /* TODO: UTC time, set to zero for now */ - - op->b_o_s = 1; /* its the first packet of the stream */ - op->e_o_s = 0; /* its not the last packet of the stream */ - op->bytes = FISHEAD_SIZE; /* length of the packet in bytes */ - - return 0; -} - -/* create a ogg_packet from a fisbone_packet structure. - * call this method after the fisbone_packet is filled and all message header fields are added - * by calling add_message_header_field method. - */ -int ogg_from_fisbone(fisbone_packet *fp,ogg_packet *op) { - - int packet_size; - - if (!fp || !op) return -1; - - packet_size = FISBONE_SIZE + fp->current_header_size; - - memset (op, 0, sizeof (*op)); - op->packet = _ogg_calloc (packet_size, sizeof(unsigned char)); - if (!op->packet) return -1; - - memset (op->packet, 0, packet_size); - memcpy (op->packet, FISBONE_IDENTIFIER, 8); /* identifier */ - *((ogg_uint32_t*)(op->packet+8)) = _le_32 (FISBONE_MESSAGE_HEADER_OFFSET); /* offset of the message header fields */ - *((ogg_uint32_t*)(op->packet+12)) = _le_32 (fp->serial_no); /* serialno of the respective stream */ - *((ogg_uint32_t*)(op->packet+16)) = _le_32 (fp->nr_header_packet); /* number of header packets */ - *((ogg_int64_t*)(op->packet+20)) = _le_64 (fp->granule_rate_n); /* granulrate numerator */ - *((ogg_int64_t*)(op->packet+28)) = _le_64 (fp->granule_rate_d); /* granulrate denominator */ - *((ogg_int64_t*)(op->packet+36)) = _le_64 (fp->start_granule); /* start granule */ - *((ogg_uint32_t*)(op->packet+44)) = _le_32 (fp->preroll); /* preroll, for theora its 0 */ - *(op->packet+48) = fp->granule_shift; /* granule shift */ - if (fp->message_header_fields) - memcpy((op->packet+FISBONE_SIZE), fp->message_header_fields, fp->current_header_size); - - - op->b_o_s = 0; - op->e_o_s = 0; - op->bytes = packet_size; /* size of the packet in bytes */ - - return 0; -} - -/* fills up a fishead_packet from memory */ -static int fishead_from_data (const unsigned char * data, int len, fishead_packet *fp) { - if (!data) return -1; - - if (memcmp(data, FISHEAD_IDENTIFIER, 8)) - return -1; - - fp->version_major = _le_16 (*((ogg_uint16_t*)(data+8))); /* version major */ - fp->version_minor = _le_16 (*((ogg_uint16_t*)(data+10))); /* version minor */ - fp->ptime_n = _le_64 (*((ogg_int64_t*)(data+12))); /* presentationtime numerator */ - fp->ptime_d = _le_64 (*((ogg_int64_t*)(data+20))); /* presentationtime denominator */ - fp->btime_n = _le_64 (*((ogg_int64_t*)(data+28))); /* basetime numerator */ - fp->btime_d = _le_64 (*((ogg_int64_t*)(data+36))); /* basetime denominator */ - memcpy(fp->UTC, data+44, 20); - - return 0; -} - -/* fills up a fishead_packet from a fishead ogg_packet of a skeleton bistream */ -int fishead_from_ogg (ogg_packet *op, fishead_packet *fp) { - return fishead_from_data (op->packet, op->bytes, fp); -} - -/* fills up a fishead_packet from a fishead ogg_page of a skeleton bistream */ -int fishead_from_ogg_page (const ogg_page *og, fishead_packet *fp) { - return fishead_from_data (og->body, og->body_len, fp); -} - -/* fills up a fisbone_packet from memory */ -static int fisbone_from_data (const unsigned char * data, int len, fisbone_packet *fp) { - - if (!fp) return -1; - - if (memcmp(data, FISBONE_IDENTIFIER, 8)) - return -1; - - fp->serial_no = _le_32 (*((ogg_uint32_t*)(data+12))); /* serialno of the stream represented by this fisbone packet */ - fp->nr_header_packet = _le_32 (*((ogg_uint32_t*)(data+16))); /* number of header packets */ - fp->granule_rate_n = _le_64 (*((ogg_int64_t*)(data+20))); /* granulrate numerator */ - fp->granule_rate_d = _le_64 (*((ogg_int64_t*)(data+28))); /* granulrate denominator */ - fp->start_granule = _le_64 (*((ogg_int64_t*)(data+36))); /* start granule */ - fp->preroll = _le_32 (*((ogg_uint32_t*)(data+44))); /* preroll, for theora its 0 */ - fp->granule_shift = *(data+48); /* granule shift */ - fp->current_header_size = len - FISBONE_SIZE; - fp->message_header_fields = _ogg_calloc(fp->current_header_size+1, sizeof(char)); - if (!fp->message_header_fields) return -1; - memcpy(fp->message_header_fields, data+FISBONE_SIZE, fp->current_header_size); - - return 0; -} - -/* fills up a fisbone_packet from a fisbone ogg_packet of a skeleton bitstream */ -int fisbone_from_ogg (ogg_packet *op, fisbone_packet *fp) { - return fisbone_from_data (op->packet, op->bytes, fp); -} - -/* fills up a fisbone_packet from a fisbone ogg_page of a skeleton bistream */ -int fisbone_from_ogg_page (const ogg_page *og, fisbone_packet *fp) { - return fisbone_from_data (og->body, og->body_len, fp); -} - -int fisbone_clear(fisbone_packet *fp) -{ - if (!fp) return -1; - _ogg_free(fp->message_header_fields); - return 0; -} - -int add_fishead_to_stream(ogg_stream_state *os, fishead_packet *fp) { - - ogg_packet op; - int ret; - - ret = ogg_from_fishead(fp, &op); - if (ret<0) return ret; - ogg_stream_packetin(os, &op); - _ogg_free(op.packet); - - return 0; -} - -int add_fisbone_to_stream(ogg_stream_state *os, fisbone_packet *fp) { - - ogg_packet op; - int ret; - - ret = ogg_from_fisbone(fp, &op); - if (ret<0) return ret; - ogg_stream_packetin(os, &op); - _ogg_free(op.packet); - - return 0; -} - -int add_eos_packet_to_stream(ogg_stream_state *os) { - - ogg_packet op; - - memset (&op, 0, sizeof(op)); - op.e_o_s = 1; - ogg_stream_packetin(os, &op); - - return 0; -} - -int flush_ogg_stream_to_file(ogg_stream_state *os, FILE *out) { - - ogg_page og; - int result; - - while((result = ogg_stream_flush(os, &og))) - { - if(!result) break; - result = write_ogg_page_to_file(&og, out); - if(result != og.header_len + og.body_len) - return 1; - } - - return 0; -} diff --git a/recordmydesktop/src/skeleton.h b/recordmydesktop/src/skeleton.h deleted file mode 100644 index d088e3e..0000000 --- a/recordmydesktop/src/skeleton.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * skeleton.h - * author: Tahseen Mohammad - */ - -#ifndef _SKELETON_H -#define _SKELETON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdio.h> -#include <ogg/ogg.h> - -#define SKELETON_VERSION_MAJOR 3 -#define SKELETON_VERSION_MINOR 0 -#define FISHEAD_IDENTIFIER "fishead\0" -#define FISBONE_IDENTIFIER "fisbone\0" -#define FISHEAD_SIZE 64 -#define FISBONE_SIZE 52 -#define FISBONE_MESSAGE_HEADER_OFFSET 44 - -/* fishead_packet holds a fishead header packet. */ -typedef struct { - ogg_uint16_t version_major; /* skeleton version major */ - ogg_uint16_t version_minor; /* skeleton version minor */ - /* Start time of the presentation - * For a new stream presentationtime & basetime is same. */ - ogg_int64_t ptime_n; /* presentation time numerator */ - ogg_int64_t ptime_d; /* presentation time denominator */ - ogg_int64_t btime_n; /* basetime numerator */ - ogg_int64_t btime_d; /* basetime denominator */ - /* will holds the time of origin of the stream, a 20 bit field. */ - unsigned char UTC[20]; -} fishead_packet; - -/* fisbone_packet holds a fisbone header packet. */ -typedef struct { - ogg_uint32_t serial_no; /* serial no of the corresponding stream */ - ogg_uint32_t nr_header_packet; /* number of header packets */ - /* granule rate is the temporal resolution of the logical bitstream */ - ogg_int64_t granule_rate_n; /* granule rate numerator */ - ogg_int64_t granule_rate_d; /* granule rate denominator */ - ogg_int64_t start_granule; /* start granule value */ - ogg_uint32_t preroll; /* preroll */ - unsigned char granule_shift; /* 1 byte value holding the granule shift */ - char *message_header_fields; /* holds all the message header fields */ - /* current total size of the message header fields, for realloc purpose, initially zero */ - ogg_uint32_t current_header_size; -} fisbone_packet; - -extern int write_ogg_page_to_file(ogg_page *og, FILE *out); -extern int add_message_header_field(fisbone_packet *fp, char *header_key, char *header_value); -/* remember to deallocate the returned ogg_packet properly */ -extern int ogg_from_fishead(fishead_packet *fp,ogg_packet *op); -extern int ogg_from_fisbone(fisbone_packet *fp,ogg_packet *op); -extern int fisbone_clear(fisbone_packet *fp); -extern int fishead_from_ogg(ogg_packet *op,fishead_packet *fp); -extern int fisbone_from_ogg(ogg_packet *op,fisbone_packet *fp); -extern int fishead_from_ogg_page(const ogg_page *og,fishead_packet *fp); -extern int fisbone_from_ogg_page(const ogg_page *og,fisbone_packet *fp); -extern int add_fishead_to_stream(ogg_stream_state *os, fishead_packet *fp); -extern int add_fisbone_to_stream(ogg_stream_state *os, fisbone_packet *fp); -extern int add_eos_packet_to_stream(ogg_stream_state *os); -extern int flush_ogg_stream_to_file(ogg_stream_state *os, FILE *out); - -#ifdef __cplusplus -} -#endif - -#endif /* _SKELETON_H */ - - - - - - diff --git a/recordmydesktop/src/test-rectinsert-data.c b/recordmydesktop/src/test-rectinsert-data.c deleted file mode 100644 index 9540a5f..0000000 --- a/recordmydesktop/src/test-rectinsert-data.c +++ /dev/null @@ -1,382 +0,0 @@ -/****************************************************************************** -* for recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2008 Martin Nordholts * -* * -* 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 * -* * -******************************************************************************/ - -#include "config.h" -#include "test-rectinsert-data.h" - -#include "test-rectinsert-types.h" - - -// Defines to increase readability of test data -#define O FALSE -#define E TRUE - - -RectInsertTestdataEntry rectinsert_test_data[] = { - - // Test #1 - - { "Put a rect in place", - - { 2, 2, 2, 2 }, - - { O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - // Test #2 - - { "Put a rect in place and make sure it gets an even size and position", - - { 15, 2, 4, 3 }, - - { O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - // Test #3 - - { "Put a new rect within an existing rect", - - { 14, 2, 4, 2 }, - - { O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - // Test #4 - - { "Put a new rect over an existing rect and make sure it beocomes even", - - { 1, 1, 3, 3 }, - - { E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - - // Test #5 - - { "Put a new rect that partly covers an existing rect", - - { 10, 4, 6, 6 }, - - { E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - // Test #6 - - { "Put new small heighted but wide rect over an existing rect area", - - { 0, 8, 20, 2 }, - - { E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - // Test #7 - - { "Put new small widthed but high rect over two existing rect areas", - - { 2, 2, 2, 18 }, - - { E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - // Test #8 - - { "Prepare for test 10", - - { 8, 14, 4, 4 }, - - { E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,E,E, E,E,O,O,O, O,O,O,O,O, - - O,O,E,E,O, O,O,O,E,E, E,E,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,E,E, E,E,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,E,E, E,E,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - // Test #9 - - { "Prepare for test 10 (again)", - - { 16, 14, 2, 2 }, - - { E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,E,E, E,E,O,O,O, O,E,E,O,O, - - O,O,E,E,O, O,O,O,E,E, E,E,O,O,O, O,E,E,O,O, - O,O,E,E,O, O,O,O,E,E, E,E,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,E,E, E,E,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O } }, - - - // Test #10 - - { "Put a rect that covers two separate rects", - - { 6, 12, 14, 8 }, - - { E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - E,E,E,E,O, O,O,O,O,O, O,O,O,O,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, E,E,E,E,E, E,O,O,O,O, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,O,O,O,O, O,O,O,O,O, O,O,O,O,O, - O,O,E,E,O, O,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - O,O,E,E,O, O,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - O,O,E,E,O, O,E,E,E,E, E,E,E,E,E, E,E,E,E,E } }, - - - // Test #11 - - { "Cover the whole area", - - { 0, 0, 20, 20 }, - - { E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, - E,E,E,E,E, E,E,E,E,E, E,E,E,E,E, E,E,E,E,E } }, - - - // Mark end of tests - - { NULL, } -}; - diff --git a/recordmydesktop/src/test-rectinsert-data.h b/recordmydesktop/src/test-rectinsert-data.h deleted file mode 100644 index 7957b30..0000000 --- a/recordmydesktop/src/test-rectinsert-data.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** -* for recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2008 Martin Nordholts * -* * -* 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 * -* * -******************************************************************************/ - -#ifndef TEST_RECTINSERT_DATA_H -#define TEST_RECTINSERT_DATA_H - -#include "test-rectinsert-types.h" - -extern RectInsertTestdataEntry rectinsert_test_data[]; - -#endif /* TEST_RECTINSERT_DATA_H */ diff --git a/recordmydesktop/src/test-rectinsert-types.h b/recordmydesktop/src/test-rectinsert-types.h deleted file mode 100644 index b39322a..0000000 --- a/recordmydesktop/src/test-rectinsert-types.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** -* for recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2008 Martin Nordholts * -* * -* 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 * -* * -******************************************************************************/ - -#ifndef TEST_RECTINSERT_TYPES_H -#define TEST_RECTINSERT_TYPES_H - - -#include "rmd_types.h" - - -#define STATE_WIDTH 20 -#define STATE_HEIGHT 20 - - -typedef struct RectInsertTestdataEntry { - const char *description; - XRectangle new_rect; - boolean expected_state[STATE_WIDTH * STATE_HEIGHT]; -} RectInsertTestdataEntry; - - -#endif /* TEST_RECTINSERT_TYPES_H */ diff --git a/recordmydesktop/src/test-rectinsert.c b/recordmydesktop/src/test-rectinsert.c deleted file mode 100644 index 71d2030..0000000 --- a/recordmydesktop/src/test-rectinsert.c +++ /dev/null @@ -1,177 +0,0 @@ -/****************************************************************************** -* for recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2008 Martin Nordholts * -* * -* 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 * -* * -******************************************************************************/ - -#include "config.h" -#include "rmd_rectinsert.h" - -#include "test-rectinsert-types.h" -#include "test-rectinsert-data.h" -#include "rmd_types.h" - - - -static void rmdSetPixel(boolean *state, int x, int y, boolean value) { - int index = y * STATE_WIDTH + x; - - // Guard against non-optimal implementations - if (index < 0 || index >= STATE_WIDTH * STATE_HEIGHT) { - return; - } - - state[y * STATE_WIDTH + x] = value; -} - -static boolean rmdGetPixel(boolean *state, int x, int y) { - int index = y * STATE_WIDTH + x; - - // Guard against non-optimal implementations - if (index < 0 || index >= STATE_WIDTH * STATE_HEIGHT) { - return FALSE; - } - - return state[y * STATE_WIDTH + x]; -} - -static void rmdWriteGeomToState(XRectangle *rect, boolean *state) { - int x, y; - - for (y = rect->y; y < rect->y + rect->height; y++) { - for (x = rect->x; x < rect->x + rect->width; x++) { - rmdSetPixel(state, x, y, TRUE); - } - } -} - -static void rmdClearState(boolean *state) { - int x, y; - - for (y = 0; y < STATE_HEIGHT; y++) { - for (x = 0; x < STATE_WIDTH; x++) { - rmdSetPixel(state, x, y, FALSE); - } - } -} - -static void rmdWarnIfNonOptimal(XRectangle *rect) { - if (rect->x < 0 || rect->x >= STATE_WIDTH || - rect->y < 0 || rect->y >= STATE_HEIGHT || - rect->width == 0 || rect->width > STATE_WIDTH || - rect->height == 0 || rect->height > STATE_HEIGHT) - { - // The rmdRectInsert() implementation is not optimal - printf(" Non-optimal rect (and rmdRectInsert() implementation) encountered!\n" - " rect x = %d, y = %d, width = %hu, height = %hu\n", - rect->x, - rect->y, - rect->width, - rect->height); - } -} - -static void GetState(RectArea *root, boolean *state) { - RectArea *current = root; - - rmdClearState(state); - - while (current) - { - rmdWarnIfNonOptimal(¤t->rect); - - rmdWriteGeomToState(¤t->rect, state); - - current = current->next; - } -} - -static boolean rmdStatesEqual(boolean *a, boolean *b) { - int x, y; - - for (y = 0; y < STATE_HEIGHT; y++) { - for (x = 0; x < STATE_WIDTH; x++) { - if (rmdGetPixel(a, x, y) != rmdGetPixel(b, x, y)) { - return FALSE; - } - } - } - - return TRUE; -} - -static void rmdPrintState(boolean *state) { - int x, y; - - for (y = 0; y < STATE_HEIGHT; y++) { - printf(" "); - - for (x = 0; x < STATE_WIDTH; x++) { - printf(rmdGetPixel(state, x, y) ? "X" : "O"); - printf(x != STATE_WIDTH - 1 ? "," : ""); - printf((x + 1) % 5 == 0 ? " " : ""); - } - - printf("\n"); - printf((y + 1) % 5 == 0 ? "\n" : ""); - } -} - -/** - * This program tests the rmdRectInsert() functionality by calling - * rmdRectInsert() with various testdata and after each call comparing - * the current state with a predefied set of expected states. - */ -int main(int argc, char **argv) { - boolean current_state[STATE_WIDTH * STATE_HEIGHT]; - RectArea *root = NULL; - int i = 0; - int result = 0; - - printf("== Testing rmdRectInsert() ==\n"); - - // Run until there we find end of tests data - while (rectinsert_test_data[i].description != NULL) { - - printf("Test #%d: %s\n", i + 1, rectinsert_test_data[i].description); - rmdRectInsert(&root, &rectinsert_test_data[i].new_rect); - GetState(root, current_state); - - if (!rmdStatesEqual(current_state, rectinsert_test_data[i].expected_state)) { - printf(" FAILURE!\n"); - printf(" Current state:\n"); - rmdPrintState(current_state); - - printf(" Expected state:\n"); - rmdPrintState(rectinsert_test_data[i].expected_state); - - // Just set to failure and keep going... - result = -1; - } - else { - printf(" PASS\n"); - } - - // Run next test - printf("\n"); - i++; - } - - return result; -} |