* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "omplrclnt.h"
+int omnplay_get_content(omnplay_instance_t* app, playlist_item_t *items, int limit,
+ omnplay_get_content_cb_proc proc, void* data)
+{
+ int r, c = 0;
+ OmPlrClipInfo clip_info;
+ char clip_name[omPlrMaxClipDirLen];
+
+ pthread_mutex_lock(&app->players.lock);
+
+ r = OmPlrClipGetFirst((OmPlrHandle)app->players.item[0].handle, clip_name, sizeof(clip_name));
+ for(; c < limit && !r;)
+ {
+ /* get clip info */
+ clip_info.maxMsTracks = 0;
+ clip_info.size = sizeof(clip_info);
+
+ r = OmPlrClipGetInfo((OmPlrHandle)app->players.item[0].handle, clip_name, &clip_info);
+
+ if(!r)
+ {
+ /* copy item props */
+ strncpy(items[c].id, clip_name, PATH_MAX);
+ items[c].in = clip_info.firstFrame;
+ items[c].dur = clip_info.lastFrame - clip_info.firstFrame;
+
+ /* callback */
+ pthread_mutex_unlock(&app->players.lock);
+ if(proc)
+ proc(app, &items[c], data);
+ pthread_mutex_lock(&app->players.lock);
+
+ c++;
+ };
+
+ r = OmPlrClipGetNext((OmPlrHandle)app->players.item[0].handle, clip_name, sizeof(clip_name));
+ };
+
+ pthread_mutex_unlock(&app->players.lock);
+
+ return c;
+};
+
+
static gboolean on_main_window_delete_event( GtkWidget *widget, GdkEvent *event, gpointer user_data )
{
- gtk_exit(0);
- return TRUE;
+ g_print ("delete event occurred [start]\n");
+ gdk_threads_leave();
+ omnplay_release((omnplay_instance_t*)user_data);
+ gdk_threads_enter();
+ g_print ("delete event occurred [finish]\n");
+
+ return FALSE;
+}
+
+static void on_main_window_destroy( GtkWidget *widget, gpointer user_data )
+{
+ g_print ("destroy occurred\n");
+ gtk_main_quit();
}
omnplay_instance_t* omnplay_create(int argc, char** argv)
free(app);
};
+static int find_index_of_playlist_item(omnplay_instance_t* app, int start, int idx)
+{
+ while(1)
+ {
+ if(app->playlist.item[start].omn_idx == idx)
+ return start;
+
+ if(app->playlist.item[start].type & OMNPLAY_PLAYLIST_BLOCK_END)
+ break;
+
+ start++;
+ };
+
+ return -1;
+};
+
static void omnplay_update_status(omnplay_player_t* player, OmPlrStatus *prev , OmPlrStatus *curr)
{
+ int idx;
char tc_cur[32], tc_rem[32], state[32], status[32];
const char *clip;
strcpy(status, "OFFLINE");
};
+ /* update status in status page */
gdk_threads_enter();
gtk_label_set_text(GTK_LABEL (player->label_tc_cur), tc_cur);
gtk_label_set_text(GTK_LABEL (player->label_tc_rem), tc_rem);
gdk_flush();
gdk_threads_leave();
+ /* update remaining time */
+ gdk_threads_enter();
+ pthread_mutex_lock(&player->app->playlist.lock);
+ pthread_mutex_lock(&player->app->players.lock);
+ if(curr->state == omPlrStatePlay || curr->state == omPlrStateCuePlay)
+ {
+ idx = find_index_of_playlist_item(player->app, player->playlist_start, curr->currClipNum);
+ if(idx >= 0)
+ {
+ frames2tc(curr->currClipStartPos + curr->currClipLen - curr->pos, 25.0, tc_rem);
+ omnplay_playlist_draw_item_rem(player->app, idx, tc_rem);
+ }
+ if(curr->currClipNum != prev->currClipNum && 1 != prev->numClips)
+ {
+ tc_rem[0] = 0;
+ idx = find_index_of_playlist_item(player->app, player->playlist_start, prev->currClipNum);
+ if(idx >= 0)
+ omnplay_playlist_draw_item_rem(player->app, idx, tc_rem);
+ };
+ }
+ else
+ {
+ tc_rem[0] = 0;
+ idx = find_index_of_playlist_item(player->app, player->playlist_start, curr->currClipNum);
+ if(idx >= 0)
+ omnplay_playlist_draw_item_rem(player->app, idx, tc_rem);
+ idx = find_index_of_playlist_item(player->app, player->playlist_start, prev->currClipNum);
+ if(idx >= 0)
+ omnplay_playlist_draw_item_rem(player->app, idx, tc_rem);
+ };
+ pthread_mutex_unlock(&player->app->players.lock);
+ pthread_mutex_unlock(&player->app->playlist.lock);
+ gdk_flush();
+ gdk_threads_leave();
+
+
memcpy(prev, curr, sizeof(OmPlrStatus));
};
if(player->app->players.path[0])
{
pthread_mutex_lock(&player->app->players.lock);
-// r = OmPlrClipSetDirectory((OmPlrHandle)player->handle, player->app->players.path);
+ r = OmPlrClipSetDirectory((OmPlrHandle)player->handle, player->app->players.path);
pthread_mutex_unlock(&player->app->players.lock);
if(r)
return NULL;
};
-static int get_first_selected_item_playlist(omnplay_instance_t* app)
+void get_selected_items_playlist_proc(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
- int idx;
- GtkTreeIter iter;
- GtkTreeModel *model;
+ int idx, *list = (int*)data;
+ gtk_tree_model_get(model, iter, 7, &idx, -1);
+ list[list[0] + 1] = idx;
+ list[0] = list[0] + 1;
+};
+
+static int* get_selected_items_playlist(omnplay_instance_t* app)
+{
+ int* list = NULL;
GtkTreeSelection *selection;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(app->playlist_grid));
- if(selection && gtk_tree_selection_get_selected(selection, &model, &iter))
+ if(selection)
+ {
+ list = (int*)malloc(sizeof(int) * (MAX_PLAYLIST_ITEMS + 1));
+ memset(list, 0, sizeof(int) * (MAX_PLAYLIST_ITEMS + 1));
+
+ gtk_tree_selection_selected_foreach(
+ selection,
+ get_selected_items_playlist_proc,
+ list);
+
+ if(!list[0])
+ {
+ free(list);
+ list = NULL;
+ };
+ };
+
+ return list;
+};
+
+static int idx_in_players_range(omnplay_instance_t* app, int idx)
+{
+ int i, r = 0;
+
+ for(i = 0; i < app->players.count && !r; i++)
{
- gtk_tree_model_get(model, &iter, 7, &idx, -1);
- return idx;
+ int a, b;
+
+ a = app->players.item[i].playlist_start;
+ b = app->players.item[i].playlist_length;
+
+ if(b <= 0)
+ continue;
+
+ b = a + b - 1;
+
+ if(idx >= a && idx <= b) r = 1;
};
- return -1;
+
+ return r;
+};
+
+static int idxs_in_players_range(omnplay_instance_t* app, int start, int stop)
+{
+ int i, r = 0;
+
+ for(i = 0; i < app->players.count && !r; i++)
+ {
+ int a, b;
+
+ a = app->players.item[i].playlist_start;
+ b = app->players.item[i].playlist_length;
+
+ if(b <= 0)
+ continue;
+
+ b = a + b - 1;
+
+#define IN_RANGE(A,B,C) (A <= C && C <= B)
+ if( IN_RANGE(a,b,start) ||
+ IN_RANGE(a,b,stop) ||
+ IN_RANGE(start,stop,a) ||
+ IN_RANGE(start,stop,b))
+ r = 1;
+ };
+
+ return r;
+};
+
+static void omnplay_playlist_block(omnplay_instance_t* app, control_buttons_t button)
+{
+ int start, stop, r, i;
+ int* list = get_selected_items_playlist(app);
+
+ if(!list)
+ return;
+
+ pthread_mutex_lock(&app->playlist.lock);
+ pthread_mutex_lock(&app->players.lock);
+
+ start = list[1];
+ stop = list[list[0]];
+
+ if(!idxs_in_players_range(app, start, stop))
+ {
+ int loop = (button == BUTTON_PLAYLIST_BLOCK_LOOP)?OMNPLAY_PLAYLIST_BLOCK_LOOP:0;
+
+ /* update selected item */
+ for(i = start; i <= stop; i++)
+ {
+ int t = OMNPLAY_PLAYLIST_BLOCK_BODY | loop;
+
+ if(i == start) t |= OMNPLAY_PLAYLIST_BLOCK_BEGIN;
+ if(i == stop) t |= OMNPLAY_PLAYLIST_BLOCK_END;
+
+ app->playlist.item[i].type = (playlist_item_type_t)t;
+
+ omnplay_playlist_draw_item(app, i);
+ };
+
+ /* update border items */
+ if(!start && !(app->playlist.item[start - 1].type & OMNPLAY_PLAYLIST_BLOCK_END))
+ {
+ app->playlist.item[start - 1].type = (playlist_item_type_t)(OMNPLAY_PLAYLIST_BLOCK_END
+ | app->playlist.item[start - 1].type);
+ omnplay_playlist_draw_item(app, start - 1);
+ };
+ if((stop + 1) < app->playlist.count && !(app->playlist.item[stop + 1].type & OMNPLAY_PLAYLIST_BLOCK_BEGIN))
+ {
+ app->playlist.item[stop + 1].type = (playlist_item_type_t)(OMNPLAY_PLAYLIST_BLOCK_BEGIN
+ | app->playlist.item[stop + 1].type);
+ omnplay_playlist_draw_item(app, stop + 1);
+ };
+ }
+ else
+ fprintf(stderr, "omnplay_playlist_block: range [%d %d] do OVERLAP player\n",
+ start, stop);
+
+ pthread_mutex_unlock(&app->players.lock);
+ pthread_mutex_unlock(&app->playlist.lock);
+
+ free(list);
+};
+
+static int get_first_selected_item_playlist(omnplay_instance_t* app)
+{
+ int idx;
+ int* list = get_selected_items_playlist(app);
+ if(!list) return -1;
+ idx = list[1];
+ free(list);
+ return idx;
};
static int get_playlist_block(omnplay_instance_t* app, int idx, int* start_ptr, int* stop_ptr)
return NULL;
};
-static void omnplay_cue(omnplay_instance_t* app)
+static void omnplay_playlist_delete_items(omnplay_instance_t* app, int* idxs, int count)
+{
+ int i, j, idx;
+ GtkTreePath* path;
+
+ pthread_mutex_lock(&app->playlist.lock);
+ pthread_mutex_lock(&app->players.lock);
+
+ for(j = 0; j < count; j++)
+ {
+ idx = idxs[j] - j;
+
+ /* fix block types */
+ if(idx)
+ app->playlist.item[idx - 1].type = (playlist_item_type_t)(app->playlist.item[idx - 1].type |
+ OMNPLAY_PLAYLIST_BLOCK_END);
+ if(idx + 1 < app->playlist.count)
+ app->playlist.item[idx + 1].type = (playlist_item_type_t)(app->playlist.item[idx + 1].type |
+ OMNPLAY_PLAYLIST_BLOCK_BEGIN);
+
+ /* shift playlist items */
+ memmove
+ (
+ &app->playlist.item[idx],
+ &app->playlist.item[idx + 1],
+ (app->playlist.count - idx - 1) * sizeof(playlist_item_t)
+ );
+
+ /* decrement items count */
+ app->playlist.count--;
+
+ /* increment servers indexes */
+ for(i = 0; i < app->players.count; i++)
+ if(app->players.item[i].playlist_start >= idx)
+ app->players.item[i].playlist_start--;
+
+
+ };
+
+ /* redraw playlist */
+ omnplay_playlist_draw(app);
+
+ /* select */
+ path = gtk_tree_path_new_from_indices(idxs[0], -1);
+ gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(app->playlist_grid)), path);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(app->playlist_grid), path, NULL, FALSE);
+ gtk_tree_path_free(path);
+
+
+ pthread_mutex_unlock(&app->players.lock);
+ pthread_mutex_unlock(&app->playlist.lock);
+};
+
+static void omnplay_playlist_item_del(omnplay_instance_t* app)
+{
+ int i, idx, c;
+ int *list, *list2;
+
+ list = get_selected_items_playlist(app);
+ if(!list) return;
+
+ list2 = (int*)malloc(sizeof(int) * list[0]);
+
+ for(i = 0, c = 0; i < list[0]; i++)
+ {
+ /* check for playing block */
+ if(idx_in_players_range(app, list[i + 1]))
+ continue;
+
+ /* save index */
+ list2[c++] = list[i + 1];
+ };
+
+ if(c)
+ omnplay_playlist_delete_items(app, list2, c);
+
+ free(list2);
+ free(list);
+};
+
+static int omnplay_playlist_insert_check(omnplay_instance_t* app, int idx, playlist_item_type_t* t)
+{
+ *t = OMNPLAY_PLAYLIST_ITEM_BLOCK_SINGLE;
+
+ /* before or after playlist */
+ if(!idx || idx == app->playlist.count)
+ return 1;
+
+ /* check for block borders */
+ if( app->playlist.item[idx - 1].type & OMNPLAY_PLAYLIST_BLOCK_END &&
+ app->playlist.item[idx + 0].type & OMNPLAY_PLAYLIST_BLOCK_BEGIN)
+ return 1;
+
+ /* check for playing block */
+ if(idx_in_players_range(app, idx))
+ return 0;
+
+ if(app->playlist.item[idx].type & OMNPLAY_PLAYLIST_BLOCK_LOOP)
+ *t = OMNPLAY_PLAYLIST_ITEM_LOOP_BODY;
+ else
+ *t = OMNPLAY_PLAYLIST_ITEM_BLOCK_BODY;
+
+ return 1;
+};
+
+static void omnplay_playlist_insert_items(omnplay_instance_t* app, int idx,
+ playlist_item_t* items, int count)
+{
+ int i;
+ GtkTreePath* path;
+
+ pthread_mutex_lock(&app->playlist.lock);
+ pthread_mutex_lock(&app->players.lock);
+
+ /* shift playlist items */
+ memmove
+ (
+ &app->playlist.item[idx + count],
+ &app->playlist.item[idx],
+ (app->playlist.count - idx) * sizeof(playlist_item_t)
+ );
+
+ /* copy new items */
+ memcpy
+ (
+ &app->playlist.item[idx],
+ items,
+ count * sizeof(playlist_item_t)
+ );
+
+ /* increment servers indexes */
+ for(i = 0; i < app->players.count; i++)
+ if(app->players.item[i].playlist_start >= idx)
+ app->players.item[i].playlist_start += idx;
+
+ /* increment items count */
+ app->playlist.count += count;
+
+ /* redraw playlist */
+ omnplay_playlist_draw(app);
+
+ /* select */
+ path = gtk_tree_path_new_from_indices(idx + count, -1);
+ gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(app->playlist_grid)), path);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(app->playlist_grid), path, NULL, FALSE);
+ gtk_tree_path_free(path);
+
+ pthread_mutex_unlock(&app->players.lock);
+ pthread_mutex_unlock(&app->playlist.lock);
+};
+
+static void omnplay_playlist_item_add(omnplay_instance_t* app, int after)
+{
+ int idx;
+ playlist_item_t item;
+ playlist_item_type_t t;
+
+ /* find insert position */
+ idx = get_first_selected_item_playlist(app);
+ if(idx < 0)
+ idx = 0;
+ else
+ idx += (after)?1:0;
+
+ if(!omnplay_playlist_insert_check(app, idx, &t))
+ return;
+
+ fprintf(stderr, "allowed insert into idx=%d\n", idx);
+
+ /* clear item */
+ memset(&item, 0, sizeof(playlist_item_t));
+ if(ui_playlist_item_dialog(app, &item))
+ {
+ omnplay_library_normalize_item(app, &item);
+ item.type = t;
+ omnplay_playlist_insert_items(app, idx, &item, 1);
+ };
+};
+
+static void omnplay_playlist_item_edit(omnplay_instance_t* app)
+{
+ int idx;
+ playlist_item_t item;
+
+ /* find insert position */
+ idx = get_first_selected_item_playlist(app);
+
+ if(idx < 0)
+ return;
+
+ /* check for playing block */
+ if(idx_in_players_range(app, idx))
+ return;
+
+ item = app->playlist.item[idx];
+
+ if(ui_playlist_item_dialog(app, &item))
+ {
+ omnplay_library_normalize_item(app, &item);
+ app->playlist.item[idx] = item;
+ omnplay_playlist_draw_item(app, idx);
+ };
+};
+
+static void omnplay_ctl(omnplay_instance_t* app, control_buttons_t button)
{
+ int i, r;
int idx, start, stop;
omnplay_player_t *player;
return;
};
- /* 1. stop */
pthread_mutex_lock(&app->players.lock);
- OmPlrStop((OmPlrHandle)player->handle);
- player->playlist_start = -1;
- player->playlist_count = -1;
+
+ if(BUTTON_PLAYER_STOP == button || BUTTON_PLAYER_CUE == button)
+ {
+ /* stop */
+ OmPlrStop((OmPlrHandle)player->handle);
+
+ /* detach previous clips */
+ player->playlist_length = -1;
+ OmPlrDetachAllClips((OmPlrHandle)player->handle);
+ };
+
+ if(BUTTON_PLAYER_CUE == button)
+ {
+ int o, c, p = 0;
+
+ /* Attach clips to timeline */
+ for(i = start, c = 0, o = 0; i <= stop; i++)
+ {
+ OmPlrClipInfo clip;
+
+ /* get clip info */
+ clip.maxMsTracks = 0;
+ clip.size = sizeof(clip);
+ r = OmPlrClipGetInfo((OmPlrHandle)player->handle, app->playlist.item[i].id, &clip);
+
+ if(!r)
+ {
+ unsigned int l;
+
+ fprintf(stderr, "OmPlrClipGetInfo(%s): firstFrame=%d, lastFrame=%d\n",
+ app->playlist.item[i].id, clip.firstFrame, clip.lastFrame);
+
+ /* should we fix playlist clip timings */
+ if(!(
+ app->playlist.item[i].in >= clip.firstFrame &&
+ app->playlist.item[i].in + app->playlist.item[i].dur <= clip.lastFrame) ||
+ !app->playlist.item[i].dur)
+ {
+ fprintf(stderr, "cue: item [%s] will be updated [%d;%d]->[%d;%d]\n",
+ app->playlist.item[i].id,
+ app->playlist.item[i].in, app->playlist.item[i].dur,
+ clip.firstFrame, clip.lastFrame - clip.firstFrame);
+
+ app->playlist.item[i].in = clip.firstFrame;
+ app->playlist.item[i].dur = clip.lastFrame - clip.firstFrame;
+ omnplay_playlist_draw_item(app, i);
+ };
+
+ r = OmPlrAttach((OmPlrHandle)player->handle,
+ app->playlist.item[i].id,
+ app->playlist.item[i].in,
+ app->playlist.item[i].in + app->playlist.item[i].dur,
+ 0, omPlrShiftModeAfter, &l);
+ };
+
+ if(r)
+ {
+ fprintf(stderr, "cue: failed with %d, %s\n", r, OmPlrGetErrorString((OmPlrError)r));
+ app->playlist.item[i].omn_idx = -1;
+ app->playlist.item[i].omn_offset = -1;
+ app->playlist.item[i].error |= PLAYLIST_ITEM_ERROR_CUE;
+ }
+ else
+ {
+ app->playlist.item[i].omn_idx = c;
+ app->playlist.item[i].omn_offset = o;
+ app->playlist.item[i].error &= 0xF ^ PLAYLIST_ITEM_ERROR_CUE;
+
+ /* save selected item offset */
+ if(i == idx) p = o;
+
+ c++;
+ o += app->playlist.item[i].dur;
+ };
+ };
+
+ if(c)
+ {
+ OmPlrStatus hs;
+
+ /* Set timeline min/max */
+ OmPlrSetMinPosMin((OmPlrHandle)player->handle);
+ OmPlrSetMaxPosMax((OmPlrHandle)player->handle);
+
+ /* Set timeline position */
+ hs.minPos = 0;
+ hs.size = sizeof(OmPlrStatus);
+ OmPlrGetPlayerStatus((OmPlrHandle)player->handle, &hs);
+ OmPlrSetPos((OmPlrHandle)player->handle, hs.minPos + p);
+
+ /* setup loop */
+ if(app->playlist.item[start].type & OMNPLAY_PLAYLIST_BLOCK_LOOP)
+ OmPlrLoop((OmPlrHandle)player->handle, hs.minPos, hs.maxPos);
+ else
+ OmPlrLoop((OmPlrHandle)player->handle, hs.minPos, hs.minPos);
+
+ player->playlist_start = start;
+ player->playlist_length = stop - start + 1;
+
+ /* Cue */
+ OmPlrCuePlay((OmPlrHandle)player->handle, 0.0);
+ };
+ };
+
+ if(BUTTON_PLAYER_PLAY == button)
+ {
+ /* play */
+ OmPlrPlay((OmPlrHandle)player->handle, 1.0);
+ };
+
+ if(BUTTON_PLAYER_PAUSE == button)
+ /* pause */
+ OmPlrPlay((OmPlrHandle)player->handle, 0.0);
+
pthread_mutex_unlock(&app->players.lock);
- /* 2. detach previous clips */
+ pthread_mutex_unlock(&app->playlist.lock);
+};
+
+static void omnplay_playlist_item_swap(omnplay_instance_t* app, int dir)
+{
+ int sel, a, b, e = 1;
+ GtkTreePath* path;
+ playlist_item_t item;
+
+ /* find insert position */
+ sel = get_first_selected_item_playlist(app);
+ if(sel < 0)
+ return;
+
+ if(dir < 0)
+ {
+ a = sel - 1;
+ b = sel;
+ sel = a;
+ }
+ else
+ {
+ a = sel;
+ b = sel + 1;
+ sel = b;
+ };
+
+ /* check for playing block */
+ if(idx_in_players_range(app, a) || idx_in_players_range(app, b))
+ return;
+
+ pthread_mutex_lock(&app->playlist.lock);
pthread_mutex_lock(&app->players.lock);
- OmPlrDetachAllClips((OmPlrHandle)player->handle);
- pthread_mutex_unlock(&app->players.lock);
- // http://research.m1stereo.tv/viewvc-int/viewvc.cgi/Ingest2Srv/trunk/SrvPlayCtl.cpp?view=markup
+ /* swap */
+ item = app->playlist.item[a];
+ app->playlist.item[a] = app->playlist.item[b];
+ app->playlist.item[b] = item;
+
+ /* rewite type */
+ if(app->playlist.item[a].type != app->playlist.item[b].type)
+ {
+ e = 0;
+ app->playlist.item[a].type = OMNPLAY_PLAYLIST_ITEM_BLOCK_SINGLE;
+ app->playlist.item[b].type = OMNPLAY_PLAYLIST_ITEM_BLOCK_SINGLE;
+ };
+
+ /* redraw main items */
+ omnplay_playlist_draw_item(app, a);
+ omnplay_playlist_draw_item(app, b);
+
+ /* fix block types */
+ if(a && !e)
+ {
+ app->playlist.item[a - 1].type = (playlist_item_type_t)(app->playlist.item[a - 1].type |
+ OMNPLAY_PLAYLIST_BLOCK_END);
+ omnplay_playlist_draw_item(app, a - 1);
+ };
+ if(b + 1 < app->playlist.count && !e)
+ {
+ app->playlist.item[b + 1].type = (playlist_item_type_t)(app->playlist.item[b + 1].type |
+ OMNPLAY_PLAYLIST_BLOCK_BEGIN);
+ omnplay_playlist_draw_item(app, b + 1);
+ };
+
+ /* select */
+ path = gtk_tree_path_new_from_indices(sel, -1);
+ gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(app->playlist_grid)), path);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(app->playlist_grid), path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ pthread_mutex_unlock(&app->players.lock);
pthread_mutex_unlock(&app->playlist.lock);
+};
+
+static void omnplay_library_add(omnplay_instance_t* app, int after)
+{
+ int idx, c, i;
+ playlist_item_t* items;
+ playlist_item_type_t t;
+
+ /* find insert position */
+ idx = get_first_selected_item_playlist(app);
+ if(idx < 0)
+ idx = 0;
+ else
+ idx += (after)?1:0;
+
+ if(!omnplay_playlist_insert_check(app, idx, &t))
+ return;
+ items = omnplay_library_get_selected(app, &c);
+
+ /* clear item */
+ if(items)
+ {
+ for(i = 0; i < c; i++)
+ {
+ items[i].type = t;
+ items[i].error = 0;
+ };
+ omnplay_playlist_insert_items(app, idx, items, c);
+ };
};
+
static gboolean omnplay_button_click(omnplay_instance_t* app, control_buttons_t button)
{
switch(button)
{
case BUTTON_PLAYLIST_ITEM_ADD:
+ omnplay_playlist_item_add(app, 0);
+ break;
case BUTTON_PLAYLIST_ITEM_DEL:
+ omnplay_playlist_item_del(app);
+ break;
case BUTTON_PLAYLIST_ITEM_EDIT:
+ omnplay_playlist_item_edit(app);
+ break;
case BUTTON_PLAYLIST_LOAD:
omnplay_playlist_load(app);
break;
break;
case BUTTON_PLAYLIST_BLOCK_SINGLE:
case BUTTON_PLAYLIST_BLOCK_LOOP:
+ omnplay_playlist_block(app, button);
+ break;
case BUTTON_PLAYLIST_ITEM_UP:
+ omnplay_playlist_item_swap(app, -1);
+ break;
case BUTTON_PLAYLIST_ITEM_DOWN:
+ omnplay_playlist_item_swap(app, +1);
+ break;
case BUTTON_PLAYER_CUE:
- omnplay_cue(app);
case BUTTON_PLAYER_PLAY:
case BUTTON_PLAYER_PAUSE:
case BUTTON_PLAYER_STOP:
+ omnplay_ctl(app, button);
+ break;
case BUTTON_LIBRARY_ADD:
+ omnplay_library_add(app, 0);
+ break;
case BUTTON_LIBRARY_REFRESH:
+ omnplay_library_refresh(app);
+ break;
+ case BUTTON_LIBRARY_FIND:
+ omnplay_library_search(app, 0);
+ break;
+ case BUTTON_LIBRARY_FIND_NEXT:
+ omnplay_library_search(app, 1);
break;
};
return FALSE;
};
+static gboolean on_playlist_grid_key(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+ omnplay_instance_t* app = (omnplay_instance_t*)data;
+
+ switch(event->keyval)
+ {
+ case GDK_C:
+ case GDK_c:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ fprintf(stderr, "CTRL+c\n");
+ return TRUE;
+ };
+ break;
+ case GDK_V:
+ case GDK_v:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ fprintf(stderr, "CTRL+v\n");
+ return TRUE;
+ };
+ break;
+ case GDK_X:
+ case GDK_x:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ fprintf(stderr, "CTRL+x\n");
+ return TRUE;
+ };
+ break;
+ case GDK_S:
+ case GDK_s:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ omnplay_playlist_save(app);
+ return TRUE;
+ };
+ break;
+ case GDK_O:
+ case GDK_o:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ omnplay_playlist_load(app);
+ return TRUE;
+ };
+ break;
+ case GDK_KEY_space:
+ omnplay_ctl(app, BUTTON_PLAYER_PLAY);
+ return TRUE;
+ case GDK_KEY_Return:
+ omnplay_ctl(app, BUTTON_PLAYER_CUE);
+ return TRUE;
+ case GDK_KEY_Insert:
+ omnplay_playlist_item_add(app, 0);
+ return TRUE;
+ case GDK_KEY_Delete:
+ omnplay_playlist_item_del(app);
+ return TRUE;
+ case GDK_KEY_BackSpace:
+ omnplay_playlist_item_edit(app);
+ return TRUE;
+ };
+
+ return FALSE;
+};
+
+static gboolean on_library_grid_key(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+ omnplay_instance_t* app = (omnplay_instance_t*)data;
+
+ switch(event->keyval)
+ {
+ case GDK_C:
+ case GDK_c:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ fprintf(stderr, "CTRL+c\n");
+ return TRUE;
+ };
+ break;
+ case GDK_V:
+ case GDK_v:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ fprintf(stderr, "CTRL+v\n");
+ return TRUE;
+ };
+ break;
+ case GDK_X:
+ case GDK_x:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ fprintf(stderr, "CTRL+x\n");
+ return TRUE;
+ };
+ break;
+ };
+
+ return FALSE;
+};
+
void omnplay_init(omnplay_instance_t* app)
{
int i;
+ pthread_mutexattr_t attr;
- gtk_signal_connect( GTK_OBJECT( app->window ), "destroy",
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ gtk_signal_connect( GTK_OBJECT( app->window ), "delete-event",
GTK_SIGNAL_FUNC(on_main_window_delete_event), app);
+ gtk_signal_connect( GTK_OBJECT( app->window ), "destroy",
+ GTK_SIGNAL_FUNC(on_main_window_destroy), app);
+
+ gtk_widget_add_events(app->playlist_grid, GDK_BUTTON_PRESS_MASK);
+ gtk_signal_connect(GTK_OBJECT(app->playlist_grid), "key-press-event",
+ GTK_SIGNAL_FUNC(on_playlist_grid_key), app);
+
+ gtk_widget_add_events(app->library_grid, GDK_BUTTON_PRESS_MASK);
+ gtk_signal_connect(GTK_OBJECT(app->library_grid), "key-press-event",
+ GTK_SIGNAL_FUNC(on_library_grid_key), app);
+
/* create lock */
- pthread_mutex_init(&app->players.lock, NULL);
+ pthread_mutex_init(&app->players.lock, &attr);
/* create a omneon status thread */
for(i = 0; i < app->players.count; i++)
omnplay_thread_proc, &app->players.item[i]);
/* create lock */
- pthread_mutex_init(&app->playlist.lock, NULL);
+ pthread_mutex_init(&app->playlist.lock, &attr);
/* attach buttons click */
for(i = 1; i < BUTTON_LAST; i++)
gtk_signal_connect(GTK_OBJECT(app->buttons[i]), "clicked",
GTK_SIGNAL_FUNC( on_button_click), app );
+ /* create lock */
+ pthread_mutex_init(&app->library.lock, &attr);
+
+ /* load library */
+ omnplay_library_load(app);
};
void omnplay_release(omnplay_instance_t* app)
/* destroy lock */
pthread_mutex_destroy(&app->playlist.lock);
+
+ /* load library */
+ omnplay_library_save(app);
+
+ /* destroy library lock */
+ pthread_mutex_destroy(&app->library.lock);
+};
+
+void omnplay_playlist_normalize(omnplay_instance_t* app)
+{
+ int i;
+
+ /* normalize playlist */
+ for(i = 0; i < app->playlist.count; i++)
+ if(omnplay_library_normalize_item(app, &app->playlist.item[i]))
+ omnplay_playlist_draw_item(app, i);
};