> -----Original Message----- > From: Philipp Brüschweiler [mailto:ble...@gmail.com] > Sent: Tuesday, August 21, 2012 11:01 PM > To: tecto...@gmail.com > Cc: wayland-devel@lists.freedesktop.org; juan.j.z...@linux.intel.com; Tang, > Ning > Subject: Re: [PATCH 06/14] tablet-shell: add trash function when dragging > launcher icon. > > On Tue, Aug 21, 2012 at 1:49 PM, <tecto...@gmail.com> wrote: > > From: Ning Tang <ning.t...@intel.com> > > > > Determine whether to accpet the data by the allocation of trash area. > > If the icon is in it, then drop event will delete either the icon > > image as well as tag in ini file. > > > > Signed-off-by: Ning Tang <tecto...@gmail.com> > > > > --- > > clients/tablet-shell.c | 153 > ++++++++++++++++++++++++++++++++++++++++++++++++- > > weston-tablet.ini | 1 + > > 2 files changed, 151 insertions(+), 3 deletions(-) > > > > diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c index > > eaaa8d7..860bba8 100644 > > --- a/clients/tablet-shell.c > > +++ b/clients/tablet-shell.c > > @@ -103,17 +103,22 @@ static char *key_launcher_icon; static char > > *key_launcher_path; static void launcher_section_done(void *data); > > static void layout_section_done(void *data); > > +static char *key_trash_image; > > /* launcher drag */ > > struct launcher *gl_launcher_drag = NULL; static int launcher_size; > > static int key_layout_rows; static int key_layout_columns; static > > int layout_moving; > > +/* trash parameters */ > > +static cairo_surface_t *trash_surface = NULL; struct rectangle > > +*trash_allocation = NULL; > > > > static const struct config_key shell_config_keys[] = { > > { "lockscreen-icon", CONFIG_KEY_STRING, > &key_lockscreen_icon }, > > { "lockscreen", CONFIG_KEY_STRING, > &key_lockscreen_background }, > > { "homescreen", CONFIG_KEY_STRING, > &key_homescreen_background > > }, > > + { "trash-image", CONFIG_KEY_STRING, &key_trash_image }, > > { "layout-rows", CONFIG_KEY_UNSIGNED_INTEGER, > &key_layout_rows }, > > { "layout-columns", CONFIG_KEY_UNSIGNED_INTEGER, > &key_layout_columns }, > > { "icon-size", CONFIG_KEY_UNSIGNED_INTEGER, > &launcher_size }, > > @@ -175,6 +180,49 @@ paint_background(cairo_t *cr, const char *path, > struct rectangle *allocation) > > } > > } > > > > +/*simple draw trash function*/ > > +static void > > +homescreen_draw_trash(void *data, int x, int y) { > > + cairo_t *cr; > > + cairo_surface_t *surface; > > + struct homescreen *homescreen = data; > > Why don't you call this function with a struct homescreen* argument? > AFAICS it's only called by you directly. > I will change that, thank you. :)
> > + > > + if (key_trash_image) { > > + if (!trash_surface) { > > + trash_surface = > load_cairo_surface(key_trash_image); > > + } > > + } else { > > + trash_surface = NULL; > > + } > > + > > + if (!trash_surface) { > > + fprintf(stderr, "no trash image.\n"); > > + return; > > + } > > + > > + // set up trash allocation > > + if (!trash_allocation) { > > + trash_allocation = malloc(sizeof *trash_allocation); > > + trash_allocation->x = x; > > + trash_allocation->y = y; > > + trash_allocation->width = > > + > cairo_image_surface_get_width(trash_surface); > > + trash_allocation->height = > > + > cairo_image_surface_get_height(trash_surface); > > + } > > Could you do this initialization at startup instead on each redraw? > Yeah, that would be better. > > + surface = window_get_surface(homescreen->window); > > + cr = cairo_create(surface); > > + > > + cairo_set_source_surface(cr, trash_surface, > > + trash_allocation->x, > > + trash_allocation->y); > > + cairo_paint(cr); > > + > > + cairo_destroy(cr); > > + cairo_surface_destroy(surface); } > > + > > static void > > homescreen_draw(struct widget *widget, void *data) { @@ -203,6 > > +251,13 @@ homescreen_draw(struct widget *widget, void *data) > > } > > } > > > > + /* draw trash if dragging*/ > > + if(gl_launcher_drag && gl_launcher_drag->widget) { > > + homescreen_draw_trash(homescreen, > > + allocation.width * 0.6, > > + allocation.height * 0.6); > > + } > > + > > cairo_destroy(cr); > > cairo_surface_destroy(surface); } @@ -404,17 +459,83 @@ > > launcher_motion_handler(struct widget *widget, struct input *input, > > return CURSOR_HAND1; > > } > > > > +static int > > +layout_delete_launcher(struct launcher *launcher) { > > + char *config_file = config_file_path("weston-tablet.ini"); > > + FILE *fp; > > + char line[512]; > > + uint32_t found_pos = 0; > > + uint32_t next_pos = 0; > > + uint32_t end_length = 0; > > + uint32_t layout_num = launcher->layout->index; > > + uint32_t launcher_num = launcher->index; > > + > > + fp = fopen(config_file, "r"); > > + if (fp == NULL) { > > + fprintf(stderr, "couldn't open %s.\n", config_file); > > + return -1; > > You test the return value of this function against 0, so you should return 0 > on > error, not -1. But I think this function is generally kind of hacky... And I > think it > should be moved to shared/config-parser.c together with the other config > handling functions. > Yes a little hacky and not a decent way...I thought it wasn't so common to add In shared/config-parser.c. I would fix it. > > + } > > + while (fgets(line, sizeof line, fp)) { > > + if (strcmp("[layout]\n", line) == 0) > > + layout_num--; > > + if (layout_num == 0 && strcmp("[launcher]\n", line) == 0) > { > > + launcher_num--; > > + if (launcher_num == 0) { > > + found_pos = ftell(fp) - 11; > > + break; > > + } > > + } > > + } > > + fseek(fp, found_pos, SEEK_SET); > > + if (!fread(line, 1, 511, fp)) > > + { > > + fprintf(stderr, "read ini file error.\n"); > > + } > > + char *next = strchr(line + 10, '['); > > + next_pos = next - line + found_pos; > > + > > + char *start_content = malloc(sizeof (char) * (found_pos + 1)); > > + fseek(fp, 0, SEEK_END); > > + end_length = ftell(fp) - next_pos; > > + char *end_content = malloc(sizeof (char) * (end_length + 1)); > > + if (!start_content || !end_content) { > > + fprintf(stderr, "Not enough memory when changing ini > file.\n"); > > + return -1; > > + } > > + fseek(fp, 0, SEEK_SET); > > + if (!fread(start_content, 1, found_pos, fp)) > > + fprintf(stderr, "read ini file error.\n"); > > + fseek(fp, next_pos, SEEK_SET); > > + if (!fread(end_content, 1, end_length, fp)) > > + fprintf(stderr, "read ini file error.\n"); > > + fclose(fp); > > + fp = fopen(config_file, "w"); > > + fwrite(start_content, found_pos, 1, fp); > > + fwrite(end_content, end_length, 1, fp); > > + free(start_content); > > + free(end_content); > > + fclose(fp); > > + printf("launcher deleted.\n"); > > + return 1; > > +} > > static void > > launcher_data_handler(struct window *window, > > struct input *input, > > float x, float y, const char **types, void > > *data) { > > - if (!types) > > + if (!types || !trash_allocation) > > return; > > if (strcmp(types[0], "application/tablet-launcher") != 0) { > > return; > > } > > - input_accept(input, types[0]); > > + if (x > trash_allocation->x&& > > + x < trash_allocation->x + trash_allocation->width && > > + y > trash_allocation->y && > > + y < trash_allocation->y + trash_allocation->height) { > > I think it would be worth it to refactor this comparison into its own > function. > Maybe even move it to window.c, as it seems generally useful. > OK, I'll refactor it. Thanks. In window.c widget_find_widget() has similar usage. It may be reused. :) > > + input_accept(input, NULL); > > + } else { > > + input_accept(input, types[0]); > > + } > > } > > > > static void > > @@ -433,7 +554,31 @@ launcher_drop_handler(struct window *window, > > struct input *input, > > > > launcher->dragging = 0; > > launcher->pressed = 0; > > - gl_launcher_drag = NULL; > > + > > + if (x > trash_allocation->x && > > + x < trash_allocation->x + trash_allocation->width && > > + y > trash_allocation->y && > > + y < trash_allocation->y + trash_allocation->height) { > > + if (layout_delete_launcher(launcher)) { > > + wl_list_remove(&launcher->link); > > + widget_destroy(launcher->widget); > > + launcher->widget = NULL; > > + free((char*)launcher->path); > > + cairo_surface_destroy(launcher->icon); > > + > wl_data_source_destroy(launcher->data_source); > > + wl_surface_destroy(launcher->drag_surface); > > + cairo_surface_destroy(launcher->translucent); > > + cairo_surface_destroy(launcher->opaque); > > + int i = 1; > > + wl_list_for_each(temp_launcher, > > + &layout->launcher_list, > link) { > > + temp_launcher->index = i++; > > + } > > + > window_schedule_redraw(layout->homescreen->window); > > + } > > + } else { > > + gl_launcher_drag = NULL; > > + } > > > window_schedule_redraw(launcher->layout->homescreen->window); > > } > > > > @@ -900,6 +1045,7 @@ tablet_shell_add_layout(struct tablet *tablet) > > > > /* let layout know number of layouts */ > > layout->layout_list = &homescreen->layout_list; > > + layout->index = wl_list_length(layout->layout_list); > > > > wl_list_insert(homescreen->layout_list.prev, &layout->link); > > widget_set_button_handler(layout->widget, > > @@ -937,6 +1083,7 @@ layout_add_launcher(struct tablet *tablet, > > launcher->layout = layout; > > > > wl_list_insert(layout->launcher_list.prev, &launcher->link); > > + launcher->index = wl_list_length(&layout->launcher_list); > > > > launcher->widget = widget_add_widget(layout->widget, launcher); > > widget_set_enter_handler(launcher->widget, > > diff --git a/weston-tablet.ini b/weston-tablet.ini index > > b5239a8..58fd688 100644 > > --- a/weston-tablet.ini > > +++ b/weston-tablet.ini > > @@ -7,6 +7,7 @@ animation=zoom > > layout-rows=6 > > layout-columns=8 > > icon-size=64 > > +trash-image=/usr/share/weston/trash.png > > > > [layout] > > [launcher] > > -- > > 1.7.11.5 > > > > _______________________________________________ > > wayland-devel mailing list > > wayland-devel@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel