语言

Menu
Sites
Language
watch application crashing with cairo library

I m trying to draw line with cairo but when i mtrying to install and run app on watch app is crashing on watch without showing any UI. i m using this following code
 

#include <tizen.h>
#include <cairo.h>
#include <math.h>
#include <Evas_GL.h>
#include <cairo-evas-gl.h>
//#include "watchcairo.h"
#include "basicui.h"
 
typedef struct appdata {
 
/* Variables for basic UI contents */
Evas_Object *win;
Evas_Object *img;
Evas_Object *label;
Ecore_Animator* ani;
 
/* Variables for watch size information */
int width;
int height;
 
/* Variables for cairo evasgl backend contents */
cairo_t *cairo;
cairo_surface_t *surface;
cairo_device_t *cairo_device;
 
/* Variables for evasgl contents */
Evas_GL *evas_gl;
Evas_GL_Config *evas_gl_config;
Evas_GL_Surface *evas_gl_surface;
Evas_GL_Context *evas_gl_context;
 
} appdata_s;
 
#define TEXT_BUF_SIZE 256
 
/*
 * @brief Update a watch face screen
 * @param[in] ad application's data structure
 * @param[in] watch_time current time information for update
 * @param[in] ambient ambient mode status
 */
 
 
/*
 * @brief Update a watch face screen
 * @param[in] ad application's data structure
 * @param[in] obj destination surface for update
 */
void
cairo_drawing(void *data, Evas_Object *obj)
{
appdata_s *ad = data;
/* Variables for time */
int ret;
 
 
 
int hour24, minute, second;
second = 25;
minute = 24;
hour24 = 10;
//watch_time_get_hour24(watch_time, &hour24);
//watch_time_get_minute(watch_time, &minute);
//watch_time_get_second(watch_time, &second);
//watch_time_delete(watch_time);
 
/* Set background color as light red */
cairo_set_source_rgba(ad->cairo, 1.0, 0.8, 0.8, 1);
cairo_paint(ad->cairo);
 
/* Variables for display time */
double x, y, side, radian;
cairo_line_cap_t line_cap_style;
cairo_line_join_t line_join_style;
 
/*
* How to draw second hand
* 1. Set second hand's line style, width, color
* 2. Set second hand's line start position
* 3. Compute second hand's line end position
* 4. Draw second hand
* 5. Stroke second hand as line configuration from step.1
*/
 
/* Set second hand line style, width */
line_cap_style = CAIRO_LINE_CAP_ROUND;
line_join_style = CAIRO_LINE_JOIN_BEVEL;
cairo_set_line_width(ad->cairo, 2);
cairo_set_line_join(ad->cairo, line_join_style);
cairo_set_line_cap(ad->cairo, line_cap_style);
 
/* Set second hand line color */
cairo_set_source_rgba(ad->cairo, 1.0, 0.3, 0.3, 0.8);
 
/*
* Set line start position
* The start position should be at the center of the screen
*/
x = ad->width/2;
y = ad->height/2;
cairo_move_to(ad->cairo, x, y);
 
/*
* Compute the line end position
* Using side and radian
*/
side = ad->width/2*0.65;
radian = -second *(M_PI/180);
x = ad->width/2 - (side * sin(radian*6));
y = ad->height/2 - (side * cos(radian*6));
 
/* Draw second hand */
cairo_line_to(ad->cairo, x, y);
cairo_close_path(ad->cairo);
 
/*
* Stroke second hand
* With it's line configure */
cairo_stroke(ad->cairo);
 
/*
* How to draw minute hand
* 1. Set minute hand's line style, width, color
* 2. Set minute hand's line start position
* 3. Compute minute hand's line end position
* 4. Draw minute hand
* 5. Stroke minute hand as line configuration from step.1
*/
 
/* Set minute hand line style, width */
line_cap_style = CAIRO_LINE_CAP_BUTT;
line_join_style = CAIRO_LINE_JOIN_MITER;
cairo_set_line_width(ad->cairo, 4);
cairo_set_line_join(ad->cairo, line_join_style);
cairo_set_line_cap(ad->cairo, line_cap_style);
 
/* Set minute hand line color */
cairo_set_source_rgba(ad->cairo, 1.0, 0.5, 0.5, 0.8);
 
/*
* Set line start position
* The start position should be at the center of the screen
*/
x = ad->width/2;
y = ad->height/2;
cairo_move_to(ad->cairo, x, y);
 
/*
* Compute the line end position
* Using side and radian
*/
side = ad->width/2*0.8;
radian = -minute *(M_PI/180);
x = ad->width/2 - (side * sin(radian*6));
y = ad->height/2 - (side * cos(radian*6));
 
/* Draw minute hand */
cairo_line_to(ad->cairo, x, y);
cairo_close_path(ad->cairo);
 
/*
* Stroke minute hand
* With it's line configuration */
cairo_stroke(ad->cairo);
 
/*
* How to draw hour hand
* 1. Set hour hand's line style, width, color
* 2. Set hour hand's line start position
* 3. Compute hour hand's line end position
* 4. Draw hour hand
* 5. Stroke hour hand as line configuration from step.1
*/
 
/* Set hour hand line style, width */
line_cap_style = CAIRO_LINE_CAP_SQUARE;
line_join_style = CAIRO_LINE_JOIN_ROUND;
cairo_set_line_width(ad->cairo, 6);
cairo_set_line_join(ad->cairo, line_join_style);
cairo_set_line_cap(ad->cairo, line_cap_style);
 
/* Set hour hand line color */
cairo_set_source_rgba(ad->cairo, 1.0, 0.4, 0.4, 0.8);
 
/*
* Set line start position
* start position should be at the center of the screen
*/
x = ad->width/2;
y = ad->height/2;
cairo_move_to(ad->cairo, x, y);
 
/*
* Compute the line end position
* Using side and radian
*/
side = ad->width/2*0.5;
radian = -hour24 *(M_PI/180);
x = ad->width/2 - (side * sin(radian*30));
y = ad->height/2 - (side * cos(radian*30));
 
/* Draw hour hand */
cairo_line_to(ad->cairo, x, y);
cairo_close_path(ad->cairo);
 
/*
* Stroke hour hand
* With it's line configuration */
cairo_stroke(ad->cairo);
 
/* Render stacked cairo APIs on cairo context's surface */
cairo_surface_flush(ad->surface);
}
 
