~ubuntu-branches/ubuntu/feisty/liquidwar/feisty

« back to all changes in this revision

Viewing changes to src/alleg2.c

  • Committer: Bazaar Package Importer
  • Author(s): Eduard Bloch
  • Date: 2002-03-15 10:25:19 UTC
  • Revision ID: james.westby@ubuntu.com-20020315102519-oh5c0i7s7j7pbtay
Tags: upstream-5.4.5
ImportĀ upstreamĀ versionĀ 5.4.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************/
 
2
/*                                                                  */
 
3
/*            L   I  QQ  U U I DD    W   W  A  RR    555            */
 
4
/*            L   I Q  Q U U I D D   W   W A A R R   5              */
 
5
/*            L   I Q  Q U U I D D   W W W AAA RR    55             */
 
6
/*            L   I Q Q  U U I D D   WW WW A A R R     5            */
 
7
/*            LLL I  Q Q  U  I DD    W   W A A R R   55             */
 
8
/*                                                                  */
 
9
/*                             b                                    */
 
10
/*                             bb  y y                              */
 
11
/*                             b b yyy                              */
 
12
/*                             bb    y                              */
 
13
/*                                 yy                               */
 
14
/*                                                                  */
 
15
/*                     U U       FFF  O   O  TTT                    */
 
16
/*                     U U       F   O O O O  T                     */
 
17
/*                     U U TIRET FF  O O O O  T                     */
 
18
/*                     U U       F   O O O O  T                     */
 
19
/*                      U        F    O   O   T                     */
 
20
/*                                                                  */
 
21
/********************************************************************/
 
22
 
 
23
/*****************************************************************************/
 
24
/* Liquid War is a unique multiplayer wargame                                */
 
25
/* Copyright (C) 1998-2002 Christian Mauduit                                 */
 
26
/*                                                                           */
 
27
/* This program is free software; you can redistribute it and/or modify      */
 
28
/* it under the terms of the GNU General Public License as published by      */
 
29
/* the Free Software Foundation; either version 2 of the License, or         */
 
30
/* (at your option) any later version.                                       */
 
31
/*                                                                           */
 
32
/* This program is distributed in the hope that it will be useful,           */
 
33
/* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
 
34
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
 
35
/* GNU General Public License for more details.                              */
 
36
/*                                                                           */
 
37
/* You should have received a copy of the GNU General Public License         */
 
38
/* along with this program; if not, write to the Free Software               */
 
39
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
40
/*                                                                           */
 
41
/* Liquid War homepage : http://www.ufoot.org/liquidwar                      */
 
42
/* Contact author      : ufoot@ufoot.org                                     */
 
43
/*****************************************************************************/
 
44
 
 
45
/********************************************************************/
 
46
/* nom           : alleg2.c                                         */
 
47
/* contenu       : reprogrammation de qq fonctions d'allegro        */
 
48
/* date de modif : 3 mai 98                                         */
 
49
/********************************************************************/
 
50
 
 
51
/*==================================================================*/
 
52
/* includes                                                         */
 
53
/*==================================================================*/
 
54
 
 
55
#include <string.h>
 
56
 
 
57
#include "alleg2.h"
 
58
#include "exit.h"
 
59
 
 
60
/*==================================================================*/
 
61
/* variables globales                                               */
 
62
/*==================================================================*/
 
63
 
 
64
/*==================================================================*/
 
65
/* variables statiques                                              */
 
66
/*==================================================================*/
 
67
extern void _draw_scrollable_frame (DIALOG *d,
 
68
              int listsize, int offset, int height,
 
69
              int fg_color, int bg);
 
70
extern int isspace(int c);
 
71
 
 
72
/*==================================================================*/
 
73
/* fonctions                                                        */
 
74
/*==================================================================*/
 
75
 
 
76
/*------------------------------------------------------------------*/
 
77
/* utilitaires                                                      */
 
78
/*------------------------------------------------------------------*/
 
79
 
 
80
static void dotted_rect(int x1, int y1, int x2, int y2, int fg, int bg)
 
