experimental-legacy/ecdb/trunk/src/ecdb_burn.c

196 lines
4.3 KiB
C

#include "ecdb.h"
typedef struct Burn_Data Burn_Data;
struct Burn_Data
{
BurnDisc *disc;
BurnSession *session;
Ecore_List *sources;
Ecore_List *tracks;
Ecdb_Project *proj;
};
void *_progress_update(void *d);
int _progress_gui_update(void *d);
int ecdb_burn_finished(void *data, int type, void *event);
/* Event handlers */
int
ecdb_burn_project(Ecdb_Project *proj)
{
char reasons[BURN_REASONS_LEN];
int padding, i;
Burn_Data *data;
BurnTrack *track;
BurnSource *source;
BurnWriteOpts *opts;
pthread_t progress_update;
i = 0;
data = calloc(1, sizeof(Burn_Data));
data->sources = ecore_list_new();
data->tracks = ecore_list_new();
data->proj = proj;
if (proj->burn_mode != BURN_AUDIO)
padding = 300*1024;
data->disc = burn_disc_create();
data->session = burn_session_create();
burn_disc_add_session(data->disc, data->session, BURN_POS_END);
track = burn_track_create();
burn_track_define_data(track, 0, padding, 1, proj->burn_mode);
while ((source = ecdb_image_project(proj)))
{
if (burn_track_set_source(track, source) != BURN_SOURCE_OK)
{
printf("Error: Cannot attach source object to track "
"object!\n");
return 1;
}
burn_session_add_track(data->session, track, BURN_POS_END);
ecore_list_append(data->sources, source);
ecore_list_append(data->tracks, track);
i++;
}
if (!i)
{
printf("Failed to add any files to burn disc!\n");
return 1;
}
opts = burn_write_opts_new(proj->drive->tangible[0].drive);
burn_write_opts_set_perform_opc(opts, proj->opc);
burn_write_opts_set_multi(opts, proj->multi);
if (proj->simulate)
printf("Simulating Burn!\n");
burn_write_opts_set_simulate(opts, proj->simulate);
burn_drive_set_speed(proj->drive->tangible->drive, 0, proj->speed);
burn_write_opts_set_underrun_proof(opts, proj->underrun_proof);
printf("Searching for burn mode\n");
if (burn_write_opts_auto_write_type(opts, data->disc, reasons, 0)
== BURN_WRITE_NONE)
{
printf("Error: Failed to find a suitable write mode for "
"disc!\n");
return 1;
}
burn_disc_write(opts, data->disc);
burn_write_opts_free(opts);
printf("Disc now burning\n");
pthread_create(&progress_update, NULL, _progress_update, data);
pthread_detach(progress_update);
ecore_timer_add(0.5, _progress_gui_update, data);
ecore_event_handler_add(ECDB_DRIVE_ACTION_FINISHED, ecdb_burn_finished,
data);
return 0;
}
/* Hopefully at some point EFL will become thread-safe, or ecore_timer will
* work with burn_drive_get_status without segfaulting. At that point we can
* do away with this.
*/
void *
_progress_update(void *d)
{
Burn_Data *data;
BurnProgress p;
struct burn_drive *drive;
data = d;
if (!data->proj->drive->tangible)
{
printf("No tangible drive!\n");
pthread_exit(NULL);
}
drive = data->proj->drive->tangible[0].drive;
printf("Progress update active\n");
while (TRUE)
{
data->proj->stat = burn_drive_get_status(drive, &p);
if (data->proj->stat == BURN_DRIVE_SPAWNING)
{
sleep(3);
continue;
}
else if (data->proj->stat == BURN_DRIVE_IDLE)
{
pthread_exit(NULL);
break;
}
data->proj->progress = p;
sleep(5);
}
}
int
_progress_gui_update(void *data)
{
Burn_Data *d;
d = data;
if (d->proj->stat == BURN_DRIVE_IDLE)
{
ecore_event_add(ECDB_DRIVE_ACTION_FINISHED, NULL, NULL, data);
printf("Burn finished\n");
return ECORE_CALLBACK_CANCEL;
}
else
ecore_event_add(ECDB_DRIVE_ACTION_UPDATE, NULL, NULL, data);
return ECORE_CALLBACK_RENEW;
}
int
ecdb_burn_finished(void *data, int type, void *event)
{
Burn_Data *proj;
BurnTrack *track;
BurnSource *source;
proj = data;
ecore_list_first_goto(proj->sources);
ecore_list_first_goto(proj->tracks);
printf("Freeing source and tracks\n");
while ((source = ecore_list_remove(proj->sources)))
{
burn_source_free(source);
track = ecore_list_remove(proj->tracks);
burn_track_free(track);
}
ecore_list_destroy(proj->sources);
ecore_list_destroy(proj->tracks);
printf("Freeing session and disc\n");
burn_session_free(proj->session);
burn_disc_free(proj->disc);
printf("Releasing drive\n");
burn_drive_release(proj->proj->drive->tangible[0].drive, 1);
burn_drive_info_free(proj->proj->drive->tangible);
printf("Ze brun hath finish\n");
/* To be removed from here at some point */
ecore_list_destroy(proj->proj->files);
FREE(proj->proj);
FREE(proj);
ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, NULL, NULL, NULL);
return 0;
}