static Eina_Bool
animate_cb(void *data)
{
/* Display this cairo watch on screen */
Evas_Object *obj = (Evas_Object *)data;
evas_object_image_pixels_dirty_set(obj, EINA_TRUE);
return EINA_TRUE;
}
 
static void
update_watch(appdata_s *ad)
{
/* Variables for time */
char watch_text[TEXT_BUF_SIZE];
 
snprintf(watch_text, TEXT_BUF_SIZE, "<align=center>Watch Cairo EvasGL</align>");
 
/* Set label */
elm_object_text_set(ad->label, watch_text);
}
 
/*
 * Create and display the selected watch face screen
   ( User can change watch face in Wearable's Settings
Select watch face option in 'Settings' - 'Display' - 'Watch face' menu )
 * In this function,
 * First, get the watch application's elm_win
 * Second, create an evas object image as a destination surface
 *  then, create evasgl contents using evas object image's data
 *  after create evasgl, create cairo context and surface for gl backend using evasgl
 * Third, Create a label for display the given time as a text type
 * Last, call update_watch() function to draw and display the first screen
 */
static void
create_base_gui(appdata_s *ad)
{
int ret;
 
/*
* Window
* Get the watch application's elm_win.
* elm_win is mandatory to manipulate window
*/
elm_config_accel_preference_set("hw");
 
 
evas_object_resize(ad->win, ad->width, ad->height);
 
/* Create image */
ad->img = evas_object_image_filled_add(evas_object_evas_get(ad->win));
evas_object_image_size_set(ad->img, ad->width, ad->height);
evas_object_resize(ad->img, ad->width, ad->height);
evas_object_show(ad->img);
 
/* Create the evas gl handle ,context & config */
Evas_Native_Surface ns;
ad->evas_gl = evas_gl_new(evas_object_evas_get(ad->img));
ad->evas_gl_config = evas_gl_config_new();
ad->evas_gl_config->color_format = EVAS_GL_RGBA_8888;
ad->evas_gl_surface = evas_gl_surface_create(ad->evas_gl, ad->evas_gl_config, ad->width, ad->height);
ad->evas_gl_context = evas_gl_context_create(ad->evas_gl, NULL);
evas_gl_native_surface_get(ad->evas_gl, ad->evas_gl_surface, &ns);
evas_object_image_native_surface_set(ad->img, &ns);
 
/*
* Set callback function to display cairo drawing on evas object image
* When every animate callback called
*/
evas_object_image_pixels_get_callback_set(ad->img, cairo_drawing, ad);
 
/* Create cairo context, surface & device with evasgl */
setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
ad->cairo_device = (cairo_device_t *)cairo_evas_gl_device_create(ad->evas_gl, ad->evas_gl_context);
cairo_gl_device_set_thread_aware(ad->cairo_device, 0);
ad->surface = (cairo_surface_t *)cairo_gl_surface_create_for_evas_gl(ad->cairo_device, ad->evas_gl_surface, ad->evas_gl_config, ad->width, ad->height);
ad->cairo = cairo_create(ad->surface);
 
/* Create label */
ad->label = elm_label_add(ad->win);
evas_object_resize(ad->label, ad->width, ad->height/3);
evas_object_move(ad->label, 0, ad->height/3);
evas_object_show(ad->label);
 
 
 
/* Display first screen of watch */
update_watch(ad);
 
 
/* Show window after base gui is set up */
evas_object_show(ad->win);
 
/* Update destination surface */
ad->ani = ecore_animator_add(animate_cb, ad->img);
evas_object_data_set(ad->img, "ani", ad->ani);
}
 
