source: trunk/Lucide/gui/luutils.cpp @ 399

Last change on this file since 399 was 367, checked in by dmik, 12 years ago

Merged bramches/kmk (r294:365) to trunk.

File size: 16.3 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: CDDL 1.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the COMMON DEVELOPMENT AND
5 * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6 * this file except in compliance with the License. You may obtain a copy of
7 * the License at http://www.sun.com/cddl/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Initial Developer of the Original Code is
15 * Eugene Romanenko, netlabs.org.
16 * Portions created by the Initial Developer are Copyright (C) 2006
17 * the Initial Developer. All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the terms of
22 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23 * in which case the provisions of the LGPL are applicable instead of those
24 * above. If you wish to allow use of your version of this file only under the
25 * terms of the LGPL, and not to allow others to use your version of this file
26 * under the terms of the CDDL, indicate your decision by deleting the
27 * provisions above and replace them with the notice and other provisions
28 * required by the LGPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under the terms of any one of the CDDL
30 * or the LGPL.
31 *
32 * ***** END LICENSE BLOCK ***** */
33
34
35#include "os2all.h"
36
37#include <time.h>
38#include <stdio.h>
39#include <string.h>
40#include <stdlib.h>
41#include <string>
42
43#if defined(__WATCOM__)
44#include <strstrea.h>
45#else
46#include <sstream>
47#include <algorithm>
48#endif
49
50#include "luutils.h"
51#include "messages.h"
52
53static bool initCountryInfo();
54
55static COUNTRYINFO CtryInfo;
56static bool countryInfoLoaded = initCountryInfo();
57
58
59afbuf::afbuf( unsigned int s )
60{
61    size = s;
62    buffer = new char[ s ];
63    memset( buffer, 0, s );
64}
65
66
67BOOL CreateGraphicsBuffer( HAB hab, PRECTL prectl, HPS hps,
68                           HPS *phpsBuffer, HDC *phdcBuffer )
69{
70    LONG cPlanes;
71    LONG cBitCount;
72    ULONG ulFlags;
73    HBITMAP hbm;
74    BITMAPINFOHEADER bmp;
75    SIZEL sizl;
76    FONTMETRICS fm;
77    FATTRS fat;
78    SIZEF sizf;
79    HPS hpsBuffer;
80    HDC hdc, hdcBuffer;
81    hdc = GpiQueryDevice( hps );
82    ulFlags = GpiQueryPS( hps, &sizl );
83
84    hdcBuffer = DevOpenDC( hab, OD_MEMORY, "*",  0L, NULL, hdc );
85    if ( hdcBuffer )
86    {
87        sizl.cx = sizl.cy = 0;
88
89        hpsBuffer = GpiCreatePS( hab, hdcBuffer, &sizl, ulFlags | GPIA_ASSOC );
90
91        *phpsBuffer = hpsBuffer;
92        *phdcBuffer = hdcBuffer;
93
94        DevQueryCaps( hdc, CAPS_COLOR_PLANES, 1L, &cPlanes );
95        DevQueryCaps( hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount );
96
97        bmp.cbFix     = sizeof( BITMAPINFOHEADER );
98        bmp.cx        = (SHORT)( prectl->xRight - prectl->xLeft );
99        bmp.cy        = (SHORT)( prectl->yTop - prectl->yBottom );
100        bmp.cPlanes   = (SHORT)cPlanes;
101        bmp.cBitCount = (SHORT)cBitCount;
102
103        hbm = GpiCreateBitmap( hpsBuffer, (PBITMAPINFOHEADER2)&bmp,
104                               0x0000, NULL, NULL );
105        if ( hbm )
106        {
107            GpiSetBitmap( hpsBuffer, hbm );
108            GpiQueryFontMetrics( hps, sizeof( FONTMETRICS ), &fm );
109
110            memset( &fat, 0, sizeof( fat ) );
111
112            fat.usRecordLength = sizeof( FATTRS );
113            fat.lMatch = fm.lMatch;
114            strcpy( fat.szFacename, fm.szFacename );
115
116            GpiDeleteSetId( hpsBuffer, 1L );
117            GpiCreateLogFont( hpsBuffer, 0, 1L, &fat );
118            GpiSetCharSet( hpsBuffer, 1L );
119
120            sizf.cx = MAKEFIXED( fm.lEmInc, 0 );
121            sizf.cy = MAKEFIXED( fm.lMaxBaselineExt, 0 );
122            GpiSetCharBox( hpsBuffer, &sizf );
123
124            return TRUE;
125        }
126
127        GpiDestroyPS( hpsBuffer );
128        DevCloseDC( hdcBuffer );
129        hpsBuffer = hdcBuffer = NULLHANDLE;
130    }
131
132    return FALSE;
133}
134
135void BlitGraphicsBuffer( HPS hps, HPS hpsBuffer, PRECTL prclPaint )
136{
137    POINTL aptl[ 3 ];
138
139    aptl[ 0 ].x = prclPaint->xLeft;
140    aptl[ 0 ].y = prclPaint->yBottom;
141    aptl[ 1 ].x = prclPaint->xRight;
142    aptl[ 1 ].y = prclPaint->yTop;
143    aptl[ 2 ].x = prclPaint->xLeft;
144    aptl[ 2 ].y = prclPaint->yBottom;
145
146    GpiBitBlt( hps, hpsBuffer, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE );
147}
148
149void DestroyGraphicsBuffer( HPS hpsBuffer, HDC hdcBuffer )
150{
151    if( hpsBuffer && hdcBuffer )
152    {
153        HBITMAP hbm = GpiSetBitmap( hpsBuffer, NULLHANDLE );
154
155        if ( hbm != NULLHANDLE ) {
156            GpiDeleteBitmap( hbm );
157        }
158
159        GpiDestroyPS( hpsBuffer );
160        DevCloseDC( hdcBuffer );
161
162        hpsBuffer = hdcBuffer = NULLHANDLE;
163    }
164}
165
166
167char *newstrdup( const char *s )
168{
169    if ( s == NULL ) {
170        return NULL;
171    }
172    char *temp = new char[ strlen( s ) + 1 ];
173    strcpy( temp, s );
174    return temp;
175}
176
177
178struct ER_WINDOW_POS
179{
180    SWP    Swp;
181    USHORT XRestore;
182    USHORT YRestore;
183    USHORT CXRestore;
184    USHORT CYRestore;
185    USHORT XMinimize;
186    USHORT YMinimize;
187};
188
189
190BOOL PMRestoreWindowPos( PCSZ pIniName, PCSZ pAppName, PCSZ pKeyName,
191                         HWND hwnd, BOOL activate, BOOL chkCoord,
192                         BOOL min, BOOL max, BOOL hide )
193{
194    HINI          hini;
195    ER_WINDOW_POS wp;
196    ULONG         ulWpSize = sizeof( ER_WINDOW_POS );
197    ULONG         SwpOptions = SWP_MOVE | SWP_SIZE | SWP_SHOW;
198    BOOL          rval = FALSE;
199
200    if ( activate && !hide ) {
201        SwpOptions |= SWP_ACTIVATE;
202    }
203
204    if ( pIniName == NULL ) { // ᅵᅵ襬 ï¿œ user profile
205        hini = HINI_USER;
206    }
207    else {
208        hini = PrfOpenProfile( WinQueryAnchorBlock( hwnd ), pIniName );
209    }
210
211    if ( hini != NULLHANDLE )
212    {
213        if ( PrfQueryProfileData( hini, pAppName, pKeyName, &wp, &ulWpSize ) )
214        {
215            if ( wp.Swp.fl & SWP_MAXIMIZE ) {
216                SwpOptions |= SWP_MAXIMIZE;
217            }
218            else if ( wp.Swp.fl & SWP_MINIMIZE ) {
219                SwpOptions |= SWP_MINIMIZE;
220            }
221
222            if ( min ) {
223                SwpOptions &= ~SWP_MAXIMIZE;
224                SwpOptions |= SWP_MINIMIZE;
225            }
226            if ( max ) {
227                SwpOptions &= ~SWP_MINIMIZE;
228                SwpOptions |= SWP_MAXIMIZE;
229            }
230            if ( hide ) {
231                SwpOptions &= ~SWP_SHOW;
232                SwpOptions |= SWP_HIDE;
233            }
234
235            if ( chkCoord )
236            {
237                LONG sx, sy;
238                sx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
239                sy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
240
241                if ( wp.Swp.x > sx ) {
242                    wp.Swp.x = sx - wp.Swp.cx;
243                }
244                if ( wp.Swp.y > sy ) {
245                    wp.Swp.y = sy - wp.Swp.cy;
246                }
247            }
248
249            WinSetWindowPos( hwnd, NULLHANDLE,
250                             wp.Swp.x, wp.Swp.y, wp.Swp.cx, wp.Swp.cy,
251                             SwpOptions );
252
253            WinSetWindowUShort( hwnd, QWS_XRESTORE,  wp.XRestore );
254            WinSetWindowUShort( hwnd, QWS_YRESTORE,  wp.YRestore );
255            WinSetWindowUShort( hwnd, QWS_CXRESTORE, wp.CXRestore );
256            WinSetWindowUShort( hwnd, QWS_CYRESTORE, wp.CYRestore );
257            WinSetWindowUShort( hwnd, QWS_XMINIMIZE, wp.XMinimize );
258            WinSetWindowUShort( hwnd, QWS_YMINIMIZE, wp.YMinimize );
259            rval = TRUE;
260        }
261
262        if ( pIniName != NULL ) {
263            PrfCloseProfile( hini );
264        }
265    }
266    return rval;
267}
268
269void PMStoreWindowPosI( HINI ini, PCSZ pAppName, PCSZ pKeyName, HWND hwnd )
270{
271    ER_WINDOW_POS wp;
272
273    WinQueryWindowPos( hwnd, &wp.Swp );
274    wp.XRestore  = WinQueryWindowUShort( hwnd, QWS_XRESTORE );
275    wp.YRestore  = WinQueryWindowUShort( hwnd, QWS_YRESTORE );
276    wp.CXRestore = WinQueryWindowUShort( hwnd, QWS_CXRESTORE );
277    wp.CYRestore = WinQueryWindowUShort( hwnd, QWS_CYRESTORE );
278    wp.XMinimize = WinQueryWindowUShort( hwnd, QWS_XMINIMIZE );
279    wp.YMinimize = WinQueryWindowUShort( hwnd, QWS_YMINIMIZE );
280
281    PrfWriteProfileData( ini, pAppName, pKeyName, &wp, sizeof( wp ) );
282}
283
284BOOL PMStoreWindowPos( PCSZ pIniName, PCSZ pAppName, PCSZ pKeyName, HWND hwnd )
285{
286    HAB           hab = WinQueryAnchorBlock( hwnd );
287    HINI          hini;
288    BOOL          rval = FALSE;
289
290    if ( pIniName == NULL )
291    {
292        PMStoreWindowPosI( HINI_USER, pAppName, pKeyName, hwnd );
293        rval = TRUE;
294    }
295    else
296    {
297        if ( ( hini = PrfOpenProfile( hab, pIniName ) ) != NULLHANDLE )
298        {
299            PMStoreWindowPosI( hini, pAppName, pKeyName, hwnd );
300            PrfCloseProfile( hini );
301            rval = TRUE;
302        }
303    }
304    return rval;
305}
306
307
308SHORT getStringPixSize( HPS hps, PCSZ str )
309{
310    POINTL ptl[ 3 ] = { 0 };
311    GpiQueryTextBox( hps, strlen( str ), (PSZ)str, 3, ptl );
312    return (SHORT)( ptl[ 2 ].x - ptl[ 0 ].x );
313}
314
315
316#if defined(__WATCOM__)
317static void end_zeros_trim( char *s )
318{
319    size_t l = strlen( s );
320    char *end_str = ( s + l ) - 1;
321
322    while ( *end_str == '0' ) {
323        *end_str-- = 0;
324    }
325
326    if ( *end_str == '.' ) {
327        *end_str = 0;
328    }
329}
330#endif
331
332std::string str( double n )
333{
334#if defined(__WATCOM__)
335    char *pt;
336    char buf[ 60 ];
337    memset( buf, 0, sizeof buf );
338
339    ostrstream o( buf, sizeof buf );
340    o.flags( ios::dec | ios::showpoint | ios::fixed );
341    o << n;
342    end_zeros_trim( buf );
343
344    return buf;
345#else
346    std::basic_ostringstream< char > o;
347    o.flags( std::ios::dec | std::ios::showpoint | std::ios::fixed );
348    o << n;
349    std::string ret = o.str();
350    std::string::iterator it = ret.end();
351    while ( it != ret.begin() && *--it == '0' )
352        it = ret.erase(it);
353    if ( *it == '.')
354        ret.erase(it);
355    return ret;
356#endif
357}
358
359
360void centerWindow( HWND parent, HWND hwnd )
361{
362    SWP swpf;
363    WinQueryWindowPos( parent, &swpf );
364    SWP swp;
365    WinQueryWindowPos( hwnd, &swp );
366    POINTL ptl = { ( swpf.cx - swp.cx ) / 2, ( swpf.cy - swp.cy ) / 2 };
367    WinMapWindowPoints( parent, HWND_DESKTOP, &ptl, 1 );
368    WinSetWindowPos( hwnd, HWND_TOP, ptl.x, ptl.y, 0, 0, SWP_MOVE );
369}
370
371
372static bool initCountryInfo()
373{
374    static const char *pmnkey = "PM_National";
375
376    memset( &CtryInfo, 0, sizeof( COUNTRYINFO ) );
377    COUNTRYCODE Country   = {0};
378    ULONG       ulInfoLen = 0;
379
380    DosQueryCtryInfo( sizeof( CtryInfo ), &Country, &CtryInfo, &ulInfoLen );
381
382    char buf[ 10 ];
383    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sDate",
384                           CtryInfo.szDateSeparator, buf, sizeof( buf ) );
385    CtryInfo.szDateSeparator[ 0 ] = buf[ 0 ];
386    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sTime",
387                           CtryInfo.szTimeSeparator, buf, sizeof( buf ) );
388    CtryInfo.szTimeSeparator[ 0 ] = buf[ 0 ];
389    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sDecimal",
390                           CtryInfo.szDecimal, buf, sizeof( buf ) );
391    CtryInfo.szDecimal[ 0 ] = buf[ 0 ];
392    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sThousand",
393                           CtryInfo.szThousandsSeparator, buf, sizeof( buf ) );
394    CtryInfo.szThousandsSeparator[ 0 ] = buf[ 0 ];
395    PrfQueryProfileString( HINI_USERPROFILE, pmnkey, "sList",
396                           CtryInfo.szDataSeparator, buf, sizeof( buf ) );
397    CtryInfo.szDataSeparator[ 0 ] = buf[ 0 ];
398
399    return true;
400}
401
402
403static const char *format01 = "%02d%s%02d%s%04d";
404static const char *format23 = "%04d%s%02d%s%02d";
405
406static void dateToStr( struct tm *tmbuf, char *buf, int buflen )
407{
408    switch ( CtryInfo.fsDateFmt )
409    {
410        case 0:
411            snprintf( buf, buflen, format01,
412                      tmbuf->tm_mon + 1, CtryInfo.szDateSeparator, tmbuf->tm_mday,
413                      CtryInfo.szDateSeparator, tmbuf->tm_year + 1900 );
414            break;
415        case 1:
416            snprintf( buf, buflen, format01,
417                      tmbuf->tm_mday, CtryInfo.szDateSeparator, tmbuf->tm_mon + 1,
418                      CtryInfo.szDateSeparator, tmbuf->tm_year + 1900 );
419            break;
420        case 2:
421            snprintf( buf, buflen, format23,
422                      tmbuf->tm_year + 1900, CtryInfo.szDateSeparator,
423                      tmbuf->tm_mon + 1, CtryInfo.szDateSeparator, tmbuf->tm_mday );
424            break;
425        case 3:
426            snprintf( buf, buflen, format23,
427                      tmbuf->tm_year + 1900, CtryInfo.szDateSeparator,
428                      tmbuf->tm_mday, CtryInfo.szDateSeparator, tmbuf->tm_mon + 1 );
429            break;
430    }
431}
432
433static const char *format0 = "%d%s%02d%s%02d %s";
434static const char *format1 = "%02d%s%02d%s%02d";
435
436static void timeToStr( struct tm *tmbuf, char *buf, int buflen )
437{
438    switch ( CtryInfo.fsTimeFmt )
439    {
440        case 0:
441            snprintf( buf, buflen, format0,
442                      (int)( ( tmbuf->tm_hour > 12 ) ? ( tmbuf->tm_hour - 12 ) :
443                                                         tmbuf->tm_hour ),
444                      CtryInfo.szTimeSeparator, (int)tmbuf->tm_min,
445                      CtryInfo.szTimeSeparator, (int)tmbuf->tm_sec,
446                      (char *)( ( tmbuf->tm_hour < 12 ) ? "AM" : "PM" ) );
447            break;
448        case 1:
449            snprintf( buf, buflen, format1, tmbuf->tm_hour,
450                      CtryInfo.szTimeSeparator, tmbuf->tm_min,
451                      CtryInfo.szTimeSeparator, tmbuf->tm_sec );
452            break;
453    }
454}
455
456std::string time2string( unsigned long time )
457{
458    struct tm tmbuf = { 0 };
459#if defined(__WATCOM__)
460    _localtime( &time, &tmbuf );
461#else
462    time_t t = time;
463    localtime_r(&t, &tmbuf );
464#endif
465    char datbuf[ 16 ] = "";
466    char timbuf[ 16 ] = "";
467    dateToStr( &tmbuf, datbuf, sizeof( datbuf ) );
468    timeToStr( &tmbuf, timbuf, sizeof( timbuf ) );
469
470    std::string s = datbuf;
471    s += "  ";
472    s += timbuf;
473
474    return s;
475}
476
477SHORT setZoomValues( HWND lbox )
478{
479    char *actsizetext = newstrdupL( TBHINT_ACTUAL_SIZE );
480    char *fitwindtext = newstrdupL( TBHINT_FIT_WINDOW );
481    char *fitwidthtext = newstrdupL( TBHINT_FIT_WIDTH );
482    WinSetWindowText( lbox, actsizetext );
483    WinInsertLboxItem( lbox, LIT_END, actsizetext );
484    WinInsertLboxItem( lbox, LIT_END, fitwindtext );
485    WinInsertLboxItem( lbox, LIT_END, fitwidthtext );
486    WinInsertLboxItem( lbox, LIT_END, "12.5%" );
487    WinInsertLboxItem( lbox, LIT_END, "25%" );
488    WinInsertLboxItem( lbox, LIT_END, "50%" );
489    WinInsertLboxItem( lbox, LIT_END, "100%" );
490    WinInsertLboxItem( lbox, LIT_END, "125%" );
491    WinInsertLboxItem( lbox, LIT_END, "150%" );
492    WinInsertLboxItem( lbox, LIT_END, "200%" );
493    WinInsertLboxItem( lbox, LIT_END, "300%" );
494    WinInsertLboxItem( lbox, LIT_END, "400%" );
495    WinInsertLboxItem( lbox, LIT_END, "800%" );
496    WinInsertLboxItem( lbox, LIT_END, "1600%" );
497
498    HPS hps = WinGetPS( lbox );
499    SHORT actsizelen = getStringPixSize( hps, actsizetext );
500    SHORT fitwindlen = getStringPixSize( hps, fitwindtext );
501    SHORT fitwidthlen = getStringPixSize( hps, fitwidthtext );
502    WinReleasePS( hps );
503
504    delete fitwidthtext;
505    delete fitwindtext;
506    delete actsizetext;
507
508    return std::max( actsizelen, std::max( fitwindlen, fitwidthlen ) );
509}
510
511double convZoom( SHORT v )
512{
513    double z = -3;
514    switch ( v )
515    {
516        case 0:   z = 1;      break;
517        case 1:   z = -2;     break;
518        case 2:   z = -1;     break;
519        case 3:   z = 0.125;  break;
520        case 4:   z = 0.25;   break;
521        case 5:   z = 0.5;    break;
522        case 6:   z = 1;      break;
523        case 7:   z = 1.25;   break;
524        case 8:   z = 1.5;    break;
525        case 9:   z = 2;      break;
526        case 10:  z = 3;      break;
527        case 11:  z = 4;      break;
528        case 12:  z = 8;      break;
529        case 13:  z = 16;     break;
530    }
531    return z;
532}
533
534char *getTmpDir( char *buf )
535{
536    char *tmpenv = getenv( "TMP" );
537    strcpy( buf, ( tmpenv == NULL ) ? ".\\" : tmpenv );
538    if ( buf[ strlen( buf ) - 1 ] != '\\' ) {
539        strcat( buf, "\\" );
540    }
541    return buf;
542}
Note: See TracBrowser for help on using the repository browser.