Mercurial > pidgin
comparison src/conversation.c @ 2191:657dbe515608
[gaim-migrate @ 2201]
genericize buddy icon stuff
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Wed, 29 Aug 2001 23:41:43 +0000 |
| parents | edf8c5a70e5b |
| children | d615f7e2d8c4 |
comparison
equal
deleted
inserted
replaced
| 2190:24d947eff811 | 2191:657dbe515608 |
|---|---|
| 73 extern GdkColor fgcolor; | 73 extern GdkColor fgcolor; |
| 74 | 74 |
| 75 void check_everything(GtkWidget *entry); | 75 void check_everything(GtkWidget *entry); |
| 76 gboolean keypress_callback(GtkWidget *entry, GdkEventKey * event, struct conversation *c); | 76 gboolean keypress_callback(GtkWidget *entry, GdkEventKey * event, struct conversation *c); |
| 77 | 77 |
| 78 static void update_icon(struct conversation *); | |
| 79 static void remove_icon(struct conversation *); | |
| 80 | |
| 78 /*------------------------------------------------------------------------*/ | 81 /*------------------------------------------------------------------------*/ |
| 79 /* Helpers */ | 82 /* Helpers */ |
| 80 /*------------------------------------------------------------------------*/ | 83 /*------------------------------------------------------------------------*/ |
| 81 | 84 |
| 82 | 85 |
| 154 c->history = g_string_new(""); | 157 c->history = g_string_new(""); |
| 155 conversations = g_list_append(conversations, c); | 158 conversations = g_list_append(conversations, c); |
| 156 show_conv(c); | 159 show_conv(c); |
| 157 if (c->gc && c->gc->prpl && c->gc->prpl->insert_convo) | 160 if (c->gc && c->gc->prpl && c->gc->prpl->insert_convo) |
| 158 (*c->gc->prpl->insert_convo)(c->gc, c); | 161 (*c->gc->prpl->insert_convo)(c->gc, c); |
| 162 update_icon(c); | |
| 159 plugin_event(event_new_conversation, name, 0, 0, 0); | 163 plugin_event(event_new_conversation, name, 0, 0, 0); |
| 160 return c; | 164 return c; |
| 161 } | 165 } |
| 162 | 166 |
| 163 | 167 |
| 409 gtkspell_detach(GTK_TEXT(c->entry)); | 413 gtkspell_detach(GTK_TEXT(c->entry)); |
| 410 | 414 |
| 411 if (!c->is_chat) { | 415 if (!c->is_chat) { |
| 412 if (c->gc && c->gc->prpl && c->gc->prpl->remove_convo) | 416 if (c->gc && c->gc->prpl && c->gc->prpl->remove_convo) |
| 413 (*c->gc->prpl->remove_convo)(c->gc, c); | 417 (*c->gc->prpl->remove_convo)(c->gc, c); |
| 418 remove_icon(c); | |
| 414 if (display_options & OPT_DISP_ONE_WINDOW) { | 419 if (display_options & OPT_DISP_ONE_WINDOW) { |
| 415 if (g_list_length(conversations) > 1) { | 420 if (g_list_length(conversations) > 1) { |
| 416 gtk_notebook_remove_page(GTK_NOTEBOOK(convo_notebook), | 421 gtk_notebook_remove_page(GTK_NOTEBOOK(convo_notebook), |
| 417 g_list_index(conversations, c)); | 422 g_list_index(conversations, c)); |
| 418 } else { | 423 } else { |
| 1783 | 1788 |
| 1784 update_buttons_by_protocol(cnv); | 1789 update_buttons_by_protocol(cnv); |
| 1785 | 1790 |
| 1786 if (cnv->gc && cnv->gc->prpl && cnv->gc->prpl->insert_convo) | 1791 if (cnv->gc && cnv->gc->prpl && cnv->gc->prpl->insert_convo) |
| 1787 (*cnv->gc->prpl->insert_convo)(cnv->gc, cnv); | 1792 (*cnv->gc->prpl->insert_convo)(cnv->gc, cnv); |
| 1793 update_icon(cnv); | |
| 1788 } | 1794 } |
| 1789 | 1795 |
| 1790 void update_convo_add_button(struct conversation *c) | 1796 void update_convo_add_button(struct conversation *c) |
| 1791 { | 1797 { |
| 1792 int dispstyle = set_dispstyle(0); | 1798 int dispstyle = set_dispstyle(0); |
| 1890 C = (struct conversation *)c->data; | 1896 C = (struct conversation *)c->data; |
| 1891 c = c->next; | 1897 c = c->next; |
| 1892 | 1898 |
| 1893 if (C->gc && C->gc->prpl && C->gc->prpl->remove_convo) | 1899 if (C->gc && C->gc->prpl && C->gc->prpl->remove_convo) |
| 1894 (*C->gc->prpl->remove_convo)(C->gc, C); | 1900 (*C->gc->prpl->remove_convo)(C->gc, C); |
| 1901 remove_icon(C); | |
| 1895 } | 1902 } |
| 1896 } | 1903 } |
| 1897 | 1904 |
| 1898 void set_convo_gc(struct conversation *c, struct gaim_connection *gc) | 1905 void set_convo_gc(struct conversation *c, struct gaim_connection *gc) |
| 1899 { | 1906 { |
| 1910 | 1917 |
| 1911 update_buttons_by_protocol(c); | 1918 update_buttons_by_protocol(c); |
| 1912 | 1919 |
| 1913 if (c->gc && c->gc->prpl && c->gc->prpl->insert_convo) | 1920 if (c->gc && c->gc->prpl && c->gc->prpl->insert_convo) |
| 1914 (*c->gc->prpl->insert_convo)(c->gc, c); | 1921 (*c->gc->prpl->insert_convo)(c->gc, c); |
| 1922 update_icon(c); | |
| 1915 } | 1923 } |
| 1916 | 1924 |
| 1917 void update_buttons_by_protocol(struct conversation *c) | 1925 void update_buttons_by_protocol(struct conversation *c) |
| 1918 { | 1926 { |
| 1919 if (!c->gc) | 1927 if (!c->gc) |
| 2334 | 2342 |
| 2335 imhtml = c->text; | 2343 imhtml = c->text; |
| 2336 win = c->window; | 2344 win = c->window; |
| 2337 if (c->gc && c->gc->prpl->remove_convo) | 2345 if (c->gc && c->gc->prpl->remove_convo) |
| 2338 (*c->gc->prpl->remove_convo)(c->gc, c); | 2346 (*c->gc->prpl->remove_convo)(c->gc, c); |
| 2347 remove_icon(c); | |
| 2339 show_conv(c); | 2348 show_conv(c); |
| 2340 gtk_widget_destroy(c->text); | 2349 gtk_widget_destroy(c->text); |
| 2341 gtk_widget_reparent(imhtml, c->sw); | 2350 gtk_widget_reparent(imhtml, c->sw); |
| 2342 c->text = imhtml; | 2351 c->text = imhtml; |
| 2343 gtk_widget_destroy(win); | 2352 gtk_widget_destroy(win); |
| 2344 if (c->gc && c->gc->prpl->insert_convo) | 2353 if (c->gc && c->gc->prpl->insert_convo) |
| 2345 (*c->gc->prpl->insert_convo)(c->gc, c); | 2354 (*c->gc->prpl->insert_convo)(c->gc, c); |
| 2355 update_icon(c); | |
| 2346 | 2356 |
| 2347 x = x->next; | 2357 x = x->next; |
| 2348 } | 2358 } |
| 2349 } else { | 2359 } else { |
| 2350 GList *x, *m; | 2360 GList *x, *m; |
| 2355 GtkWidget *imhtml; | 2365 GtkWidget *imhtml; |
| 2356 | 2366 |
| 2357 imhtml = c->text; | 2367 imhtml = c->text; |
| 2358 if (c->gc && c->gc->prpl->remove_convo) | 2368 if (c->gc && c->gc->prpl->remove_convo) |
| 2359 (*c->gc->prpl->remove_convo)(c->gc, c); | 2369 (*c->gc->prpl->remove_convo)(c->gc, c); |
| 2370 remove_icon(c); | |
| 2360 show_conv(c); | 2371 show_conv(c); |
| 2361 gtk_widget_destroy(c->text); | 2372 gtk_widget_destroy(c->text); |
| 2362 gtk_widget_reparent(imhtml, c->sw); | 2373 gtk_widget_reparent(imhtml, c->sw); |
| 2363 c->text = imhtml; | 2374 c->text = imhtml; |
| 2364 if (c->gc && c->gc->prpl->insert_convo) | 2375 if (c->gc && c->gc->prpl->insert_convo) |
| 2365 (*c->gc->prpl->insert_convo)(c->gc, c); | 2376 (*c->gc->prpl->insert_convo)(c->gc, c); |
| 2377 update_icon(c); | |
| 2366 | 2378 |
| 2367 x = x->next; | 2379 x = x->next; |
| 2368 } | 2380 } |
| 2369 if (all_convos) | 2381 if (all_convos) |
| 2370 gtk_widget_destroy(all_convos); | 2382 gtk_widget_destroy(all_convos); |
| 2459 c = c->next; | 2471 c = c->next; |
| 2460 if (b->hasfont) continue; | 2472 if (b->hasfont) continue; |
| 2461 sprintf(b->fontface, "%s", fontface); | 2473 sprintf(b->fontface, "%s", fontface); |
| 2462 } | 2474 } |
| 2463 } | 2475 } |
| 2476 | |
| 2477 #if USE_PIXBUF | |
| 2478 #include <gdk-pixbuf/gdk-pixbuf.h> | |
| 2479 #include <gdk-pixbuf/gdk-pixbuf-loader.h> | |
| 2480 #define SCALE 48 | |
| 2481 | |
| 2482 static gboolean redraw_icon(gpointer data) | |
| 2483 { | |
| 2484 struct conversation *c = data; | |
| 2485 | |
| 2486 GList *frames; | |
| 2487 GdkPixbufFrame *frame; | |
| 2488 GdkPixbuf *buf; | |
| 2489 GdkPixbuf *scale; | |
| 2490 GdkPixmap *src; | |
| 2491 GdkPixmap *pm; | |
| 2492 GdkBitmap *bm; | |
| 2493 GdkGC *gc; | |
| 2494 gint delay; | |
| 2495 | |
| 2496 if (!g_list_find(conversations, c)) { | |
| 2497 debug_printf("I think this is a bug.\n"); | |
| 2498 return FALSE; | |
| 2499 } | |
| 2500 | |
| 2501 frames = gdk_pixbuf_animation_get_frames(c->anim); | |
| 2502 frame = g_list_nth_data(frames, c->frame); | |
| 2503 switch (gdk_pixbuf_frame_get_action(frame)) { | |
| 2504 case GDK_PIXBUF_FRAME_RETAIN: | |
| 2505 buf = gdk_pixbuf_frame_get_pixbuf(frame); | |
| 2506 scale = gdk_pixbuf_scale_simple(buf, | |
| 2507 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
| 2508 gdk_pixbuf_animation_get_width(c->anim), 1), | |
| 2509 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
| 2510 gdk_pixbuf_animation_get_height(c->anim), 1), | |
| 2511 GDK_INTERP_NEAREST); | |
| 2512 gdk_pixbuf_render_pixmap_and_mask(scale, &src, NULL, 0); | |
| 2513 gdk_pixbuf_unref(scale); | |
| 2514 gtk_pixmap_get(GTK_PIXMAP(c->icon), &pm, &bm); | |
| 2515 gc = gdk_gc_new(pm); | |
| 2516 gdk_draw_pixmap(pm, gc, src, 0, 0, | |
| 2517 MAX(gdk_pixbuf_frame_get_x_offset(frame) * SCALE / | |
| 2518 gdk_pixbuf_animation_get_width(c->anim), 1), | |
| 2519 MAX(gdk_pixbuf_frame_get_y_offset(frame) * SCALE / | |
| 2520 gdk_pixbuf_animation_get_height(c->anim), 1), | |
| 2521 -1, -1); | |
| 2522 gdk_pixmap_unref(src); | |
| 2523 gtk_widget_queue_draw(c->icon); | |
| 2524 gdk_gc_unref(gc); | |
| 2525 break; | |
| 2526 case GDK_PIXBUF_FRAME_DISPOSE: | |
| 2527 buf = gdk_pixbuf_frame_get_pixbuf(frame); | |
| 2528 scale = gdk_pixbuf_scale_simple(buf, | |
| 2529 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
| 2530 gdk_pixbuf_animation_get_width(c->anim), 1), | |
| 2531 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
| 2532 gdk_pixbuf_animation_get_height(c->anim), 1), | |
| 2533 GDK_INTERP_NEAREST); | |
| 2534 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
| 2535 gdk_pixbuf_unref(scale); | |
| 2536 gtk_pixmap_set(GTK_PIXMAP(c->icon), pm, bm); | |
| 2537 gdk_pixmap_unref(pm); | |
| 2538 if (bm) | |
| 2539 gdk_bitmap_unref(bm); | |
| 2540 break; | |
| 2541 case GDK_PIXBUF_FRAME_REVERT: | |
| 2542 frame = frames->data; | |
| 2543 buf = gdk_pixbuf_frame_get_pixbuf(frame); | |
| 2544 scale = gdk_pixbuf_scale_simple(buf, | |
| 2545 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
| 2546 gdk_pixbuf_animation_get_width(c->anim), 1), | |
| 2547 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
| 2548 gdk_pixbuf_animation_get_height(c->anim), 1), | |
| 2549 GDK_INTERP_NEAREST); | |
| 2550 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
| 2551 gdk_pixbuf_unref(scale); | |
| 2552 gtk_pixmap_set(GTK_PIXMAP(c->icon), pm, bm); | |
| 2553 gdk_pixmap_unref(pm); | |
| 2554 if (bm) | |
| 2555 gdk_bitmap_unref(bm); | |
| 2556 break; | |
| 2557 } | |
| 2558 | |
| 2559 c->frame = (c->frame + 1) % g_list_length(frames); | |
| 2560 delay = MAX(gdk_pixbuf_frame_get_delay_time(frame), 13); | |
| 2561 c->icon_timer = gtk_timeout_add(delay * 10, redraw_icon, c); | |
| 2562 | |
| 2563 return FALSE; | |
| 2564 } | |
| 2565 #endif | |
| 2566 | |
| 2567 void remove_icon(struct conversation *c) | |
| 2568 { | |
| 2569 #if USE_PIXBUF | |
| 2570 if (c->icon) | |
| 2571 gtk_container_remove(GTK_CONTAINER(c->bbox), c->icon); | |
| 2572 c->icon = NULL; | |
| 2573 if (c->anim) | |
| 2574 gdk_pixbuf_animation_unref(c->anim); | |
| 2575 c->anim = NULL; | |
| 2576 if (c->unanim) | |
| 2577 gdk_pixbuf_unref(c->unanim); | |
| 2578 c->unanim = NULL; | |
| 2579 if (c->icon_timer) | |
| 2580 gtk_timeout_remove(c->icon_timer); | |
| 2581 c->icon_timer = 0; | |
| 2582 c->frame = 0; | |
| 2583 #endif | |
| 2584 } | |
| 2585 | |
| 2586 void update_icon(struct conversation *c) | |
| 2587 { | |
| 2588 #if USE_PIXBUF | |
| 2589 void *data; | |
| 2590 int len; | |
| 2591 | |
| 2592 GdkPixbufLoader *load; | |
| 2593 GdkPixbuf *scale; | |
| 2594 GdkPixmap *pm; | |
| 2595 GdkBitmap *bm; | |
| 2596 | |
| 2597 if (!c) | |
| 2598 return; | |
| 2599 | |
| 2600 if (!c->gc) | |
| 2601 return; | |
| 2602 data = get_icon_data(c->gc, normalize(c->name), &len); | |
| 2603 if (!data) | |
| 2604 return; | |
| 2605 | |
| 2606 load = gdk_pixbuf_loader_new(); | |
| 2607 gdk_pixbuf_loader_write(load, data, len); | |
| 2608 c->anim = gdk_pixbuf_loader_get_animation(load); | |
| 2609 | |
| 2610 if (c->anim) { | |
| 2611 GList *frames = gdk_pixbuf_animation_get_frames(c->anim); | |
| 2612 GdkPixbuf *buf = gdk_pixbuf_frame_get_pixbuf(frames->data); | |
| 2613 scale = gdk_pixbuf_scale_simple(buf, | |
| 2614 MAX(gdk_pixbuf_get_width(buf) * SCALE / | |
| 2615 gdk_pixbuf_animation_get_width(c->anim), 1), | |
| 2616 MAX(gdk_pixbuf_get_height(buf) * SCALE / | |
| 2617 gdk_pixbuf_animation_get_height(c->anim), 1), | |
| 2618 GDK_INTERP_NEAREST); | |
| 2619 | |
| 2620 if (gdk_pixbuf_animation_get_num_frames(c->anim) > 1) { | |
| 2621 int delay = MAX(gdk_pixbuf_frame_get_delay_time(frames->data), 13); | |
| 2622 c->frame = 1; | |
| 2623 c->icon_timer = gtk_timeout_add(delay * 10, redraw_icon, c); | |
| 2624 } | |
| 2625 } else { | |
| 2626 c->unanim = gdk_pixbuf_loader_get_pixbuf(load); | |
| 2627 if (!c->unanim) { | |
| 2628 gdk_pixbuf_loader_close(load); | |
| 2629 return; | |
| 2630 } | |
| 2631 scale = gdk_pixbuf_scale_simple(c->unanim, SCALE, SCALE, GDK_INTERP_NEAREST); | |
| 2632 } | |
| 2633 | |
| 2634 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); | |
| 2635 gdk_pixbuf_unref(scale); | |
| 2636 | |
| 2637 c->icon = gtk_pixmap_new(pm, bm); | |
| 2638 gtk_box_pack_start(GTK_BOX(c->bbox), c->icon, FALSE, FALSE, 5); | |
| 2639 gtk_widget_show(c->icon); | |
| 2640 gdk_pixmap_unref(pm); | |
| 2641 if (bm) | |
| 2642 gdk_bitmap_unref(bm); | |
| 2643 | |
| 2644 gdk_pixbuf_loader_close(load); | |
| 2645 #endif | |
| 2646 } | |
| 2647 | |
| 2648 void got_new_icon(struct gaim_connection *gc, char *who) | |
| 2649 { | |
| 2650 struct conversation *c = find_conversation(who); | |
| 2651 if (c->gc == gc) | |
| 2652 update_icon(c); | |
| 2653 } |