81
{
 
82
   int x = ((x1+y1) & 1) ? 1 : 0;
 
83
   int c;
 
84
 
 
85
   for (c=x1; c<=x2; c++) {
 
86
      putpixel(screen, c, y1, (((c+y1) & 1) == x) ? fg : bg);
 
87
      putpixel(screen, c, y2, (((c+y2) & 1) == x) ? fg : bg);
 
88
   }
 
89
 
 
90
   for (c=y1+1; c<y2; c++) {
 
91
      putpixel(screen, x1, c, (((c+x1) & 1) == x) ? fg : bg);
 
92
      putpixel(screen, x2, c, (((c+x2) & 1) == x) ? fg : bg);
 
93
   }
 
94
}
 
95
 
 
96
/* _draw_textbox:
 
97
 *  Helper function to draw a textbox object.
 
98
 */
 
99
static void my_draw_textbox
 
100
         (char *thetext, int *listsize, int draw, int offset,
 
101
                   int wword, int tabsize, int x, int y, int w, int h,
 
102
                   int disabled, int fore, int deselect, int disable)
 
103
{
 
104
  int fg = fore;
 
105
   int y1 = y+4;
 
106
   int x1;
 
107
   int len;
 
108
   int ww = w-4;
 
109
   char s[16];
 
110
   char text[16];
 
111
   char space[16];
 
112
   char *printed = text;
 
113
   char *scanned = text;
 
114
   char *oldscan = text;
 
115
   char *ignore = NULL;
 
116
   char *tmp, *ptmp;
 
117
   int width;
 
118
   int line = 0;
 
119
   int i = 0;
 
120
 
 
121
   usetc(s+usetc(s, '.'), 0);
 
122
   usetc(text+usetc(text, ' '), 0);
 
123
   usetc(space+usetc(space, ' '), 0);
 
124
 
 
125
   /* find the correct text */
 
126
   if (thetext != NULL) {
 
127
      printed = thetext;
 
128
      scanned = thetext;
 
129
   }
 
130
 
 
131
   /* do some drawing setup */
 
132
   if (draw) {
 
133
      /* initial start blanking at the top */
 
134
      rectfill(screen, x+2, y+2, x+w-1, y1-1, deselect);
 
135
   }
 
136
 
 
137
   /* choose the text color */
 
138
   if (disabled)
 
139
      fg = disable;
 
140
 
 
141
   text_mode(deselect);
 
142
 
 
143
   /* loop over the entire string */
 
144
 while (1) {
 
145
      width = 0;
 
146
 
 
147
      /* find the next break */
 
148
      while (ugetc(scanned)) {
 
149
         /* check for a forced break */
 
150
         if (ugetc(scanned) == '\n') {
 
151
            scanned += uwidth(scanned);
 
152
 
 
153
            /* we are done parsing the line end */
 
154
            break;
 
155
         }
 
156
 
 
157
         /* the next character length */
 
158
         usetc(s+usetc(s, ugetc(scanned)), 0);
 
159
         len = text_length(font, s);
 
160
 
 
161
         /* modify length if its a tab */
 
162
         if (ugetc(s) == '\t')
 
163
            len = tabsize * text_length(font, space);
 
164
 
 
165
         /* check for the end of a line by excess width of next char */
 
166
         if (width+len >= ww) {
 
167
            /* we have reached end of line do we go back to find start */
 
168
            if (wword) {
 
169
               /* remember where we were */
 
170
               oldscan = scanned;
 
171
 
 
172
               /* go backwards looking for start of word */
 
173
               while (!uisspace(ugetc(scanned))) {
 
174
                  /* don't wrap too far */
 
175
                  if (scanned == printed) {
 
176
                     /* the whole line is filled, so stop here */
 
177
                     scanned = oldscan;
 
178
                     break;
 
179
                  }
 
180
                  /* look further backwards to wrap */
 
181
                  tmp = ptmp = printed;
 
182
                  while (tmp < scanned) {
 
183
                     ptmp = tmp;
 
184
                     tmp += uwidth(tmp);
 
185
                  }
 
186
                  scanned = ptmp;
 
187
               }
 
188
               /* put the space at the end of the line */
 
189
               ignore = scanned;
 
190
               scanned += uwidth(scanned);
 
191
 
 
192
               /* check for endline at the convenient place */
 
193
               if (ugetc(scanned) == '\n')
 
194
                  scanned += uwidth(scanned);
 
195
            }
 
196
            /* we are done parsing the line end */
 
197
            break;
 
198
         }
 
199
         /* the character can be added */
 
200
         scanned += uwidth(scanned);
 
201
         width += len;
 
202
      }
 
203
 
 
204
      /* check if we are to print it */
 
205
      if ((draw) && (line >= offset) && (y1+text_height(font) < (y+h-1))) {
 
206
         x1 = x+4;
 
207
 
 
208
         /* the initial blank bit */
 
209
         rectfill(screen, x+2, y1, x1-1, y1+text_height(font), deselect);
 
210
 
 
211
         /* print up to the marked character */
 
212
         while (printed != scanned) {
 
213
            /* do special stuff for each charater */
 
214
            switch (ugetc(printed)) {
 
215
 
 
216
               case '\r':
 
217
               case '\n':
 
218
                  /* don't print endlines in the text */
 
219
                  break;
 
220
 
 
221
               /* possibly expand the tabs */
 
222
               case '\t':
 
223
                  for (i=0; i<tabsize; i++) {
 
224
                     usetc(s+usetc(s, ' '), 0);
 
225
                     textout(screen, font, s, x1, y1, -1);
 
226
                     x1 += text_length(font, s);
 
227
                  }
 
228
                  break;
 
229
 
 
230
               /* print a normal charater */
 
231
               default:
 
232
                  if (printed != ignore) {
 
233
                     usetc(s+usetc(s, ugetc(printed)), 0);
 
234
                     textout(screen, font, s, x1, y1, -1);
 
235
                     x1 += text_length(font, s);
 
236
                  }
 
237
            }
 
238
 
 
239
            /* goto the next character */
 
240
            printed += uwidth(printed);
 
241
         }
 
242
         /* the last blank bit */
 
243
         if (x1 < x+w-1)
 
244
            rectfill(screen, x1, y1, x+w-1, y1+text_height(font)-1, deselect);
 
245
 
 
246
         /* print the line end */
 
247
         y1 += text_height(font);
 
248
      }
 
249
      printed = scanned;
 
250
 
 
251
      /* we have done a line */
 
252
      line++;
 
253
 
 
254
            /* check if we are at the end of the string */
 
255
      if (!ugetc(printed)) {
 
256
         /* the under blank bit */
 
257
         if (draw)
 
258
            rectfill(screen, x+1, y1, x+w-1, y+h-1, deselect);
 
259
 
 
260
         /* tell how many lines we found */
 
261
         *listsize = line;
 
262
         return;
 
263
      }
 
264
   }
 
265
}
 
