~ubuntu-branches/ubuntu/maverick/crossfire-client/maverick

« back to all changes in this revision

Viewing changes to gtk-v2/src/info.c

  • Committer: Bazaar Package Importer
  • Author(s): Kari Pahula
  • Date: 2007-04-13 21:15:44 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070413211544-vjo6zesj6g0wgmwf
Tags: 1.10.0-1
* New upstream release
* Install the README, README-dev and TODO files specific to the GTK2
  client to the corresponding package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
char *rcsid_gtk2_info_c =
2
 
    "$Id: info.c,v 1.5 2006/01/31 14:22:27 cavesomething Exp $";
 
2
    "$Id: info.c 5486 2007-02-11 09:03:55Z mwedel $";
3
3
/*
4
4
    Crossfire client, a client program for the crossfire program.
5
5
 
30
30
#endif
31
31
 
32
32
#include <gtk/gtk.h>
 
33
#include <ctype.h>
33
34
 
34
35
#include "client.h"
35
36
 
40
41
 
41
42
#include "main.h"
42
43
 
43
 
GtkWidget *textview_info1, *textview_info2, *sw1, *sw2;
44
 
GtkTextBuffer *textbuf1, *textbuf2;
45
 
GtkTextMark *textmark1, *textmark2;
46
 
 
47
 
/* text_tag2 to represent it for for textbuffer 2 */
48
 
GtkTextTag      *text_tag1[NUM_COLORS], *text_tag2[NUM_COLORS];
49
 
GtkAdjustment   *adj1, *adj2;
 
44
struct Info_Pane 
 
45
{
 
46
    GtkWidget       *textview;
 
47
    GtkWidget       *scrolled_window;
 
48
    GtkTextBuffer   *textbuffer;
 
49
    GtkTextMark     *textmark;
 
50
    GtkAdjustment   *adjustment;
 
51
    GtkTextTag      *text_tags[NUM_COLORS];
 
52
} info_pane[2];
 
53
 
 
54
 
 
55
static void message_callback(int flag, int type, int subtype, char *message);
 
56
 
 
57
/* Index into the different fonts.  font_families holds the names to
 
58
 * use for the font with pango - pango seems to take a comma seperated
 
59
 * listed.  What really should be done is let the use choose the fonts
 
60
 * to use, since most systems do not have most of the font families
 
61
 * listed (taken from gtk1 client)
 
62
 */
 
63
#define FONT_NORMAL     0
 
64
#define FONT_ARCANE     1
 
65
#define FONT_STRANGE    2
 
66
#define FONT_FIXED      3
 
67
#define FONT_HAND       4
 
68
#define NUM_FONTS       5
 
69
 
 
70
/* A fair number of these fonts can be found at:
 
71
 * http://www.dafont.com
 
72
 * This is in no way an endorsement of that site - just a place to go
 
73
 * to find them.
 
74
 * Fonts I found there:  blackforest, annstone (note, it doesn't have numbers!),
 
75
 *  dobkin
 
76
 * For a reason I'm not sure of, it doesn't seem to use the other fonts - I notice
 
77
 * with xfontsel, the options for weight and size are not enabled, so may be related
 
78
 * to that.
 
79
 * MSW 2006-09-17
 
80
 */
 
81
static char *font_families[NUM_FONTS] = {
 
82
    "arial,bookman,agate", 
 
83
    "cuneifontlight,linotext,blackforest,becker,arnoldboecklin,caligula,helvetica",
 
84
    "annstone,shalomstick",
 
85
    /* fixed doesn't scale, so put it at the end */
 
86
    "courier,andale mono,urw bookman l,fixed",
 
87
    "dobkin,coronetscript,muriel,genoa,parkavenue,rechtmanscript,luxi serif"
 
88
};
 
89
 
 
90
extern  char *colorname[NUM_COLORS];
50
91
 
51
92
void info_init(GtkWidget *window_root)
52
93
{
53
94
    int i;
54
95
    GtkTextIter end;
55
 
    extern  char *colorname[NUM_COLORS];
56
 
 
57
 
    textview_info1 = lookup_widget(window_root,"textview_info1");
58
 
    textview_info2 = lookup_widget(window_root,"textview_info2");
59
 
    sw1 = lookup_widget(window_root, "scrolledwindow_textview1");
60
 
    sw2 = lookup_widget(window_root, "scrolledwindow_textview2");
61
 
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview_info1), GTK_WRAP_WORD);
62
 
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview_info2), GTK_WRAP_WORD);
63
 
    textbuf1=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview_info1));
