Add initial animator zoom code

This commit is contained in:
Matthew Allum 2005-05-15 23:16:19 +00:00
parent 3838ffe065
commit 9c9dad903c
12 changed files with 521 additions and 104 deletions

View File

@ -1,3 +1,21 @@
2005-05-16 mallum,,, <mallum@openedhand.com>
* clutter/Makefile.am:
* clutter/cltr-animator.c:
* clutter/cltr-animator.h:
* clutter/cltr-list.c: (distfunc), (cltr_list_new),
(cltr_list_get_active_cell_co_ords), (cltr_list_show),
(cltr_list_on_activate_cell), (cltr_list_handle_xevent),
(cltr_list_animate), (cltr_list_timeout_cb),
(cltr_list_update_layout), (cltr_list_paint):
* clutter/cltr-list.h:
* clutter/cltr-private.h:
* clutter/cltr.h:
* clutter/pixbuf.c: (load_png_file):
* examples/player.c:
* examples/select.c: (usage), (populate), (cell_activated), (main):
Work on animator zooming. Also build up select.c much
2005-05-14 mallum,,, <mallum@openedhand.com>
* clutter/cltr-animator.c:

View File

@ -2,6 +2,7 @@ source_h = pixbuf.h util.h fonts.h \
cltr.h \
cltr-private.h \
cltr-glu.h \
cltr-animator.h \
cltr-events.h \
cltr-texture.h \
cltr-widget.h \
@ -17,6 +18,7 @@ source_h = pixbuf.h util.h fonts.h \
source_c = pixbuf.c util.c fonts.c \
cltr-core.c \
cltr-glu.c \
cltr-animator.c \
cltr-texture.c \
cltr-widget.c \
cltr-events.c \

View File