266
 
 
267
 
 
268
 
 
269
/* d_textbox_proc:
 
270
 *  A text box object. The dp field points to a char * which is the text
 
271
 *  to be displayed in the text box. If the text is long, there will be
 
272
 *  a vertical scrollbar on the right hand side of the object which can
 
273
 *  be used to scroll through the text. The default is to print the text
 
274
 *  with word wrapping, but if the D_SELECTED flag is set, the text will
 
275
 *  be printed with character wrapping. The d1 field is used internally
 
276
 *  to store the number of lines of text, and d2 is used to store how far
 
277
 *  it has scrolled through the text.
 
278
 */
 
279
int my_textbox_proc(int msg, DIALOG *d, int c)
 
280
{
 
281
   int height, bar;
 
282
   int fg_color = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
 
283
 
 
284
   /* calculate the actual height */
 
285
   height = (d->h-4) / text_height(font);
 
286
 
 
287
   if (msg==MSG_DRAW)
 
288
   {
 
289
         /* tell the object to sort of draw, but only calculate the listsize */
 
290
         my_draw_textbox(d->dp, &d->d1,
 
291
                       0, /* DONT DRAW anything */
 
292
                       d->d2, !(d->flags & D_SELECTED), 8,
 
293
                       d->x, d->y, d->w, d->h,
 
294
                       (d->flags & D_DISABLED),
 
295
                       0, 0, 0);
 
296
 
 
297
         if (d->d1 > height) {
 
298
            bar = 12;
 
299
         }
 
300
         else {
 
301
            bar = 0;
 
302
            d->d2 = 0;
 
303
         }
 
304
 
 
305
         /* now do the actual drawing */
 
306
         my_draw_textbox(d->dp, &d->d1, 1, d->d2,
 
307
                       !(d->flags & D_SELECTED), 8,
 
308
                       d->x, d->y, d->w-bar-1, d->h,
 
309
                       (d->flags & D_DISABLED),
 
310
                       fg_color, d->bg, gui_mg_color);
 
311
 
 
312
         /* draw the frame around */
 
313
         _draw_scrollable_frame(d, d->d1, d->d2, height, fg_color, d->bg);
 
314
    return D_O_K;
 
315
   }
 
316
   else
 
317
      return d_textbox_proc (msg,d,c);
 
318
}
 