64
 
    textbuf2=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview_info2));
65
 
    adj1 = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(sw1));
66
 
    adj2 = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(sw2));
67
 
 
68
 
    gtk_text_buffer_get_end_iter(textbuf1, &end);
69
 
    textmark1 =  gtk_text_buffer_create_mark(textbuf1, NULL, &end, FALSE);
70
 
 
71
 
    gtk_text_buffer_get_end_iter(textbuf2, &end);
72
 
    textmark2 =  gtk_text_buffer_create_mark(textbuf2, NULL, &end, FALSE);
 
96
 
 
97
    info_pane[0].textview = lookup_widget(window_root,"textview_info1");
 
98
    info_pane[1].textview = lookup_widget(window_root,"textview_info2");
 
99
    info_pane[0].scrolled_window = lookup_widget(window_root, "scrolledwindow_textview1");
 
100
    info_pane[1].scrolled_window = lookup_widget(window_root, "scrolledwindow_textview2");
 
101
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(info_pane[0].textview), GTK_WRAP_WORD);
 
102
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(info_pane[1].textview), GTK_WRAP_WORD);
 
103
    info_pane[0].textbuffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(info_pane[0].textview));
 
104
    info_pane[1].textbuffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(info_pane[1].textview));
 
105
    info_pane[0].adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(info_pane[0].scrolled_window));
 
106
    info_pane[1].adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(info_pane[1].scrolled_window));
 
107
 
 
108
    gtk_text_buffer_get_end_iter(info_pane[0].textbuffer, &end);
 
109
    info_pane[0].textmark =  gtk_text_buffer_create_mark(info_pane[0].textbuffer, NULL, &end, FALSE);
 
110
 
 
111
    gtk_text_buffer_get_end_iter(info_pane[1].textbuffer, &end);
 
112
    info_pane[1].textmark =  gtk_text_buffer_create_mark(info_pane[1].textbuffer, NULL, &end, FALSE);
73
113
 
74
114
    for (i=0; i<NUM_COLORS; i++) {
75
 
        text_tag1[i] = gtk_text_buffer_create_tag(textbuf1, NULL, "foreground", colorname[i],NULL);
76
 
        text_tag2[i] = gtk_text_buffer_create_tag(textbuf2, NULL, "foreground", colorname[i],NULL);
77
 
    }
 
115
        info_pane[0].text_tags[i] = gtk_text_buffer_create_tag(info_pane[0].textbuffer, NULL, "foreground", colorname[i],NULL);
 
116
        info_pane[1].text_tags[i] = gtk_text_buffer_create_tag(info_pane[1].textbuffer, NULL, "foreground", colorname[i],NULL);
 
117
    }
 
118
 
 
119
    setTextManager(MSG_TYPE_BOOK,message_callback);
 
120
    setTextManager(MSG_TYPE_CARD,message_callback);
 
121
    setTextManager(MSG_TYPE_PAPER,message_callback);
 
122
    setTextManager(MSG_TYPE_SIGN,message_callback);
 
123
    setTextManager(MSG_TYPE_MONUMENT,message_callback);
 
124
    setTextManager(MSG_TYPE_SCRIPTED_DIALOG,message_callback);
 
125
    setTextManager(MSG_TYPE_MOTD,message_callback);
 
126
    setTextManager(MSG_TYPE_ADMIN,message_callback);
 
127
    setTextManager(MSG_TYPE_SHOP,message_callback);
 
128
    setTextManager(MSG_TYPE_COMMAND,message_callback);
 
129
 
 
130
}
 
131
 
 
132
 
 
133
static void add_to_textbuf(int pane, char *message, int weight, int style, int font, char *color, int underline)
 
134
{
 
135
    GtkTextIter end;
 
136
    GdkRectangle rect;
 
137
    int scroll_to_end=0;
 
138
    gdouble scale=1.0;
 
139
    GtkTextTag      *tag;
 
140
    char    tagname[MAX_BUF];
 
141
 
 
142
    gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(info_pane[pane].textview), &rect);
 
143
    if ((info_pane[pane].adjustment->value + rect.height) >= info_pane[pane].adjustment->upper ) scroll_to_end=1;
 
144
 
 
145
    /* A bit of a hack, but relative to the proportional fonts, the fixed font is
 
146
     * bigger, and thus needs to be scaled down some for things to look
 
147
     * right
 
148
     */
 