/*
 * @brief Hook to take necessary actions before main event loop starts
 * @param[in] width watch application's given elm_win's width
 * @param[in] height watch application's given elm_win's height
 * @param[in] data application's data structure
 * Initialize UI resources and application's data
 * If this function returns true, the main loop of application starts
 * If this function returns false, the application is terminated
 */
static bool
app_create(int width, int height, void *data)
{
appdata_s *ad = data;
ad->width = width;
ad->height = height;
create_base_gui(ad);
 
return true;
}
 
/*
 * @brief This callback function is called when another application
 * sends the launch request to the application
 */
static void
app_control(app_control_h app_control, void *data)
{
/* Handle the launch request. */
}
 
/*
 * @brief This callback function is called each time
 * the application is completely obscured by another application
 * and becomes invisible to the user
 */
static void
app_pause(void *data)
{
/* Take necessary actions when application becomes invisible. */
}
 
/*
 * @brief This callback function is called each time
 * the application becomes visible to the user
 */
static void
app_resume(void *data)
{
/* Take necessary actions when application becomes visible */
}
 
static void
app_terminate(void *data)
{
/* Release all resources */
appdata_s *ad = data;
/* Destroy cairo surface, context and device */
cairo_surface_destroy(ad->surface);
cairo_destroy(ad->cairo);
cairo_device_destroy(ad->cairo_device);
 
/* Destroy evasgl surface, context and config */
evas_gl_surface_destroy(ad->evas_gl, ad->evas_gl_surface);
evas_gl_context_destroy(ad->evas_gl, ad->evas_gl_context);
evas_gl_config_free(ad->evas_gl_config);
evas_gl_free(ad->evas_gl);
}
 
 
/*
 * @brief This function will be called when the language is changed
 */
static void
watch_app_lang_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LANGUAGE_CHANGED*/
char *locale = NULL;
app_event_get_language(event_info, &locale);
elm_language_set(locale);
free(locale);
return;
}
 
/*
 * @brief This function will be called when the region is changed
 */
static void
watch_app_region_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_REGION_FORMAT_CHANGED*/
}
 
 
static void
ui_app_lang_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LANGUAGE_CHANGED*/
char *locale = NULL;
system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
elm_language_set(locale);
free(locale);
return;
}
 
static void
ui_app_orient_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/
return;
}
 
static void
ui_app_region_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_REGION_FORMAT_CHANGED*/
}
 
static void
ui_app_low_battery(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LOW_BATTERY*/
}
 
static void
ui_app_low_memory(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LOW_MEMORY*/
}
 
/*
 * @brief Main function of the application
 */
int
main(int argc, char *argv[])
{
appdata_s ad = {0,};
int ret = 0;
 
    ui_app_lifecycle_callback_s event_callback;
    memset(&event_callback, 0x00, sizeof(ui_app_lifecycle_callback_s));
 
app_event_handler_h handlers[5] = {NULL, };
 
event_callback.create = app_create;
event_callback.terminate = app_terminate;
event_callback.pause = app_pause;
event_callback.resume = app_resume;
event_callback.app_control = app_control;
//event_callback.time_tick = app_time_tick;
//event_callback.ambient_tick = app_ambient_tick;
//event_callback.ambient_changed = app_ambient_changed;
 
 
ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
 
ret = ui_app_main(argc, argv, &event_callback, &ad);
if (ret != APP_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "watch_app_main() is failed. err = %d", ret);
 
return ret;
}