root/trunk/txlib/txwdraw.c

Revision 14, 70.1 kB (checked in by jvw, 2 years ago)

HEX/ASCII (sector) editor control added

Line 
1//
2//                     TxWin, Textmode Windowing Library
3//
4//   Original code Copyright (c) 1995-2005 Fsys Software and Jan van Wijk
5//
6// ==========================================================================
7//
8// This file contains Original Code and/or Modifications of Original Code as
9// defined in and that are subject to the GNU Lesser General Public License.
10// You may not use this file except in compliance with the License.
11// BY USING THIS FILE YOU AGREE TO ALL TERMS AND CONDITIONS OF THE LICENSE.
12// A copy of the License is provided with the Original Code and Modifications,
13// and is also available at http://www.dfsee.com/txwin/lgpl.htm
14//
15// This library is free software; you can redistribute it and/or modify
16// it under the terms of the GNU Lesser General Public License as published
17// by the Free Software Foundation; either version 2.1 of the License,
18// or (at your option) any later version.
19//
20// This library is distributed in the hope that it will be useful,
21// but WITHOUT ANY WARRANTY; without even the implied warranty of
22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23// See the GNU Lesser General Public License for more details.
24//
25// You should have received a copy of the GNU Lesser General Public License
26// along with this library; (lgpl.htm) if not, write to the Free Software
27// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28//
29// Questions on TxWin licensing can be directed to: txwin@fsys.nl
30//
31// ==========================================================================
32//
33// TX Windowed text, drawing functions
34//
35// Author: J. van Wijk
36//
37// JvW  16-04-2004 Added color scheme logic
38// JvW  21-08-2001 Added save/restore window content
39// JvW  11-07-2001 Added <Ctrl>-arrow help to SBVIEW status (non-focus state)
40// JvW  25-07-1998 Initial version, split off from txwind
41
42#include <txlib.h>                              // public interface
43#include <txwpriv.h>                            // private window interface
44
45#include <txwdraw.h>                            // colorscheme definitions
46
47#if defined (LINUX)
48static    ULONG  txwcs_id =  TXWCS_3D_CMDR;     // id for current scheme
49TXW_COLORSCHEME *txwcs    = &txwcs_3c;          // current color scheme
50#else
51static    ULONG  txwcs_id =  TXWCS_3D_GREY;     // id for current scheme
52TXW_COLORSCHEME *txwcs    = &txwcs_3g;          // current color scheme
53#endif
54
55TXW_COLORSCHEME *txwcschemes[TXWCS_LAST_SCHEME +1] =
56{
57   NULL,
58   &txwcs_st,                                   // TXWCS_STANDARD            1
59   &txwcs_sh,                                   // TXWCS_STD_HALF            2
60   &txwcs_sf,                                   // TXWCS_STD_FULL            3
61   &txwcs_nb,                                   // TXWCS_NO_BLINK            4
62   &txwcs_3g,                                   // TXWCS_3D_GREY             5
63   &txwcs_3h,                                   // TXWCS_3D_HALF             6
64   &txwcs_3f,                                   // TXWCS_3D_FULL             7
65   &txwcs_cm,                                   // TXWCS_COMMANDER           8
66   &txwcs_3c,                                   // TXWCS_3D_CMDR             9
67   &txwcs_ch,                                   // TXWCS_HALF_CMDR          10
68   &txwcs_cf,                                   // TXWCS_FULL_CMDR          11
69   &txwcs_3w,                                   // TXWCS_3D_WHITE           12
70   &txwcs_bw,                                   // TXWCS_BNW_ONLY           13
71   &txwcs_bh,                                   // TXWCS_BNW_FULL           14
72   &txwcs_bf,                                   // TXWCS_BNW_HALF           15
73};
74
75//- wrong double in cp850                       xx   x x x x       x x
76//- wrong half   in cp850   x   x   xx          xx              x    x   x
77//- wrong full   in cp850                       xx           x           x
78static char *txws_dno437 = "³ÚÄ¿³ÀÄَà ºÉÍ»ºÈÍŒ[][]ºÚÄ¿ºÀÄَà ³ÚÄ¿ºÀÍŒŽÃ  ";
79static char *txws_double = "³ÚÄ¿³ÀÄَà ºÉÍ»ºÈÍŒµÆ[]ºÖÄ·ºÓÄœŽÃ  ³ÚÄ·ºÔÍŒŽÃ  ";
80static char *txws_hno437 = "| Ü | ß ||  ÛÛÛÛÛÛÛÛ[][]ÛÛßÛÛÛÜÛÛÛ  | Ü ÛÛÛÛ||  ";
81static char *txws_half   = "Þ Ü Ý ß ÝÞ  ÝÛßÛÞÛÜÛÝÞ[]ÛÛßÛÛÛÜÛÛÛ  Þ Ü ÛÞÛÛÝÞ  ";
82static char *txws_fno437 = "°°°°°°°°°°  ±±±±±±±±[][]²²²²²²²²²²  ÛÛÛÛÛÛÛÛÛÛ  ";
83static char *txws_full   = "°°°°°°°°ÝÞ  ±±±±±±±±ÝÞ[]²²²²²²²²ÝÞ  ÛÛÛÛÛÛÛÛÝÞ  ";
84static char *txws_custom = NULL;
85
86
87/*****************************************************************************/
88// Set custom linestyle for border painting
89/*****************************************************************************/
90BOOL txwSetLinesCustom                          // RET   linestyle string OK
91(
92   char               *custom                   // IN   custom string (40)
93)
94{
95   BOOL                rc  = FALSE;
96
97   ENTER();
98
99   if (custom && (strlen(custom) == TXLP_SIZE))
100   {
101      TRACES(("custom lines: '%s'\n", custom));
102      txws_custom = custom;
103      rc = TRUE;
104   }
105   BRETURN( rc);
106}                                               // end 'txwSetLinesCustom'
107/*---------------------------------------------------------------------------*/
108
109
110/*****************************************************************************/
111// Query current and set new window ColorScheme by scheme-value or letter
112/*****************************************************************************/
113ULONG txwColorScheme                            // RET   Current scheme
114(
115   ULONG               scheme,                  // IN    Scheme selector value
116   TXTT                name                     // OUT   Scheme name or NULL
117)
118{
119   ULONG               rc = txwcs_id;
120
121   ENTER();
122
123   switch (scheme)
124   {
125      case TXWCS_QUERY_ONLY:                    // query only
126         break;
127
128      case TXWCS_NEXT_SCHEME:
129         if ((++txwcs_id) > TXWCS_LAST_SCHEME)
130         {
131            txwcs_id  = TXWCS_FIRST_SCHEME;
132         }
133         break;
134
135      case TXWCS_PREV_SCHEME:
136         if ((--txwcs_id) < TXWCS_FIRST_SCHEME)
137         {
138            txwcs_id  = TXWCS_LAST_SCHEME;
139         }
140         break;
141
142      default:                                  // explicit scheme selection
143         if ((scheme >= TXWCS_FIRST_SCHEME) &&
144             (scheme <= TXWCS_LAST_SCHEME))
145         {
146            txwcs_id  = scheme;
147         }
148         else
149         {
150            switch (toupper(scheme))
151            {
152               case 'N': txwcs_id = TXWCS_NO_BLINK;    break;
153               case 'C': txwcs_id = TXWCS_COMMANDER;   break;
154               case 'M': txwcs_id = TXWCS_3D_CMDR;     break;
155               case 'H': txwcs_id = TXWCS_HALF_CMDR;   break;
156               case 'F': txwcs_id = TXWCS_FULL_CMDR;   break;
157               case 'D': txwcs_id = TXWCS_STANDARD;    break;
158               case 'E': txwcs_id = TXWCS_STD_HALF;    break;
159               case 'S': txwcs_id = TXWCS_STD_FULL;    break;
160               case 'W': txwcs_id = TXWCS_3D_WHITE;    break;
161               case 'B': txwcs_id = TXWCS_BNW_ONLY;    break;
162               case 'L': txwcs_id = TXWCS_BNW_HALF;    break;
163               case 'P': txwcs_id = TXWCS_BNW_FULL;    break;
164               case 'X': txwcs_id = TXWCS_3D_HALF;     break;
165               case 'Y': txwcs_id = TXWCS_3D_FULL;     break;
166               default:  txwcs_id = TXWCS_3D_GREY;     break;
167            }
168         }
169         break;
170   }
171   if (txwcs_id != rc)                          // change scheme ?
172   {
173      txwcs = txwcschemes[txwcs_id];
174      if (txwa->sbview)                         // set default SB colors too
175      {
176         txwa->sbview->window->sb.altcol = txwcs->sbcolors;
177      }
178   }
179   if (name != NULL)
180   {
181      strcpy( name, txwcs->name);
182   }
183   RETURN (rc);
184}                                               // end 'txwColorScheme'
185/*---------------------------------------------------------------------------*/
186
187
188/*****************************************************************************/
189// Create selist from the available Color schemes
190/*****************************************************************************/
191ULONG TxSelistColorSchemes                      // RET   result
192(
193   TXSELIST          **list                     // OUT   selection list
194)
195{
196   ULONG               rc    = NO_ERROR;        // function return
197   ULONG               items = TXWCS_LAST_SCHEME - TXWCS_FIRST_SCHEME +1;
198
199   ENTER();
200
201   rc = TxSelCreate( items, items, items, TXS_AS_NOSTATIC, FALSE, NULL, list);
202   if (rc == NO_ERROR)
203   {
204      TXSELIST        *selist = *list;
205      ULONG            line;
206
207      selist->selected = txwcs_id -1;           // current scheme
208      for (line = 0; (line < items) && (rc == NO_ERROR); line++)
209      {
210         TXS_ITEM  *item = TxAlloc( 1, sizeof(TXS_ITEM));
211
212         if (item != NULL)
213         {
214            if (((item->text = TxAlloc( 1, TXMAXTT)) != NULL) &&
215                ((item->desc = TxAlloc( 1, TXMAXTM)) != NULL)  )
216            {
217               strcpy( item->text, txwcschemes[line+1]->name);
218               strcpy( item->desc, txwcschemes[line+1]->desc);
219               item->value  = TXDID_MAX + line +1; // scheme id code
220               item->helpid = TXWH_USE_OWNER_HELP; // from owner-menu-item
221            }
222            else
223            {
224               rc = TX_ALLOC_ERROR;
225            }
226            selist->items[line] = item;
227            selist->count       = line +1;      // number of items in list
228
229         }
230         else
231         {
232            rc = TX_ALLOC_ERROR;
233         }
234      }
235      if (rc != NO_ERROR)
236      {
237         txSelDestroy( list);                   // free partial list memory
238      }
239   }
240   RETURN (rc);
241}                                               // end 'TxSelistColorSchemes'
242/*---------------------------------------------------------------------------*/
243
244
245/*****************************************************************************/
246// Save window contents to be restored at destroy time (incl borders)
247/*****************************************************************************/
248ULONG txwSaveWindowContent
249(
250   TXWINBASE          *wnd                      // IN    window
251)
252{
253   ULONG               rc  = NO_ERROR;
254   TXWINDOW           *win = wnd->window;
255   TXRECT              area;
256   short               sx;
257   short               sy;
258   short               i;
259
260   ENTER();
261
262   if (win->style & TXWS_MOVEABLE)              // move & resize allowed
263   {                                            // save whole screen area
264      area = txwa->screen;
265   }
266   else                                         // just save window area
267   {
268      area = win->border;
269   }
270   sx = area.right  - area.left  +1;
271   sy = area.bottom - area.top   +1;
272
273   TxFreeMem( wnd->oldContent);                 // free previous, if any
274   if ((wnd->oldContent = TxAlloc( (sx * sy), sizeof(TXCELL))) != NULL)
275   {
276      TRACES(("Saving %hd lines of %hd cells\n", sy, sx));
277      TRECTA("area", (&area));
278      for (i = 0; i < sy; i++)
279      {
280         txwScrReadCellString( area.top + i, area.left,
281                               &(wnd->oldContent[i * sx]), sx);
282      }
283   }
284   else
285   {
286      rc = TX_ALLOC_ERROR;
287   }
288   RETURN( rc);
289}                                               // end 'txwSaveWindowContent'
290/*---------------------------------------------------------------------------*/
291
292/*****************************************************************************/
293// Restore window contents, incl borders or clipped within 1 or 2 area's
294/*****************************************************************************/
295ULONG txwRestoreWindowContent
296(
297   TXWINBASE          *wnd,                     // IN    window
298   TXRECT             *clip1,                   // IN    partial restore area 1
299   TXRECT             *clip2                    // IN    partial restore area 2
300)
301{
302   ULONG               rc  = NO_ERROR;
303   TXWINDOW           *win = wnd->window;
304   TXRECT              area;
305   short               sx;
306   short               sy;
307   short               i;
308
309   ENTER();
310
311   TXSCREEN_BEGIN_UPDATE();
312   if (wnd->oldContent != NULL)
313   {
314      if (win->style & TXWS_MOVEABLE)           // move & resize allowed
315      {                                         // whole screen is saved
316         area = txwa->screen;
317      }
318      else                                      // window area saved only
319      {
320         area = win->border;
321      }
322      sx = area.right  - area.left  +1;
323      sy = area.bottom - area.top   +1;
324
325      TRACES(("Restoring (at most) %hd lines of %hd cells\n", sy, sx));
326      TRECTA("area ", (&area));
327      TRECTA("clip1", clip1);
328      TRECTA("clip2", clip2);
329
330      for (i = 0; i < sy; i++)
331      {
332         if ((clip1 != NULL) ||                 // 1st area defined
333             (clip2 == NULL))                   // or none (whole window)
334         {
335            txwScrDrawCellString( area.top + i, area.left, clip1,
336                                  &(wnd->oldContent[i * sx]), sx, TXSB_COLOR_NORMAL);
337         }
338         if  (clip2 != NULL)                    // 2nd area defined
339         {
340            txwScrDrawCellString( area.top + i, area.left, clip2,
341                                  &(wnd->oldContent[i * sx]), sx, TXSB_COLOR_NORMAL);
342         }
343      }
344   }
345   TXSCREEN_ENDOF_UPDATE();
346   RETURN( rc);
347}                                               // end 'txwRestoreWindowContent'
348/*---------------------------------------------------------------------------*/
349
350
351/*****************************************************************************/
352// Default paint window border and focus indication, for any window-class
353/*****************************************************************************/
354void txwPaintBorder
355(
356   TXWINBASE          *wnd,                     // IN    current window
357   BOOL                focus                    // IN    focus indicator
358)
359{
360   TXWINDOW           *win;
361   TXRECT              clip;                    // parent Clip rectangle
362   TXWHANDLE           hwnd = (TXWHANDLE) wnd;
363
364   ENTER();
365
366   TXSCREEN_BEGIN_UPDATE();
367   if ((txwValidateAndClip( hwnd, &win, TRUE, &clip)) != NULL)
368   {
369      ULONG            style;
370      TXRECT           fill;
371      short            pos;
372      TXCELL           bc;
373      short            sx;
374      short            sy;
375      short            cy;
376      char            *lc;                      // line character
377      char             borderclear[TXLP_SIZE];
378      BOOL             act = (focus || (wnd->us[TXQWS_FLAGS] & TXFF_ACTIVE));
379      BYTE             ba;
380      int              csi_offset = 0;          // colorscheme offset to Win...
381
382      TRACES(("wnd:%8.8lx, focus: %s  Minimized: %s style:%8.8lx\n", wnd,
383             ( focus) ? "Yes" : "No",
384             ( wnd->us[TXQWS_FLAGS] & TXFF_MINIMIZED) ? "ON " : "OFF", win->style));
385      TRECTA("clip  ", (&clip));
386      TRECTA("border", (&win->border));
387      style = win->style;
388      bc    = win->borderclear;
389      ba    = win->borderclear.at;              // remember original attribute
390      sx    = win->border.right  - win->border.left  +1;
391      sy    = win->border.bottom - win->border.top   +1;
392      cy    = win->client.bottom - win->client.top   +1;
393
394      if (ba != cSchemeColor)                   // user specific color scheme ?
395      {
396         csi_offset = ba - cWinBorder_top;
397      }
398      else                                      // use class-specific defaults
399      {
400         switch (win->class)                    // class-specific border colors
401         {
402            case TXW_FRAME:                     // Regular windows borders,
403               if (wnd == txwa->desktop)        // except the Desktop itself
404               {
405                               csi_offset = cDskBorder_top  - cWinBorder_top; break;
406               }
407            case TXW_CANVAS:                                                  break;
408            case TXW_LISTBOX:
409               if (win->style & TXLS_DROP_VALUE) // spin-value is a Dlg-control
410               {
411                               csi_offset = cDlgBorder_top  - cWinBorder_top; break;
412               }
413            case TXW_STATIC:                                                  break;
414
415            case TXW_SBVIEW:   csi_offset = cSbvBorder_top  - cWinBorder_top; break;
416            case TXW_TEXTVIEW: csi_offset = cViewBorder_top - cWinBorder_top; break;
417            case TXW_BUTTON:
418               if ((win->style & TXBS_PRIMARYSTYLES) == TXBS_PUSHBUTTON)
419               {
420                               csi_offset = cPushBorder_top - cWinBorder_top; break;
421               }
422            default:           csi_offset = cDlgBorder_top  - cWinBorder_top; break;
423         }
424      }
425
426      memset( borderclear, win->borderclear.ch, TXLP_SIZE);
427      if (style & TXWS_BRACKETSIDE)             // use side bracket lines
428      {                                         // on active-dialog and focus
429         borderclear[TXLP_FOCUS  + TXLP_L1L] = '[';
430         borderclear[TXLP_FOCUS  + TXLP_R1L] = ']';
431         borderclear[TXLP_ACTIVE + TXLP_L1L] = '[';
432         borderclear[TXLP_ACTIVE + TXLP_R1L] = ']';
433      }
434      lc = borderclear;
435
436      if (style & TXWS_BORDERLINES)             // change to linestyle ...
437      {
438         switch (txwcs->linestyle)              // check scheme linestyle
439         {
440            case TXW_CS_CUST: lc = (txws_custom   != NULL) ? txws_custom : borderclear; break;
441            case TXW_CS_HALF: lc = (txwa->codepage == 437) ? txws_half   : txws_hno437; break;
442            case TXW_CS_FULL: lc = (txwa->codepage == 437) ? txws_full   : txws_fno437; break;
443            default:          lc = (txwa->codepage == 437) ? txws_double : txws_dno437;
444               break;
445         }
446         if ((txwcs->linestyle   != TXW_CS_3D_LINES)   || //- leave 3D lines single
447             ((sy == 1) || (style & TXWS_BRACKETSIDE)) || //- except on one-liners
448             (win->class         == TXW_BUTTON))          //- and any buttons
449         {
450            if (focus)                                     lc += TXLP_FOCUS;
451            else if (wnd->us[TXQWS_FLAGS] & TXFF_ACTIVE)   lc += TXLP_ACTIVE;
452            else if (wnd->us[TXQWS_FLAGS] & TXFF_SELECTED) lc += TXLP_SELECTED;
453         }
454      }
455
456      TRACES(("using line-chars: '%*.*s'\n", TXLP_POS, TXLP_POS, lc));
457
458      if (style & TXWS_FOOTRBORDER)
459      {
460         fill        = win->border;
461         fill.top    = fill.bottom;
462         txwIntersectRect( &clip, &fill, &fill);
463
464         if (txwIsRectShowing( hwnd, &fill))    // whole footer visible ?
465         {
466            bc.ch = lc[TXLP_BOT];
467            bc.at = TxwSC( cWinBorder_bot + csi_offset);
468            if ((style & TXWS_TF_TEXTONLY) == 0) // unless lines surpressed
469            {
470               txwScrFillRectangle( &fill, bc);
471            }
472            if (win->footer && strlen(win->footer))
473            {
474               TRACES(( "Window footer: '%s'\n", win->footer));
475               if ((style & TXWS_LEFTJUSTIFY) || (strlen(win->footer) > sx -2))
476               {
477                  pos = win->border.left;
478                  if (style & TXWS_SIDEBORDERS)
479                  {
480                     pos++;
481                  }
482               }
483               else
484               {
485                  pos = win->border.left + ((sx - strlen(win->footer)) / 2);
486               }
487               if ( (style & TXWS_BORDERLINES) && (pos > 1) &&
488                   ((style & TXWS_TF_TEXTONLY) == 0)) // unless lines surpressed
489               {
490                  bc.ch = lc[TXLP_TXL];
491                  txwScrDrawCellString( win->border.bottom,
492                                        pos -1,
493                                        &clip, &bc, (short ) 1, TXSB_COLOR_NORMAL);
494
495                  bc.ch = lc[TXLP_TXR];
496                  txwScrDrawCellString( win->border.bottom,
497                                        pos +strlen(win->footer),
498                                        &clip, &bc, (short ) 1, TXSB_COLOR_NORMAL);
499               }
500               TRACES(("Write %u length footer to pos %hd\n", strlen(win->footer), pos));
501               txwScrDrawCharStrCol( win->border.bottom, pos, &fill, win->footer, ((act) ?
502                              TxwAC( cWinFooterFocus + csi_offset,   win->footerfocus) :
503                              TxwAC( cWinFooterStand + csi_offset,   win->footercolor)));
504            }
505         }
506      }
507      if (style & TXWS_TITLEBORDER)
508      {
509         fill        = win->border;
510         fill.bottom = fill.top;
511         txwIntersectRect( &clip, &fill, &fill);
512
513         if (txwIsRectShowing( hwnd, &fill))    // whole titlebar visible ?
514         {
515            bc.ch = lc[TXLP_TOP];
516            bc.at = TxwSC( cWinBorder_top + csi_offset);
517            if ((style & TXWS_TF_TEXTONLY) == 0) // unless lines surpressed
518            {
519               txwScrFillRectangle( &fill, bc);
520            }
521            if (win->title && strlen(win->title))
522            {
523               TRACES(( "Window title: '%s'\n", win->title));
524               if ((style & TXWS_LEFTJUSTIFY) || (strlen(win->title) > sx -2))
525               {
526                  pos = win->border.left;
527                  if (style & TXWS_SIDEBORDERS)
528                  {
529                     pos++;
530                  }
531               }
532               else
533               {
534                  pos = win->border.left + ((sx - strlen(win->title)) / 2);
535               }
536               if ( (style & TXWS_BORDERLINES) && (pos > 1) &&
537                   ((style & TXWS_TF_TEXTONLY) == 0)) // unless lines surpressed
538               {
539                  bc.ch = lc[TXLP_TXL];
540                  txwScrDrawCellString( win->border.top,
541                                        pos -1,
542                                        &clip, &bc, (short ) 1, TXSB_COLOR_NORMAL);
543
544                  bc.ch = lc[TXLP_TXR];
545                  txwScrDrawCellString( win->border.top,
546                                        pos +strlen(win->title),
547                                        &clip, &bc, (short ) 1, TXSB_COLOR_NORMAL);
548               }
549               txwScrDrawCharStrCol( win->border.top, pos, &fill,  win->title, ((act) ?
550                              TxwAC( cWinTitleFocus + csi_offset,  win->titlefocus) :
551                              TxwAC( cWinTitleStand + csi_offset,  win->titlecolor)));
552            }
553            if (wnd->us[TXQWS_FLAGS] & TXFF_MINIMIZED)
554            {
555               TRACES(("Add 'F12' to titlebar of wnd:%8.8lx\n", wnd))
556               txwScrDrawCharStrCol( win->border.top,
557                                     win->border.right -3, &fill, "F12",
558                              TxwAC( cWinFooterFocus + csi_offset, win->footerfocus));
559            }
560            #if defined (HAVEMOUSE)
561            else if (((win->class == TXW_FRAME )          ||
562                      (win->class == TXW_CANVAS)          ||  //- frame or canvas,
563                      (win->class == TXW_TEXTVIEW))       &&  //- or a textview
564                     ((win->style  & TXCS_CLOSE_BUTTON))  &&  //- with close-button
565                   (txwIsDescendant( hwnd, txwa->modality)))  //- and now active
566            {
567               TRACES(("Add '[X]' close-button to titlebar of wnd:%8.8lx\n", wnd))
568               txwScrDrawCharStrCol( win->border.top,
569                                     win->border.right -3, &fill, "[X]",
570                              TxwAC( cWinFooterFocus + csi_offset, win->footerfocus));
571            }
572            #endif
573         }
574      }
575      if (style & TXWS_SIDEBORDERS)
576      {
577         short         upscroll = TXW_INVALID_COORD; // linenr up    arrow
578         short         dnscroll = TXW_INVALID_COORD; // linenr downn arrow
579         TXSELIST     *list;
580
581         fill        = win->border;
582         fill.right  = fill.left;
583         if ((sy == 1) || (style & TXWS_BRACKETSIDE))
584         {
585            fill.top    = win->client.top;      // next to client area only
586            fill.bottom = win->client.bottom;
587            txwIntersectRect( &clip, &fill, &fill);
588
589            if (txwIsRectShowing( hwnd, &fill)) // whole titlebar visible ?
590            {
591               bc.ch = lc[TXLP_L1L];            // lft & rgt use same color!
592               bc.at = TxwSC( cWinBorder_rgt + csi_offset);
593               txwScrFillRectangle( &fill, bc);
594            }
595         }
596         else                                   // multi line window, left
597         {
598            txwIntersectRect( &clip, &fill, &fill);
599
600            if (txwIsRectShowing( hwnd, &fill)) // whole titlebar visible ?
601            {
602               bc.ch = lc[TXLP_LFT];
603               bc.at = TxwSC( cWinBorder_lft + csi_offset);
604               txwScrFillRectangle( &fill, bc);
605
606               bc.ch = lc[TXLP_TLC];
607               bc.at = TxwSC( cWinBorder_tlc + csi_offset);
608               txwScrDrawCellString( win->border.top,
609                                     win->border.left,
610                                     &clip, &bc, (short ) 1, TXSB_COLOR_NORMAL);
611               bc.ch = lc[TXLP_BLC];
612               bc.at = TxwSC( cWinBorder_blc + csi_offset);
613               txwScrDrawCellString( win->border.bottom,
614                                     win->border.left,
615                                     &clip, &bc, (short ) 1, TXSB_COLOR_NORMAL);
616            }
617         }
618
619         fill        = win->border;
620         fill.left   = fill.right;
621         if ((sy == 1) || (style & TXWS_BRACKETSIDE))
622         {
623            fill.top    = win->client.top;      // next to client area only
624            fill.bottom = win->client.bottom;
625            txwIntersectRect( &clip, &fill, &fill);
626
627            if (txwIsRectShowing( hwnd, &fill)) // whole titlebar visible ?
628            {
629               bc.ch = lc[TXLP_R1L];
630               bc.at = TxwSC( cWinBorder_rgt + csi_offset);
631               txwScrFillRectangle( &fill, bc);
632            }
633         }
634         else                                   // multi line window, right
635         {
636            txwIntersectRect( &clip, &fill, &fill);
637
638            if (txwIsRectShowing( hwnd, &fill)) // whole titlebar visible ?
639            {
640               bc.ch = lc[TXLP_RGT];
641               bc.at = TxwSC( cWinBorder_rgt + csi_offset);
642               txwScrFillRectangle( &fill, bc);
643
644               bc.ch = lc[TXLP_TRC];
645               bc.at = TxwSC( cWinBorder_trc + csi_offset);
646               txwScrDrawCellString( win->border.top,    win->border.right,
647                                     &clip, &bc, (short ) 1, TXSB_COLOR_NORMAL);
648               bc.ch = lc[TXLP_BRC];
649               bc.at = TxwSC( cWinBorder_brc + csi_offset);
650               txwScrDrawCellString( win->border.bottom, win->border.right,
651                                     &clip, &bc, (short ) 1, TXSB_COLOR_NORMAL);
652               switch (win->class)
653               {
654                  case TXW_TEXTVIEW:
655                     //- to be refined, does not work on most text view
656                     //- windows because the frame has the border, not
657                     //- the TEXTVIEW control
658
659                     if (win->tv.topline > 0)
660                     {
661                        upscroll = win->border.top +1;
662                     }
663                     if (win->tv.topline < win->tv.maxtop)
664                     {
665                        dnscroll = win->border.bottom -1;
666                     }
667                     break;
668
669                  case TXW_LISTBOX:
670                     if ((list = win->lb.list) != NULL)
671                     {
672                        if (list->top > 0)
673                        {
674                           upscroll = win->border.top +1