Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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