libpayload: remove trailing whitespace and run dos2unix
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / pdcurses / window.c
1 /* Public Domain Curses */
2
3 #include <curspriv.h>
4
5 RCSID("$Id: window.c,v 1.62 2008/07/13 16:08:18 wmcbrine Exp $")
6
7 /*man-start**************************************************************
8
9   Name:                                                         window
10
11   Synopsis:
12         WINDOW *newwin(int nlines, int ncols, int begy, int begx);
13         WINDOW *derwin(WINDOW* orig, int nlines, int ncols,
14                 int begy, int begx);
15         WINDOW *subwin(WINDOW* orig, int nlines, int ncols,
16                 int begy, int begx);
17         WINDOW *dupwin(WINDOW *win);
18         int delwin(WINDOW *win);
19         int mvwin(WINDOW *win, int y, int x);
20         int mvderwin(WINDOW *win, int pary, int parx);
21         int syncok(WINDOW *win, bool bf);
22         void wsyncup(WINDOW *win);
23         void wcursyncup(WINDOW *win);
24         void wsyncdown(WINDOW *win);
25
26         WINDOW *resize_window(WINDOW *win, int nlines, int ncols);
27         int wresize(WINDOW *win, int nlines, int ncols);
28         WINDOW *PDC_makelines(WINDOW *win);
29         WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx);
30         void PDC_sync(WINDOW *win);
31
32   Description:
33         newwin() creates a new window with the given number of lines,
34         nlines and columns, ncols. The upper left corner of the window
35         is at line begy, column begx. If nlines is zero, it defaults to
36         LINES - begy; ncols to COLS - begx. Create a new full-screen
37         window by calling newwin(0, 0, 0, 0).
38
39         delwin() deletes the named window, freeing all associated
40         memory. In the case of overlapping windows, subwindows should be
41         deleted before the main window.
42
43         mvwin() moves the window so that the upper left-hand corner is
44         at position (y,x). If the move would cause the window to be off
45         the screen, it is an error and the window is not moved. Moving
46         subwindows is allowed.
47
48         subwin() creates a new subwindow within a window.  The
49         dimensions of the subwindow are nlines lines and ncols columns.
50         The subwindow is at position (begy, begx) on the screen.  This
51         position is relative to the screen, and not to the window orig.
52         Changes made to either window will affect both.  When using this
53         routine, you will often need to call touchwin() before calling
54         wrefresh().
55
56         derwin() is the same as subwin(), except that begy and begx are
57         relative to the origin of the window orig rather than the
58         screen.  There is no difference between subwindows and derived
59         windows.
60
61         mvderwin() moves a derived window (or subwindow) inside its
62         parent window.  The screen-relative parameters of the window are
63         not changed.  This routine is used to display different parts of
64         the parent window at the same physical position on the screen.
65
66         dupwin() creates an exact duplicate of the window win.
67
68         wsyncup() causes a touchwin() of all of the window's parents.
69
70         If wsyncok() is called with a second argument of TRUE, this
71         causes a wsyncup() to be called every time the window is
72         changed.
73
74         wcursyncup() causes the current cursor position of all of a
75         window's ancestors to reflect the current cursor position of the
76         current window.
77
78         wsyncdown() causes a touchwin() of the current window if any of
79         its parent's windows have been touched.
80
81         resize_window() allows the user to resize an existing window. It
82         returns the pointer to the new window, or NULL on failure.
83
84         wresize() is an ncurses-compatible wrapper for resize_window().
85         Note that, unlike ncurses, it will NOT process any subwindows of
86         the window. (However, you still can call it _on_ subwindows.) It
87         returns OK or ERR.
88
89         PDC_makenew() allocates all data for a new WINDOW * except the
90         actual lines themselves. If it's unable to allocate memory for
91         the window structure, it will free all allocated memory and
92         return a NULL pointer.
93
94         PDC_makelines() allocates the memory for the lines.
95
96         PDC_sync() handles wrefresh() and wsyncup() calls when a window
97         is changed.
98
99   Return Value:
100         newwin(), subwin(), derwin() and dupwin() return a pointer
101         to the new window, or NULL on failure. delwin(), mvwin(),
102         mvderwin() and syncok() return OK or ERR. wsyncup(),
103         wcursyncup() and wsyncdown() return nothing.
104
105   Errors:
106         It is an error to call resize_window() before calling initscr().
107         Also, an error will be generated if we fail to create a newly
108         sized replacement window for curscr, or stdscr. This could
109         happen when increasing the window size. NOTE: If this happens,
110         the previously successfully allocated windows are left alone;
111         i.e., the resize is NOT cancelled for those windows.
112
113   Portability                                X/Open    BSD    SYS V
114         newwin                                  Y       Y       Y
115         delwin                                  Y       Y       Y
116         mvwin                                   Y       Y       Y
117         subwin                                  Y       Y       Y
118         derwin                                  Y       -       Y
119         mvderwin                                Y       -       Y
120         dupwin                                  Y       -      4.0
121         wsyncup                                 Y       -      4.0
122         syncok                                  Y       -      4.0
123         wcursyncup                              Y       -      4.0
124         wsyncdown                               Y       -      4.0
125         resize_window                           -       -       -
126         wresize                                 -       -       -
127         PDC_makelines                           -       -       -
128         PDC_makenew                             -       -       -
129         PDC_sync                                -       -       -
130
131 **man-end****************************************************************/
132
133 #include <stdlib.h>
134
135 WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx)
136 {
137     WINDOW *win;
138
139     PDC_LOG(("PDC_makenew() - called: lines %d cols %d begy %d begx %d\n",
140              nlines, ncols, begy, begx));
141
142     /* allocate the window structure itself */
143
144     if ((win = calloc(1, sizeof(WINDOW))) == (WINDOW *)NULL)
145         return win;
146
147     /* allocate the line pointer array */
148
149     if ((win->_y = malloc(nlines * sizeof(chtype *))) == NULL)
150     {
151         free(win);
152         return (WINDOW *)NULL;
153     }
154
155     /* allocate the minchng and maxchng arrays */
156
157     if ((win->_firstch = malloc(nlines * sizeof(int))) == NULL)
158     {
159         free(win->_y);
160         free(win);
161         return (WINDOW *)NULL;
162     }
163
164     if ((win->_lastch = malloc(nlines * sizeof(int))) == NULL)
165     {
166         free(win->_firstch);
167         free(win->_y);
168         free(win);
169         return (WINDOW *)NULL;
170     }
171
172     /* initialize window variables */
173
174     win->_maxy = nlines;  /* real max screen size */
175     win->_maxx = ncols;   /* real max screen size */
176     win->_begy = begy;
177     win->_begx = begx;
178     win->_bkgd = ' ';     /* wrs 4/10/93 -- initialize background to blank */
179     win->_clear = (bool) ((nlines == LINES) && (ncols == COLS));
180     win->_bmarg = nlines - 1;
181     win->_parx = win->_pary = -1;
182
183     /* init to say window all changed */
184
185     touchwin(win);
186
187     return win;
188 }
189
190 WINDOW *PDC_makelines(WINDOW *win)
191 {
192     int i, j, nlines, ncols;
193
194     PDC_LOG(("PDC_makelines() - called: lines %d cols %d\n", nlines, ncols));
195
196     if (!win)
197         return (WINDOW *)NULL;
198
199     nlines = win->_maxy;
200     ncols = win->_maxx;
201
202     for (i = 0; i < nlines; i++)
203     {
204         if ((win->_y[i] = malloc(ncols * sizeof(chtype))) == NULL)
205         {
206             /* if error, free all the data */
207
208             for (j = 0; j < i; j++)
209                 free(win->_y[j]);
210
211             free(win->_firstch);
212             free(win->_lastch);
213             free(win->_y);
214             free(win);
215
216             return (WINDOW *)NULL;
217         }
218     }
219
220     return win;
221 }
222
223 void PDC_sync(WINDOW *win)
224 {
225     PDC_LOG(("PDC_sync() - called:\n"));
226
227     if (win->_immed)
228         wrefresh(win);
229     if (win->_sync)
230         wsyncup(win);
231 }
232
233 WINDOW *newwin(int nlines, int ncols, int begy, int begx)
234 {
235     WINDOW *win;
236
237     PDC_LOG(("newwin() - called:lines=%d cols=%d begy=%d begx=%d\n",
238              nlines, ncols, begy, begx));
239
240     if (!nlines)
241         nlines = LINES - begy;
242     if (!ncols)
243         ncols  = COLS  - begx;
244
245     if ( (begy + nlines > SP->lines || begx + ncols > SP->cols)
246         || !(win = PDC_makenew(nlines, ncols, begy, begx))
247         || !(win = PDC_makelines(win)) )
248         return (WINDOW *)NULL;
249
250     werase(win);
251
252     return win;
253 }
254
255 int delwin(WINDOW *win)
256 {
257     int i;
258
259     PDC_LOG(("delwin() - called\n"));
260
261     if (!win)
262         return ERR;
263
264     /* subwindows use parents' lines */
265
266     if (!(win->_flags & (_SUBWIN|_SUBPAD)))
267         for (i = 0; i < win->_maxy && win->_y[i]; i++)
268             if (win->_y[i])
269                 free(win->_y[i]);
270
271     free(win->_firstch);
272     free(win->_lastch);
273     free(win->_y);
274     free(win);
275
276     return OK;
277 }
278
279 int mvwin(WINDOW *win, int y, int x)
280 {
281     PDC_LOG(("mvwin() - called\n"));
282
283     if (!win || (y + win->_maxy > LINES || y < 0)
284              || (x + win->_maxx > COLS || x < 0))
285         return ERR;
286
287     win->_begy = y;
288     win->_begx = x;
289     touchwin(win);
290
291     return OK;
292 }
293
294 WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
295 {
296     WINDOW *win;
297     int i;
298     int j = begy - orig->_begy;
299     int k = begx - orig->_begx;
300
301     PDC_LOG(("subwin() - called: lines %d cols %d begy %d begx %d\n",
302              nlines, ncols, begy, begx));
303
304     /* make sure window fits inside the original one */
305
306     if (!orig || (begy < orig->_begy) || (begx < orig->_begx) ||
307         (begy + nlines) > (orig->_begy + orig->_maxy) ||
308         (begx + ncols) > (orig->_begx + orig->_maxx))
309         return (WINDOW *)NULL;
310
311     if (!nlines)
312         nlines = orig->_maxy - 1 - j;
313     if (!ncols)
314         ncols  = orig->_maxx - 1 - k;
315
316     if ( !(win = PDC_makenew(nlines, ncols, begy, begx)) )
317         return (WINDOW *)NULL;
318
319     /* initialize window variables */
320
321     win->_attrs = orig->_attrs;
322     win->_bkgd = orig->_bkgd;
323     win->_leaveit = orig->_leaveit;
324     win->_scroll = orig->_scroll;
325     win->_nodelay = orig->_nodelay;
326     win->_use_keypad = orig->_use_keypad;
327     win->_immed = orig->_immed;
328     win->_sync = orig->_sync;
329     win->_pary = j;
330     win->_parx = k;
331     win->_parent = orig;
332
333     for (i = 0; i < nlines; i++, j++)
334         win->_y[i] = orig->_y[j] + k;
335
336     win->_flags |= _SUBWIN;
337
338     return win;
339 }
340
341 WINDOW *derwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
342 {
343     return subwin(orig, nlines, ncols, begy + orig->_begy, begx + orig->_begx);
344 }
345
346 int mvderwin(WINDOW *win, int pary, int parx)
347 {
348     int i, j;
349     WINDOW *mypar;
350
351     if (!win || !(win->_parent))
352         return ERR;
353
354     mypar = win->_parent;
355
356     if (pary < 0 || parx < 0 || (pary + win->_maxy) > mypar->_maxy ||
357                                 (parx + win->_maxx) > mypar->_maxx)
358         return ERR;
359
360     j = pary;
361
362     for (i = 0; i < win->_maxy; i++)
363         win->_y[i] = (mypar->_y[j++]) + parx;
364
365     win->_pary = pary;
366     win->_parx = parx;
367
368     return OK;
369 }
370
371 WINDOW *dupwin(WINDOW *win)
372 {
373     WINDOW *new;
374     chtype *ptr, *ptr1;
375     int nlines, ncols, begy, begx, i;
376
377     if (!win)
378         return (WINDOW *)NULL;
379
380     nlines = win->_maxy;
381     ncols = win->_maxx;
382     begy = win->_begy;
383     begx = win->_begx;
384
385     if ( !(new = PDC_makenew(nlines, ncols, begy, begx))
386         || !(new = PDC_makelines(new)) )
387         return (WINDOW *)NULL;
388
389     /* copy the contents of win into new */
390
391     for (i = 0; i < nlines; i++)
392     {
393         for (ptr = new->_y[i], ptr1 = win->_y[i];
394              ptr < new->_y[i] + ncols; ptr++, ptr1++)
395             *ptr = *ptr1;
396
397         new->_firstch[i] = 0;
398         new->_lastch[i] = ncols - 1;
399     }
400
401     new->_curx = win->_curx;
402     new->_cury = win->_cury;
403     new->_maxy = win->_maxy;
404     new->_maxx = win->_maxx;
405     new->_begy = win->_begy;
406     new->_begx = win->_begx;
407     new->_flags = win->_flags;
408     new->_attrs = win->_attrs;
409     new->_clear = win->_clear;
410     new->_leaveit = win->_leaveit;
411     new->_scroll = win->_scroll;
412     new->_nodelay = win->_nodelay;
413     new->_use_keypad = win->_use_keypad;
414     new->_tmarg = win->_tmarg;
415     new->_bmarg = win->_bmarg;
416     new->_parx = win->_parx;
417     new->_pary = win->_pary;
418     new->_parent = win->_parent;
419     new->_bkgd = win->_bkgd;
420     new->_flags = win->_flags;
421
422     return new;
423 }
424
425 WINDOW *resize_window(WINDOW *win, int nlines, int ncols)
426 {
427     WINDOW *new;
428     int i, save_cury, save_curx, new_begy, new_begx;
429
430     PDC_LOG(("resize_window() - called: nlines %d ncols %d\n",
431              nlines, ncols));
432
433     if (!win)
434         return (WINDOW *)NULL;
435
436     if (win->_flags & _SUBPAD)
437     {
438         if ( !(new = subpad(win->_parent, nlines, ncols,
439                             win->_begy, win->_begx)) )
440             return (WINDOW *)NULL;
441     }
442     else if (win->_flags & _SUBWIN)
443     {
444         if ( !(new = subwin(win->_parent, nlines, ncols,
445                             win->_begy, win->_begx)) )
446             return (WINDOW *)NULL;
447     }
448     else
449     {
450         if (win == SP->slk_winptr)
451         {
452             new_begy = SP->lines - SP->slklines;
453             new_begx = 0;
454         }
455         else
456         {
457             new_begy = win->_begy;
458             new_begx = win->_begx;
459         }
460
461         if ( !(new = PDC_makenew(nlines, ncols, new_begy, new_begx)) )
462             return (WINDOW *)NULL;
463     }
464
465     save_curx = min(win->_curx, new->_maxx);
466     save_cury = min(win->_cury, new->_maxy);
467
468     if (!(win->_flags & (_SUBPAD|_SUBWIN)))
469     {
470         if ( !(new = PDC_makelines(new)) )
471             return (WINDOW *)NULL;
472
473         werase(new);
474
475         copywin(win, new, 0, 0, 0, 0, min(win->_maxy, new->_maxy) - 1,
476                 min(win->_maxx, new->_maxx) - 1, FALSE);
477
478         for (i = 0; i < win->_maxy && win->_y[i]; i++)
479             if (win->_y[i])
480                 free(win->_y[i]);
481     }
482
483     new->_flags = win->_flags;
484     new->_attrs = win->_attrs;
485     new->_clear = win->_clear;
486     new->_leaveit = win->_leaveit;
487     new->_scroll = win->_scroll;
488     new->_nodelay = win->_nodelay;
489     new->_use_keypad = win->_use_keypad;
490     new->_tmarg = (win->_tmarg > new->_maxy - 1) ? 0 : win->_tmarg;
491     new->_bmarg = (win->_bmarg == win->_maxy - 1) ?
492                   new->_maxy - 1 : min(win->_bmarg, (new->_maxy - 1));
493     new->_parent = win->_parent;
494     new->_immed = win->_immed;
495     new->_sync = win->_sync;
496     new->_bkgd = win->_bkgd;
497
498     new->_curx = save_curx;
499     new->_cury = save_cury;
500
501     free(win->_firstch);
502     free(win->_lastch);
503     free(win->_y);
504
505     *win = *new;
506     free(new);
507
508     return win;
509 }
510
511 int wresize(WINDOW *win, int nlines, int ncols)
512 {
513     return (resize_window(win, nlines, ncols) ? OK : ERR);
514 }
515
516 void wsyncup(WINDOW *win)
517 {
518     WINDOW *tmp;
519
520     PDC_LOG(("wsyncup() - called\n"));
521
522     for (tmp = win; tmp; tmp = tmp->_parent)
523         touchwin(tmp);
524 }
525
526 int syncok(WINDOW *win, bool bf)
527 {
528     PDC_LOG(("syncok() - called\n"));
529
530     if (!win)
531         return ERR;
532
533     win->_sync = bf;
534
535     return OK;
536 }
537
538 void wcursyncup(WINDOW *win)
539 {
540     WINDOW *tmp;
541
542     PDC_LOG(("wcursyncup() - called\n"));
543
544     for (tmp = win; tmp && tmp->_parent; tmp = tmp->_parent)
545         wmove(tmp->_parent, tmp->_pary + tmp->_cury, tmp->_parx + tmp->_curx);
546 }
547
548 void wsyncdown(WINDOW *win)
549 {
550     WINDOW *tmp;
551
552     PDC_LOG(("wsyncdown() - called\n"));
553
554     for (tmp = win; tmp; tmp = tmp->_parent)
555     {
556         if (is_wintouched(tmp))
557         {
558             touchwin(win);
559             break;
560         }
561     }
562 }