comparison src/gtkconv.c @ 12801:d24bc9737de8

[gaim-migrate @ 15148] Avoid infinite loopage when we can't generate enough colors. Hopefully someone will come up with a better solution and this will get removed; until then... committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Tue, 10 Jan 2006 03:30:37 +0000
parents eda1572c788b
children ebef62bc831a
comparison
equal deleted inserted replaced
12800:532db13558c3 12801:d24bc9737de8
126 #define MIN_BRIGHTNESS_CONTRAST 75 126 #define MIN_BRIGHTNESS_CONTRAST 75
127 #define MIN_COLOR_CONTRAST 200 127 #define MIN_COLOR_CONTRAST 200
128 128
129 #define NUM_NICK_COLORS 220 129 #define NUM_NICK_COLORS 220
130 static GdkColor *nick_colors = NULL; 130 static GdkColor *nick_colors = NULL;
131 static guint nbr_nick_colors;
131 132
132 typedef struct { 133 typedef struct {
133 GtkWidget *window; 134 GtkWidget *window;
134 135
135 GtkWidget *entry; 136 GtkWidget *entry;
161 static void update_typing_icon(GaimGtkConversation *gtkconv); 162 static void update_typing_icon(GaimGtkConversation *gtkconv);
162 static char *item_factory_translate_func (const char *path, gpointer func_data); 163 static char *item_factory_translate_func (const char *path, gpointer func_data);
163 gboolean gaim_gtkconv_has_focus(GaimConversation *conv); 164 gboolean gaim_gtkconv_has_focus(GaimConversation *conv);
164 static void gaim_gtkconv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data); 165 static void gaim_gtkconv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data);
165 static void gaim_gtkconv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data); 166 static void gaim_gtkconv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data);
166 static GdkColor* generate_nick_colors(guint numcolors, GdkColor background); 167 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
167 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 168 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
168 static void gaim_gtkconv_update_fields(GaimConversation *conv, GaimGtkConvFields fields); 169 static void gaim_gtkconv_update_fields(GaimConversation *conv, GaimGtkConvFields fields);
169 170
170 static GdkColor *get_nick_color(GaimGtkConversation *gtkconv, const char *name) { 171 static GdkColor *get_nick_color(GaimGtkConversation *gtkconv, const char *name) {
171 static GdkColor col; 172 static GdkColor col;
172 GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml); 173 GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml);
173 float scale; 174 float scale;
174 175
175 col = nick_colors[g_str_hash(name) % NUM_NICK_COLORS]; 176 col = nick_colors[g_str_hash(name) % nbr_nick_colors];
176 scale = ((1-(LUMINANCE(style->base[GTK_STATE_NORMAL]) / LUMINANCE(style->white))) * 177 scale = ((1-(LUMINANCE(style->base[GTK_STATE_NORMAL]) / LUMINANCE(style->white))) *
177 (LUMINANCE(style->white)/MAX(MAX(col.red, col.blue), col.green))); 178 (LUMINANCE(style->white)/MAX(MAX(col.red, col.blue), col.green)));
178 179
179 /* The colors are chosen to look fine on white; we should never have to darken */ 180 /* The colors are chosen to look fine on white; we should never have to darken */
180 if (scale > 1) { 181 if (scale > 1) {
4281 if (hidden) 4282 if (hidden)
4282 gaim_gtk_conv_window_add_gtkconv(hidden_convwin, gtkconv); 4283 gaim_gtk_conv_window_add_gtkconv(hidden_convwin, gtkconv);
4283 else 4284 else
4284 gaim_gtkconv_placement_place(gtkconv); 4285 gaim_gtkconv_placement_place(gtkconv);
4285 4286
4286 if (nick_colors == NULL) 4287 if (nick_colors == NULL) {
4287 nick_colors = generate_nick_colors(NUM_NICK_COLORS, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); 4288 nbr_nick_colors = NUM_NICK_COLORS;
4289 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]);
4290 }
4288 } 4291 }
4289 4292
4290 static void 4293 static void
4291 gaim_gtkconv_new_hidden(GaimConversation *conv) 4294 gaim_gtkconv_new_hidden(GaimConversation *conv)
4292 { 4295 {
8065 return ((col_diff > color_contrast) && (br_diff > brightness_contrast)); 8068 return ((col_diff > color_contrast) && (br_diff > brightness_contrast));
8066 } 8069 }
8067 8070
8068 8071
8069 static GdkColor* 8072 static GdkColor*
8070 generate_nick_colors(guint numcolors, GdkColor background) 8073 generate_nick_colors(guint *color_count, GdkColor background)
8071 { 8074 {
8075 guint numcolors = *color_count;
8072 guint i = 0, j = 0; 8076 guint i = 0, j = 0;
8073 GdkColor *colors = g_new(GdkColor, numcolors); 8077 GdkColor *colors = g_new(GdkColor, numcolors);
8074 GdkColor nick_highlight; 8078 GdkColor nick_highlight;
8075 GdkColor send_color; 8079 GdkColor send_color;
8080 time_t breakout_time;
8076 8081
8077 gdk_color_parse(HIGHLIGHT_COLOR, &nick_highlight); 8082 gdk_color_parse(HIGHLIGHT_COLOR, &nick_highlight);
8078 gdk_color_parse(SEND_COLOR, &send_color); 8083 gdk_color_parse(SEND_COLOR, &send_color);
8079 8084
8080 srand(background.red + background.green + background.blue + 1); 8085 srand(background.red + background.green + background.blue + 1);
8086
8087 breakout_time = time(NULL) + 3;
8081 8088
8082 /* first we look through the list of "good" colors: colors that differ from every other color in the 8089 /* first we look through the list of "good" colors: colors that differ from every other color in the
8083 * list. only some of them will differ from the background color though. lets see if we can find 8090 * list. only some of them will differ from the background color though. lets see if we can find
8084 * numcolors of them that do 8091 * numcolors of them that do
8085 */ 8092 */
8086 while (i < numcolors && j < NUM_NICK_SEED_COLORS ) 8093 while (i < numcolors && j < NUM_NICK_SEED_COLORS && time(NULL) < breakout_time)
8087 { 8094 {
8088 GdkColor color = nick_seed_colors[j]; 8095 GdkColor color = nick_seed_colors[j];
8089 8096
8090 if (color_is_visible(color, background, MIN_COLOR_CONTRAST, MIN_BRIGHTNESS_CONTRAST) && 8097 if (color_is_visible(color, background, MIN_COLOR_CONTRAST, MIN_BRIGHTNESS_CONTRAST) &&
8091 color_is_visible(color, nick_highlight, MIN_COLOR_CONTRAST / 2, 0) && 8098 color_is_visible(color, nick_highlight, MIN_COLOR_CONTRAST / 2, 0) &&
8100 /* we might not have found numcolors in the last loop. if we did, we'll never enter this one. 8107 /* we might not have found numcolors in the last loop. if we did, we'll never enter this one.
8101 * if we did not, lets just find some colors that don't conflict with the background. its 8108 * if we did not, lets just find some colors that don't conflict with the background. its
8102 * expensive to find colors that not only don't conflict with the background, but also do not 8109 * expensive to find colors that not only don't conflict with the background, but also do not
8103 * conflict with each other. 8110 * conflict with each other.
8104 */ 8111 */
8105 while(i < numcolors ) 8112 while(i < numcolors && time(NULL) < breakout_time)
8106 { 8113 {
8107 GdkColor color = { 0, rand() % 65536, rand() % 65536, rand() % 65536 }; 8114 GdkColor color = { 0, rand() % 65536, rand() % 65536, rand() % 65536 };
8108 8115
8109 gaim_debug(GAIM_DEBUG_WARNING, NULL, 8116 gaim_debug(GAIM_DEBUG_WARNING, NULL,
8110 "Looking for random colors to fill the list, I have found %i so far.\n",i); 8117 "Looking for random colors to fill the list, I have found %i so far.\n",i);
8116 colors[i] = color; 8123 colors[i] = color;
8117 i++; 8124 i++;
8118 } 8125 }
8119 } 8126 }
8120 8127
8128 if (i < numcolors) {
8129 GdkColor *c = colors;
8130 gaim_debug(GAIM_DEBUG_WARNING, NULL, "Unable to generate enough random colors before timeout. %u colors found.\n", i);
8131 colors = g_memdup(c, i * sizeof(GdkColor));
8132 g_free(c);
8133 *color_count = i;
8134
8135 }
8136
8121 return colors; 8137 return colors;
8122 } 8138 }