319
 
 
320
int my_button_proc(int msg, DIALOG *d, int c)
 
321
{
 
322
   int state1, state2;
 
323
   int g;
 
324
 
 
325
   if (msg==MSG_DRAW)
 
326
   {
 
327
         if (d->flags & D_SELECTED) {
 
328
            g = 1;
 
329
            state1 = d->bg;
 
330
            state2 = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
 
331
         }
 
332
         else {
 
333
            g = 0; 
 
334
            state1 = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
 
335
            state2 = d->bg;
 
336
         }
 
337
 
 
338
         rectfill(screen, d->x+1+g, d->y+1+g, d->x+d->w-2+g, d->y+d->h-2+g, state2);
 
339
         rect(screen, d->x+g, d->y+g, d->x+d->w-1+g, d->y+d->h-1+g, state1);
 
340
         text_mode(-1);
 
341
         gui_textout(screen, d->dp, d->x+d->w/2+g, d->y+d->h/2-text_height(font)/2+g, /*state1*/ -1, TRUE);
 
342
 
 
343
         if (d->flags & D_SELECTED) {
 
344
            vline(screen, d->x, d->y, d->y+d->h-1, d->bg);
 
345
            hline(screen, d->x, d->y, d->x+d->w-1, d->bg);
 
346
         }
 
347
         else {
 
348
            vline(screen, d->x+d->w, d->y+1, d->y+d->h-1, d->fg);
 
349
            hline(screen, d->x+1, d->y+d->h, d->x+d->w, d->fg);
 
350
         }
 
351
         if ((d->flags & D_GOTFOCUS) &&
 
352
             (!(d->flags & D_SELECTED) || !(d->flags & D_EXIT)))
 
353
            dotted_rect(d->x+1+g, d->y+1+g, d->x+d->w-2+g, d->y+d->h-2+g, state1, state2);
 
354
    return D_O_K;
 
355
   }
 
356
   else return d_button_proc (msg,d,c);
 
357
}
 
358
 
 
359
/* d_text_proc:
 
360
 *  Simple dialog procedure: draws the text string which is pointed to by dp.
 
361
 */
 
362
int my_text_proc(int msg, DIALOG *d, int c)
 
363
{
 
364
   if (msg==MSG_DRAW) {
 
365
      text_mode(-1);
 
366
      gui_textout(screen, d->dp, d->x, d->y, -1, FALSE);
 
367
   }
 
368
 
 
369
   return D_O_K;
 
370
}
 
371
 
 
372
/* d_ctext_proc:
 
373
 *  Simple dialog procedure: draws the text string which is pointed to by dp,
 
374
 *  centering it around the object's x coordinate.
 
375
 */
 
376
int my_ctext_proc(int msg, DIALOG *d, int c)
 
377
{
 
378
   if (msg==MSG_DRAW) {
 
379
      text_mode(-1);
 
380
      gui_textout(screen, d->dp, d->x, d->y, -1, TRUE);
 
381
   }
 
382
 
 
383
   return D_O_K;
 
384
}
 
