Implemented a configuration file (with settings global and per device)

This commit is contained in:
Pierre Pronchery 2014-02-22 01:54:24 +01:00
parent 6af7352c10
commit 67a98b9120
5 changed files with 216 additions and 18 deletions

View File

@ -128,6 +128,10 @@ struct _Camera
/* prototypes */
/* accessors */
static String * _camera_get_config_filename(Camera * camera, char const * name);
/* useful */
static int _camera_error(Camera * camera, char const * message, int ret);
static int _camera_ioctl(Camera * camera, unsigned long request,
@ -182,7 +186,7 @@ static DesktopToolbar _camera_toolbar[] =
/* functions */
/* camera_new */
Camera * camera_new(GtkWidget * window, GtkAccelGroup * group,
char const * device, int hflip, int vflip)
char const * device)
{
Camera * camera;
GtkWidget * vbox;
@ -191,12 +195,10 @@ Camera * camera_new(GtkWidget * window, GtkAccelGroup * group,
if((camera = object_new(sizeof(*camera))) == NULL)
return NULL;
/* FIXME implement a preferences file */
if(device == NULL)
device = "/dev/video0";
camera->device = string_new(device);
camera->hflip = hflip ? TRUE : FALSE;
camera->vflip = vflip ? TRUE : FALSE;
camera->device = (device != NULL)
? string_new(device) : string_new("/dev/video0");
camera->hflip = FALSE;
camera->vflip = FALSE;
camera->ratio = TRUE;
camera->interp = GDK_INTERP_BILINEAR;
camera->source = 0;
@ -323,6 +325,27 @@ GtkWidget * camera_get_widget(Camera * camera)
}
/* camera_set_aspect_ratio */
void camera_set_aspect_ratio(Camera * camera, gboolean ratio)
{
camera->ratio = ratio;
}
/* camera_set_hflip */
void camera_set_hflip(Camera * camera, gboolean flip)
{
camera->hflip = flip;
}
/* camera_set_vflip */
void camera_set_vflip(Camera * camera, gboolean flip)
{
camera->vflip = flip;
}
/* useful */
/* camera_add_overlay */
CameraOverlay * camera_add_overlay(Camera * camera, char const * filename,
@ -341,6 +364,61 @@ CameraOverlay * camera_add_overlay(Camera * camera, char const * filename,
}
/* camera_load */
char const * _load_variable(Camera * camera, Config * config,
char const * variable);
int camera_load(Camera * camera)
{
int ret = 0;
char * filename;
Config * config;
char const * p;
if((filename = _camera_get_config_filename(camera, CAMERA_CONFIG_FILE))
== NULL)
return -1;
if((config = config_new()) == NULL
|| config_load(config, filename) != 0)
ret = -1;
else
{
/* horizontal flipping */
camera->hflip = FALSE;
if((p = _load_variable(camera, config, "hflip")) != NULL
&& strtoul(p, NULL, 0) != 0)
camera->hflip = TRUE;
/* vertical flipping */
camera->vflip = FALSE;
if((p = _load_variable(camera, config, "vflip")) != NULL
&& strtoul(p, NULL, 0) != 0)
camera->vflip = TRUE;
/* aspect ratio */
camera->ratio = TRUE;
if((p = _load_variable(camera, config, "ratio")) != NULL
&& strtoul(p, NULL, 0) == 0)
camera->ratio = FALSE;
/* FIXME also implement interpolation and overlay images */
}
if(config != NULL)
config_delete(config);
free(filename);
return ret;
}
char const * _load_variable(Camera * camera, Config * config,
char const * variable)
{
char const * ret;
/* check for any value specific to this camera */
if((ret = config_get(config, camera->device, variable)) != NULL)
return ret;
/* return the global value set (if any) */
return config_get(config, NULL, variable);
}
/* camera_open_gallery */
void camera_open_gallery(Camera * camera)
{
@ -357,6 +435,41 @@ void camera_open_gallery(Camera * camera)
}
/* camera_save */
static int _save_variable_bool(Camera * camera, Config * config,
char const * variable, gboolean value);
int camera_save(Camera * camera)
{
int ret = -1;
char * filename;
Config * config;
if((filename = _camera_get_config_filename(camera, CAMERA_CONFIG_FILE))
== NULL)
return -1;
if((config = config_new()) != NULL
&& access(filename, R_OK) == 0
&& config_load(config, filename) == 0)
{
/* XXX may fail */
_save_variable_bool(camera, config, "hflip", camera->hflip);
_save_variable_bool(camera, config, "vflip", camera->vflip);
_save_variable_bool(camera, config, "ratio", camera->ratio);
/* FIXME also implement interpolation and overlay images */
ret = config_save(config, filename);
}
free(filename);
return 0;
}
static int _save_variable_bool(Camera * camera, Config * config,
char const * variable, gboolean value)
{
return config_set(config, camera->device, variable, value ? "1" : "0");
}
/* camera_show_preferences */
static void _preferences_apply(Camera * camera);
static void _preferences_cancel(Camera * camera);
@ -427,7 +540,7 @@ static void _preferences_cancel(Camera * camera)
static void _preferences_save(Camera * camera)
{
/* FIXME implement */
camera_save(camera);
}
static void _preferences_window(Camera * camera)
@ -829,6 +942,19 @@ void camera_stop(Camera * camera)
/* private */
/* functions */
/* accessors */
/* camera_get_config_filename */
static String * _camera_get_config_filename(Camera * camera, char const * name)
{
char const * homedir;
if((homedir = getenv("HOME")) == NULL)
homedir = g_get_home_dir();
return string_new_append(homedir, "/", name, NULL);
}
/* useful */
/* camera_error */
static int _error_text(char const * message, int ret);

View File

@ -21,6 +21,11 @@
# include "overlay.h"
/* Camera */
/* defaults */
# define CAMERA_CONFIG_FILE ".camera"
/* public */
/* types */
typedef struct _Camera Camera;
@ -34,12 +39,16 @@ typedef enum _CameraSnapshotFormat
/* functions */
Camera * camera_new(GtkWidget * window, GtkAccelGroup * group,
char const * device, int hflip, int vflip);
char const * device);
void camera_delete(Camera * camera);
/* accessors */
GtkWidget * camera_get_widget(Camera * camera);
void camera_set_aspect_ratio(Camera * camera, gboolean ratio);
void camera_set_hflip(Camera * camera, gboolean flip);
void camera_set_vflip(Camera * camera, gboolean flip);
/* useful */
void camera_open_gallery(Camera * camera);
@ -48,6 +57,9 @@ int camera_snapshot(Camera * camera, CameraSnapshotFormat format);
void camera_show_preferences(Camera * camera, gboolean show);
void camera_show_properties(Camera * camera, gboolean show);
int camera_load(Camera * camera);
int camera_save(Camera * camera);
void camera_start(Camera * camera);
void camera_stop(Camera * camera);

View File

@ -64,8 +64,13 @@ static int _camera(int embedded, char const * device, int hflip, int vflip,
if(embedded != 0)
return _camera_embedded(device, hflip, vflip, overlay);
if((camera = camerawindow_new(device, hflip, vflip)) == NULL)
if((camera = camerawindow_new(device)) == NULL)
return error_print(PACKAGE);
camerawindow_load(camera);
if(hflip >= 0)
camerawindow_set_hflip(camera, hflip ? TRUE : FALSE);
if(vflip >= 0)
camerawindow_set_vflip(camera, vflip ? TRUE : FALSE);
if(overlay != NULL)
camerawindow_add_overlay(camera, overlay, 50);
gtk_main();
@ -85,12 +90,16 @@ static int _camera_embedded(char const * device, int hflip, int vflip,
gtk_widget_realize(window);
g_signal_connect_swapped(window, "embedded", G_CALLBACK(
_embedded_on_embedded), window);
if((camera = camera_new(window, NULL, device, hflip, vflip)) == NULL)
if((camera = camera_new(window, NULL, device)) == NULL)
{
error_print(PACKAGE);
gtk_widget_destroy(window);
return -1;
}
if(hflip >= 0)
camera_set_hflip(camera, hflip ? TRUE : FALSE);
if(vflip >= 0)
camera_set_vflip(camera, vflip ? TRUE : FALSE);
if(overlay != NULL)
camera_add_overlay(camera, overlay, 50);
widget = camera_get_widget(camera);
@ -127,8 +136,10 @@ static int _usage(void)
fprintf(stderr, _("Usage: %s [-d device][-O filename][-HVx]\n"
" -d Video device to open\n"
" -H Flip horizontally\n"
" -h Do not flip horizontally\n"
" -O Use this file as an overlay\n"
" -V Flip vertically\n"
" -v Do not flip vertically\n"
" -x Start in embedded mode\n"), PROGNAME);
return 1;
}
@ -142,8 +153,8 @@ int main(int argc, char * argv[])
int o;
int embedded = 0;
char const * device = NULL;
int hflip = 0;
int vflip = 0;
int hflip = -1;
int vflip = -1;
char const * overlay = NULL;
if(setlocale(LC_ALL, "") == NULL)
@ -151,7 +162,7 @@ int main(int argc, char * argv[])
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
gtk_init(&argc, &argv);
while((o = getopt(argc, argv, "d:HO:Vx")) != -1)
while((o = getopt(argc, argv, "d:HhO:Vvx")) != -1)
switch(o)
{
case 'd':
@ -160,12 +171,18 @@ int main(int argc, char * argv[])
case 'H':
hflip = 1;
break;
case 'h':
hflip = 0;
break;
case 'O':
overlay = optarg;
break;
case 'V':
vflip = 1;
break;
case 'v':
vflip = 0;
break;
case 'x':
embedded = 1;
break;

View File

@ -155,7 +155,7 @@ static const DesktopMenubar _camerawindow_menubar[] =
/* public */
/* functions */
/* camerawindow_new */
CameraWindow * camerawindow_new(char const * device, int hflip, int vflip)
CameraWindow * camerawindow_new(char const * device)
{
CameraWindow * camera;
GtkAccelGroup * group;
@ -171,8 +171,7 @@ CameraWindow * camerawindow_new(char const * device, int hflip, int vflip)
if(camera->window != NULL)
{
gtk_widget_realize(camera->window);
camera->camera = camera_new(camera->window, group, device,
hflip, vflip);
camera->camera = camera_new(camera->window, group, device);
}
if(camera->camera == NULL)
{
@ -221,6 +220,13 @@ void camerawindow_delete(CameraWindow * camera)
/* accessors */
/* camerawindow_set_aspect_ratio */
void camerawindow_set_aspect_ratio(CameraWindow * camera, gboolean ratio)
{
camera_set_aspect_ratio(camera->camera, ratio);
}
/* camerawindow_set_fullscreen */
void camerawindow_set_fullscreen(CameraWindow * camera, int fullscreen)
{
@ -231,6 +237,20 @@ void camerawindow_set_fullscreen(CameraWindow * camera, int fullscreen)
}
/* camerawindow_set_hflip */
void camerawindow_set_hflip(CameraWindow * camera, gboolean flip)
{
camera_set_hflip(camera->camera, flip);
}
/* camerawindow_set_vflip */
void camerawindow_set_vflip(CameraWindow * camera, gboolean flip)
{
camera_set_vflip(camera->camera, flip);
}
/* useful */
/* camerawindow_add_overlay */
CameraOverlay * camerawindow_add_overlay(CameraWindow * camera,
@ -240,6 +260,21 @@ CameraOverlay * camerawindow_add_overlay(CameraWindow * camera,
}
/* camerawindow_load */
int camerawindow_load(CameraWindow * camera)
{
return camera_load(camera->camera);
}
/* camerawindow_save */
int camerawindow_save(CameraWindow * camera)
{
return camera_save(camera->camera);
}
/* private */
/* callbacks */
/* camerawindow_on_close */
static void _camerawindow_on_close(gpointer data)

View File

@ -27,14 +27,22 @@ typedef struct _CameraWindow CameraWindow;
/* functions */
CameraWindow * camerawindow_new(char const * device, int hflip, int vflip);
CameraWindow * camerawindow_new(char const * device);
void camerawindow_delete(CameraWindow * camera);
/* accessors */
void camerawindow_set_aspect_ratio(CameraWindow * camera, gboolean ratio);
void camerawindow_set_fullscreen(CameraWindow * camera, int fullscreen);
void camerawindow_set_hflip(CameraWindow * camera, gboolean flip);
void camerawindow_set_vflip(CameraWindow * camera, gboolean flip);
/* useful */
CameraOverlay * camerawindow_add_overlay(CameraWindow * camera,
char const * filename, int opacity);
int camerawindow_load(CameraWindow * window);
int camerawindow_save(CameraWindow * window);
#endif /* !CAMERA_WINDOW_H */