149
    if (font == FONT_FIXED)  scale=0.9;
 
150
 
 
151
    /* In order not to create thousands of tags (memory leak) or have to do logic to
 
152
     * periodically clean up old text tags, give each text tag a name that describes
 
153
     * all the attributes.  If that tag exists, re-use it.  If it doesn't, create
 
154
     * a new tag of that name.
 
155
     */
 
156
    sprintf(tagname, "weight%d-style%d-family%s-foreground%s-scale%f-underline%d",
 
157
            weight, style, font_families[font], color, scale, underline);
 
158
 
 
159
    if ((tag=gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(info_pane[pane].textbuffer),tagname))==NULL) {
 
160
        tag = gtk_text_buffer_create_tag(info_pane[pane].textbuffer, tagname,
 
161
                "weight", weight,
 
162
                "style", style,
 
163
                "family", font_families[font],
 
164
                "foreground", color,
 
165
                "scale", scale,
 
166
                "underline", underline,
 
167
                 NULL);
 
168
    }
 
169
 
 
170
    gtk_text_buffer_get_end_iter(info_pane[pane].textbuffer, &end);
 
171
 
 
172
    gtk_text_buffer_insert_with_tags(info_pane[pane].textbuffer, &end, message , strlen(message),
 
173
            tag, NULL);
 
174
 
 
175
    if (scroll_to_end)
 
176
        gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(info_pane[pane].textview), info_pane[pane].textmark);
 
177
 
 
178
}
 
179
 
 
180
/* Unlike the gtk client, we don't do anything tricky like popups
 
181
 * with different message types.
 
182
 * However, we will choose different fonts, etc, based on this information -
 
183
 * for this reason, we just use one callback, and change those minor
 
184
 * things based on the callback.
 
185
 * We also need to parse the data.
 
186
 */
 
187
static void message_callback(int orig_color, int type, int subtype, char *message) {
 
188
    char *marker, *current, *original;
 
189
    int weight=PANGO_WEIGHT_NORMAL;
 
190
    int style=PANGO_STYLE_NORMAL;
 
191
    int font=FONT_NORMAL, underline=PANGO_UNDERLINE_NONE;
 
192
    char *color=colorname[orig_color];
 
193
 
 
194
    current = strdup(message);
 
195
    original = current;         /* Just so we know what to free */
 
196
 
 
197
    /* The server prefixes the message with a flag which denotes
 
198
     * if it is an auto message or not - we don't care for the gtk2
 
199
     * client, but want to strip it out.
 
200
     */
 
201
    if (type == MSG_TYPE_SIGN && isdigit(message[0])) {
 
202
        current+=2;     /* Skip the number and space */
 
203
    }
 
204
 
 
205
    while ((marker = strchr(current,'['))!= NULL) {
 
206
        *marker = 0;
 
207
        add_to_textbuf(0,current, weight, style, font, color, underline);
 
208
        current=marker+1;
 
209
        if ((marker = strchr(current,']')) == NULL) {
 
210
            free(original);
 
211
            return;
 
212
        }
 
213
        *marker = 0;
 
214
        if (!strcmp(current,"b"))       weight = PANGO_WEIGHT_BOLD;
 
215
        else if (!strcmp(current,"/b")) weight = PANGO_WEIGHT_NORMAL;
 
216
        else if (!strcmp(current,"i"))  style = PANGO_STYLE_ITALIC;
 
217
        else if (!strcmp(current,"/i")) style = PANGO_STYLE_NORMAL;
 
218
        else if (!strcmp(current,"ul"))         underline=PANGO_UNDERLINE_SINGLE;
 
219
        else if (!strcmp(current,"/ul"))        underline=PANGO_UNDERLINE_NONE;
 
220
        else if (!strcmp(current,"fixed"))      font = FONT_FIXED;
 
221
        else if (!strcmp(current,"arcane"))     font = FONT_ARCANE;
 
222
        else if (!strcmp(current,"hand"))       font = FONT_HAND;
 
223
        else if (!strcmp(current,"strange"))    font = FONT_STRANGE;
 
224
        else if (!strcmp(current,"print"))      font = FONT_NORMAL;
 
225
        else if (!strcmp(current,"/color"))     color = colorname[orig_color];
 
226
        else if (!strncmp(current,"color=",6))  color = current + 6;
 
227
        else LOG(LOG_INFO, "info.c::message_callback", "unidentified message: %s\n", current);
 
228
        current = marker+1;
 
229
 
 
230
    }
 
231
    add_to_textbuf(0,current, weight, style, font, color, underline);
 
232
    add_to_textbuf(0, "\n", weight, style, font, color, underline);
 
233
    free(original);
78
234
}
79
235
 
