1 /* TN5250
2 * Copyright (C) 1997-2008 Michael Madore
3 *
4 * This file is part of TN5250.
5 *
6 * TN5250 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1, or (at your option)
9 * any later version.
10 *
11 * TN5250 is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this software; see the file COPYING. If not, write to
18 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307 USA
20 *
21 */
22 #include "tn5250-private.h"
23
24 #ifdef NDEBUG
25 #define ASSERT_VALID(This)
26 #else
27 #define ASSERT_VALID(This) \
28 { \
29 TN5250_ASSERT ((This) != NULL); \
30 TN5250_ASSERT ((This)->cy >= 0); \
31 TN5250_ASSERT ((This)->cx >= 0); \
32 TN5250_ASSERT ((This)->cy < (This)->h); \
33 TN5250_ASSERT ((This)->cx < (This)->w); \
34 }
35 #endif
36
37
38 /****f* lib5250/tn5250_dbuffer_new
39 * NAME
40 * tn5250_dbuffer_new
41 * SYNOPSIS
42 * ret = tn5250_dbuffer_new (width, height);
43 * INPUTS
44 * int width -
45 * int height -
46 * DESCRIPTION
47 * Allocates a new display buffer.
48 *****/
49 Tn5250DBuffer *
tn5250_dbuffer_new(int width,int height)50 tn5250_dbuffer_new (int width, int height)
51 {
52 Tn5250DBuffer *This = tn5250_new (Tn5250DBuffer, 1);
53
54 if (This == NULL)
55 {
56 return NULL;
57 }
58
59 This->w = width;
60 This->h = height;
61 This->cx = This->cy = 0;
62 This->tcx = This->tcy = 0;
63 This->next = This->prev = NULL;
64
65 This->field_count = 0;
66 This->entry_field_count = 0;
67 This->window_count = 0;
68 This->scrollbar_count = 0;
69 This->menubar_count = 0;
70 This->field_list = NULL;
71 This->window_list = NULL;
72 This->scrollbar_list = NULL;
73 This->menubar_list = NULL;
74 This->master_mdt = 0;
75 This->header_data = NULL;
76 This->header_length = 0;
77
78 This->script_slot = NULL;
79
80 This->data = tn5250_new (unsigned char, width * height);
81 if (This->data == NULL)
82 {
83 free (This);
84 return NULL;
85 }
86
87 tn5250_dbuffer_clear (This);
88 return This;
89 }
90
91
92 /****f* lib5250/tn5250_dbuffer_copy
93 * NAME
94 * tn5250_dbuffer_copy
95 * SYNOPSIS
96 * ret = tn5250_dbuffer_copy (dsp);
97 * INPUTS
98 * Tn5250DBuffer * dsp -
99 * DESCRIPTION
100 * Allocates a new display buffer and copies the contents of the old
101 * one.
102 *****/
103 Tn5250DBuffer *
tn5250_dbuffer_copy(Tn5250DBuffer * dsp)104 tn5250_dbuffer_copy (Tn5250DBuffer * dsp)
105 {
106 Tn5250DBuffer *This = tn5250_new (Tn5250DBuffer, 1);
107
108 if (This == NULL)
109 {
110 return NULL;
111 }
112
113 ASSERT_VALID (dsp);
114
115 This->w = dsp->w;
116 This->h = dsp->h;
117 This->cx = dsp->cx;
118 This->cy = dsp->cy;
119 This->tcx = dsp->tcx;
120 This->tcy = dsp->tcy;
121 This->data = tn5250_new (unsigned char, dsp->w * dsp->h);
122 if (This->data == NULL)
123 {
124 free (This);
125 return NULL;
126 }
127 memcpy (This->data, dsp->data, dsp->w * dsp->h);
128
129 This->field_list = tn5250_field_list_copy (dsp->field_list);
130 This->window_list = tn5250_window_list_copy (dsp->window_list);
131 This->header_length = dsp->header_length;
132 if (dsp->header_data != NULL)
133 {
134 This->header_data = (unsigned char *) malloc (This->header_length);
135 memcpy (This->header_data, dsp->header_data, dsp->header_length);
136 }
137 else
138 {
139 This->header_data = NULL;
140 }
141
142 ASSERT_VALID (This);
143 return This;
144 }
145
146
147 /****f* lib5250/tn5250_dbuffer_destroy
148 * NAME
149 * tn5250_dbuffer_destroy
150 * SYNOPSIS
151 * tn5250_dbuffer_destroy (This);
152 * INPUTS
153 * Tn5250DBuffer * This -
154 * DESCRIPTION
155 * Free a display buffer and destroy all sub-structures.
156 *****/
157 void
tn5250_dbuffer_destroy(Tn5250DBuffer * This)158 tn5250_dbuffer_destroy (Tn5250DBuffer * This)
159 {
160 free (This->data);
161 if (This->header_data != NULL)
162 {
163 free (This->header_data);
164 }
165 (void) tn5250_field_list_destroy (This->field_list);
166 (void) tn5250_window_list_destroy (This->window_list);
167 free (This);
168 return;
169 }
170
171
172 /****f* lib5250/tn5250_dbuffer_set_header_data
173 * NAME
174 * tn5250_dbuffer_set_header_data
175 * SYNOPSIS
176 * tn5250_dbuffer_set_header_data (This, data, len);
177 * INPUTS
178 * Tn5250DBuffer * This -
179 * unsigned char * data -
180 * int len -
181 * DESCRIPTION
182 * Set the format table header data.
183 *****/
184 void
tn5250_dbuffer_set_header_data(Tn5250DBuffer * This,unsigned char * data,int len)185 tn5250_dbuffer_set_header_data (Tn5250DBuffer * This, unsigned char *data,
186 int len)
187 {
188 if (This->header_data != NULL)
189 {
190 free (This->header_data);
191 }
192 This->header_length = len;
193 if (data != NULL)
194 {
195 TN5250_ASSERT (len > 0);
196 This->header_data = (unsigned char *) malloc (len);
197 memcpy (This->header_data, data, len);
198 }
199 return;
200 }
201
202
203 /****f* lib5250/tn5250_dbuffer_send_data_for_aid_key
204 * NAME
205 * tn5250_dbuffer_send_data_for_aid_key
206 * SYNOPSIS
207 * ret = tn5250_dbuffer_send_data_for_aid_key (This, k);
208 * INPUTS
209 * Tn5250DBuffer * This -
210 * int k -
211 * DESCRIPTION
212 * Determine, according to the format table header, if we should send
213 * data for this aid key.
214 *****/
215 int
tn5250_dbuffer_send_data_for_aid_key(Tn5250DBuffer * This,int k)216 tn5250_dbuffer_send_data_for_aid_key (Tn5250DBuffer * This, int k)
217 {
218 int byte, bit, result;
219
220 if (This->header_data == NULL || This->header_length <= 6)
221 {
222 result = 1;
223 TN5250_LOG (("tn5250_dbuffer_send_data_for_aid_key: no format table header or key mask.\n"));
224 goto send_data_done;
225 }
226
227 #ifndef NDEBUG
228 TN5250_LOG (("tn5250_dbuffer_send_data_for_aid_key: format table header = \n"));
229 for (byte = 0; byte < This->header_length; byte++)
230 {
231 TN5250_LOG (("0x%02X ", This->header_data[byte]));
232 }
233 TN5250_LOG (("\n"));
234 #endif
235
236 switch (k)
237 {
238 case TN5250_SESSION_AID_F1:
239 byte = 6;
240 bit = 7;
241 break;
242 case TN5250_SESSION_AID_F2:
243 byte = 6;
244 bit = 6;
245 break;
246 case TN5250_SESSION_AID_F3:
247 byte = 6;
248 bit = 5;
249 break;
250 case TN5250_SESSION_AID_F4:
251 byte = 6;
252 bit = 4;
253 break;
254 case TN5250_SESSION_AID_F5:
255 byte = 6;
256 bit = 3;
257 break;
258 case TN5250_SESSION_AID_F6:
259 byte = 6;
260 bit = 2;
261 break;
262 case TN5250_SESSION_AID_F7:
263 byte = 6;
264 bit = 1;
265 break;
266 case TN5250_SESSION_AID_F8:
267 byte = 6;
268 bit = 0;
269 break;
270 case TN5250_SESSION_AID_F9:
271 byte = 5;
272 bit = 7;
273 break;
274 case TN5250_SESSION_AID_F10:
275 byte = 5;
276 bit = 6;
277 break;
278 case TN5250_SESSION_AID_F11:
279 byte = 5;
280 bit = 5;
281 break;
282 case TN5250_SESSION_AID_F12:
283 byte = 5;
284 bit = 4;
285 break;
286 case TN5250_SESSION_AID_F13:
287 byte = 5;
288 bit = 3;
289 break;
290 case TN5250_SESSION_AID_F14:
291 byte = 5;
292 bit = 2;
293 break;
294 case TN5250_SESSION_AID_F15:
295 byte = 5;
296 bit = 1;
297 break;
298 case TN5250_SESSION_AID_F16:
299 byte = 5;
300 bit = 0;
301 break;
302 case TN5250_SESSION_AID_F17:
303 byte = 4;
304 bit = 7;
305 break;
306 case TN5250_SESSION_AID_F18:
307 byte = 4;
308 bit = 6;
309 break;
310 case TN5250_SESSION_AID_F19:
311 byte = 4;
312 bit = 5;
313 break;
314 case TN5250_SESSION_AID_F20:
315 byte = 4;
316 bit = 4;
317 break;
318 case TN5250_SESSION_AID_F21:
319 byte = 4;
320 bit = 3;
321 break;
322 case TN5250_SESSION_AID_F22:
323 byte = 4;
324 bit = 2;
325 break;
326 case TN5250_SESSION_AID_F23:
327 byte = 4;
328 bit = 1;
329 break;
330 case TN5250_SESSION_AID_F24:
331 byte = 4;
332 bit = 0;
333 break;
334 default:
335 result = 1;
336 goto send_data_done;
337 }
338
339 result = ((This->header_data[byte] & (0x80 >> bit)) == 0);
340 send_data_done:
341 TN5250_LOG (("tn5250_dbuffer_send_data_for_aid_key() = %d\n", result));
342 return result;
343 }
344
345
346 /****f* lib5250/tn5250_dbuffer_field_data
347 * NAME
348 * tn5250_dbuffer_field_data
349 * SYNOPSIS
350 * ret = tn5250_dbuffer_field_data (This, field);
351 * INPUTS
352 * Tn5250DBuffer * This -
353 * Tn5250Field * field -
354 * DESCRIPTION
355 * Return a pointer into the display buffer data where the specified
356 * field begins.
357 *****/
358 unsigned char *
tn5250_dbuffer_field_data(Tn5250DBuffer * This,Tn5250Field * field)359 tn5250_dbuffer_field_data (Tn5250DBuffer * This, Tn5250Field * field)
360 {
361 return &This->data[field->start_row * This->w + field->start_col];
362 }
363
364
365 /****f* lib5250/tn5250_dbuffer_set_size
366 * NAME
367 * tn5250_dbuffer_set_size
368 * SYNOPSIS
369 * tn5250_dbuffer_set_size (This, rows, cols);
370 * INPUTS
371 * Tn5250DBuffer * This -
372 * int rows -
373 * int cols -
374 * DESCRIPTION
375 * Resize the display (say, to 132 columns ;)
376 *****/
377 void
tn5250_dbuffer_set_size(Tn5250DBuffer * This,int rows,int cols)378 tn5250_dbuffer_set_size (Tn5250DBuffer * This, int rows, int cols)
379 {
380 This->w = cols;
381 This->h = rows;
382
383 free (This->data);
384 This->data = tn5250_new (unsigned char, rows * cols);
385 TN5250_ASSERT (This->data != NULL);
386
387 tn5250_dbuffer_clear (This);
388 return;
389 }
390
391
392 /****f* lib5250/tn5250_dbuffer_cursor_set
393 * NAME
394 * tn5250_dbuffer_cursor_set
395 * SYNOPSIS
396 * tn5250_dbuffer_cursor_set (This, y, x);
397 * INPUTS
398 * Tn5250DBuffer * This -
399 * int y -
400 * int x -
401 * DESCRIPTION
402 * DOCUMENT ME!!!
403 *****/
404 void
tn5250_dbuffer_cursor_set(Tn5250DBuffer * This,int y,int x)405 tn5250_dbuffer_cursor_set (Tn5250DBuffer * This, int y, int x)
406 {
407 This->cy = y;
408 This->cx = x;
409
410 TN5250_LOG (("This->cy = %d, This->cx = %d\n", This->cy, This->cx));
411
412 ASSERT_VALID (This);
413 return;
414 }
415
416
417 /****f* lib5250/tn5250_dbuffer_clear
418 * NAME
419 * tn5250_dbuffer_clear
420 * SYNOPSIS
421 * tn5250_dbuffer_clear (This);
422 * INPUTS
423 * Tn5250DBuffer * This -
424 * DESCRIPTION
425 * DOCUMENT ME!!!
426 *****/
427 void
tn5250_dbuffer_clear(Tn5250DBuffer * This)428 tn5250_dbuffer_clear (Tn5250DBuffer * This)
429 {
430 memset (This->data, 0, This->w * This->h);
431 This->cx = This->cy = 0;
432 tn5250_dbuffer_clear_table (This);
433 return;
434 }
435
436
437 /****f* lib5250/tn5250_dbuffer_add_field
438 * NAME
439 * tn5250_dbuffer_add_field
440 * SYNOPSIS
441 * tn5250_dbuffer_add_field (This, field);
442 * INPUTS
443 * Tn5250DBuffer * This -
444 * Tn5250Field * field -
445 * DESCRIPTION
446 * DOCUMENT ME!!!
447 *****/
448 void
tn5250_dbuffer_add_field(Tn5250DBuffer * This,Tn5250Field * field)449 tn5250_dbuffer_add_field (Tn5250DBuffer * This, Tn5250Field * field)
450 {
451 field->id = This->field_count++;
452 field->table = This;
453 This->field_list = tn5250_field_list_add (This->field_list, field);
454
455 if ((!tn5250_field_is_continued_middle (field))
456 && (!tn5250_field_is_continued_last (field)))
457 {
458 This->entry_field_count++;
459 }
460 field->entry_id = This->entry_field_count;
461
462 TN5250_LOG (("adding field: field->id: %d, field->entry_id: %d\n",
463 field->id, field->entry_id));
464 return;
465 }
466
467
468 /****f* lib5250/tn5250_dbuffer_clear_table
469 * NAME
470 * tn5250_dbuffer_clear_table
471 * SYNOPSIS
472 * tn5250_dbuffer_clear_table (This);
473 * INPUTS
474 * Tn5250DBuffer * This -
475 * DESCRIPTION
476 * DOCUMENT ME!!!
477 *****/
478 void
tn5250_dbuffer_clear_table(Tn5250DBuffer * This)479 tn5250_dbuffer_clear_table (Tn5250DBuffer * This)
480 {
481 TN5250_LOG (("tn5250_dbuffer_clear_table() entered.\n"));
482 This->field_list = tn5250_field_list_destroy (This->field_list);
483 /* Comment this for now since the table is cleared just after we have
484 * received a Create Window Structured Field command. We don't really
485 * want to blow away our newly created window.
486 * FIXME
487 */
488 /*
489 This->window_list = tn5250_window_list_destroy (This->window_list);
490 This->scrollbar_list = tn5250_scrollbar_list_destroy (This->scrollbar_list);
491 */
492 This->field_count = 0;
493 This->entry_field_count = 0;
494 /*
495 This->window_count = 0;
496 This->scrollbar_count = 0;
497 */
498 This->master_mdt = 0;
499 This->header_length = 0;
500 if (This->header_data != NULL)
501 {
502 free (This->header_data);
503 This->header_data = NULL;
504 }
505 return;
506 }
507
508
509 /****f* lib5250/tn5250_dbuffer_field_yx
510 * NAME
511 * tn5250_dbuffer_field_yx
512 * SYNOPSIS
513 * ret = tn5250_dbuffer_field_yx (This, y, x);
514 * INPUTS
515 * Tn5250DBuffer * This -
516 * int y -
517 * int x -
518 * DESCRIPTION
519 * DOCUMENT ME!!!
520 *****/
521 Tn5250Field *
tn5250_dbuffer_field_yx(Tn5250DBuffer * This,int y,int x)522 tn5250_dbuffer_field_yx (Tn5250DBuffer * This, int y, int x)
523 {
524 Tn5250Field *iter;
525 if ((iter = This->field_list) != NULL)
526 {
527 do
528 {
529 if (tn5250_field_hit_test (iter, y, x))
530 {
531 return iter;
532 }
533 iter = iter->next;
534 }
535 while (iter != This->field_list);
536 }
537 return NULL;
538 }
539
540
541 /****f* lib5250/tn5250_dbuffer_first_non_bypass
542 * NAME
543 * tn5250_dbuffer_first_non_bypass
544 * SYNOPSIS
545 * field = tn5250_dbuffer_first_non_bypass (dbuffer);
546 * INPUTS
547 * Tn5250DBuffer * dbuffer - The display buffer to use.
548 * DESCRIPTION
549 * Returns a pointer to the first non-bypass field in the format table,
550 * or NULL if there are no non-bypass fields.
551 *****/
552 Tn5250Field *
tn5250_dbuffer_first_non_bypass(Tn5250DBuffer * This)553 tn5250_dbuffer_first_non_bypass (Tn5250DBuffer * This)
554 {
555 Tn5250Field *iter;
556 if ((iter = This->field_list) != NULL)
557 {
558 do
559 {
560 if (!tn5250_field_is_bypass (iter))
561 {
562 return iter;
563 }
564 iter = iter->next;
565 }
566 while (iter != This->field_list);
567 }
568 return NULL;
569 }
570
571
572 /****f* lib5250/tn5250_dbuffer_right
573 * NAME
574 * tn5250_dbuffer_right
575 * SYNOPSIS
576 * tn5250_dbuffer_right (This, n);
577 * INPUTS
578 * Tn5250DBuffer * This -
579 * int n -
580 * DESCRIPTION
581 * DOCUMENT ME!!!
582 *****/
583 void
tn5250_dbuffer_right(Tn5250DBuffer * This,int n)584 tn5250_dbuffer_right (Tn5250DBuffer * This, int n)
585 {
586 if (This->menubar_count > 0)
587 {
588 Tn5250Menubar *menubar =
589 tn5250_menubar_hit_test (This->menubar_list, This->cx, This->cy);
590
591 if (menubar != NULL)
592 {
593 tn5250_menubar_select_next (menubar, &This->cx, &This->cy);
594 ASSERT_VALID (This);
595 return;
596 }
597 }
598
599 This->cx += n;
600 This->cy += (This->cx / This->w);
601 This->cx = (This->cx % This->w);
602 This->cy = (This->cy % This->h);
603
604 ASSERT_VALID (This);
605 return;
606 }
607
608
609 /****f* lib5250/tn5250_dbuffer_left
610 * NAME
611 * tn5250_dbuffer_left
612 * SYNOPSIS
613 * tn5250_dbuffer_left (This);
614 * INPUTS
615 * Tn5250DBuffer * This -
616 * DESCRIPTION
617 * DOCUMENT ME!!!
618 *****/
619 void
tn5250_dbuffer_left(Tn5250DBuffer * This)620 tn5250_dbuffer_left (Tn5250DBuffer * This)
621 {
622 if (This->menubar_count > 0)
623 {
624 Tn5250Menubar *menubar =
625 tn5250_menubar_hit_test (This->menubar_list, This->cx, This->cy);
626
627 if (menubar != NULL)
628 {
629 tn5250_menubar_select_prev (menubar, &This->cx, &This->cy);
630 ASSERT_VALID (This);
631 return;
632 }
633 }
634
635 This->cx--;
636 if (This->cx == -1)
637 {
638 This->cx = This->w - 1;
639 This->cy--;
640 if (This->cy == -1)
641 {
642 This->cy = This->h - 1;
643 }
644 }
645
646 ASSERT_VALID (This);
647 return;
648 }
649
650
651 /****f* lib5250/tn5250_dbuffer_up
652 * NAME
653 * tn5250_dbuffer_up
654 * SYNOPSIS
655 * tn5250_dbuffer_up (This);
656 * INPUTS
657 * Tn5250DBuffer * This -
658 * DESCRIPTION
659 * DOCUMENT ME!!!
660 *****/
661 void
tn5250_dbuffer_up(Tn5250DBuffer * This)662 tn5250_dbuffer_up (Tn5250DBuffer * This)
663 {
664 if (This->menubar_count > 0)
665 {
666 Tn5250Menubar *menubar =
667 tn5250_menubar_hit_test (This->menubar_list, This->cx, This->cy);
668
669 if (menubar != NULL)
670 {
671 tn5250_menubar_select_prev (menubar, &This->cx, &This->cy);
672 ASSERT_VALID (This);
673 return;
674 }
675 }
676
677 if (--This->cy == -1)
678 This->cy = This->h - 1;
679
680 ASSERT_VALID (This);
681 return;
682 }
683
684
685 /****f* lib5250/tn5250_dbuffer_down
686 * NAME
687 * tn5250_dbuffer_down
688 * SYNOPSIS
689 * tn5250_dbuffer_down (This);
690 * INPUTS
691 * Tn5250DBuffer * This -
692 * DESCRIPTION
693 * DOCUMENT ME!!!
694 *****/
695 void
tn5250_dbuffer_down(Tn5250DBuffer * This)696 tn5250_dbuffer_down (Tn5250DBuffer * This)
697 {
698 if (This->menubar_count > 0)
699 {
700 Tn5250Menubar *menubar =
701 tn5250_menubar_hit_test (This->menubar_list, This->cx, This->cy);
702
703 if (menubar != NULL)
704 {
705 tn5250_menubar_select_next (menubar, &This->cx, &This->cy);
706 ASSERT_VALID (This);
707 return;
708 }
709 }
710
711 if (++This->cy == This->h)
712 {
713 This->cy = 0;
714 }
715
716 ASSERT_VALID (This);
717 return;
718 }
719
720
721 /****f* lib5250/tn5250_dbuffer_goto_ic
722 * NAME
723 * tn5250_dbuffer_goto_ic
724 * SYNOPSIS
725 * tn5250_dbuffer_goto_ic (This);
726 * INPUTS
727 * Tn5250DBuffer * This -
728 * DESCRIPTION
729 * DOCUMENT ME!!!
730 *****/
731 void
tn5250_dbuffer_goto_ic(Tn5250DBuffer * This)732 tn5250_dbuffer_goto_ic (Tn5250DBuffer * This)
733 {
734 ASSERT_VALID (This);
735
736 This->cy = This->tcy;
737 This->cx = This->tcx;
738
739 ASSERT_VALID (This);
740 return;
741 }
742
743 /****f* lib5250/tn5250_dbuffer_addch
744 * NAME
745 * tn5250_dbuffer_addch
746 * SYNOPSIS
747 * tn5250_dbuffer_addch (This, c);
748 * INPUTS
749 * Tn5250DBuffer * This -
750 * unsigned char c -
751 * DESCRIPTION
752 * DOCUMENT ME!!!
753 *****/
754 void
tn5250_dbuffer_addch(Tn5250DBuffer * This,unsigned char c)755 tn5250_dbuffer_addch (Tn5250DBuffer * This, unsigned char c)
756 {
757 ASSERT_VALID (This);
758
759 This->data[(This->cy * This->w) + This->cx] = c;
760 tn5250_dbuffer_right (This, 1);
761
762 ASSERT_VALID (This);
763 return;
764 }
765
766
767 /****f* lib5250/tn5250_dbuffer_del
768 * NAME
769 * tn5250_dbuffer_del
770 * SYNOPSIS
771 * tn5250_dbuffer_del (This, fieldid, shiftcount);
772 * INPUTS
773 * Tn5250DBuffer * This -
774 * int shiftcount -
775 * DESCRIPTION
776 * DOCUMENT ME!!!
777 *****/
778 void
tn5250_dbuffer_del(Tn5250DBuffer * This,int fieldid,int shiftcount)779 tn5250_dbuffer_del (Tn5250DBuffer * This, int fieldid, int shiftcount)
780 {
781 Tn5250Field *iter, *field;
782 int x = This->cx, y = This->cy, fwdx, fwdy, i;
783
784 field = tn5250_field_list_find_by_id (This->field_list, fieldid);
785 iter = field;
786
787 while (tn5250_field_is_continued (iter))
788 {
789 if (tn5250_field_is_continued_last (iter))
790 {
791 break;
792 }
793 iter = iter->next;
794 shiftcount =
795 shiftcount + tn5250_field_count_right (iter,
796 tn5250_field_start_row (iter),
797 tn5250_field_start_col (iter));
798 }
799
800 iter = field;
801
802 for (i = 0; i < shiftcount; i++)
803 {
804 fwdx = x + 1;
805 fwdy = y;
806 if (fwdx == This->w)
807 {
808 fwdx = 0;
809 fwdy++;
810 }
811
812 if (tn5250_field_is_continued (iter)
813 && (!tn5250_field_is_continued_last (iter))
814 && (fwdx > tn5250_field_end_col (iter)))
815 {
816 iter = iter->next;
817 fwdx = tn5250_field_start_col (iter);
818 fwdy = tn5250_field_start_row (iter);
819 i--;
820 }
821
822 This->data[y * This->w + x] = This->data[fwdy * This->w + fwdx];
823 x = fwdx;
824 y = fwdy;
825 }
826 This->data[y * This->w + x] = 0x00;
827
828 ASSERT_VALID (This);
829 return;
830 }
831
832
833 /****f* lib5250/tn5250_dbuffer_del_this_field_only
834 * NAME
835 * tn5250_dbuffer_del_this_field_only
836 * SYNOPSIS
837 * tn5250_dbuffer_del_this_field_only (This, shiftcount);
838 * INPUTS
839 * Tn5250DBuffer * This -
840 * int shiftcount -
841 * DESCRIPTION
842 * DOCUMENT ME!!!
843 *****/
844 void
tn5250_dbuffer_del_this_field_only(Tn5250DBuffer * This,int shiftcount)845 tn5250_dbuffer_del_this_field_only (Tn5250DBuffer * This, int shiftcount)
846 {
847 /* This function is actually the original tn5250_dbuffer_del() function
848 * without the continuous field support. Generally, tn5250_dbuffer_del()
849 * should be used and not this function. This function should only be
850 * when you need to delete a character from a single field within a
851 * continuous field group. The only this should ever be necessary is
852 * when deleting a character from a wordwrap field.
853 */
854 int x = This->cx, y = This->cy, fwdx, fwdy, i;
855
856 for (i = 0; i < shiftcount; i++)
857 {
858 fwdx = x + 1;
859 fwdy = y;
860 if (fwdx == This->w)
861 {
862 fwdx = 0;
863 fwdy++;
864 }
865 This->data[y * This->w + x] = This->data[fwdy * This->w + fwdx];
866 x = fwdx;
867 y = fwdy;
868 }
869 This->data[y * This->w + x] = TN5250_DISPLAY_WORD_WRAP_SPACE;
870
871 ASSERT_VALID (This);
872 return;
873 }
874
875
876 /****f* lib5250/tn5250_dbuffer_ins
877 * NAME
878 * tn5250_dbuffer_ins
879 * SYNOPSIS
880 * tn5250_dbuffer_ins (This, fieldid, c, shiftcount);
881 * INPUTS
882 * Tn5250DBuffer * This -
883 * int fieldid -
884 * unsigned char c -
885 * int shiftcount -
886 * DESCRIPTION
887 * DOCUMENT ME!!!
888 *****/
889 void
tn5250_dbuffer_ins(Tn5250DBuffer * This,int fieldid,unsigned char c,int shiftcount)890 tn5250_dbuffer_ins (Tn5250DBuffer * This, int fieldid,
891 unsigned char c, int shiftcount)
892 {
893 Tn5250Field *iter, *field;
894 int x = This->cx, y = This->cy, i;
895 unsigned char c2;
896
897 field = tn5250_field_list_find_by_id (This->field_list, fieldid);
898 iter = field;
899
900 while (tn5250_field_is_continued (iter))
901 {
902 if (tn5250_field_is_continued_last (iter))
903 {
904 break;
905 }
906 iter = iter->next;
907 shiftcount =
908 shiftcount + tn5250_field_count_right (iter,
909 tn5250_field_start_row (iter),
910 tn5250_field_start_col (iter));
911 }
912
913 iter = field;
914
915 for (i = 0; i <= shiftcount; i++)
916 {
917 c2 = This->data[y * This->w + x];
918 This->data[y * This->w + x] = c;
919 c = c2;
920 if (++x == This->w)
921 {
922 x = 0;
923 y++;
924 }
925
926 if (tn5250_field_is_continued (iter)
927 && (!tn5250_field_is_continued_last (iter))
928 && (x > tn5250_field_end_col (iter)))
929 {
930 iter = iter->next;
931 x = tn5250_field_start_col (iter);
932 y = tn5250_field_start_row (iter);
933 i--;
934 }
935 }
936
937 tn5250_dbuffer_right (This, 1);
938
939 ASSERT_VALID (This);
940 return;
941 }
942
943
944 /****f* lib5250/tn5250_dbuffer_set_ic
945 * NAME
946 * tn5250_dbuffer_set_ic
947 * SYNOPSIS
948 * tn5250_dbuffer_set_ic (This, y, x);
949 * INPUTS
950 * Tn5250DBuffer * This -
951 * int y -
952 * int x -
953 * DESCRIPTION
954 * DOCUMENT ME!!!
955 *****/
956 void
tn5250_dbuffer_set_ic(Tn5250DBuffer * This,int y,int x)957 tn5250_dbuffer_set_ic (Tn5250DBuffer * This, int y, int x)
958 {
959 This->tcx = x;
960 This->tcy = y;
961
962 ASSERT_VALID (This);
963 return;
964 }
965
966
967 /****f* lib5250/tn5250_dbuffer_roll
968 * NAME
969 * tn5250_dbuffer_roll
970 * SYNOPSIS
971 * tn5250_dbuffer_roll (This, top, bot, lines);
972 * INPUTS
973 * Tn5250DBuffer * This -
974 * int top -
975 * int bot -
976 * int lines -
977 * DESCRIPTION
978 * DOCUMENT ME!!!
979 *****/
980 void
tn5250_dbuffer_roll(Tn5250DBuffer * This,int top,int bot,int lines)981 tn5250_dbuffer_roll (Tn5250DBuffer * This, int top, int bot, int lines)
982 {
983 int n, c;
984
985 ASSERT_VALID (This);
986
987 if (lines == 0)
988 {
989 return;
990 }
991
992 if (lines < 0)
993 {
994 /* Move text up */
995 for (n = top; n <= bot; n++)
996 {
997 if (n + lines >= top)
998 {
999 for (c = 0; c < This->w; c++)
1000 {
1001 This->data[(n + lines) * This->w + c] =
1002 This->data[n * This->w + c];
1003 }
1004 }
1005 }
1006 }
1007 else
1008 {
1009 for (n = bot; n >= top; n--)
1010 {
1011 if (n + lines <= bot)
1012 {
1013 for (c = 0; c < This->w; c++)
1014 {
1015 This->data[(n + lines) * This->w + c] =
1016 This->data[n * This->w + c];
1017 }
1018 }
1019 }
1020 }
1021 ASSERT_VALID (This);
1022 return;
1023 }
1024
1025
1026 /****f* lib5250/tn5250_dbuffer_char_at
1027 * NAME
1028 * tn5250_dbuffer_char_at
1029 * SYNOPSIS
1030 * ret = tn5250_dbuffer_char_at (This, y, x);
1031 * INPUTS
1032 * Tn5250DBuffer * This -
1033 * int y -
1034 * int x -
1035 * DESCRIPTION
1036 * DOCUMENT ME!!!
1037 *****/
1038 unsigned char
tn5250_dbuffer_char_at(Tn5250DBuffer * This,int y,int x)1039 tn5250_dbuffer_char_at (Tn5250DBuffer * This, int y, int x)
1040 {
1041 ASSERT_VALID (This);
1042 TN5250_ASSERT (y >= 0);
1043 TN5250_ASSERT (x >= 0);
1044 TN5250_ASSERT (y < This->h);
1045 TN5250_ASSERT (x < This->w);
1046 return This->data[y * This->w + x];
1047 }
1048
1049
1050 /****f* lib5250/tn5250_dbuffer_msg_line
1051 * NAME
1052 * tn5250_dbuffer_msg_line
1053 * SYNOPSIS
1054 * ret = tn5250_dbuffer_msg_line (This);
1055 * INPUTS
1056 * Tn5250DBuffer * This -
1057 * DESCRIPTION
1058 * Determine which line we should use as the operator error line.
1059 *****/
1060 int
tn5250_dbuffer_msg_line(Tn5250DBuffer * This)1061 tn5250_dbuffer_msg_line (Tn5250DBuffer * This)
1062 {
1063 int l;
1064 l = 1000;
1065 if (This->header_data && (This->header_length >= 4))
1066 {
1067 l = This->header_data[3] - 1;
1068 }
1069 if ((l > tn5250_dbuffer_height (This) - 1) || (l < 0))
1070 {
1071 l = tn5250_dbuffer_height (This) - 1;
1072 }
1073 return l;
1074 }
1075
1076
1077 /****f* lib5250/tn5250_dbuffer_prevword
1078 * NAME
1079 * tn5250_dbuffer_prevword
1080 * SYNOPSIS
1081 * tn5250_dbuffer_prevword (This);
1082 * INPUTS
1083 * Tn5250DBuffer * This -
1084 * DESCRIPTION
1085 * DOCUMENT ME!!!
1086 *****/
1087 void
tn5250_dbuffer_prevword(Tn5250DBuffer * This)1088 tn5250_dbuffer_prevword (Tn5250DBuffer * This)
1089 {
1090 int state = 0;
1091 int maxiter;
1092
1093 TN5250_LOG (("dbuffer_prevword: entered.\n"));
1094
1095 maxiter = (This->w * This->h);
1096 TN5250_ASSERT (maxiter > 0);
1097
1098 while (--maxiter)
1099 {
1100 tn5250_dbuffer_left (This);
1101 switch (state)
1102 {
1103 case 0:
1104 if (This->data[This->cy * This->w + This->cx] <= 0x40)
1105 {
1106 state++;
1107 }
1108 break;
1109 case 1:
1110 if (This->data[This->cy * This->w + This->cx] > 0x40)
1111 {
1112 state++;
1113 }
1114 break;
1115 case 2:
1116 if (This->data[This->cy * This->w + This->cx] <= 0x40)
1117 {
1118 tn5250_dbuffer_right (This, 1);
1119 return;
1120 }
1121 break;
1122 }
1123 }
1124 return;
1125 }
1126
1127
1128 /****f* lib5250/tn5250_dbuffer_nextword
1129 * NAME
1130 * tn5250_dbuffer_nextword
1131 * SYNOPSIS
1132 * tn5250_dbuffer_nextword (This);
1133 * INPUTS
1134 * Tn5250DBuffer * This -
1135 * DESCRIPTION
1136 * DOCUMENT ME!!!
1137 *****/
1138 void
tn5250_dbuffer_nextword(Tn5250DBuffer * This)1139 tn5250_dbuffer_nextword (Tn5250DBuffer * This)
1140 {
1141 int foundblank = 0;
1142 int maxiter;
1143
1144 TN5250_LOG (("dbuffer_nextword: entered.\n"));
1145
1146 maxiter = (This->w * This->h);
1147 TN5250_ASSERT (maxiter > 0);
1148
1149 while (--maxiter)
1150 {
1151 tn5250_dbuffer_right (This, 1);
1152 if (This->data[This->cy * This->w + This->cx] <= 0x40)
1153 {
1154 foundblank++;
1155 }
1156 if ((foundblank) && (This->data[This->cy * This->w + This->cx] > 0x40))
1157 {
1158 break;
1159 }
1160 }
1161
1162 ASSERT_VALID (This);
1163 return;
1164 }
1165
1166
1167 /***** lib5250/tn5250_dbuffer_add_window
1168 * NAME
1169 * tn5250_dbuffer_add_window
1170 * SYNOPSIS
1171 * tn5250_dbuffer_add_window (This, window);
1172 * INPUTS
1173 * Tn5250DBuffer * This -
1174 * Tn5250Window * window -
1175 * DESCRIPTION
1176 * DOCUMENT ME!!!
1177 *****/
1178 void
tn5250_dbuffer_add_window(Tn5250DBuffer * This,Tn5250Window * window)1179 tn5250_dbuffer_add_window (Tn5250DBuffer * This, Tn5250Window * window)
1180 {
1181 window->id = This->window_count++;
1182 window->table = This;
1183 This->window_list = tn5250_window_list_add (This->window_list, window);
1184
1185 TN5250_LOG (("adding window: window->id: %d\n", window->id));
1186 return;
1187 }
1188
1189
1190 /***** lib5250/tn5250_dbuffer_add_scrollbar
1191 * NAME
1192 * tn5250_dbuffer_add_scrollbar
1193 * SYNOPSIS
1194 * tn5250_dbuffer_add_scrollbar (This, scrollbar);
1195 * INPUTS
1196 * Tn5250DBuffer * This -
1197 * Tn5250Scrollbar * scrollbar -
1198 * DESCRIPTION
1199 * DOCUMENT ME!!!
1200 *****/
1201 void
tn5250_dbuffer_add_scrollbar(Tn5250DBuffer * This,Tn5250Scrollbar * scrollbar)1202 tn5250_dbuffer_add_scrollbar (Tn5250DBuffer * This,
1203 Tn5250Scrollbar * scrollbar)
1204 {
1205 scrollbar->id = This->scrollbar_count++;
1206 scrollbar->table = This;
1207 This->scrollbar_list =
1208 tn5250_scrollbar_list_add (This->scrollbar_list, scrollbar);
1209
1210 TN5250_LOG (("adding scrollbar: scrollbar->id: %d\n", scrollbar->id));
1211 return;
1212 }
1213
1214
1215 /***** lib5250/tn5250_dbuffer_add_menubar
1216 * NAME
1217 * tn5250_dbuffer_add_menubar
1218 * SYNOPSIS
1219 * tn5250_dbuffer_add_menubar (This, menubar);
1220 * INPUTS
1221 * Tn5250DBuffer * This -
1222 * Tn5250Menubar * menubar -
1223 * DESCRIPTION
1224 * DOCUMENT ME!!!
1225 *****/
1226 void
tn5250_dbuffer_add_menubar(Tn5250DBuffer * This,Tn5250Menubar * menubar)1227 tn5250_dbuffer_add_menubar (Tn5250DBuffer * This, Tn5250Menubar * menubar)
1228 {
1229 menubar->id = This->menubar_count++;
1230 menubar->table = This;
1231 This->menubar_list = tn5250_menubar_list_add (This->menubar_list, menubar);
1232
1233 TN5250_LOG (("adding selection field: menubar->id: %d\n", menubar->id));
1234 return;
1235 }
1236