385
 
 
386
 
 
387
/* d_slider_proc:
 
388
 *  A slider control object. This object returns a value in d2, in the
 
389
 *  range from 0 to d1. It will display as a vertical slider if h is
 
390
 *  greater than or equal to w; otherwise, it will display as a horizontal
 
391
 *  slider. dp can contain an optional bitmap to use for the slider handle; 
 
392
 *  dp2 can contain an optional callback function, which is called each 
 
393
 *  time d2 changes. The callback function should have the following
 
394
 *  prototype:
 
395
 *
 
396
 *  int function(void *dp3, int d2);
 
397
 *
 
398
 *  The d_slider_proc object will return the value of the callback function.
 
399
 */
 
400
int my_slider_proc(int msg, DIALOG *d, int c)
 
401
{
 
402
   BITMAP *slhan = NULL;
 
403
   int oldpos, newpos;
 
404
   int sfg;                /* slider foreground color */
 
405
   int vert = TRUE;        /* flag: is slider vertical? */
 
406
   int hh = 7;             /* handle height (width for horizontal sliders) */
 
407
   int hmar;               /* handle margin */
 
408
   int slp;                /* slider position */
 
409
   int mp;                 /* mouse position */
 
410
   int irange;
 
411
   int slx, sly, slh, slw;
 
412
   int msx, msy;
 
413
   int retval = D_O_K;
 
414
   int upkey, downkey;
 
415
   int pgupkey, pgdnkey;
 
416
   int homekey, endkey;
 
417
   int delta;
 
418
   fixed slratio, slmax, slpos;
 
419
   int (*proc)(void *cbpointer, int d2value);
 
420
 
 
421
   /* check for slider direction */
 
422
   if (d->h < d->w)
 
423
      vert = FALSE;
 
424
 
 
425
   /* set up the metrics for the control */
 
426
   if (d->dp != NULL) {
 
427
      slhan = (BITMAP *)d->dp;
 
428
      if (vert)
 
429
         hh = slhan->h;
 
430
      else
 
431
         hh = slhan->w;
 
432
   }
 
433
 
 
434
   hmar = hh/2;
 
435
   irange = (vert) ? d->h : d->w;
 
436
   slmax = itofix(irange-hh);
 
437
   slratio = slmax / (d->d1);
 
438
   slpos = slratio * d->d2;
 
439
   slp = fixtoi(slpos);
 
440
 
 
441
   switch (msg) {
 
442
 
 
443
      case MSG_DRAW:
 
444
         sfg = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
 
445
 
 
446
         if (vert) {
 
447
            rectfill(screen, d->x, d->y, d->x+d->w/2-2, d->y+d->h, d->bg);
 
448
            rectfill(screen, d->x+d->w/2-1, d->y, d->x+d->w/2+1, d->y+d->h, sfg);
 
449
            rectfill(screen, d->x+d->w/2+2, d->y, d->x+d->w, d->y+d->h, d->bg);
 
450
    }
 
451
         else {
 
452
            rectfill(screen, d->x, d->y, d->x+d->w, d->y+d->h/2-2, d->bg);
 
453
            rectfill(screen, d->x, d->y+d->h/2-1, d->x+d->w, d->y+d->h/2+1, sfg);
 
454
            rectfill(screen, d->x, d->y+d->h/2+2, d->x+d->w, d->y+d->h, d->bg);
 
455
         }
 
456
 
 
457
    rect(screen, d->x, d->y, d->x+d->w, d->y+d->h, sfg);
 
458
    /* ligne du desssus ajoutee par moi pour le cadre */
 
459
 
 
460
         /* okay, background and slot are drawn, now draw the handle */
 
461
         if (slhan) {
 
462
            if (vert) {
 
463
               slx = d->x+(d->w/2)-(slhan->w/2);
 
464
               sly = d->y+d->h-(hh+slp);
 
465
            } 
 
466
            else {
 
467
               slx = d->x+slp;
 
468
               sly = d->y+(d->h/2)-(slhan->h/2);
 
469
            }
 
470
            draw_sprite(screen, slhan, slx, sly);
 
471
         } 
 
472
         else {
 
473
            /* draw default handle */
 
474
            if (vert) {
 
475
               slx = d->x;
 
476
               sly = d->y+d->h-(hh+slp);
 
477
               slw = d->w;
 
478
               slh = hh;
 
479
            } else {
 
480
               slx = d->x+slp;
 
481
               sly = d->y;
 
482
               slw = hh;
 
483
               slh = d->h;
 
484
            }
 
485
 
 
486
            /* draw body */
 
487
            rectfill(screen, slx+2, sly, slx+(slw-2), sly+slh, sfg);
 
488
            vline(screen, slx+1, sly+1, sly+slh-1, sfg);
 
489
            vline(screen, slx+slw-1, sly+1, sly+slh-1, sfg);
 
490
            vline(screen, slx, sly+2, sly+slh-2, sfg);
 
491
            vline(screen, slx+slw, sly+2, sly+slh-2, sfg);
 
492
            vline(screen, slx+1, sly+2, sly+slh-2, d->bg);
 
493
            hline(screen, slx+2, sly+1, slx+slw-2, d->bg);
 
494
            putpixel(screen, slx+2, sly+2, d->bg);
 
495
         }
 
496
 
 
497
         if (d->flags & D_GOTFOCUS)
 
498
            dotted_rect(d->x+1, d->y+1, d->x+d->w-1, d->y+d->h-1, sfg, d->bg);
 
499
       /* coord du dotted rect modifiee par moi , cad +1 et -2 */
 
500
         break;
 
501
 
 
502
      case MSG_WANTFOCUS:
 
503
      case MSG_LOSTFOCUS:
 
504
         return D_WANTFOCUS;
 
505
 
 
506
      case MSG_KEY:
 
507
         if (!(d->flags & D_GOTFOCUS))
 
508
            return D_WANTFOCUS;
 
509
         else
 
510
            return D_O_K;
 
511
 
 
512
      case MSG_CHAR:
 
513
         /* handle movement keys to move slider */
 
514
         c >>= 8;
 
515
 
 
516
         if (vert) {
 
517
            upkey = KEY_UP;
 
518
            downkey = KEY_DOWN;
 
519
            pgupkey = KEY_PGUP;
 
520
            pgdnkey = KEY_PGDN;
 
521
            homekey = KEY_END;
 
522
            endkey = KEY_HOME;
 
523
         } 
 
524
         else {
 
525
            upkey = KEY_RIGHT;
 
526
            downkey = KEY_LEFT;
 
527
            pgupkey = KEY_PGDN;
 
528
            pgdnkey = KEY_PGUP;
 
529
            homekey = KEY_HOME;
 
530
            endkey = KEY_END;
 
531
         }
 
532
 
 
533
         if (c == upkey)
 
534
            delta = 1;
 
535
         else if (c == downkey)
 
536
            delta = -1;
 
537
         else if (c == pgdnkey)
 
538
            delta = -d->d1 / 16;
 
539
         else if (c == pgupkey)
 
540
            delta = d->d1 / 16;
 
541
         else if (c == homekey)
 
542
            delta = -d->d2;
 
543
         else if (c == endkey)
 
544
            delta = d->d1 - d->d2;
 
545
         else
 
546
            delta = 0;
 
547
 
 
548
         if (delta) {
 
549
            oldpos = slp;
 
550
 
 
551
            while (1) {
 
552
               d->d2 = d->d2+delta;
 
553
               slpos = slratio*d->d2;
 
554
               slp = fixtoi(slpos);
 
555
               if ((slp != oldpos) || (d->d2 <= 0) || (d->d2 >= d->d1))
 
556
                  break;
 
557
            }
 
558
 
 
559
            if (d->d2 < 0)
 
560
               d->d2 = 0;
 
561
            if (d->d2 > d->d1)
 
562
               d->d2 = d->d1;
 
563
 
 
564
            retval = D_USED_CHAR;
 
565
 
 
566
            /* call callback function here */
 
567
            if (d->dp2) {
 
568
               proc = d->dp2;
 
569
               retval |= (*proc)(d->dp3, d->d2);
 
570
            }
 
571
 
 
572
            show_mouse(NULL);
 
573
            SEND_MESSAGE(d, MSG_DRAW, 0);
 
574
            show_mouse(screen);
 
575
         }
 
576
         break;
 
577
 
 
578
      case MSG_CLICK:
 
579
         /* track the mouse until it is released */
 
580
         mp = slp;
 
581
 
 
582
         while (mouse_b) {
 
583
            msx = mouse_x;
 
584
            msy = mouse_y;
 
585
            oldpos = d->d2;
 
586
            if (vert)
 
587
               mp = (d->y+d->h-hmar)-msy;
 
588
            else
 
589
               mp = msx-(d->x+hmar);
 
590
            if (mp < 0)
 
591
               mp = 0;
 
592
            if (mp > irange-hh)
 
593
               mp = irange-hh;
 
594
            slpos = itofix(mp);
 
595
            slmax = fdiv(slpos, slratio);
 
596
            newpos = fixtoi(slmax);
 
597
            if (newpos != oldpos) {
 
598
               d->d2 = newpos;
 
599
 
 
600
               /* call callback function here */
 
601
               if (d->dp2 != NULL) {
 
602
                  proc = d->dp2;
 
603
                  retval |= (*proc)(d->dp3, d->d2);
 
604
               }
 
605
 
 
606
               if (d->d2 != oldpos) {
 
607
                  show_mouse(NULL);
 
608
                  SEND_MESSAGE(d, MSG_DRAW, 0);
 
609
                  show_mouse(screen);
 
610
               }
 
611
            }
 
612
 
 
613
            /* let other objects continue to animate */
 
614
            broadcast_dialog_message(MSG_IDLE, 0);
 
615
         }
 
616
         break;
 
617
   }
 
618
 
 
619
   return retval;
 
620
}
 
