~ubuntu-branches/debian/sid/screen/sid

« back to all changes in this revision

Viewing changes to list_window.c

  • Committer: Bazaar Package Importer
  • Author(s): Axel Beckert
  • Date: 2011-10-09 03:29:31 UTC
  • mto: (7.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20111009032931-7iy5ngnvbt2cuwym
Tags: upstream-4.1.0~20110819git450e8f3
ImportĀ upstreamĀ versionĀ 4.1.0~20110819git450e8f3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2010
 
2
 *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
 
3
 *      Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 3, or (at your option)
 
8
 * any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program (see the file COPYING); if not, see
 
17
 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
 
18
 * 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 
19
 *
 
20
 ****************************************************************
 
21
 */
 
22
 
 
23
/* Deals with the list of windows */
 
24
 
 
25
/* NOTE: A 'struct win *' is used as the 'data' for each row. It might make more sense
 
26
 * to use 'struct win* ->w_number' as the 'data', instead, because that way, we can
 
27
 * verify that the window does exist (by looking at wtab[]).
 
28
 */
 
29
 
 
30
#include "config.h"
 
31
#include "screen.h"
 
32
#include "layer.h"
 
33
#include "extern.h"
 
34
#include "list_generic.h"
 
35
 
 
36
extern struct layer *flayer;
 
37
extern struct display *display, *displays;
 
38
 
 
39
extern char *wlisttit;
 
40
extern char *wliststr;
 
41
 
 
42
extern struct mchar mchar_blank, mchar_so;
 
43
extern int renditions[];
 
44
 
 
45
extern struct win **wtab, *windows, *fore;
 
46
extern int maxwin;
 
47
 
 
48
extern char *noargs[];
 
49
 
 
50
static char ListID[] = "window";
 
51
 
 
52
struct gl_Window_Data
 
53
{
 
54
  struct win *group;    /* Set only for a W_TYPE_GROUP window */
 
55
  int order;            /* MRU? NUM? */
 
56
  int onblank;
 
57
  int nested;
 
58
  struct win *fore;     /* The foreground window we had. */
 
59
};
 
60
 
 
61
/* Is this wdata for a group window? */
 
62
#define WLIST_FOR_GROUP(wdate)  ((wdata)->group && !(wdata)->onblank && Layer2Window(flayer) && Layer2Window(flayer)->w_type == W_TYPE_GROUP)
 
63
 
 
64
/* This macro should not be used if 'fn' is expected to update the window list */
 
65
#define FOR_EACH_WINDOW(_wdata, _w, fn) do {    \
 
66
    if ((_wdata)->order == WLIST_MRU)   \
 
67
      { \
 
68
        struct win *_ww;        \
 
69
        for (_ww = windows; _ww; _ww = _ww->w_next)     \
 
70
          {     \
 
71
            _w = _ww;   \
 
72
            fn  \
 
73
          }     \
 
74
      } \
 
75
    else        \
 
76
      { \
 
77
        struct win **_ww, *_witer;      \
 
78
        for (_ww = wtab, _witer = windows; _witer && _ww - wtab < maxwin; _ww++)        \
 
79
          {     \
 
80
            if (!(_w = *_ww))   continue;       \
 
81
            fn  \
 
82
            _witer = _witer->w_next;    \
 
83
          }     \
 
84
      } \
 
85
  } while (0)
 
86
 
 
87
/* Is 'a' an ancestor of 'd'? */
 
88
static int
 
89
window_ancestor(struct win *a, struct win *d)
 
90
{
 
91
  if (!a)
 
92
    return 1;   /* Every window is a descendant of the 'null' group */
 
93
  for (; d; d = d->w_group)
 
94
    if (d->w_group == a)
 
95
      return 1;
 
96
  return 0;
 
97
}
 
98
 
 
99
static void
 
100
window_kill_confirm(char *buf, int len, char *data)
 
101
{
 
102
  struct win *w = windows;
 
103
  struct action act;
 
104
 
 
105
  if (len || (*buf != 'y' && *buf != 'Y'))
 
106
    {
 
107
      *buf = 0;
 
108
      return;
 
109
    }
 
110
 
 
111
  /* Loop over the windows to make sure that the window actually still exists. */
 
112
  for (; w; w = w->w_next)
 
113
    if (w == (struct win *)data)
 
114
      break;
 
115
 
 
116
  if (!w)
 
117
    return;
 
118
 
 
119
  /* Pretend the selected window is the foreground window. Then trigger a non-interactive 'kill' */
 
120
  fore = w;
 
121
  act.nr = RC_KILL;
 
122
  act.args = noargs;
 
123
  act.argl = 0;
 
124
  act.quiet = 0;
 
125
  DoAction(&act, -1);
 
126
}
 