80
236
/* draw_info adds a line to the info window.
102
258
     * etc)
103
259
     * We need to find out the position before putting in new text -
104
260
     * otherwise, that operation will mess up our position, and
105
 
     * not giv us right info.
 
261
     * not give us right info.
106
262
     */
107
 
    gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(textview_info1), &rect);
108
 
    if ((adj1->value + rect.height) >= adj1->upper ) scroll_to_end=1;
 
263
    gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(info_pane[0].textview), &rect);
 
264
    if ((info_pane[0].adjustment->value + rect.height) >= info_pane[0].adjustment->upper ) scroll_to_end=1;
109
265
 
110
266
    if (color == NDI_BLACK) {
111
 
        gtk_text_buffer_get_end_iter(textbuf1, &end);
112
 
        gtk_text_buffer_insert(textbuf1, &end, str , strlen(str));
113
 
        gtk_text_buffer_insert(textbuf1, &end, "\n" , 1);
 
267
        gtk_text_buffer_get_end_iter(info_pane[0].textbuffer, &end);
 
268
        gtk_text_buffer_insert(info_pane[0].textbuffer, &end, str , strlen(str));
 
269
        gtk_text_buffer_insert(info_pane[0].textbuffer, &end, "\n" , 1);
114
270
 
115
271
        if (scroll_to_end)
116
 
            gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(textview_info1), textmark1);
 
272
            gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(info_pane[0].textview), info_pane[0].textmark);
117
273
    } else {
118
 
        gtk_text_buffer_get_end_iter(textbuf1, &end);
119
 
        gtk_text_buffer_insert_with_tags(textbuf1, &end, str , strlen(str), text_tag1[ncolor], NULL);
120
 
        gtk_text_buffer_insert(textbuf1, &end, "\n" , 1);
 
274
        gtk_text_buffer_get_end_iter(info_pane[0].textbuffer, &end);
 
275
        gtk_text_buffer_insert_with_tags(info_pane[0].textbuffer, &end, str , strlen(str), info_pane[0].text_tags[ncolor], NULL);
 
276
        gtk_text_buffer_insert(info_pane[0].textbuffer, &end, "\n" , 1);
121
277
 
122
278
        if (scroll_to_end)
123
 
            gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(textview_info1), textmark1);
 
279
            gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(info_pane[0].textview), info_pane[0].textmark);
124
280
 
125
 
        gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(textview_info2), &rect);
126
 
        if ((adj2->value + rect.height) >= adj2->upper ) scroll_to_end=1;
 
281
        gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(info_pane[1].textview), &rect);
 
282
        if ((info_pane[1].adjustment->value + rect.height) >= info_pane[1].adjustment->upper ) scroll_to_end=1;
127
283
        else scroll_to_end=0;
128
284
 
129
 
        gtk_text_buffer_get_end_iter(textbuf2, &end);
130
 
        gtk_text_buffer_insert_with_tags(textbuf2, &end, str , strlen(str), text_tag2[ncolor], NULL);
131
 
        gtk_text_buffer_insert(textbuf2, &end, "\n" , 1);
 
285
        gtk_text_buffer_get_end_iter(info_pane[1].textbuffer, &end);
 
286
        gtk_text_buffer_insert_with_tags(info_pane[1].textbuffer, &end, str , strlen(str), info_pane[1].text_tags[ncolor], NULL);
 
287
        gtk_text_buffer_insert(info_pane[1].textbuffer, &end, "\n" , 1);
132
288
 
133
289
        if (scroll_to_end)
134
 
            gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(textview_info2), textmark2);
 
290
            gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(info_pane[1].textview), info_pane[1].textmark);
135
291
    }
136
292
}
137
293
 
145
301
 * support it.
146
302
 */
147
303
void menu_clear() {
148
 
    gtk_text_buffer_set_text(textbuf1, "", 0);
149
 
    gtk_text_buffer_set_text(textbuf2, "", 0);
 
304
    gtk_text_buffer_set_text(info_pane[0].textbuffer, "", 0);
 
305
    gtk_text_buffer_set_text(info_pane[1].textbuffer, "", 0);
150
306
}
151
307
 
152
308
/* All the following are 'dummy' functions.  Basically, there are callbacks