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

277 lines
6.6 KiB
C
Raw Normal View History

#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;
};
2008-04-07 01:04:15 +00:00
int ecdb_burn_finished(void *data, int type, void *event);
2008-05-15 00:14:33 +00:00
int ecdb_burn_project_init(Ecdb_Burn_Project *proj);
int ecdb_erase_project_init(Ecdb_Erase_Project *proj);
static void ecdb_burn_progress_handler(void *data, void *buffer,
unsigned int nbyte);
2008-05-15 00:14:33 +00:00
Ecdb_Burn_Project *
ecdb_burn_project_new(void)
{
Ecdb_Burn_Project *proj;
proj = calloc(1, sizeof(Ecdb_Burn_Project));
if (!proj)
return NULL;
if (!ecdb_burn_project_init(proj))
{
FREE(proj);
return NULL;
}
return proj;
}
int
ecdb_burn_project_init(Ecdb_Burn_Project *proj)
{
if (!ecdb_project_init(ECDB_PROJECT(proj)))
return FALSE;
/* Create some sane defaults */
2008-06-10 03:33:53 +00:00
ecdb_project_type_set(ECDB_PROJECT(proj), ECDB_BURN_PROJECT);
2008-05-15 00:14:33 +00:00
proj->burn_mode = BURN_MODE1;
proj->fifo_chunksize = 2048;
proj->fifo_chunks = 2048;
proj->underrun_proof = TRUE;
proj->opc = TRUE;
proj->multi = TRUE;
2008-05-21 01:01:37 +00:00
proj->files = ecdb_source_new();
2008-05-15 00:14:33 +00:00
return TRUE;
}
void
ecdb_burn_project_destroy(Ecdb_Burn_Project *proj)
{
ecdb_source_destroy(proj->files);
FREE(proj->volume_id);
FREE(proj->publisher_id);
FREE(proj->data_preparer_id);
FREE(proj->system_id);
FREE(proj->application_id);
FREE(proj->copywrite_id);
FREE(proj->abstract_id);
FREE(proj->biblio_id);
2008-06-05 19:20:29 +00:00
ecdb_project_destroy(ECDB_PROJECT(proj));
FREE(proj);
}
int
2008-05-15 00:14:33 +00:00
ecdb_burn_project(Ecdb_Burn_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));
2008-05-15 00:14:33 +00:00
if (!data)
{
printf("Error: Cannot create burn data structure!\n");
return FALSE;
}
data->proj = ECDB_PROJECT(proj);
data->sources = ecore_list_new();
data->tracks = ecore_list_new();
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);
2008-05-21 01:38:44 +00:00
source = ecdb_image_project(proj);
if (!source)
{
2008-05-21 01:38:44 +00:00
printf("Failed to add any files to burn disc!\n");
return ECDB_ERROR_IMAGE_CREATE;
}
2008-05-21 01:38:44 +00:00
if (burn_track_set_source(track, source) != BURN_SOURCE_OK)
{
2008-05-21 01:38:44 +00:00
printf("Error: Cannot attach source object to track "
"object!\n");
return ECDB_ERROR_SOURCE_ATTACH;
}
2008-05-21 01:38:44 +00:00
burn_session_add_track(data->session, track, BURN_POS_END);
ecore_list_append(data->sources, source);
ecore_list_append(data->tracks, track);
2008-05-15 00:14:33 +00:00
opts = burn_write_opts_new(ECDB_PROJECT(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)
2008-04-07 01:04:15 +00:00
printf("Simulating Burn!\n");
burn_write_opts_set_simulate(opts, proj->simulate);
2008-05-15 00:14:33 +00:00
burn_drive_set_speed(ECDB_PROJECT(proj)->drive->tangible->drive, 0,
proj->speed);
burn_write_opts_set_underrun_proof(opts, proj->underrun_proof);
2008-04-07 01:04:15 +00:00
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 ECDB_ERROR_WRITE_MODE;
}
burn_disc_write(opts, data->disc);
burn_write_opts_free(opts);
2008-04-07 01:04:15 +00:00
printf("Disc now burning\n");
ECDB_PROJECT(proj)->pipe = ecore_pipe_add(ecdb_burn_progress_handler,
NULL);
pthread_create(&progress_update, NULL, ecdb_drive_progress_update,
proj);
pthread_detach(progress_update);
2008-06-05 19:20:29 +00:00
ECDB_PROJECT(proj)->ev_handler = ecore_event_handler_add
(ECDB_DRIVE_ACTION_FINISHED, ecdb_burn_finished,
2008-04-07 01:04:15 +00:00
data);
return ECDB_ERROR_NONE;
2008-05-15 00:14:33 +00:00
}
/* This function is pretty naive... Should probably update it at some time */
void *
ecdb_drive_progress_update(void *data)
{
const Ecdb_Project *proj;
BurnProgress p;
struct burn_drive *drive;
proj = data;
2008-05-15 00:14:33 +00:00
if (!proj->drive->tangible)
{
printf("No tangible drive!\n");
ecore_pipe_del(proj->pipe);
/* Call failure here */
pthread_exit(NULL);
}
2008-05-15 00:14:33 +00:00
drive = proj->drive->tangible[0].drive;
2008-04-07 01:04:15 +00:00
printf("Progress update active\n");
2008-11-17 22:17:24 +00:00
while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
usleep(100000);
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE)
{
2008-11-17 22:17:24 +00:00
if (p.sectors > 0)
ecore_pipe_write(proj->pipe, &p, sizeof(p));
usleep(100000);
}
2008-11-17 22:17:24 +00:00
ecore_pipe_write(proj->pipe, "AC", sizeof("AC"));
ecore_pipe_del(proj->pipe);
/* Call the finished event handler here */
pthread_exit(NULL);
}
static void
ecdb_burn_progress_handler(void *data, void *buffer, unsigned int nbyte)
2008-04-07 01:04:15 +00:00
{
BurnProgress *p;
Evas_Object *swallow;
char buf[1024];
static int last_sector = 0;
if ((nbyte != sizeof(BurnProgress)) || (!strcmp((char *)buffer, "AC")))
{
ecore_event_add(ECDB_DRIVE_ACTION_FINISHED, NULL, NULL, NULL);
last_sector = 0;
return;
}
else
{
p = buffer;
}
2008-04-07 01:04:15 +00:00
/* Libburn reports p->sector as being 0 right at the end of the job,
* so store the last sector and use that to determine the proper
* percentage/sector to set
*/
if (last_sector <= p->sector)
last_sector = p->sector;
else
last_sector = p->sectors;
swallow = evas_object_name_find(ecore_evas_get(em->main_win_ee),
"burn_image_page");
snprintf(buf, sizeof(buf), "%d/%d", last_sector, p->sectors);
edje_object_part_text_set(swallow, "progress_text", buf);
snprintf(buf, sizeof(buf), "%d%%", (int)((double)(last_sector + 1) /
(double)p->sectors * 100.0));
edje_object_part_text_set(swallow, "progress_percent", buf);
2008-04-07 01:04:15 +00:00
}
int
ecdb_burn_finished(void *data, int type, void *event)
{
Burn_Data *proj;
BurnTrack *track;
BurnSource *source;
proj = data;
2008-10-31 13:23:31 +00:00
ecore_list_first(proj->sources);
ecore_list_first(proj->tracks);
2008-04-07 01:04:15 +00:00
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);
2008-05-15 00:14:33 +00:00
printf("Burn Complete\n");
2008-04-07 01:04:15 +00:00
ecore_event_handler_del(proj->proj->ev_handler);
2008-06-05 19:20:29 +00:00
switch (proj->proj->type)
{
case ECDB_AUDIO_PROJECT:
ecdb_audio_project_destroy(ECDB_AUDIO(proj->proj));
break;
default:
ecdb_burn_project_destroy(ECDB_BURN(proj->proj));
}
2008-04-07 01:04:15 +00:00
FREE(proj);
/* To be removed from here at some point */
2008-06-05 19:20:29 +00:00
return TRUE;
2008-04-07 01:04:15 +00:00
}