621
 
 
622
/* d_edit_proc:
 
623
 *  An editable text object (the dp field points to the string). When it
 
624
 *  has the input focus (obtained by clicking on it with the mouse), text
 
625
 *  can be typed into this object. The d1 field specifies the maximum
 
626
 *  number of characters that it will accept, and d2 is the text cursor 
 
627
 *  position within the string.
 
628
 */
 
629
int my_edit_proc(int msg, DIALOG *d, int c)
 
630
{
 
631
   int f, l, p, w, x, fg;
 
632
   int b; 
 
633
   int scroll; 
 
634
   char *s;
 
635
   char buf[2];
 
636
 
 
637
   s = d->dp;
 
638
   l = strlen(s);
 
639
   if (d->d2 > l) 
 
640
      d->d2 = l;
 
641
 
 
642
  /* calculate maximal number of displayable characters */
 
643
   b = x = 0;
 
644
   if (d->d2 == l)  {
 
645
      buf[0] = ' ';
 
646
      buf[1] = 0;
 
647
      x = text_length(font, buf);
 
648
   }
 
649
 
 
650
   buf[1] = 0;
 
651
   for (p=d->d2; p>=0; p--) {
 
652
      buf[0] = s[p];
 
653
      b++;
 
654
      x += text_length(font, buf);
 
655
      if (x > d->w) 
 
656
         break;
 
657
   }
 
658
 
 
659
   if (x <= d->w) {
 
660
      b = l; 
 
661
      scroll = FALSE;
 
662
   }
 
663
   else {
 
664
      b--; 
 
665
      scroll = TRUE;
 
666
   }
 
667
 
 
668
   switch (msg) {
 
669
 
 
670
      case MSG_START:
 
671
         d->d2 = l;
 
672
         break;
 
673
 
 
674
      case MSG_DRAW:
 
675
         fg = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
 
676
         x = 0;
 
677
 
 
678
         if (scroll) {
 
679
            p = d->d2-b+1; 
 
680
            b = d->d2; 
 
681
         }
 
682
         else 
 
683
            p = 0; 
 
684
 
 
685
         for (; p<=b; p++) {
 
686
            buf[0] = s[p] ? s[p] : ' ';
 
687
            w = text_length(font, buf);
 
688
            if (x+w > d->w) 
 
689
               break;
 
690
            f = ((p == d->d2) && (d->flags & D_GOTFOCUS));
 
691
       text_mode(f ? d->fg : d->bg); /* modif de chez tonton */
 
692
       textout(screen, font, buf, d->x+x, d->y, f ? d->bg : d->fg);
 
693
       text_mode(-1);
 
694
            textout(screen, font, buf, d->x+x, d->y, -1);  /* idem chez tata*/
 
695
            x += w;
 
696
         }
 
697
         if (x<d->w)
 
698
            rectfill(screen, d->x+x, d->y, d->x+d->w-1, d->y+text_height(font)-1, d->bg);
 
699
         break;
 
700
 
 
701
      case MSG_CLICK:
 
702
         x = d->x;
 
703
 
 
704
         if (scroll) {
 
705
            p = d->d2-b+1; 
 
706
            b = d->d2; 
 
707
         }
 
708
         else
 
709
            p = 0; 
 
710
 
 
711
         for (; p<b; p++) {
 
712
            buf[0] = s[p];
 
713
            x += text_length(font, buf);
 
714
            if (x > mouse_x) 
 
715
               break;
 
716
         }
 
717
         d->d2 = MID(0, p, l);
 
718
         show_mouse(NULL);
 
719
         SEND_MESSAGE(d, MSG_DRAW, 0);
 
720
         show_mouse(screen);
 
721
         break;
 
722
 
 
723
      case MSG_WANTFOCUS:
 
724
      case MSG_LOSTFOCUS:
 
725
      case MSG_KEY:
 
726
         return D_WANTFOCUS;
 
727
 
 
728
      case MSG_CHAR:
 
729
         if ((c >> 8) == KEY_LEFT) {
 
730
            if (d->d2 > 0) d->d2--;
 
731
         }
 
732
         else if ((c >> 8) == KEY_RIGHT) {
 
733
            if (d->d2 < l) d->d2++;
 
734
         }
 
735
         else if ((c >> 8) == KEY_HOME) {
 
736
            d->d2 = 0;
 
737
         }
 
738
         else if ((c >> 8) == KEY_END) {
 
739
            d->d2 = l;
 
740
         }
 
741
         else if ((c >> 8) == KEY_DEL) {
 
742
            if (d->d2 < l)
 
743
               for (p=d->d2; s[p]; p++) 
 
744
                  s[p] = s[p+1];
 
745
         }
 
746
         else if ((c >> 8) == KEY_BACKSPACE) {
 
747
            if (d->d2 > 0) {
 
748
               d->d2--;
 
749
               for (p=d->d2; s[p]; p++) 
 
750
                  s[p] = s[p+1];
 
751
            }
 
752
         }
 
753
         else if ((c >> 8) == KEY_ENTER) {
 
754
            if (d->flags & D_EXIT) {
 
755
               show_mouse(NULL);
 
756
               SEND_MESSAGE(d, MSG_DRAW, 0);
 
757
               show_mouse(screen);
 
758
               return D_CLOSE;
 
759
            }
 
760
            else
 
761
               return D_O_K;
 
762
         }
 
763
         else {
 
764
            c &= 0xff;
 
765
            if ((c >= 32) && (c <= 255)) {
 
766
               if (l < d->d1) {
 
767
                  while (l >= d->d2) {
 
768
                     s[l+1] = s[l];
 
769
                     l--;
 
770
                  }
 
771
                  s[d->d2] = c;
 
772
                  d->d2++;
 
773
               }
 
774
            }
 
775
            else
 
776
               return D_O_K;
 
777
         }
 
778
 
 
779
         /* if we changed something, better redraw... */
 
780
         show_mouse(NULL);
 
781
         SEND_MESSAGE(d, MSG_DRAW, 0);
 
782
         show_mouse(screen);
 
783
         return D_USED_CHAR;
 
784
   }
 
785
 
 
786
   return D_O_K;
 
787
}
 
788
 
 
789
/*------------------------------------------------------------------*/
 
790
BITMAP *my_create_bitmap (int w, int h)
 
791
{
 
792
 BITMAP *bmp;
 
793
 
 
794
 bmp=create_bitmap (w,h);
 
795
 if (bmp==NULL)
 
796
    my_exit (EXIT_CODE_MEM_TROUBLE);
 
797
 
 
798
 return bmp;
 
799
}
 
800