127
 
 
128
static struct ListRow *
 
129
gl_Window_add_group(struct ListData *ldata, struct ListRow *row)
 
130
{
 
131
  /* Right now, 'row' doesn't have any child. */
 
132
  struct gl_Window_Data *wdata = ldata->data;
 
133
  struct win *group = row->data, *w;
 
134
  struct ListRow *cur = row;
 
135
 
 
136
  ASSERT(wdata->nested);
 
137
 
 
138
  FOR_EACH_WINDOW(wdata, w,
 
139
    if (w->w_group != group)
 
140
      continue;
 
141
 
 
142
    cur = glist_add_row(ldata, w, cur);
 
143
    if (w == wdata->fore)
 
144
      ldata->selected = cur;
 
145
 
 
146
    if (w->w_type == W_TYPE_GROUP)
 
147
      cur = gl_Window_add_group(ldata, cur);
 
148
  );
 
149
 
 
150
  return cur;
 
151
}
 
152
 
 
153
static void
 
154
gl_Window_rebuild(struct ListData *ldata)
 
155
{
 
156
  struct ListRow *row = NULL;
 
157
  struct gl_Window_Data *wdata = ldata->data;
 
158
  struct win *w;
 
159
 
 
160
  FOR_EACH_WINDOW(wdata, w,
 
161
    if (w->w_group != wdata->group)
 
162
      continue;
 
163
    row = glist_add_row(ldata, w, row);
 
164
    if (w == wdata->fore)
 
165
      ldata->selected = row;
 
166
    if (w->w_type == W_TYPE_GROUP && wdata->nested)
 
167
      row = gl_Window_add_group(ldata, row);
 
168
  );
 
169
  glist_display_all(ldata);
 
170
}
 
171
 
 
172
static struct ListRow *
 
173
gl_Window_findrow(struct ListData *ldata, struct win *p)
 
174
{
 
175
  struct ListRow *row = ldata->root;
 
176
  for (; row; row = row->next)
 
177
    {
 
178
      if (row->data == p)
 
179
        break;
 
180
    }
 
181
  return row;
 
182
}
 
183
 
 
184
static int
 
185
gl_Window_remove(struct ListData *ldata, struct win *p)
 
186
{
 
187
  struct ListRow *row = gl_Window_findrow(ldata, p);
 
188
  if (!row)
 
189
    return 0;
 
190
 
 
191
  /* Remove 'row'. Update 'selected', 'top', 'root' if necessary. */
 
192
  if (row->next)
 
193
    row->next->prev = row->prev;
 
194
  if (row->prev)
 
195
    row->prev->next = row->next;
 
196
 
 
197
  if (ldata->selected == row)
 
198
    ldata->selected = row->prev ? row->prev : row->next;
 
199
  if (ldata->top == row)
 
200
    ldata->top = row->prev ? row->prev : row->next;
 
201
  if (ldata->root == row)
 
202
    ldata->root = row->next;
 
203
 
 
204
  ldata->list_fn->gl_freerow(ldata, row);
 
205
  free(row);
 
206
 
 
207
  return 1;
 
208
}
 
209
 
 
210
static int
 
211
gl_Window_header(struct ListData *ldata)
 
212
{
 
213
  char *str;
 
214
  struct gl_Window_Data *wdata = ldata->data;
 
215
  int g;
 
216
 
 
217
  if ((g = (wdata->group != NULL)))
 
218
    {
 
219
      LPutWinMsg(flayer, "Group: ", 7, &mchar_blank, 0, 0);
 
220
      LPutWinMsg(flayer, wdata->group->w_title, strlen(wdata->group->w_title), &mchar_blank, 7, 0);
 
221
    }
 
222
 
 
223
  display = 0;
 
224
  str = MakeWinMsgEv(wlisttit, (struct win *)0, '%', flayer->l_width, (struct event *)0, 0);
 
225
 
 
226
  LPutWinMsg(flayer, str, strlen(str), &mchar_blank, 0, g);
 
227
  return 2 + g;
 
228
}
 
229
 
 
230
static int
 
231
gl_Window_footer(struct ListData *ldata)
 
232
{
 
233
  return 0;
 
234
}
 
235
 
 
236
static int
 
