source: branches/branch-1-0/src/xcenter/ctr_setup.c@ 1465

Last change on this file since 1465 was 1465, checked in by rlwalsh, 18 months ago

XCenter: add support for full-sized icons; add automatic resizing
when fonts change; fix a bug that could cause the WinList widget
to paint over the next widget.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 55.9 KB
Line 
1
2/*
3 *@@sourcefile ctr_setup.c:
4 * XCenter instance setup.
5 *
6 * Function prefix for this file:
7 * -- ctrp* also.
8 *
9 * This is all new with V1.0.0 and contains
10 * code formerly in ctr_notebook.c.
11 *
12 *@@added V1.0.0 (2000-11-27) [umoeller]
13 *@@header "shared\center.h"
14 */
15
16/*
17 * Copyright (C) 2000-2007 Ulrich M”ller.
18 * This file is part of the XWorkplace source package.
19 * XWorkplace is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published
21 * by the Free Software Foundation, in version 2 as it comes in the
22 * "COPYING" file of the XWorkplace main distribution.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 */
28
29#pragma strings(readonly)
30
31/*
32 * Suggested #include order:
33 * 1) os2.h
34 * 2) C library headers
35 * 3) setup.h (code generation and debugging options)
36 * 4) headers in helpers\
37 * 5) at least one SOM implementation header (*.ih)
38 * 6) dlgids.h, headers in shared\ (as needed)
39 * 7) headers in implementation dirs (e.g. filesys\, as needed)
40 * 8) #pragma hdrstop and then more SOM headers which crash with precompiled headers
41 */
42
43#define INCL_DOSEXCEPTIONS
44#define INCL_DOSPROCESS
45#define INCL_DOSMODULEMGR
46#define INCL_DOSSEMAPHORES // V0.9.20 (2002-07-23) [lafaix] needed for plugins.h
47#define INCL_DOSERRORS
48
49#define INCL_WINWINDOWMGR
50#define INCL_WINMENUS
51#define INCL_WINDIALOGS
52#define INCL_WINBUTTONS
53#define INCL_WINSTATICS
54#define INCL_WINSTDCNR
55#define INCL_WINSTDSLIDER
56#include <os2.h>
57
58// C library headers
59#include <stdio.h>
60#include <setjmp.h> // needed for except.h
61#include <assert.h> // needed for except.h
62
63// generic headers
64#include "setup.h" // code generation and debugging options
65
66// headers in /helpers
67#include "helpers\apmh.h" // Legacy Advanced Power Management helpers
68#include "helpers\acpih.h" // ACPI helpers
69#include "helpers\cnrh.h" // container helper routines
70#include "helpers\dialog.h" // dialog helpers
71#include "helpers\except.h" // exception handling
72#include "helpers\linklist.h" // linked list helper routines
73#include "helpers\prfh.h" // INI file helper routines
74#include "helpers\standards.h" // some standard macros
75#include "helpers\stringh.h" // string helper routines
76#include "helpers\winh.h" // PM helper routines
77#include "helpers\xstring.h" // extended string helpers
78
79// SOM headers which don't crash with prec. header files
80#include "xcenter.ih"
81#include "xfobj.ih" // XFldObject
82
83// XWorkplace implementation headers
84#include "dlgids.h" // all the IDs that are shared with NLS
85#include "shared\common.h" // the majestic XWorkplace include file
86#include "shared\errors.h" // private XWorkplace error codes
87#include "shared\notebook.h" // generic XWorkplace notebook handling
88#include "shared\wpsh.h" // some pseudo-SOM functions (WPS helper routines)
89#include "shared\plugins.h" // generic plugins support
90
91#include "shared\center.h" // public XCenter interfaces
92#include "xcenter\centerp.h" // private XCenter implementation
93
94#include "hook\xwphook.h"
95#include "config\hookintf.h" // daemon/hook interface
96
97#pragma hdrstop // VAC++ keeps crashing otherwise
98
99/* ******************************************************************
100 *
101 * Global variables
102 *
103 ********************************************************************/
104
105/* ******************************************************************
106 *
107 * XCenter setup set (see XWPSETUPENTRY)
108 *
109 ********************************************************************/
110
111/*
112 *@@ G_XCenterSetupSet:
113 * setup set of the XCenter. See XWPSETUPENTRY.
114 *
115 * Presently used key values:
116 *
117 + 1: holds the packed setup string.
118 + 2: _ulWindowStyle,
119 + 3: _ulAutoHide,
120 + 4: _flDisplayStyle,
121 + 7: _lPriorityDelta,
122 + 8: _ulPosition,
123 + 9: _ul3DBorderWidth,
124 + 10: _ulBorderSpacing,
125 + 11: _ulWidgetSpacing,
126 + 12: _fReduceDesktopWorkarea
127 + 13: _pszClientFont
128 + 14: _lcolClientBackground
129 + 15: _fHideOnClick
130 + 16: _ulHeight
131 + 17: _ulWidth
132 + 18: _fAutoScreenBorder
133 + 19: _fAutoOpen
134 +
135 */
136
137extern const XWPSETUPENTRY G_XCenterSetupSet[] =
138 {
139 /*
140 * ulWindowStyle bitfield... first a LONG, then the bitfields
141 *
142 */
143
144 // type, setup string, offset,
145 STG_LONG_DEC, NULL, FIELDOFFSET(XCenterData, ulWindowStyle),
146 // key for wpSaveState/wpRestoreState
147 2, // bitfield! only first item!
148 // default, ulExtra, min, max
149 0, 0, 0, 0,
150
151 // type, setup string, offset,
152 STG_BITFLAG, "ALWAYSONTOP", FIELDOFFSET(XCenterData, ulWindowStyle),
153 // key for wpSaveState/wpRestoreState
154 0, // bitfield! only first item!
155 // default, ulExtra, min, max
156 0, WS_TOPMOST, 0, 0,
157
158 // type, setup string, offset,
159 STG_BITFLAG, "ANIMATE", FIELDOFFSET(XCenterData, ulWindowStyle),
160 // key for wpSaveState/wpRestoreState
161 0, // bitfield! only first item!
162 // default, ulExtra, min, max
163 0, WS_ANIMATE, 0, 0,
164
165 /*
166 * flDisplayStyle bitfield... first a LONG, then the bitfields
167 *
168 */
169
170 // type, setup string, offset,
171 STG_LONG_DEC, NULL, FIELDOFFSET(XCenterData, flDisplayStyle),
172 // key for wpSaveState/wpRestoreState
173 4, // bitfield! only first item!
174 // default, ulExtra, min, max
175 XCS_FLATBUTTONS | /* XCS_SUNKBORDERS | */ XCS_SIZINGBARS | XCS_SPACINGLINES,
176 // ^^^ fixed V0.9.19 (2002-04-25) [umoeller]
177 0, 0, 0,
178
179 // type, setup string, offset,
180 STG_BITFLAG, "FLATBUTTONS", FIELDOFFSET(XCenterData, flDisplayStyle),
181 // key for wpSaveState/wpRestoreState
182 0, // bitfield! only first item!
183 // default, ulExtra, min, max
184 XCS_FLATBUTTONS, XCS_FLATBUTTONS, 0, 0,
185
186 // type, setup string, offset,
187 STG_BITFLAG, "SUNKBORDERS", FIELDOFFSET(XCenterData, flDisplayStyle),
188 // key for wpSaveState/wpRestoreState
189 0, // bitfield! only first item!
190 // default, ulExtra, min, max
191 0, XCS_SUNKBORDERS, 0, 0,
192 // default changed V0.9.16 (2001-10-15) [umoeller]
193
194 // type, setup string, offset,
195 STG_BITFLAG, "SIZINGBARS", FIELDOFFSET(XCenterData, flDisplayStyle),
196 // key for wpSaveState/wpRestoreState
197 0, // bitfield! only first item!
198 // default, ulExtra, min, max
199 XCS_SIZINGBARS, XCS_SIZINGBARS, 0, 0,
200
201 // type, setup string, offset,
202 STG_BITFLAG, "ALL3DBORDERS", FIELDOFFSET(XCenterData, flDisplayStyle),
203 // key for wpSaveState/wpRestoreState
204 0, // bitfield! only first item!
205 // default, ulExtra, min, max
206 0, XCS_ALL3DBORDERS, 0, 0,
207
208 // type, setup string, offset,
209 STG_BITFLAG, "SPACINGLINES", FIELDOFFSET(XCenterData, flDisplayStyle),
210 // key for wpSaveState/wpRestoreState
211 0, // bitfield! only first item!
212 // default, ulExtra, min, max
213 XCS_SPACINGLINES, XCS_SPACINGLINES, 0, 0,
214
215 // type, setup string, offset,
216 STG_BITFLAG, "NOHATCHOPENOBJ", FIELDOFFSET(XCenterData, flDisplayStyle),
217 // key for wpSaveState/wpRestoreState
218 0, // bitfield! only first item!
219 // default, ulExtra, min, max
220 0, XCS_NOHATCHINUSE, 0, 0,
221
222 // type, setup string, offset,
223 STG_BITFLAG, "LARGEICONS", FIELDOFFSET(XCenterData, flDisplayStyle),
224 // key for wpSaveState/wpRestoreState
225 0, // bitfield! only first item!
226 // default, ulExtra, min, max
227 0, XCS_LARGEICONS, 0, 0,
228
229 /*
230 * other LONGs
231 *
232 */
233
234 // type, setup string, offset,
235 STG_LONG_DEC, "AUTOHIDE", FIELDOFFSET(XCenterData, ulAutoHide),
236 // key for wpSaveState/wpRestoreState
237 3,
238 // default, ulExtra, min, max
239 0, 0, 0, 60000,
240
241 // type, setup string, offset,
242 STG_LONG_DEC, "PRIORITYDELTA", FIELDOFFSET(XCenterData, lPriorityDelta),
243 // key for wpSaveState/wpRestoreState
244 7,
245 // default, ulExtra, min, max
246 0, 0, 0, 31,
247
248 // type, setup string, offset,
249 STG_LONG_DEC, NULL, FIELDOFFSET(XCenterData, ulPosition),
250 // key for wpSaveState/wpRestoreState
251 8,
252 // default, ulExtra, min, max
253 XCENTER_BOTTOM, 0, 0, 3,
254
255 // type, setup string, offset,
256 STG_LONG_DEC, "3DBORDERWIDTH", FIELDOFFSET(XCenterData, ul3DBorderWidth),
257 // key for wpSaveState/wpRestoreState
258 9,
259 // default, ulExtra, min, max
260 2, 0, 0, 10,
261
262 // type, setup string, offset,
263 STG_LONG_DEC, "BORDERSPACING", FIELDOFFSET(XCenterData, ulBorderSpacing),
264 // key for wpSaveState/wpRestoreState
265 10,
266 // default, ulExtra, min, max
267 2, 0, 0, 10,
268
269 // type, setup string, offset,
270 STG_LONG_DEC, "WIDGETSPACING", FIELDOFFSET(XCenterData, ulWidgetSpacing),
271 // key for wpSaveState/wpRestoreState
272 11,
273 // default, ulExtra, min, max
274 2, 0, 1, 10,
275
276 // type, setup string, offset,
277 STG_BOOL, "REDUCEDESKTOP", FIELDOFFSET(XCenterData, fReduceDesktopWorkarea),
278 // key for wpSaveState/wpRestoreState
279 12,
280 // default, ulExtra, min, max
281 FALSE, 0, 0, 0,
282
283 // type, setup string, offset,
284 STG_PSZ, "CLIENTFONT", FIELDOFFSET(XCenterData, pszClientFont),
285 // key for wpSaveState/wpRestoreState
286 13,
287 // default, ulExtra, min, max
288 (LONG)NULL, 0, 0, 0,
289
290 // type, setup string, offset,
291 STG_LONG_RGB, "CLIENTCOLOR", FIELDOFFSET(XCenterData, lcolClientBackground),
292 // key for wpSaveState/wpRestoreState
293 14,
294 // default, ulExtra, min, max
295 0xCCCCCC, 0, 0, 0x00FFFFFF,
296
297 // type, setup string, offset,
298 STG_BOOL, "HIDEONCLICK", FIELDOFFSET(XCenterData, fHideOnClick),
299 // key for wpSaveState/wpRestoreState
300 15,
301 // default, ulExtra, min, max
302 FALSE, 0, 0, 0,
303
304 // type, setup string, offset,
305 STG_LONG_DEC, "HEIGHT", FIELDOFFSET(XCenterData, ulHeight),
306 // key for wpSaveState/wpRestoreState
307 16,
308 // default, ulExtra, min, max
309 0, 0, 0, 0xFFFF,
310
311 // type, setup string, offset,
312 STG_LONG_DEC, "WIDTH", FIELDOFFSET(XCenterData, ulWidth),
313 // key for wpSaveState/wpRestoreState
314 17,
315 // default, ulExtra, min, max
316 0, 0, 0, 0xFFFF,
317
318 // type, setup string, offset,
319 STG_BOOL, "AUTOSCREENBORDER", FIELDOFFSET(XCenterData, fAutoScreenBorder),
320 // key for wpSaveState/wpRestoreState
321 18,
322 // default, ulExtra, min, max
323 FALSE, 0, 0, 0, // V1.0.6 (2006-09-30) [pr]: changed default
324
325 // type, setup string, offset,
326 STG_BOOL, "AUTOOPEN", FIELDOFFSET(XCenterData, fAutoOpen),
327 // key for wpSaveState/wpRestoreState
328 19,
329 // default, ulExtra, min, max
330 TRUE, 1, 0, 0,
331
332 };
333
334// V1.0.0 (2002-08-12) [umoeller]
335extern ULONG G_cXCenterSetupSetEntries = ARRAYITEMCOUNT(G_XCenterSetupSet);
336
337/*
338 *@@ ctrpInitData:
339 * part of the implementation for XCenter::wpInitData.
340 *
341 *@@added V0.9.9 (2001-01-29) [umoeller]
342 */
343
344VOID ctrpInitData(XCenter *somSelf)
345{
346 XCenterData *somThis = XCenterGetData(somSelf);
347 cmnSetupInitData(G_XCenterSetupSet,
348 ARRAYITEMCOUNT(G_XCenterSetupSet),
349 somThis);
350}
351
352STATIC VOID AppendWidgetSettings(PXSTRING pstrSetup,
353 PLINKLIST pllSettings);
354
355/*
356 *@@ ctrpAppendWidgetSettings:
357 * appends the given widget setting as a
358 * setup string to the given XSTRING.
359 *
360 * Used by AppendWidgetSettings (into which
361 * this will also recurse), but also by
362 * drag'n'drop to drop trays across XCenters
363 * correctly.
364 *
365 * pstrSetup is assumed to be initialized.
366 *
367 * In addition, you must pass in a BOOL variable
368 * in pfFirstWidget that must be set to FALSE.
369 *
370 * Finally, this uses pstrTemp as a temp buffer
371 * for speed, which must be initialized and
372 * cleared after use also.
373 *
374 *@@added V0.9.19 (2002-05-04) [umoeller]
375 */
376
377VOID ctrpAppendWidgetSettings(PXSTRING pstrSetup,
378 PPRIVATEWIDGETSETTING pSetting,
379 PBOOL pfFirstWidget,
380 PXSTRING pstrTemp)
381{
382 ULONG ulSetupLen;
383
384 if (!*pfFirstWidget)
385 // not first run:
386 // add separator
387 xstrcatc(pstrSetup, ',');
388 else
389 *pfFirstWidget = FALSE;
390
391 // add widget class
392 xstrcat(pstrSetup, pSetting->Public.pszWidgetClass, 0);
393
394 // add first separator
395 xstrcatc(pstrSetup, '(');
396
397 if ( (pSetting->Public.pszSetupString)
398 && (ulSetupLen = strlen(pSetting->Public.pszSetupString))
399 )
400 {
401 // widget has a setup string:
402 // copy widget setup string to temporary buffer
403 // for encoding... this has "=" and ";"
404 // chars in it, and these should not appear
405 // in the WPS setup string
406 xstrcpy(pstrTemp,
407 pSetting->Public.pszSetupString,
408 ulSetupLen);
409
410 xstrEncode(pstrTemp,
411 "%,{}[]();=");
412 // added {}[] V0.9.19 (2002-04-25) [umoeller]
413
414 // now append encoded widget setup string
415 xstrcats(pstrSetup, pstrTemp);
416
417 } // end if ( (pSetting->pszSetupString)...
418
419 // add terminator
420 xstrcatc(pstrSetup, ')');
421
422 // add trays in round brackets, if we have any
423 if (pSetting->pllTraySettings)
424 {
425 PLISTNODE pTrayNode = lstQueryFirstNode(pSetting->pllTraySettings);
426
427 xstrcatc(pstrSetup, '{');
428
429 while (pTrayNode)
430 {
431 PTRAYSETTING pTraySetting = (PTRAYSETTING)pTrayNode->pItemData;
432
433 // "Tray(setupstring){Tray1[widget1,widget],Tray2[widget]}"
434
435 xstrcat(pstrSetup,
436 pTraySetting->pszTrayName,
437 0);
438
439 // add subwidgets in square brackets
440 xstrcatc(pstrSetup, '[');
441
442 // recurse
443 AppendWidgetSettings(pstrSetup,
444 &pTraySetting->llSubwidgetSettings);
445
446 xstrcatc(pstrSetup, ']');
447
448 pTrayNode = pTrayNode->pNext;
449 }
450
451 xstrcatc(pstrSetup, '}');
452 }
453}
454
455/*
456 *@@ AppendWidgetSettings:
457 * appends all widgets in pllSettings to the
458 * given XSTRING, including trays and subwidgets,
459 * if any.
460 *
461 *@@added V0.9.19 (2002-04-25) [umoeller]
462 */
463
464STATIC VOID AppendWidgetSettings(PXSTRING pstrSetup,
465 PLINKLIST pllSettings)
466{
467 BOOL fFirstWidget = TRUE;
468 XSTRING strSetup2;
469 PLISTNODE pNode = lstQueryFirstNode(pllSettings);
470
471 xstrInit(&strSetup2, 0);
472
473 while (pNode)
474 {
475 PPRIVATEWIDGETSETTING pSetting = (PPRIVATEWIDGETSETTING)pNode->pItemData;
476
477 ctrpAppendWidgetSettings(pstrSetup, pSetting, &fFirstWidget, &strSetup2);
478
479 pNode = pNode->pNext;
480 } // end for widgets
481
482 xstrClear(&strSetup2);
483}
484
485/*
486 *@@ ctrpQuerySetup:
487 * implementation for XCenter::xwpQuerySetup2.
488 *
489 *@@added V0.9.7 (2000-12-09) [umoeller]
490 *@@changed V0.9.19 (2002-04-25) [umoeller]: finally added trays support
491 */
492
493BOOL ctrpQuerySetup(XCenter *somSelf,
494 PVOID pstrSetup)
495{
496 BOOL brc = TRUE;
497
498 // V0.9.16 (2001-10-11) [umoeller]:
499 // removed object lock
500 // this is properly handled by xwpQuerySetup already
501
502 // compose setup string
503
504 TRY_LOUD(excpt2)
505 {
506 XCenterData *somThis = XCenterGetData(somSelf);
507
508 // temporary buffer for building the setup string
509 PLINKLIST pllSettings = ctrpQuerySettingsList(somSelf);
510 PLISTNODE pNode;
511
512 /*
513 * build string
514 *
515 */
516
517 if (_ulPosition == XCENTER_TOP)
518 xstrcat(pstrSetup, "POSITION=TOP;", 0);
519
520 // use array for the rest...
521 cmnSetupBuildString(G_XCenterSetupSet,
522 ARRAYITEMCOUNT(G_XCenterSetupSet),
523 somThis,
524 pstrSetup);
525
526 // now build widgets string... this is complex.
527 if (pNode = lstQueryFirstNode(pllSettings))
528 {
529 // we have widgets:
530 // go thru all of them and list all widget classes and setup strings
531
532 xstrcat(pstrSetup, "WIDGETS=", 0);
533
534 AppendWidgetSettings(pstrSetup, pllSettings);
535 // V0.9.19 (2002-04-25) [umoeller]
536
537 xstrcatc(pstrSetup, ';');
538 }
539 }
540 CATCH(excpt2)
541 {
542 brc = FALSE;
543 } END_CATCH();
544
545 // if we haven't crashed
546 if (brc)
547 {
548 // manually resolve parent method
549 return (wpshParentQuerySetup2(somSelf,
550 _somGetParent(_XCenter),
551 pstrSetup));
552 }
553
554 return brc;
555}
556
557/*
558 *@@ CreateWidgetFromString:
559 *
560 *@@added V0.9.19 (2002-04-25) [umoeller]
561 */
562
563STATIC BOOL CreateWidgetFromString(XCenter *somSelf,
564 PCSZ pcszClass,
565 PCSZ pcszSetup,
566 ULONG ulTrayWidgetIndex,
567 ULONG ulTrayIndex,
568 PULONG pcWidgets,
569 PBOOL pfIsTray)
570{
571 WIDGETPOSITION pos2;
572 APIRET arc;
573
574 _PmpfF(("creating \"%s\", \"%s\"",
575 STRINGORNULL(pcszClass),
576 STRINGORNULL(pcszSetup)));
577
578 pos2.ulTrayWidgetIndex = ulTrayWidgetIndex;
579 pos2.ulTrayIndex = ulTrayIndex;
580 pos2.ulWidgetIndex = -1; // to the right
581 if (arc = _xwpCreateWidget(somSelf,
582 (PSZ)pcszClass,
583 (PSZ)pcszSetup,
584 &pos2))
585 {
586 // error:
587 cmnLog(__FILE__, __LINE__, __FUNCTION__,
588 "Creating widget \"%s\" (\"%s\") failed, rc = %d.",
589 pcszClass,
590 pcszSetup,
591 arc);
592 return FALSE;
593 }
594
595 if (pfIsTray)
596 *pfIsTray = (!strcmp(pcszClass, TRAY_WIDGET_CLASS_NAME));
597
598 ++(*pcWidgets);
599
600 return TRUE;
601}
602
603STATIC BOOL ParseWidgetsString(XCenter *somSelf,
604 PSZ pszWidgets, // in: WIDGETS= data only
605 ULONG ulTrayWidgetIndex,
606 ULONG ulTrayIndex);
607
608/*
609 *@@ ParseTraysList:
610 * called from ParseWidgetsString if a
611 * trays list is encountered. We will then
612 * recurse into ParseWidgetsString with
613 * the subwidget lists.
614 *
615 *@@added V0.9.19 (2002-04-25) [umoeller]
616 */
617
618STATIC BOOL ParseTraysList(XCenter *somSelf,
619 PCSZ pcszTraysList,
620 ULONG ulTrayWidgetIndex)
621{
622 BOOL brc = TRUE;
623
624 // on input, we get
625 // "Tray1[widget1,widget]Tray2[widget]"
626 PCSZ pTrayThis = pcszTraysList;
627 ULONG cTraysSet = 0;
628 while ( (pTrayThis)
629 && (*pTrayThis)
630 && (brc)
631 )
632 {
633 // tray with widgets list comes next in square brackets
634 PCSZ pOpen,
635 pClose;
636 if ( (!(pOpen = strchr(pTrayThis, '[')))
637 || (!(pClose = strchr(pOpen, ']')))
638 )
639 brc = FALSE;
640 else
641 {
642 PSZ pszTrayName;
643 if (!(pszTrayName = strhSubstr(pTrayThis,
644 pOpen)))
645 brc = FALSE;
646 else
647 {
648 PSZ pszSubwidgetsList;
649 APIRET arc;
650
651 if (!cTraysSet)
652 // first tray: the tray widget creates
653 // an automatic tray if there's none
654 // on creation, so rename this
655 arc = _xwpRenameTray(somSelf,
656 ulTrayWidgetIndex,
657 0,
658 pszTrayName);
659 else
660 arc = _xwpCreateTray(somSelf,
661 ulTrayWidgetIndex,
662 pszTrayName);
663
664 if (arc)
665 brc = FALSE;
666 else
667 {
668
669 // now recurse with the widgets list
670 if (!(pszSubwidgetsList = strhSubstr(pOpen + 1,
671 pClose)))
672 brc = FALSE;
673 else
674 {
675 _PmpfF(("recursing with string \"%s\"",
676 pszSubwidgetsList));
677
678 brc = ParseWidgetsString(somSelf,
679 pszSubwidgetsList,
680 ulTrayWidgetIndex,
681 cTraysSet);
682
683 _PmpfF(("ParseWidgetsString returned %d", brc));
684
685 free(pszSubwidgetsList);
686 }
687
688 // next tray after closing bracket
689 pTrayThis = pClose + 1;
690
691 ++cTraysSet;
692 }
693 }
694 }
695 }
696
697 return brc;
698}
699
700/*
701 *@@ ParseWidgetsString:
702 * implementation for the WIDGETS=xxx setup
703 * string particle in ctrpSetup.
704 *
705 * Initially, this gets called from ctrpSetup
706 * with ulTrayWidgetIndex and ulTrayIndex
707 * both set to -1 to create the root widgets.
708 * If we find trays, we call ParseTraysList,
709 * which will recurse into this routine with
710 * the tray widget and tray indices set
711 * accordingly.
712 *
713 * I am not sure that I will understand what
714 * this code is doing one week from now, but
715 * apparently it's working for now.
716 *
717 *@@added V0.9.19 (2002-04-25) [umoeller]
718 */
719
720STATIC BOOL ParseWidgetsString(XCenter *somSelf,
721 PSZ pszWidgets, // in: data from WIDGETS= only
722 ULONG ulTrayWidgetIndex,
723 ULONG ulTrayIndex)
724{
725 BOOL brc = TRUE;
726
727 // now, off we go...
728 // parse the WIDGETS string
729 // format is: "widget1,widget2,widget3"
730 // where each "widget" is one of
731 // -- plain widget class name, e.g. "Pulse"
732 // -- widget class name with encoded setup
733 // string, e.g. "Pulse(WIDTH%3D130%3)"
734 // -- a tray with even more subwidgets,
735 // e.g. "Tray(setupstring){Tray1[widget1,widget]Tray2[widget]}"
736
737 PCSZ pThis = pszWidgets,
738 pStartOfWidget = pszWidgets;
739 CHAR c;
740
741 BOOL fStop = FALSE;
742
743 ULONG cWidgetsCreated = 0;
744 BOOL fLastWasTray = FALSE;
745
746 while ( (!fStop)
747 && (brc)
748 )
749 {
750 switch (c = *pThis)
751 {
752 case '\0':
753 case ',':
754 {
755 // OK, widget terminator:
756 // then we had no setup string
757 PSZ pszWidgetClass = strhSubstr(pStartOfWidget,
758 pThis); // up to comma
759
760 brc = CreateWidgetFromString(somSelf,
761 pszWidgetClass,
762 NULL,
763 ulTrayWidgetIndex,
764 ulTrayIndex,
765 &cWidgetsCreated,
766 NULL);
767
768 FREE(pszWidgetClass);
769
770 if (!c)
771 fStop = TRUE;
772 else
773 pStartOfWidget = pThis + 1;
774 }
775 break;
776
777 case '(':
778 {
779 // beginning of setup string:
780 // extract setup
781 PCSZ pClose;
782 if (!(pClose = strchr(pThis + 1, ')')))
783 {
784 cmnLog(__FILE__, __LINE__, __FUNCTION__,
785 "Expected ')' after \"%s\"",
786 pThis + 1);
787 brc = FALSE;
788 }
789 else
790 {
791 // extract widget class before bracket
792 PSZ pszWidgetClass;
793 if (!(pszWidgetClass = strhSubstr(pStartOfWidget,
794 pThis))) // up to bracket
795 {
796 cmnLog(__FILE__, __LINE__, __FUNCTION__,
797 "Invalid widget class at \"%s\"",
798 pStartOfWidget);
799 brc = FALSE;
800 }
801 else
802 {
803 // copy widget setup string to temporary
804 // buffer for decoding...
805 XSTRING strSetup2;
806 PSZ pszWidgetSetup = strhSubstr(pThis + 1,
807 pClose);
808
809 xstrInitSet(&strSetup2,
810 pszWidgetSetup);
811 xstrDecode(&strSetup2);
812 pszWidgetSetup = strSetup2.psz;
813
814 brc = CreateWidgetFromString(somSelf,
815 pszWidgetClass,
816 pszWidgetSetup,
817 ulTrayWidgetIndex,
818 ulTrayIndex,
819 &cWidgetsCreated,
820 &fLastWasTray);
821
822 FREE(pszWidgetSetup);
823 FREE(pszWidgetClass);
824 }
825
826 if (brc)
827 {
828 // continue after closing bracket;
829 // next will either be a comma or, if this
830 // is a tray, a square bracket
831 pThis = pClose + 1;
832
833 switch (*pThis)
834 {
835 case ',':
836 ++pThis;
837 pStartOfWidget = pThis;
838 continue;
839
840 case '{':
841 continue;
842
843 case '\0':
844 fStop = TRUE;
845 break;
846
847 default:
848 cmnLog(__FILE__, __LINE__, __FUNCTION__,
849 "Expected ',' after \"%s\"",
850 pClose);
851 brc = FALSE;
852 }
853 }
854 }
855 }
856 break;
857
858 case '{':
859 {
860 // beginning of trays list for tray widget:
861 // then we must have created a widget already,
862 // or this will fail
863 if (!fLastWasTray)
864 brc = FALSE;
865 else
866 {
867 PCSZ pClose;
868 if (!(pClose = strchr(pThis + 1, '}')))
869 {
870 cmnLog(__FILE__, __LINE__, __FUNCTION__,
871 "Expected '}' after \"%s\"",
872 pThis + 1);
873 brc = FALSE;
874 }
875 else
876 {
877 // now run thru the trays list:
878 PSZ pszTraysList;
879 if (!(pszTraysList = strhSubstr(pThis + 1,
880 pClose)))
881 {
882 cmnLog(__FILE__, __LINE__, __FUNCTION__,
883 "Invalid trays list at \"%s\"",
884 pThis + 1);
885 brc = FALSE;
886 }
887 else
888 {
889 // alright, call this subroutine,
890 // which will recurse into this routine
891 // with the subwidgets lists
892 brc = ParseTraysList(somSelf,
893 pszTraysList,
894 cWidgetsCreated - 1);
895 free(pszTraysList);
896 }
897 }
898
899 if (brc)
900 {
901 // continue after closing bracket;
902 // next _must_ be a comma
903 pThis = pClose + 1;
904
905 switch (*pThis)
906 {
907 case ',':
908 ++pThis;
909 pStartOfWidget = pThis;
910 continue;
911
912 case '\0':
913 fStop = TRUE;
914 break;
915
916 default:
917 cmnLog(__FILE__, __LINE__, __FUNCTION__,
918 "Expected ',' after \"%s\"",
919 pClose);
920 brc = FALSE;
921 }
922 }
923 }
924 }
925 break;
926
927 case ')':
928 case '}':
929 case '[':
930 case ']':
931 // loose closing brackets: that's invalid syntax
932 cmnLog(__FILE__, __LINE__, __FUNCTION__,
933 "Unexpected character '%c' at \"%s\"",
934 *pThis,
935 pThis);
936 brc = FALSE;
937 }
938
939 pThis++;
940 }
941
942 return brc;
943}
944
945/*
946 *@@ AppendObjects:
947 * helper for CreateDefaultWidgets.
948 *
949 *@@added V0.9.19 (2002-04-25) [umoeller]
950 *@@changed V1.0.6 (2006-08-20) [pr]: fix default Xcenter creation at install time @@fixes 749
951 */
952
953STATIC ULONG AppendObjects(PXSTRING pstr,
954 PCSZ *apcsz,
955 ULONG c)
956{
957 ULONG cAdded = 0;
958 ULONG ul;
959 for (ul = 0;
960 ul < c;
961 ++ul)
962 {
963 // V1.0.6 (2006-08-20) [pr]: unnecessary check causes install problems with
964 // creating the default XCenter due to the dependent objects not having had
965 // time to be flushed to the INI file.
966 // if (cmnQueryObjectFromID(apcsz[ul]))
967 {
968 if (cAdded)
969 xstrcatc(pstr, ',');
970
971 xstrcat(pstr,
972 "ObjButton(OBJECTHANDLE%3D",
973 0);
974 xstrcat(pstr,
975 apcsz[ul],
976 0);
977 xstrcat(pstr,
978 "%3B)",
979 0);
980
981 ++cAdded;
982 }
983 }
984
985 return cAdded;
986}
987
988/*
989 *@@ CreateDefaultWidgets:
990 * this creates the default widgets in the XCenter.
991 * by creating a setup string accordingly and then
992 * calling ParseWidgetsString directly, which will
993 * go create the widgets from the string.
994 *
995 * NOTE: This
996 *
997 *@@added V0.9.20 (2002-07-19) [umoeller]
998 */
999
1000STATIC BOOL CreateDefaultWidgets(XCenter *somSelf)
1001{
1002 BOOL brc;
1003
1004 static const char *apcszMain[] =
1005 {
1006 "<XWP_LOCKUPSTR>",
1007 "<XWP_FINDSTR>",
1008 "<XWP_SHUTDOWNSTR>",
1009 };
1010 static const char *apcszTray1[] =
1011 {
1012 "<WP_DRIVES>",
1013 "<WP_CONFIG>",
1014 "<WP_PROMPTS>"
1015 };
1016 ULONG ul;
1017 XSTRING str;
1018 WPObject *pobj;
1019 CHAR sz[200];
1020
1021 xstrInitCopy(&str,
1022 "XButton(),",
1023 0);
1024
1025 if (AppendObjects(&str,
1026 apcszMain,
1027 ARRAYITEMCOUNT(apcszMain)))
1028 xstrcatc(&str, ',');
1029
1030 xstrcat(&str,
1031 "Pulse(),"
1032 "Tray(){",
1033 0);
1034
1035 // create a default tray
1036 sprintf(sz,
1037 cmnGetString(ID_CRSI_TRAY), // tray %d
1038 1);
1039 xstrcat(&str,
1040 sz,
1041 0);
1042
1043 xstrcatc(&str, '[');
1044
1045 AppendObjects(&str,
1046 apcszTray1,
1047 ARRAYITEMCOUNT(apcszTray1));
1048
1049 xstrcat(&str,
1050 "]},WindowList,"
1051 "Time",
1052 0);
1053
1054 // on laptops, add battery widget too
1055 // @@changed V1.0.9 (2012-02-21) [slevine]: support ACPI power status
1056 // reporting. Code by David Azarewicz.
1057 if (acpihHasBattery() || apmhHasBattery())
1058 xstrcat(&str,
1059 ",Power()",
1060 0);
1061
1062 // call ParseWidgetsString directly
1063 brc = ParseWidgetsString(somSelf,
1064 str.psz,
1065 -1,
1066 -1);
1067
1068 xstrClear(&str);
1069
1070 return TRUE; // don't let this fail V1.0.0 (2002-09-20) [umoeller]
1071}
1072
1073/*
1074 *@@ ctrpSetup:
1075 * implementation for XCenter::wpSetup.
1076 *
1077 *@@added V0.9.7 (2001-01-25) [umoeller]
1078 *@@changed V0.9.16 (2001-10-15) [umoeller]: fixed widget clearing which caused a log entry for empty XCenter
1079 *@@changed V0.9.19 (2002-04-25) [umoeller]: added exception handling; rewrote WIDGETS= setup string to handle trays
1080 *@@changed V1.0.7 (2006-12-31) [pr]: added ADDWIDGETS and DELETEWIDGETS setup strings @@fixes 906
1081 *@@changed V1.0.1 (2016-10-20) [rwalsh]: move DELETEWIDGETS before ADDWIDGETS so widgets can be rearranged
1082 */
1083
1084BOOL ctrpSetup(XCenter *somSelf,
1085 PSZ pszSetupString)
1086{
1087 XCenterData *somThis = XCenterGetData(somSelf);
1088 ULONG cSuccess = 0, cb;
1089 BOOL brc;
1090 PSZ pszWidgets;
1091
1092 // scan the standard stuff from the table...
1093 // this saves us a lot of work.
1094
1095 TRY_LOUD(excpt1)
1096 {
1097 // _PmpfF(("string is \"%s\"", pszSetupString));
1098
1099 // now comes the non-standard stuff:
1100 if (brc = cmnSetupScanString(somSelf,
1101 G_XCenterSetupSet,
1102 ARRAYITEMCOUNT(G_XCenterSetupSet),
1103 somThis,
1104 pszSetupString,
1105 &cSuccess))
1106 {
1107 CHAR szValue[100];
1108
1109 _Pmpf((" cmnSetupScanString returned TRUE"));
1110 cb = sizeof(szValue);
1111 if (_wpScanSetupString(somSelf,
1112 pszSetupString,
1113 "POSITION",
1114 szValue,
1115 &cb))
1116 {
1117 if (!stricmp(szValue, "TOP"))
1118 _ulPosition = XCENTER_TOP;
1119 else if (!stricmp(szValue, "BOTTOM"))
1120 _ulPosition = XCENTER_BOTTOM;
1121 else
1122 brc = FALSE;
1123 }
1124 }
1125
1126 if (brc)
1127 {
1128 char szValue[8];
1129
1130 // if AUTOOPEN was specified, update the auto-open list;
1131 // its value should already have been set by the standard scan
1132
1133 cb = sizeof(szValue);
1134 if (_wpScanSetupString(somSelf, pszSetupString, "AUTOOPEN",
1135 szValue, &cb) && cb > 2) {
1136 int val = -1;
1137
1138 if (!stricmp(szValue, "YES"))
1139 val = TRUE;
1140 else if (!stricmp(szValue, "NO"))
1141 val = FALSE;
1142
1143 if (val != -1)
1144 _fAutoOpen = _xwpclsSetAutoOpen(_XCenter,
1145 _wpQueryHandle(somSelf),
1146 val);
1147 }
1148 }
1149
1150 if (brc)
1151 {
1152 // WIDGETS can be very long, so query size first
1153 _Pmpf((" brc still TRUE; scanning WIDGETS string"));
1154
1155 if (_wpScanSetupString(somSelf,
1156 pszSetupString,
1157 "WIDGETS",
1158 NULL,
1159 &cb))
1160 {
1161 _Pmpf(("got WIDGETS string, %d bytes, nuking existing widgets",
1162 cb));
1163
1164 if ( cb
1165 && (pszWidgets = malloc(cb))
1166 )
1167 {
1168 if (_wpScanSetupString(somSelf,
1169 pszSetupString,
1170 "WIDGETS",
1171 pszWidgets,
1172 &cb))
1173 {
1174 // first of all, remove all existing widgets,
1175 // we have a replacement here
1176 WIDGETPOSITION pos;
1177 pos.ulTrayWidgetIndex = -1;
1178 pos.ulTrayIndex = -1;
1179 pos.ulWidgetIndex = 0; // leftmost widget
1180 while (ctrpQueryWidgetsCount(somSelf)) // V0.9.16 (2001-10-15) [umoeller]
1181 if (_xwpDeleteWidget(somSelf,
1182 &pos))
1183 {
1184 // error:
1185 brc = FALSE;
1186 break;
1187 }
1188
1189 // allow "CLEAR" to just nuke the widgets
1190 // V0.9.19 (2002-04-25) [umoeller]
1191 if (!stricmp(pszWidgets, "CLEAR"))
1192 ;
1193 // allow "RESET" to reset the widgets to
1194 // the defaults
1195 // V0.9.20 (2002-07-19) [umoeller]
1196 else if (!stricmp(pszWidgets, "RESET"))
1197 brc = CreateDefaultWidgets(somSelf);
1198 else
1199 brc = ParseWidgetsString(somSelf,
1200 pszWidgets,
1201 -1,
1202 -1);
1203 }
1204
1205 free(pszWidgets);
1206 } // end if ( (pszWidgets)...
1207 }
1208 }
1209
1210 // V1.0.7 (2006-12-31) [pr]
1211 if (brc)
1212 {
1213 _Pmpf((" brc still TRUE; scanning DELETEWIDGETS string"));
1214 if (_wpScanSetupString(somSelf,
1215 pszSetupString,
1216 "DELETEWIDGETS",
1217 NULL,
1218 &cb))
1219 {
1220 _Pmpf(("got DELETEWIDGETS string, %d bytes", cb));
1221 if ( cb
1222 && (pszWidgets = malloc(cb))
1223 )
1224 {
1225 if (_wpScanSetupString(somSelf,
1226 pszSetupString,
1227 "DELETEWIDGETS",
1228 pszWidgets,
1229 &cb))
1230 {
1231 PCSZ pThis = pszWidgets,
1232 pStartOfWidget = pszWidgets;
1233
1234 for (; brc; pThis++)
1235 if ((*pThis == '\0') || (*pThis == ','))
1236 {
1237 // OK, widget terminator:
1238 // then we had no setup string
1239 PSZ pszWidgetClass = strhSubstr(pStartOfWidget,
1240 pThis); // up to comma
1241
1242 brc = !_xwpDeleteWidgetClass(somSelf, pszWidgetClass);
1243 FREE(pszWidgetClass);
1244 if (*pThis)
1245 pStartOfWidget = pThis + 1;
1246 else
1247 break;
1248 }
1249 }
1250
1251 free(pszWidgets);
1252 }
1253 }
1254 }
1255
1256 if (brc)
1257 {
1258 _Pmpf((" brc still TRUE; scanning ADDWIDGETS string"));
1259 if (_wpScanSetupString(somSelf,
1260 pszSetupString,
1261 "ADDWIDGETS",
1262 NULL,
1263 &cb))
1264 {
1265 _Pmpf(("got ADDWIDGETS string, %d bytes", cb));
1266 if ( cb
1267 && (pszWidgets = malloc(cb))
1268 )
1269 {
1270 if (_wpScanSetupString(somSelf,
1271 pszSetupString,
1272 "ADDWIDGETS",
1273 pszWidgets,
1274 &cb))
1275 brc = ParseWidgetsString(somSelf, pszWidgets, -1, -1);
1276
1277 free(pszWidgets);
1278 }
1279 }
1280 }
1281 }
1282 CATCH(excpt1)
1283 {
1284 brc = FALSE;
1285 } END_CATCH();
1286
1287 return brc;
1288}
1289
1290/*
1291 *@@ ctrpSetupOnce:
1292 * implementation for XCenter::wpSetupOnce.
1293 * Creates the default widgets if none are given.
1294 *
1295 *@@added V0.9.16 (2001-10-15) [umoeller]
1296 *@@changed V0.9.19 (2002-04-25) [umoeller]: added default tray with objects
1297 *@@changed V0.9.20 (2002-07-19) [umoeller]: now checking for whether WIDGETS is specified
1298 */
1299
1300BOOL ctrpSetupOnce(XCenter *somSelf,
1301 PSZ pszSetupString)
1302{
1303 BOOL brc = TRUE;
1304
1305 WPObject *pobjLock = NULL;
1306 TRY_LOUD(excpt1)
1307 {
1308 ULONG cb;
1309 XCenterData *somThis = XCenterGetData(somSelf);
1310
1311 // add this instance to the auto-open list if appropriate
1312 _fAutoOpen = _xwpclsSetAutoOpen(_XCenter,
1313 _wpQueryHandle(somSelf),
1314 _fAutoOpen);
1315
1316 // create default widgets if we have no widgets yet
1317 // AND the WIDGETS string is not specified on
1318 // creation (otherwise ctrpSetup will handle this)
1319 if ( (!_wpScanSetupString(somSelf, // V0.9.20 (2002-07-19) [umoeller]
1320 pszSetupString,
1321 "WIDGETS",
1322 NULL,
1323 &cb))
1324 && (pobjLock = cmnLockObject(somSelf))
1325 )
1326 {
1327 PLINKLIST pllSettings = ctrpQuerySettingsList(somSelf);
1328 if (!lstCountItems(pllSettings))
1329 CreateDefaultWidgets(somSelf);
1330 }
1331 }
1332 CATCH(excpt1) {} END_CATCH();
1333
1334 if (pobjLock)
1335 _wpReleaseObjectMutexSem(pobjLock);
1336
1337 return brc;
1338}
1339
1340/*
1341 *@@ ctrpSaveState:
1342 * implementation for XCenter::wpSaveState.
1343 *
1344 *@@added V0.9.9 (2001-01-29) [umoeller]
1345 */
1346
1347BOOL ctrpSaveState(XCenter *somSelf)
1348{
1349 BOOL brc = TRUE;
1350
1351 TRY_LOUD(excpt1)
1352 {
1353 XCenterData *somThis = XCenterGetData(somSelf);
1354
1355 /*
1356 * key 1: widget settings
1357 *
1358 */
1359
1360 if (_pszPackedWidgetSettings)
1361 // settings haven't even been unpacked yet:
1362 // just store the packed settings
1363 _wpSaveData(somSelf,
1364 (PSZ)G_pcszXCenterReal,
1365 1,
1366 _pszPackedWidgetSettings,
1367 _cbPackedWidgetSettings);
1368 else
1369 // once the settings have been unpacked
1370 // (i.e. XCenter needed access to them),
1371 // we have to repack them on each save
1372 if (_pllAllWidgetSettings)
1373 {
1374 // compose array
1375 ULONG cbSettingsArray = 0;
1376 PSZ pszSettingsArray = ctrpStuffSettings(somSelf,
1377 &cbSettingsArray);
1378 if (pszSettingsArray)
1379 {
1380 _wpSaveData(somSelf,
1381 (PSZ)G_pcszXCenterReal,
1382 1,
1383 pszSettingsArray,
1384 cbSettingsArray);
1385 free(pszSettingsArray);
1386 }
1387 }
1388
1389 /*
1390 * other keys
1391 *
1392 */
1393
1394 cmnSetupSave(somSelf,
1395 G_XCenterSetupSet,
1396 ARRAYITEMCOUNT(G_XCenterSetupSet),
1397 G_pcszXCenterReal, // class name
1398 somThis);
1399 }
1400 CATCH(excpt1)
1401 {
1402 brc = FALSE;
1403 } END_CATCH();
1404
1405 return brc;
1406}
1407
1408/*
1409 *@@ ctrpRestoreState:
1410 *
1411 *@@added V0.9.9 (2001-01-29) [umoeller]
1412 */
1413
1414BOOL ctrpRestoreState(XCenter *somSelf)
1415{
1416 BOOL brc = FALSE;
1417
1418 TRY_LOUD(excpt1)
1419 {
1420 XCenterData *somThis = XCenterGetData(somSelf);
1421
1422 /*
1423 * key 1: widget settings
1424 *
1425 */
1426
1427 BOOL fError = FALSE;
1428
1429 if (_pszPackedWidgetSettings)
1430 {
1431 free(_pszPackedWidgetSettings);
1432 _pszPackedWidgetSettings = 0;
1433 }
1434
1435 _cbPackedWidgetSettings = 0;
1436 // get size of array
1437 if (_wpRestoreData(somSelf,
1438 (PSZ)G_pcszXCenterReal,
1439 1,
1440 NULL, // query size
1441 &_cbPackedWidgetSettings))
1442 {
1443 _pszPackedWidgetSettings = (PSZ)malloc(_cbPackedWidgetSettings);
1444 if (_pszPackedWidgetSettings)
1445 {
1446 if (!_wpRestoreData(somSelf,
1447 (PSZ)G_pcszXCenterReal,
1448 1,
1449 _pszPackedWidgetSettings,
1450 &_cbPackedWidgetSettings))
1451 // error:
1452 fError = TRUE;
1453 }
1454 else
1455 fError = TRUE;
1456 }
1457 else
1458 // error:
1459 fError = TRUE;
1460
1461 if (fError)
1462 {
1463 if (_pszPackedWidgetSettings)
1464 free(_pszPackedWidgetSettings);
1465 _pszPackedWidgetSettings = NULL;
1466 _cbPackedWidgetSettings = 0;
1467 }
1468
1469 /*
1470 * other keys
1471 *
1472 */
1473
1474 cmnSetupRestore(somSelf,
1475 G_XCenterSetupSet,
1476 ARRAYITEMCOUNT(G_XCenterSetupSet),
1477 G_pcszXCenterReal, // class name
1478 somThis);
1479 }
1480 CATCH(excpt1)
1481 {
1482 brc = FALSE;
1483 } END_CATCH();
1484
1485 return brc;
1486}
1487
1488/*
1489 *@@ ctrpSaveToFile:
1490 * write the widget settings to a file, and sets its .TYPE
1491 * attribute to DRT_WIDGET.
1492 *
1493 * pszClass must not be NULL. pszSetup may be NULL.
1494 *
1495 * Returns TRUE if the operation was successful.
1496 *
1497 *@@added V0.9.14 (2001-07-30) [lafaix]
1498 */
1499
1500BOOL ctrpSaveToFile(PCSZ pszDest,
1501 PCSZ pszClass,
1502 PCSZ pszSetup)
1503{
1504 HFILE hf;
1505 ULONG ulAction;
1506 EAOP2 eaop2;
1507 PFEA2LIST pfea2l;
1508 #pragma pack(1)
1509 struct
1510 {
1511 CHAR ach[6];
1512 USHORT usMainType,
1513 usCodepage,
1514 usCount;
1515 USHORT usVal1Type,
1516 usVal1Len;
1517 CHAR achVal1[15];
1518 USHORT usVal2Type,
1519 usVal2Len;
1520 CHAR achVal2[10];
1521 } val;
1522 #pragma pack()
1523 BOOL brc = FALSE;
1524
1525 if (!DosOpen((PSZ)pszDest,
1526 &hf,
1527 &ulAction,
1528 0L,
1529 0,
1530 FILE_OPEN | OPEN_ACTION_CREATE_IF_NEW,
1531 OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
1532 0))
1533 {
1534 // Adding a "Widget settings" .TYPE EA
1535 if ((pfea2l = (PFEA2LIST)malloc(sizeof(FEA2LIST) + sizeof(val))))
1536 {
1537 pfea2l->cbList = sizeof(FEA2LIST) + sizeof(val);
1538 pfea2l->list[0].oNextEntryOffset = 0;
1539 pfea2l->list[0].fEA = 0;
1540 pfea2l->list[0].cbName = 5;
1541 pfea2l->list[0].cbValue = sizeof(val) - 6;
1542 strcpy(val.ach, ".TYPE");
1543 val.usMainType = EAT_MVMT;
1544 val.usCodepage = 0;
1545 val.usCount = 2;
1546 val.usVal1Type = EAT_ASCII;
1547 val.usVal1Len = 15; // strlen(DRT_WIDGET)
1548 memcpy(val.achVal1, DRT_WIDGET, 15);
1549 val.usVal2Type = EAT_ASCII;
1550 val.usVal2Len = 10; // strlen(DRT_TEXT)
1551 memcpy(val.achVal2, DRT_TEXT, 10);
1552 memcpy(pfea2l->list[0].szName, &val, sizeof(val));
1553 eaop2.fpFEA2List = pfea2l;
1554
1555 if (!DosSetFileInfo(hf,
1556 FIL_QUERYEASIZE,
1557 &eaop2,
1558 sizeof(eaop2)))
1559 {
1560 // create the file content:
1561 if ( // first, the widget class name, which cannot
1562 // be NULL
1563 (pszClass)
1564 && (!DosWrite(hf,
1565 (PVOID)pszClass,
1566 strlen(pszClass),
1567 &ulAction))
1568 // then, a CR/LF marker
1569 && (!DosWrite(hf,
1570 "\r\n",
1571 2,
1572 &ulAction))
1573 // and the setup string, which may be NULL
1574 && ( (pszSetup == NULL)
1575 || (!DosWrite(hf,
1576 (PVOID)pszSetup,
1577 strlen(pszSetup),
1578 &ulAction))
1579 )
1580 )
1581 brc = TRUE;
1582 }
1583
1584 free(pfea2l);
1585 } // end if ((pfea2l = (PFEA2LIST) malloc(...)))
1586
1587 DosClose(hf);
1588 }
1589
1590 return brc;
1591}
1592
1593/*
1594 *@@ ctrpReadFromFile:
1595 * returns a packed representation of the widget.
1596 *
1597 * Returns:
1598 *
1599 * -- NO_ERROR if the operation was successful. In this case,
1600 * *ppszClass and *ppszSetup receive a malloc'd buffer
1601 * each with the widget class name and setup string to
1602 * be freed by the caller.
1603 *
1604 * -- ERROR_NOT_ENOUGH_MEMORY
1605 *
1606 * -- ERROR_BAD_FORMAT: file format is invalid.
1607 *
1608 * plus the error codes of DosOpen and the like.
1609 *
1610 *@@added V0.9.14 (2001-07-30) [lafaix]
1611 *@@changed V0.9.19 (2002-05-22) [umoeller]: mostly rewritten, prototype changed; now returning APIRET and ready-made strings
1612 */
1613
1614APIRET ctrpReadFromFile(PCSZ pszSource, // in: source file name
1615 PSZ *ppszClass, // out: widget class name
1616 PSZ *ppszSetup) // out: widget setup string
1617{
1618 APIRET arc;
1619 HFILE hf;
1620 ULONG ulAction;
1621 FILESTATUS3 fs3;
1622 PSZ pszBuff = NULL;
1623
1624 if (!(arc = DosOpen((PSZ)pszSource,
1625 &hf,
1626 &ulAction,
1627 0L,
1628 0,
1629 FILE_OPEN,
1630 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
1631 0)))
1632 {
1633 // we will read the file in just one block,
1634 // so we must know its size
1635 if (!(arc = DosQueryFileInfo(hf,
1636 FIL_STANDARD,
1637 &fs3,
1638 sizeof(fs3))))
1639 {
1640 if (!(pszBuff = malloc(fs3.cbFile + 1)))
1641 {
1642 arc = ERROR_NOT_ENOUGH_MEMORY;
1643 _PmpfF(("malloc I failed (%d bytes)", fs3.cbFile + 1));
1644 }
1645 else
1646 {
1647 if (!(arc = DosRead(hf,
1648 pszBuff,
1649 fs3.cbFile,
1650 &ulAction)))
1651 {
1652 pszBuff[fs3.cbFile] = 0;
1653 }
1654 }
1655 }
1656
1657 DosClose(hf);
1658 }
1659
1660 if (!arc)
1661 {
1662 ULONG ulClassLen, ulSetupLen;
1663 PSZ pSeparator;
1664 if ( (!(pSeparator = strstr(pszBuff, "\r\n")))
1665 || (!(ulClassLen = pSeparator - pszBuff))
1666 || (!(ulSetupLen = strlen(pSeparator + 2)))
1667 )
1668 arc = ERROR_BAD_FORMAT;
1669 else
1670 {
1671 if (!(*ppszClass = malloc(ulClassLen + 1)))
1672 arc = ERROR_NOT_ENOUGH_MEMORY;
1673 else if (!(*ppszSetup = malloc(ulSetupLen + 1)))
1674 {
1675 free(*ppszClass);
1676 arc = ERROR_NOT_ENOUGH_MEMORY;
1677 }
1678 else
1679 {
1680 memcpy(*ppszClass, pszBuff, ulClassLen);
1681 (*ppszClass)[ulClassLen] = '\0';
1682 pSeparator += 2;
1683 memcpy(*ppszSetup, pSeparator, ulSetupLen);
1684 (*ppszSetup)[ulSetupLen] = '\0';
1685 }
1686 }
1687 }
1688
1689 if (pszBuff)
1690 free(pszBuff);
1691
1692 return arc;
1693}
1694
Note: See TracBrowser for help on using the repository browser.