Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmpdcurses/pdcurses/window.c
3153 views
1
/* PDCurses */
2
3
#include <curspriv.h>
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 <stdlib.h>
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
new->_bkgd = win->_bkgd;
492
werase(new);
493
494
copywin(win, new, 0, 0, 0, 0, min(win->_maxy, new->_maxy) - 1,
495
min(win->_maxx, new->_maxx) - 1, FALSE);
496
497
for (i = 0; i < win->_maxy && win->_y[i]; i++)
498
if (win->_y[i])
499
free(win->_y[i]);
500
}
501
502
new->_flags = win->_flags;
503
new->_attrs = win->_attrs;
504
new->_clear = win->_clear;
505
new->_leaveit = win->_leaveit;
506
new->_scroll = win->_scroll;
507
new->_nodelay = win->_nodelay;
508
new->_delayms = win->_delayms;
509
new->_use_keypad = win->_use_keypad;
510
new->_tmarg = (win->_tmarg > new->_maxy - 1) ? 0 : win->_tmarg;
511
new->_bmarg = (win->_bmarg == win->_maxy - 1) ?
512
new->_maxy - 1 : min(win->_bmarg, (new->_maxy - 1));
513
new->_parent = win->_parent;
514
new->_immed = win->_immed;
515
new->_sync = win->_sync;
516
new->_bkgd = win->_bkgd;
517
518
new->_curx = save_curx;
519
new->_cury = save_cury;
520
521
free(win->_firstch);
522
free(win->_lastch);
523
free(win->_y);
524
525
*win = *new;
526
free(new);
527
528
return win;
529
}
530
531
int wresize(WINDOW *win, int nlines, int ncols)
532
{
533
return (resize_window(win, nlines, ncols) ? OK : ERR);
534
}
535
536
void wsyncup(WINDOW *win)
537
{
538
WINDOW *tmp;
539
540
PDC_LOG(("wsyncup() - called\n"));
541
542
for (tmp = win; tmp; tmp = tmp->_parent)
543
touchwin(tmp);
544
}
545
546
int syncok(WINDOW *win, bool bf)
547
{
548
PDC_LOG(("syncok() - called\n"));
549
550
if (!win)
551
return ERR;
552
553
win->_sync = bf;
554
555
return OK;
556
}
557
558
void wcursyncup(WINDOW *win)
559
{
560
WINDOW *tmp;
561
562
PDC_LOG(("wcursyncup() - called\n"));
563
564
for (tmp = win; tmp && tmp->_parent; tmp = tmp->_parent)
565
wmove(tmp->_parent, tmp->_pary + tmp->_cury, tmp->_parx + tmp->_curx);
566
}
567
568
void wsyncdown(WINDOW *win)
569
{
570
WINDOW *tmp;
571
572
PDC_LOG(("wsyncdown() - called\n"));
573
574
for (tmp = win; tmp; tmp = tmp->_parent)
575
{
576
if (is_wintouched(tmp))
577
{
578
touchwin(win);
579
break;
580
}
581
}
582
}
583
584