237
gl_Window_row(struct ListData *ldata, struct ListRow *lrow)
 
238
{
 
239
  char *str;
 
240
  struct win *w, *g;
 
241
  int xoff;
 
242
  struct mchar *mchar;
 
243
  struct mchar mchar_rend = mchar_blank;
 
244
  struct gl_Window_Data *wdata = ldata->data;
 
245
 
 
246
  w = lrow->data;
 
247
 
 
248
  /* First, make sure we want to display this window in the list.
 
249
   * If we are showing a list for a group, and not on blank, then we must
 
250
   * only show the windows directly belonging to that group.
 
251
   * Otherwise, do some more checks. */
 
252
 
 
253
  for (xoff = 0, g = w->w_group; g != wdata->group; g = g->w_group)
 
254
    xoff += 2;
 
255
  display = Layer2Window(flayer) ? 0 : flayer->l_cvlist ? flayer->l_cvlist->c_display : 0;
 
256
  str = MakeWinMsgEv(wliststr, w, '%', flayer->l_width - xoff, NULL, 0);
 
257
  if (ldata->selected == lrow)
 
258
    mchar = &mchar_so;
 
259
  else if (w->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1)
 
260
    {
 
261
      mchar = &mchar_rend;
 
262
      ApplyAttrColor(renditions[REND_MONITOR], mchar);
 
263
    }
 
264
  else if ((w->w_bell == BELL_DONE || w->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1)
 
265
    {
 
266
      mchar = &mchar_rend;
 
267
      ApplyAttrColor(renditions[REND_BELL], mchar);
 
268
    }
 
269
  else if ((w->w_silence == SILENCE_FOUND || w->w_silence == SILENCE_DONE) && renditions[REND_SILENCE] != -1)
 
270
    {
 
271
      mchar = &mchar_rend;
 
272
      ApplyAttrColor(renditions[REND_SILENCE], mchar);
 
273
    }
 
274
  else
 
275
    mchar = &mchar_blank;
 
276
 
 
277
  LPutWinMsg(flayer, str, flayer->l_width, mchar, xoff, lrow->y);
 
278
  if (xoff)
 
279
    LPutWinMsg(flayer, "", xoff, mchar, 0, lrow->y);
 
280
 
 
281
  return 1;
 
282
}
 
283
 
 
284
static int
 
285
gl_Window_input(struct ListData *ldata, char **inp, int *len)
 
286
{
 
287
  struct win *win;
 
288
  unsigned char ch;
 
289
  struct display *cd = display;
 
290
  struct gl_Window_Data *wdata = ldata->data;
 
291
 
 
292
  if (!ldata->selected)
 
293
    return 0;
 
294
 
 
295
  ch = (unsigned char) **inp;
 
296
  ++*inp;
 
297
  --*len;
 
298
 
 
299
  win = ldata->selected->data;
 
300
  switch (ch)
 
301
    {
 
302
    case ' ':
 
303
    case '\n':
 
304
    case '\r':
 
305
      if (!win)
 
306
        break;
 
307
#ifdef MULTIUSER
 
308
      if (display && AclCheckPermWin(D_user, ACL_READ, win))
 
309
        return;         /* Not allowed to switch to this window. */
 
310
#endif
 
311
      if (WLIST_FOR_GROUP(wdata))
 
312
        SwitchWindow(win->w_number);
 
313
      else
 
314
        {
 
315
          /* Abort list only when not in a group window. */
 
316
          glist_abort();
 
317
          display = cd;
 
318
          if (D_fore != win)
 
319
            SwitchWindow(win->w_number);
 
320
        }
 
321
      *len = 0;
 
322
      break;
 
323
 
 
324
    case 'm':
 
325
      /* Toggle MRU-ness */
 
326
      wdata->order = wdata->order == WLIST_MRU ? WLIST_NUM : WLIST_MRU;
 
327
      glist_remove_rows(ldata);
 
328
      gl_Window_rebuild(ldata);
 
329
      break;
 
330
 
 
331
    case 'g':
 
332
      /* Toggle nestedness */
 
333
      wdata->nested = !wdata->nested;
 
334
      glist_remove_rows(ldata);
 
335
      gl_Window_rebuild(ldata);
 
336
      break;
 
337
 
 
338
    case 'a':
 
339
      /* All-window view */
 
340
      if (wdata->group)
 
341
        {
 
342
          int order = wdata->order | (wdata->nested ? WLIST_NESTED : 0);
 
343
          glist_abort();
 
344
          display = cd;
 
345
          display_windows(1, order, NULL);
 
346
          *len = 0;
 
347
        }
 
348
      else if (!wdata->nested)
 
349
        {
 
350
          wdata->nested = 1;
 
351
          glist_remove_rows(ldata);
 
352
          gl_Window_rebuild(ldata);
 
353
        }
 
354
      break;
 
355
 
 
356
    case 010:   /* ^H */
 
357
    case 0177:  /* Backspace */
 
358
      if (!wdata->group)
 
359
        break;
 
360
      if (wdata->group->w_group)
 
361
        {
 
362
          /* The parent is another group window. So switch to that window. */
 
363
          struct win *g = wdata->group->w_group;
 
364
          glist_abort();
 
365
          display = cd;
 
366
          SetForeWindow(g);
 
367
          *len = 0;
 
368
        }
 
369
      else
 
370
        {
 
371
          /* We were in a group view. Now we are moving to an all-window view.
 
372
           * So treat it as 'windowlist on blank'. */
 
373
          int order = wdata->order | (wdata->nested ? WLIST_NESTED : 0);
 
374
          glist_abort();
 
375
          display = cd;
 
376
          display_windows(1, order, NULL);
 
377
          *len = 0;
 
378
        }
 
379
      break;
 
380
 
 
381
    case ',':   /* Switch numbers with the previous window. */
 
382
      if (wdata->order == WLIST_NUM && ldata->selected->prev)
 
383
        {
 
384
          struct win *pw = ldata->selected->prev->data;
 
385
          if (win->w_group != pw->w_group)
 
386
            break;      /* Do not allow switching with the parent group */
 
387
 
 
388
          /* When a windows's number is successfully changed, it triggers a WListUpdatecv
 
389
           * with NULL window. So that causes a redraw of the entire list. So reset the
 
390
           * 'selected' after that. */
 
391
          wdata->fore = win;
 
392
          WindowChangeNumber(win, pw->w_number);
 
393
        }
 
394
      break;
 
395
 
 
396
    case '.':   /* Switch numbers with the next window. */
 
397
      if (wdata->order == WLIST_NUM && ldata->selected->next)
 
398
        {
 
399
          struct win *nw = ldata->selected->next->data;
 
400
          if (win->w_group != nw->w_group)
 
401
            break;      /* Do not allow switching with the parent group */
 
402
 
 
403
          wdata->fore = win;
 
404
          WindowChangeNumber(win, nw->w_number);
 
405
        }
 
406
      break;
 
407
 
 
408
    case 'K':   /* Kill a window */
 
409
      {
 
410
        char str[MAXSTR];
 
411
        snprintf(str, sizeof(str) - 1, "Really kill window %d (%s) [y/n]",
 
412
            win->w_number, win->w_title);
 
413
        Input(str, 1, INP_RAW, window_kill_confirm, (char *)win, 0);
 
414
      }
 
415
      break;
 
416
 
 
417
    case 033:   /* escape */
 
418
    case 007:   /* ^G */
 
419
      if (!WLIST_FOR_GROUP(wdata))
 
420
        {
 
421
          int fnumber = wdata->onblank ? wdata->fore->w_number : -1;
 
422
          glist_abort();
 
423
          display = cd;
 
424
          if (fnumber >= 0)
 
425
            SwitchWindow(fnumber);
 
426
          *len = 0;
 
427
        }
 
428
      break;
 
429
    default:
 
430
      if (ch >= '0' && ch <= '9')
 
431
        {
 
432
          struct ListRow *row = ldata->root;
 
433
          for (; row; row = row->next)
 
434
            {
 
435
              struct win *w = row->data;
 
436
              if (w->w_number == ch - '0')
 
437
                {
 
438
                  struct ListRow *old = ldata->selected;
 
439
                  if (old == row)
 
440
                    break;
 
441
                  ldata->selected = row;
 
442
                  if (ldata->selected->y == -1)
 
443
                    {
 
444
                      /* We need to list all the rows, since we are scrolling down. But first,
 
445
                       * find the top of the visible list. */
 
446
                      ldata->top = row;
 
447
                      glist_display_all(ldata);
 
448
                    }
 
449
                  else
 
450
                    {
 
451
                      /* just redisplay the two lines. */
 
452
                      ldata->list_fn->gl_printrow(ldata, old);
 
453
                      ldata->list_fn->gl_printrow(ldata, ldata->selected);
 
454
                      flayer->l_y = ldata->selected->y;
 
455
                      LaySetCursor();
 
456
                    }
 
457
                  break;
 
458
                }
 
459
            }
 
460
          break;
 
461
        }
 
462
      --*inp;
 
463
      ++*len;
 
464
      return 0;
 
465
    }
 
466
  return 1;
 
467
}
 
468
 
 
469
static int
 
470
gl_Window_freerow(struct ListData *ldata, struct ListRow *row)
 
471
{
 
472
  return 0;
 
473
}
 
474
 
 
475
static int
 
476
gl_Window_free(struct ListData *ldata)
 
477
{
 
478
  Free(ldata->data);
 
479
  return 0;
 
480
}
 
481
 
 
482
static int
 
483
gl_Window_match(struct ListData *ldata, struct ListRow *row, const char *needle)
 
484
{
 
485
  struct win *w = row->data;
 
486
  if (InStr(w->w_title, needle))
 
487
    return 1;
 
488
  return 0;
 
489
}
 
490
 
 
491
static struct GenericList gl_Window =
 
492
{
 
493
  gl_Window_header,
 
494
  gl_Window_footer,
 
495
  gl_Window_row,
 
496
  gl_Window_input,
 
497
  gl_Window_freerow,
 
498
  gl_Window_free,
 
499
  gl_Window_match
 
500
};
 
501
 
 
502
void
 
503
display_windows(int onblank, int order, struct win *group)
 
504
{
 
505
  struct win *p;
 
506
  struct ListData *ldata;
 
507
  struct gl_Window_Data *wdata;
 
508
 
 
509
  if (flayer->l_width < 10 || flayer->l_height < 6)
 
510
    {
 
511
      LMsg(0, "Window size too small for window list page");
 
512
      return;
 
513
    }
 
514
 
 
515
  if (group)
 
516
    onblank = 0;        /* When drawing a group window, ignore 'onblank' */
 
517
 
 
518
  if (onblank)
 
519
    {
 
520
      debug3("flayer %x %d %x\n", flayer, flayer->l_width, flayer->l_height);
 
521
      if (!display)
 
522
        {
 
523
          LMsg(0, "windowlist -b: display required");
 
524
          return;
 
525
        }
 
526
      p = D_fore;
 
527
      if (p)
 
528
        {
 
529
          SetForeWindow((struct win *)0);
 
530
          if (p->w_group)
 
531
            {
 
532
              D_fore = p->w_group;
 
533
              flayer->l_data = (char *)p->w_group;
 
534
            }
 
535
          Activate(0);
 
536
        }
 
537
      if (flayer->l_width < 10 || flayer->l_height < 6)
 
538
        {
 
539
          LMsg(0, "Window size too small for window list page");
 
540
          return;
 
541
        }
 
542
    }
 
543
  else
 
544
    p = Layer2Window(flayer);
 
545
  if (!group && p)
 
546
    group = p->w_group;
 
547
 
 
548
  ldata = glist_display(&gl_Window, ListID);
 
549
  if (!ldata)
 
550
    {
 
551
      if (onblank && p)
 
552
        {
 
553
          /* Could not display the list. So restore the window. */
 
554
          SetForeWindow(p);
 
555
          Activate(1);
 
556
        }
 
557
      return;
 
558
    }
 
559
 
 
560
  wdata = calloc(1, sizeof(struct gl_Window_Data));
 
561
  wdata->group = group;
 
562
  wdata->order = (order & ~WLIST_NESTED);
 
563
  wdata->nested = !!(order & WLIST_NESTED);
 
564
  wdata->onblank = onblank;
 
565
 
 
566
  /* Set the most recent window as selected. */
 
567
  wdata->fore = windows;
 
568
  while (wdata->fore && wdata->fore->w_group != group)
 
569
    wdata->fore = wdata->fore->w_next;
 
570
 
 
571
  ldata->data = wdata;
 
572
 
 
573
  gl_Window_rebuild(ldata);
 
574
}
 
575
 
 
576
static void
 
577
WListUpdate(struct win *p, struct ListData *ldata)
 
578
{
 
579
  struct gl_Window_Data *wdata = ldata->data;
 
580
  struct ListRow *row, *rbefore;
 
581
  struct win *before;
 
582
  int d = 0, sel = 0;
 
583
 
 
584
  if (!p)
 
585
    {
 
586
      if (ldata->selected)
 
587
        wdata->fore = ldata->selected->data;    /* Try to retain the current selection */
 
588
      glist_remove_rows(ldata);
 
589
      gl_Window_rebuild(ldata);
 
590
      return;
 
591
    }
 
592
 
 
593
  /* First decide if this window should be displayed at all. */
 
594
  d = 1;
 
595
  if (wdata->order == WLIST_NUM || wdata->order == WLIST_MRU)
 
596
    {
 
597
      if (p->w_group != wdata->group)
 
598
        {
 
599
          if (!wdata->nested)
 
600
            d = 0;
 
601
          else
 
602
            d = window_ancestor(wdata->group, p);
 
603
        }
 
604
    }
 
605
 
 
606
  if (!d)
 
607
    {
 
608
      if (gl_Window_remove(ldata, p))
 
609
        glist_display_all(ldata);
 
610
      return;
 
611
    }
 
612
 
 
613
  /* OK, so we keep the window in the list. Update the ordering.
 
614
   * First, find the row where this window should go to. Then, either create
 
615
   * a new row for that window, or move the exising row for the window to the
 
616
   * correct place. */
 
617
  before = NULL;
 
618
  if (wdata->order == WLIST_MRU)
 
619
    {
 
620
      if (windows != p)
 
621
        for (before = windows; before; before = before->w_next)
 
622
          if (before->w_next == p)
 
623
            break;
 
624
    }
 
625
  else if (wdata->order == WLIST_NUM)
 
626
    {
 
627
      if (p->w_number != 0)
 
628
        {
 
629
          struct win **w = wtab + p->w_number - 1;
 
630
          for (; w >= wtab; w--)
 
631
            {
 
632
              if (*w && (*w)->w_group == wdata->group)
 
633
                {
 
634
                  before = *w;
 
635
                  break;
 
636
                }
 
637
            }
 
638
        }
 
639
    }
 
640
 
 
641
  /* Now, find the row belonging to 'before' */
 
642
  if (before)
 
643
    rbefore = gl_Window_findrow(ldata, before);
 
644
  else if (wdata->nested && p->w_group) /* There's no 'before'. So find the group window */
 
645
    rbefore = gl_Window_findrow(ldata, p->w_group);
 
646
  else
 
647
    rbefore = NULL;
 
648
 
 
649
  /* For now, just remove the row containing 'p' if it is not already in the right place . */
 
650
  row = gl_Window_findrow(ldata, p);
 
651
  if (row)
 
652
    {
 
653
      if (row->prev != rbefore)
 
654
        {
 
655
          sel = ldata->selected->data == p;
 
656
          gl_Window_remove(ldata, p);
 
657
        }
 
658
      else
 
659
        p = NULL;               /* the window is in the correct place */
 
660
    }
 
661
  if (p)
 
662
    {
 
663
      row = glist_add_row(ldata, p, rbefore);
 
664
      if (sel)
 
665
        ldata->selected = row;
 
666
    }
 
667
  glist_display_all(ldata);
 
668
}
 
669
 
 
670
void
 
671
WListUpdatecv(cv, p)
 
672
struct canvas *cv;
 
673
struct win *p;
 
674
{
 
675
  struct ListData *ldata;
 
676
  struct gl_Window_Data *wdata;
 
677
 
 
678
  if (cv->c_layer->l_layfn != &ListLf)
 
679
    return;
 
680
  ldata = cv->c_layer->l_data;
 
681
  if (ldata->name != ListID)
 
682
    return;
 
683
  wdata = ldata->data;
 
684
  CV_CALL(cv, WListUpdate(p, ldata));
 
685
}
 
686
 
 
687
void
 
688
WListLinkChanged()
 
689
{
 
690
  struct display *olddisplay = display;
 
691
  struct canvas *cv;
 
692
  struct ListData *ldata;
 
693
  struct gl_Window_Data *wdata;
 
694
 
 
695
  for (display = displays; display; display = display->d_next)
 
696
    for (cv = D_cvlist; cv; cv = cv->c_next)
 
697
      {
 
698
        if (!cv->c_layer || cv->c_layer->l_layfn != &ListLf)
 
699
          continue;
 
700
        ldata = cv->c_layer->l_data;
 
701
        if (ldata->name != ListID)
 
702
          continue;
 
703
        wdata = ldata->data;
 
704
        if (!(wdata->order & WLIST_MRU))
 
705
          continue;
 
706
        CV_CALL(cv, WListUpdate(0, ldata));
 
707
      }
 
708
  display = olddisplay;
 
709
}
 
710