@ -1,20 +1,61 @@
#include "cltr.h"
#include "cltr-animator.h"
#include "cltr-private.h"
typedef void (*CltrAnimatorFinishFunc) (CltrAnimator *anim, void *userdata) ;
struct CltrAnimator
struct CltrAnimator
{
CltrWidget *widget;
gint fps;
int steps;
int n_steps, step;
CltrAnimatorFinishFunc anim_finish_cb;
gpointer *anim_finish_data;
WidgetPaintMethod wrapped_paint_func;
int zoom_init_x1, zoom_init_y1, zoom_init_x2, zoom_init_y2;
int zoom_dest_x1, zoom_dest_y1, zoom_dest_x2, zoom_dest_y2;
};
static void
cltr_animator_wrapped_paint(CltrWidget *widget);
CltrAnimator*
cltr_animator_fullzoom_new(CltrWidget *widget,
int x1,
int y1,
int x2,
int y2)
{
CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator));
anim->zoom_init_x1 = x1;
anim->zoom_init_x2 = x2;
anim->zoom_init_y1 = y1;
anim->zoom_init_y2 = y2;
anim->zoom_dest_x1 = cltr_widget_abs_x(widget);
anim->zoom_dest_x2 = cltr_widget_abs_x2(widget);
anim->zoom_dest_y1 = cltr_widget_abs_y(widget);
anim->zoom_dest_y2 = cltr_widget_abs_y2(widget);
anim->wrapped_paint_func = widget->paint;
anim->widget = widget;
widget->anim = anim;
anim->n_steps = 10;
anim->step = 0;
anim->fps = 50;
return anim;
}
CltrAnimator*
cltr_animator_new(CltrWidget *widget)
{
return NULL;
}
void
@ -23,11 +64,110 @@ cltr_animator_set_args(CltrAnimator *anim)
}
void
cltr_animator_run(CltrAnimator *anim,
CltrAnimatorFinishFunc *finish_callback
gpointer *finish_data)
static void
cltr_animator_wrapped_paint(CltrWidget *widget)
{
CltrAnimator *anim = widget->anim;
float tx = 0.0, ty = 0.0;
float x1, x2, y1, y2;
/* zoom here */
float f = (float)anim->step/anim->n_steps;
int init_width = anim->zoom_init_x2 - anim->zoom_init_x1;
int dest_width = anim->zoom_dest_x2 - anim->zoom_dest_x1;
int init_height = anim->zoom_init_y2 - anim->zoom_init_y1;
int dest_height = anim->zoom_dest_y2 - anim->zoom_dest_y1;
float max_zoom_x = (float)dest_width/init_width;
float max_zoom_y = (float)dest_height/init_height;
float trans_y = ((float)anim->zoom_init_y1);
glPushMatrix();
CLTR_DBG("f is %f ( %i/%i ) max_zoom x: %f y: %f, zooming to %f, %f",
f, anim->step, anim->n_steps, max_zoom_x, max_zoom_y,
(f * max_zoom_x), (f * max_zoom_y));
#if 0
glTranslatef (0.0 /* - (float)(anim->zoom_dest_x1) * ( (max_zoom_x * f) )*/,
- trans_y * f * max_zoom_y,
0.0);
if ((f * max_zoom_x) > 1.0 && (f * max_zoom_y) > 1.0)
{
glScalef ((f * max_zoom_x), (f * max_zoom_y), 0.0);
}
#endif
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* glOrtho (0, widget->width, widget->height, 0, -1, 1); */
/* 800 -> 80, 800-80 = 720/n_steps = x , cur = 80 + x * (n_steps - steps) */
x2 = anim->zoom_init_x2 + ( ( ((float)anim->zoom_dest_x2 - anim->zoom_init_x2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) );
x1 = anim->zoom_init_x1 + ( ( ((float)anim->zoom_dest_x1 - anim->zoom_init_x1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) );
y1 = anim->zoom_init_y1 + ( ( ((float)anim->zoom_dest_y1 - anim->zoom_init_y1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) );
y2 = anim->zoom_init_y2 + ( ( ((float)anim->zoom_dest_y2 - anim->zoom_init_y2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) );
/*
glOrtho( anim->zoom_init_x1, x2-1,
anim->zoom_init_y2-1, anim->zoom_init_y1,
-1, 1);
*/
glOrtho( x1, x2-1, y2-1, y1,
-1, 1);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
anim->wrapped_paint_func(widget);
glPopMatrix();
/* reset here */
}
static gboolean
cltr_animator_timeout_cb(gpointer data)
{
CltrAnimator *anim = (CltrAnimator *)data;
anim->step++;
if (anim->step > anim->n_steps)
return FALSE;
cltr_widget_queue_paint(anim->widget);
return TRUE;
}
void
cltr_animator_run(CltrAnimator *anim,
CltrAnimatorFinishFunc finish_callback,
gpointer *finish_data)
{
anim->anim_finish_cb = finish_callback;
anim->anim_finish_data = finish_data;
anim->widget->paint = cltr_animator_wrapped_paint;
anim->step = 0;
g_timeout_add(FPS_TO_TIMEOUT(anim->fps),
cltr_animator_timeout_cb, anim);
}

28
clutter/cltr-animator.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef _HAVE_CLTR_ANIMATOR_H
#define _HAVE_CLTR_ANIMATOR_H
#include "cltr.h"
typedef struct CltrAnimator CltrAnimator;
typedef enum CltrAnimatorType
{
CltrAnimatorFullZoom
}
CltrAnimatorType;
typedef void (*CltrAnimatorFinishFunc) (CltrAnimator *anim, void *userdata) ;
CltrAnimator*
cltr_animator_fullzoom_new(CltrWidget *widget,
int x1,
int y1,
int x2,
int y2);
void
cltr_animator_run(CltrAnimator *anim,
CltrAnimatorFinishFunc finish_callback,
gpointer *finish_data);
#endif

View File

@ -4,13 +4,17 @@
#define ANIM_FPS 50
#define FPS_TO_TIMEOUT(t) (1000/(t))
typedef struct CltrListCell
struct CltrListCell
{
CltrRect rect;
Pixbuf *pixb;
CltrTexture *texture;
} CltrListCell;
Pixbuf *thumb_pixb;
CltrTexture *thumb_texture;
Pixbuf *text_pixb;
CltrTexture *text_texture;
};
struct CltrList
{
@ -20,8 +24,14 @@ struct CltrList
int cell_height;
int cell_width;
int n_cells;
CltrListCellActivate cell_activate_cb;
gpointer cell_activate_data;
CltrListState state;
int scroll_dir;
};
static void
@ -43,26 +53,28 @@ distfunc(CltrList *list, int d)
}
CltrListCell*
cltr_list_cell_new(CltrList *list)
cltr_list_cell_new(CltrList *list,
Pixbuf *thumb_pixb,
char *text)
{
CltrListCell *cell = NULL;
ClutterFont *font;
gchar buf[24];
PixbufPixel pixel = { 0xff, 0, 0, 0 }, font_pixel = { 255, 255, 255, 255};
PixbufPixel pixel = { 0, 0, 0, 0 }, font_pixel = { 255, 255, 255, 255};
font = font_new ("Sans Bold 48");
font = font_new ("Sans Bold 32");
cell = g_malloc0(sizeof(CltrListCell));
cell->pixb = pixbuf_new(list->cell_width, list->cell_height);
cell->thumb_pixb = thumb_pixb;
pixbuf_ref(cell->thumb_pixb);
cell->thumb_texture = cltr_texture_new(cell->thumb_pixb);
pixbuf_fill_rect(cell->pixb, 0, 0, -1, -1, &pixel);
cell->text_pixb = pixbuf_new(list->cell_width - (list->cell_width/4),
list->cell_height);
g_snprintf(&buf[0], 24, "%i %i %i", rand()%10, rand()%10, rand()%10);
font_draw(font, cell->pixb, buf, 10, 10, &font_pixel);
cell->texture = cltr_texture_new(cell->pixb);
pixbuf_fill_rect(cell->text_pixb, 0, 0, -1, -1, &pixel);
font_draw(font, cell->text_pixb, text, 0, 0, &font_pixel);
cell->text_texture = cltr_texture_new(cell->text_pixb);
return cell;
}
@ -91,25 +103,80 @@ cltr_list_new(int width,
return CLTR_WIDGET(list);
}
void
cltr_list_append_cell(CltrList *list, CltrListCell *cell)
{
list->cells = g_list_append(list->cells, cell);
if (!list->active_cell)
list->active_cell = g_list_first(list->cells);
list->n_cells++;
}
/*
* This is messy hack cos, cells arn't real widgets :(
*
*/
gboolean
cltr_list_get_active_cell_co_ords(CltrList *list,
int *x1,
int *y1,
int *x2,
int *y2)
{
if (list->active_cell)
{
CltrListCell *cell = list->active_cell->data;
*x1 = cltr_rect_x1(cell->rect);
*y1 = cltr_rect_y1(cell->rect);
*x2 = cltr_rect_x2(cell->rect);
*y2 = cltr_rect_y2(cell->rect);
return TRUE;
}
return FALSE;
}
static void
cltr_list_show(CltrWidget *widget)
{
CltrList *list = CLTR_LIST(widget);
CltrList *list = CLTR_LIST(widget);
CltrListCell *cell = NULL;
int n_items = 20, i;
list->active_cell_y = (widget->height / 2) - (list->cell_height/2);
/*
for (i=0; i<n_items; i++)
{
list->cells = g_list_append(list->cells, cltr_list_cell_new(list));
}
*/
list->active_cell = g_list_first(list->cells);
cell = list->active_cell->data;
cell->rect.y = list->active_cell_y;
list->state = CLTR_LIST_STATE_BROWSE;
cltr_list_update_layout(list);
cltr_widget_queue_paint(widget);
}
void
cltr_list_on_activate_cell(CltrList *list,
CltrListCellActivate callback,
gpointer *userdata)
{
list->cell_activate_cb = callback;
list->cell_activate_data = userdata;
}
static gboolean
cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev)
{
@ -134,7 +201,10 @@ cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev)
cltr_list_scroll_down(list);
break;
case XK_Return:
CLTR_DBG("Return");
if (list->cell_activate_cb && list->active_cell)
list->cell_activate_cb(list,
list->active_cell->data,
list->cell_activate_data);
break;
case XK_Left:
case XK_KP_Left:
@ -157,50 +227,61 @@ cltr_list_animate(CltrList *list)
CltrListCell *next_active = NULL, *cell_top = NULL;
cell_top = (CltrListCell *)g_list_nth_data(list->cells, 0);
int i = 0;
if (list->state == CLTR_LIST_STATE_SCROLL_UP)
for (;;)
{
cell_item = g_list_previous(list->active_cell);
if (!cell_item)
if (list->state == CLTR_LIST_STATE_SCROLL_UP)
{
list->state = CLTR_LIST_STATE_BROWSE;
return;
cell_item = g_list_previous(list->active_cell);
if (!cell_item)
{
list->state = CLTR_LIST_STATE_BROWSE;
return;
}
next_active = (CltrListCell *)cell_item->data;
if (next_active->rect.y < list->active_cell_y)
{
cell_top->rect.y += 1;
}
else
{
list->active_cell = cell_item;
list->state = CLTR_LIST_STATE_BROWSE;
return;
}
}
else if (list->state == CLTR_LIST_STATE_SCROLL_DOWN)
{
cell_item = g_list_next(list->active_cell);
if (!cell_item)
{
list->state = CLTR_LIST_STATE_BROWSE;
return;
}
next_active = (CltrListCell *)cell_item->data;
if (next_active->rect.y > list->active_cell_y)
{
cell_top->rect.y -= 1;
}
else
{
list->active_cell = cell_item;
list->state = CLTR_LIST_STATE_BROWSE;
return;
}
}
next_active = (CltrListCell *)cell_item->data;
if (++i > 10)
return;
if (next_active->rect.y < list->active_cell_y)
{
cell_top->rect.y += 10;
}
else
{
list->active_cell = cell_item;
list->state = CLTR_LIST_STATE_BROWSE;
}
}
else if (list->state == CLTR_LIST_STATE_SCROLL_DOWN)
{
cell_item = g_list_next(list->active_cell);
if (!cell_item)
{
list->state = CLTR_LIST_STATE_BROWSE;
return;
}
next_active = (CltrListCell *)cell_item->data;
if (next_active->rect.y > list->active_cell_y)
{
cell_top->rect.y -= 10;
}
else
{
list->active_cell = cell_item;
list->state = CLTR_LIST_STATE_BROWSE;
}
cltr_list_update_layout(list);
}
}
@ -226,6 +307,42 @@ cltr_list_timeout_cb(gpointer data)
}
}
static void
cltr_list_update_layout(CltrList *list)
{
GList *cell_item = NULL;
CltrListCell *cell = NULL;
int last;
cell_item = g_list_first(list->cells);
cell = (CltrListCell *)cell_item->data;
last = cell->rect.y;
while (cell_item)
{
float scale = 0.0;
cell = (CltrListCell *)cell_item->data;
cell->rect.y = last;
if (cell->rect.y + cell->rect.height >= 0)
{
scale = distfunc(list, cell->rect.y - list->active_cell_y);
cell->rect.width = list->cell_width * scale;
cell->rect.height = list->cell_height * scale;
cell->rect.x = (list->widget.width - cell->rect.width) / 2;
}
last = cell->rect.y + cell->rect.height;
cell_item = g_list_next(cell_item);
}
}
static void
cltr_list_paint(CltrWidget *widget)
@ -247,32 +364,26 @@ cltr_list_paint(CltrWidget *widget)
glEnable(GL_BLEND);
cltr_list_update_layout(list);
while (cell_item)
{
float scale = 0.0;
cell = (CltrListCell *)cell_item->data;
col.r = 0xff; col.g = 0; col.b = 0; col.a = 0xff;
cell->rect.y = last;
if (cell->rect.y + cell->rect.height >= 0)
{
scale = distfunc(list, cell->rect.y - list->active_cell_y);
cell = (CltrListCell *)cell_item->data;
cell->rect.width = list->cell_width * scale;
cell->rect.height = list->cell_height * scale;
cell->rect.x = (list->widget.width - cell->rect.width) / 2;
}
last = cell->rect.y + cell->rect.height;
scale = distfunc(list, cell->rect.y - list->active_cell_y);
if (last > 0 && cell->rect.y < list->widget.width) /* crappy clip */
{
glDisable(GL_TEXTURE_2D);
if (cell_item == list->active_cell && list->state == CLTR_LIST_STATE_BROWSE)
col.b = 0xff;
else
@ -298,15 +409,26 @@ cltr_list_paint(CltrWidget *widget)
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0, 1.0, 1.0, 1.0);
glColor4f(1.0, 1.0, 1.0, 1.0);
cltr_texture_render_to_gl_quad(cell->texture,
cltr_texture_render_to_gl_quad(cell->text_texture,
cltr_rect_x1(cell->rect) + 100,
cltr_rect_y1(cell->rect) + 10,
cltr_rect_x2(cell->rect) - 100,
cltr_rect_y2(cell->rect) - 10);
cltr_texture_render_to_gl_quad(cell->thumb_texture,
cltr_rect_x1(cell->rect),
cltr_rect_y1(cell->rect),
cltr_rect_x1(cell->rect) + 80 ,
cltr_rect_y1(cell->rect) + 60);
glDisable(GL_BLEND);
}
cell_item = g_list_next(cell_item);

View File

@ -5,8 +5,14 @@
typedef struct CltrList CltrList;
typedef struct CltrListCell CltrListCell;
#define CLTR_LIST(w) ((CltrList*)(w))
typedef void (*CltrListCellActivate) (CltrList *list,
CltrListCell *cell,
void *userdata) ;
typedef enum CltrListState
{
CLTR_LIST_STATE_LOADING ,
@ -17,6 +23,13 @@ typedef enum CltrListState
}
CltrListState;
CltrListCell*
cltr_list_cell_new(CltrList *list,
Pixbuf *thump_pixb,
char *text);
void
cltr_list_append_cell(CltrList *list, CltrListCell *cell);
CltrWidget*
cltr_list_new(int width,
@ -24,6 +37,19 @@ cltr_list_new(int width,
int cell_width,
int cell_height);
void
cltr_list_on_activate_cell(CltrList *list,
CltrListCellActivate callback,
gpointer *userdata);
gboolean
cltr_list_get_active_cell_co_ords(CltrList *list,
int *x1,
int *y1,
int *x2,
int *y2);
void
cltr_list_scroll_down(CltrList *list);

View File

@ -60,6 +60,10 @@ struct CltrWidget
WidgetUnfocusMethod focus_out;
WidgetXEventHandler xevent_handler;
/* Anim ref */
CltrAnimator *anim;
};
typedef struct ClutterMainContext ClutterMainContext;

View File

@ -72,11 +72,13 @@ typedef void (*CltrXEventCallback) (CltrWidget *widget,
#include "cltr-texture.h"
#include "cltr-events.h"
#include "cltr-widget.h"
#include "cltr-animator.h"
#include "cltr-window.h"
#include "cltr-overlay.h"
#include "cltr-label.h"
#include "cltr-button.h"
#include "cltr-photo-grid.h"
#include "cltr-list.h"
#include "cltr-video.h"
#endif

View File

@ -96,12 +96,14 @@ load_png_file( const char *file,
if (( color_type == PNG_COLOR_TYPE_GRAY ) ||
( color_type == PNG_COLOR_TYPE_RGB ))
png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); /* req 1.2.7 */
png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_BEFORE); /* req 1.2.7 */
if (( color_type == PNG_COLOR_TYPE_PALETTE )||
( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS )))
png_set_expand(png_ptr);
png_set_packswap(png_ptr);
png_read_update_info( png_ptr, info_ptr);
/* Now load the actual data */

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,22 +1,3 @@
/* GStreamer
* Copyright (C) 2003 Julien Moutte <julien@moutte.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <clutter/cltr.h>
int Paused = 0;

View File

@ -7,6 +7,85 @@ usage(char *progname)
exit(-1);
}
gboolean
populate(CltrList *list, char *path)
{
GDir *dir;
GError *error;
const gchar *entry = NULL;
int n_pixb = 0, i =0;
Pixbuf *default_thumb_pixb = NULL;
default_thumb_pixb = pixbuf_new_from_file("clutter-logo-800x600.png");
if (!default_thumb_pixb)
g_error( "failed to open clutter-logo-800x600.png\n");
if ((dir = g_dir_open (path, 0, &error)) == NULL)
{
/* handle this much better */
g_error( "failed to open '%s'\n", path);
return FALSE;
}
g_printf("One sec.");
while ((entry = g_dir_read_name (dir)) != NULL)
{
Pixbuf *pixb = default_thumb_pixb;
CltrListCell *cell;
gchar *nice_name = NULL;
gint i = 0;
if (!(g_str_has_suffix (entry, ".mpg") ||
g_str_has_suffix (entry, ".MPG") ||
g_str_has_suffix (entry, ".mpg4") ||
g_str_has_suffix (entry, ".MPG4") ||
g_str_has_suffix (entry, ".avi") ||
g_str_has_suffix (entry, ".AVI")))
{
continue;
}
nice_name = g_strdup(entry);
i = strlen(nice_name) - 1;
while (i-- && nice_name[i] != '.') ;
if (i > 0)
nice_name[i] = '\0';
cell = cltr_list_cell_new(list, pixb, nice_name);
cltr_list_append_cell(list, cell);
g_free(nice_name);
g_printf(".");
}
g_dir_close (dir);
g_printf("\n");
return TRUE;
}
void
cell_activated (CltrList *list,
CltrListCell *cell,
void *userdata)
{
int x1, y1, x2, y2;
CltrAnimator *anim = NULL;
cltr_list_get_active_cell_co_ords(CLTR_LIST(list), &x1, &y1, &x2, &y2);
anim = cltr_animator_fullzoom_new(CLTR_LIST(list), x1, y1, x1+80, y1+60);
cltr_animator_run(anim, NULL, NULL);
}
int
main(int argc, char **argv)
{
@ -15,18 +94,20 @@ main(int argc, char **argv)
CltrFont *font = NULL;
PixbufPixel col = { 0xff, 0, 0, 0xff };
gchar *img_path = NULL;
gchar *movie_path = NULL;
gboolean want_fullscreen = FALSE;
gint cols = 3;
CltrAnimator *anim = NULL;
cltr_init(&argc, &argv);
for (i = 1; i < argc; i++)
{
if (!strcmp ("--image-path", argv[i]) || !strcmp ("-i", argv[i]))
if (!strcmp ("--movie-path", argv[i]) || !strcmp ("-i", argv[i]))
{
if (++i>=argc) usage (argv[0]);
img_path = argv[i];
movie_path = argv[i];
continue;
}
if (!strcmp ("--cols", argv[i]) || !strcmp ("-c", argv[i]))
@ -48,6 +129,12 @@ main(int argc, char **argv)
usage(argv[0]);
}
if (!movie_path)
{
g_error("usage: %s -i <movies path>", argv[0]);
exit(-1);
}
win = cltr_window_new(800, 600);
if (want_fullscreen)
@ -55,11 +142,16 @@ main(int argc, char **argv)
list = cltr_list_new(800, 600, 800, 600/5);
if (!populate(list, movie_path))
exit(-1);
cltr_widget_add_child(win, list, 0, 0);
cltr_window_focus_widget(CLTR_WINDOW(win), list);
cltr_widget_show_all(win);
cltr_list_on_activate_cell(CLTR_LIST(list), cell_activated, NULL);
cltr_main_loop();
}