Browse Source

--- Merging r15616 into '.':
U packages/fcl-web/src/base/custcgi.pp
U packages/fcl-web/src/base/fpweb.pp
U packages/fcl-web/src/base/fphttp.pp
U packages/fcl-web/src/base/custfcgi.pp
U packages/fcl-web/src/base/webpage.pp
U packages/fcl-web/src/base/websession.pp
U packages/fcl-web/src/base/httpdefs.pp
U packages/fcl-web/src/base/fphtml.pp
--- Merging r15617 into '.':
G packages/fcl-web/src/base/custcgi.pp
G packages/fcl-web/src/base/fpweb.pp
G packages/fcl-web/src/base/fphttp.pp
G packages/fcl-web/src/base/webpage.pp
G packages/fcl-web/src/base/websession.pp
G packages/fcl-web/src/base/httpdefs.pp
G packages/fcl-web/src/base/fphtml.pp
--- Merging r15621 into '.':
U packages/fcl-web/src/base/custcgi.pp
G packages/fcl-web/src/base/custfcgi.pp
U packages/fcl-web/src/base/fpapache.pp
U packages/fcl-web/src/base/fcgigate.pp
U packages/fcl-web/src/base/custweb.pp
--- Merging r15622 into '.':
G packages/fcl-web/src/base/fpapache.pp
U packages/fcl-web/src/base/fpcgi.pp
U packages/fcl-web/src/base/fpfcgi.pp
--- Merging r15665 into '.':
U packages/fcl-extra/src/daemonapp.pp
G packages/fcl-web/src/base/custweb.pp
U packages/fcl-base/src/custapp.pp
--- Merging r15667 into '.':
U packages/fcl-web/src/jsonrpc/Makefile.fpc
C packages/fcl-web/src/jsonrpc/Makefile
--- Merging r15668 into '.':
U packages/fcl-web/src/jsonrpc/fpjsonrpc.pp
--- Merging r15669 into '.':
U packages/fcl-web/src/jsonrpc/fpextdirect.pp
--- Merging r15670 into '.':
U packages/fcl-base/src/unix/eventlog.inc
U packages/fcl-base/src/eventlog.pp
U packages/fcl-base/src/dummy/eventlog.inc
U packages/fcl-base/src/win/eventlog.inc
U packages/fcl-base/src/os2/eventlog.inc
--- Merging r15686 into '.':
U packages/fcl-db/src/sqlite/customsqliteds.pas
U packages/fcl-db/src/sqlite/sqliteds.pas
U packages/fcl-db/src/sqlite/sqlite3ds.pas
--- Merging r15691 into '.':
U rtl/win/sysutils.pp
--- Merging r15696 into '.':
G packages/fcl-web/src/jsonrpc/fpextdirect.pp
--- Merging r15698 into '.':
G packages/fcl-web/src/base/custweb.pp
--- Merging r15714 into '.':
U packages/fcl-web/src/webdata/sqldbwebdata.pp
--- Merging r15719 into '.':
U packages/fcl-web/src/webdata/extjsjson.pp
--- Merging r15720 into '.':
U packages/fcl-web/src/base/websession.pp
--- Merging r15721 into '.':
G packages/fcl-web/src/base/websession.pp
--- Merging r15722 into '.':
G packages/fcl-web/src/base/custfcgi.pp
--- Merging r15763 into '.':
U compiler/utils/gppc386.pp
U compiler/utils
--- Merging r15793 into '.':
U packages/fpvectorial/Makefile.fpc
A packages/fpvectorial/src/cdrvectorialreader.pas
A packages/fpvectorial/src/svgvectorialwriter.pas
A packages/fpvectorial/examples
A packages/fpvectorial/examples/cdr2svg_mainform.lfm
A packages/fpvectorial/examples/cdr2svg_visual.lpi
A packages/fpvectorial/examples/cdr2svg_mainform.pas
A packages/fpvectorial/examples/cdr2svg_visual.ico
A packages/fpvectorial/examples/cdr2svg_visual.lpr
--- Merging r15799 into '.':
U packages/fpvectorial/src/fpvectorial.pas
U packages/fpvectorial/src/pdfvrsemantico.pas
U packages/fpvectorial/src/svgvectorialwriter.pas
U packages/fpvectorial/src/fpvtocanvas.pas
U packages/fpvectorial/examples/cdr2svg_mainform.lfm
U packages/fpvectorial/examples/cdr2svg_visual.lpi
U packages/fpvectorial/examples/cdr2svg_mainform.pas
U packages/fpvectorial/examples/cdr2svg_visual.lpr
--- Merging r15800 into '.':
G packages/fcl-web/src/jsonrpc/fpjsonrpc.pp
--- Merging r15801 into '.':
G packages/fpvectorial/src/fpvectorial.pas
G packages/fpvectorial/src/svgvectorialwriter.pas
G packages/fpvectorial/src/fpvtocanvas.pas
--- Merging r15802 into '.':
G packages/fpvectorial/examples/cdr2svg_mainform.pas
--- Merging r15804 into '.':
U rtl/objpas/dateutil.inc
--- Merging r15808 into '.':
U packages/x11/src/xlib.pp
--- Merging r15815 into '.':
U packages/fcl-web/examples/webdata/demo/extgrid.lpr
--- Merging r15816 into '.':
U packages/fcl-web/examples/webdata/demo/wmusers.pp
--- Merging r15817 into '.':
G packages/fcl-web/examples/webdata/demo/wmusers.pp
--- Merging r15826 into '.':
G packages/fpvectorial/src/fpvectorial.pas
A packages/fpvectorial/examples/fpvectorialconverter.ico
A packages/fpvectorial/examples/fpvectorialconverter.lpr
A packages/fpvectorial/examples/fpvc_mainform.lfm
A packages/fpvectorial/examples/fpvc_mainform.pas
A packages/fpvectorial/examples/fpvectorialconverter.lpi
D packages/fpvectorial/examples/cdr2svg_visual.ico
D packages/fpvectorial/examples/cdr2svg_visual.lpr
D packages/fpvectorial/examples/cdr2svg_mainform.lfm
D packages/fpvectorial/examples/cdr2svg_visual.lpi
D packages/fpvectorial/examples/cdr2svg_mainform.pas
--- Merging r15827 into '.':
U packages/fcl-image/src/freetype.pp
U packages/fcl-image/src/freetypeh.pp
--- Merging r15829 into '.':
G packages/fpvectorial/src/fpvectorial.pas
U packages/fpvectorial/src/cdrvectorialreader.pas
A packages/fpvectorial/examples/fpce_mainform.lfm
U packages/fpvectorial/examples/fpvc_mainform.lfm
A packages/fpvectorial/examples/fpcorelexplorer.ico
A packages/fpvectorial/examples/fpce_mainform.pas
A packages/fpvectorial/examples/fpcorelexplorer.lpr
A packages/fpvectorial/examples/fpcorelexplorer.lpi
Summary of conflicts:
Text conflicts: 1

# revisions: 15616,15617,15621,15622,15665,15667,15668,15669,15670,15686,15691,15696,15698,15714,15719,15720,15721,15722,15763,15793,15799,15800,15801,15802,15804,15808,15815,15816,15817,15826,15827,15829
------------------------------------------------------------------------
r15616 | joost | 2010-07-20 11:52:22 +0200 (Tue, 20 Jul 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/custcgi.pp
M /trunk/packages/fcl-web/src/base/custfcgi.pp
M /trunk/packages/fcl-web/src/base/fphtml.pp
M /trunk/packages/fcl-web/src/base/fphttp.pp
M /trunk/packages/fcl-web/src/base/fpweb.pp
M /trunk/packages/fcl-web/src/base/httpdefs.pp
M /trunk/packages/fcl-web/src/base/webpage.pp
M /trunk/packages/fcl-web/src/base/websession.pp

* Fixed FastCGI listening on a port on Windows after r15099
------------------------------------------------------------------------
------------------------------------------------------------------------
r15617 | joost | 2010-07-20 11:55:42 +0200 (Tue, 20 Jul 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/custcgi.pp
M /trunk/packages/fcl-web/src/base/fphtml.pp
M /trunk/packages/fcl-web/src/base/fphttp.pp
M /trunk/packages/fcl-web/src/base/fpweb.pp
M /trunk/packages/fcl-web/src/base/httpdefs.pp
M /trunk/packages/fcl-web/src/base/webpage.pp
M /trunk/packages/fcl-web/src/base/websession.pp

* Reverted accidentally committed files in r15616
------------------------------------------------------------------------
------------------------------------------------------------------------
r15621 | joost | 2010-07-21 12:24:01 +0200 (Wed, 21 Jul 2010) | 3 lines
Changed paths:
M /trunk/packages/fcl-web/src/base/custcgi.pp
M /trunk/packages/fcl-web/src/base/custfcgi.pp
M /trunk/packages/fcl-web/src/base/custweb.pp
M /trunk/packages/fcl-web/src/base/fcgigate.pp
M /trunk/packages/fcl-web/src/base/fpapache.pp

* Moved the handling of web-request from the TCustomWebApplication to a new class
TWebHandler. TCustomWebApplication and derivates are now a wrapper around the TWebHandler
* Added TWebHandler.OnIdle event
------------------------------------------------------------------------
------------------------------------------------------------------------
r15622 | joost | 2010-07-21 13:02:45 +0200 (Wed, 21 Jul 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/fpapache.pp
M /trunk/packages/fcl-web/src/base/fpcgi.pp
M /trunk/packages/fcl-web/src/base/fpfcgi.pp

* Set the global CustomApplication variable, usefull for logging
------------------------------------------------------------------------
------------------------------------------------------------------------
r15665 | michael | 2010-07-30 11:26:21 +0200 (Fri, 30 Jul 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-base/src/custapp.pp
M /trunk/packages/fcl-extra/src/daemonapp.pp
M /trunk/packages/fcl-web/src/base/custweb.pp

* Patch from Luiz Americo to use const string params in Log call
------------------------------------------------------------------------
------------------------------------------------------------------------
r15667 | michael | 2010-07-30 12:09:26 +0200 (Fri, 30 Jul 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/jsonrpc/Makefile
M /trunk/packages/fcl-web/src/jsonrpc/Makefile.fpc

* Dependency op fcl-process voor dbugintf
------------------------------------------------------------------------
------------------------------------------------------------------------
r15668 | michael | 2010-07-30 12:12:33 +0200 (Fri, 30 Jul 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/jsonrpc/fpjsonrpc.pp

* error handling is slightly different in ext.direct. Create virtual method so it can be overridden
------------------------------------------------------------------------
------------------------------------------------------------------------
r15669 | michael | 2010-07-30 12:13:12 +0200 (Fri, 30 Jul 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/jsonrpc/fpextdirect.pp

Ext.Direct compliant error handling. API now also handles more than one handler. Session handling added
------------------------------------------------------------------------
------------------------------------------------------------------------
r15670 | michael | 2010-07-30 15:36:31 +0200 (Fri, 30 Jul 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-base/src/dummy/eventlog.inc
M /trunk/packages/fcl-base/src/eventlog.pp
M /trunk/packages/fcl-base/src/os2/eventlog.inc
M /trunk/packages/fcl-base/src/unix/eventlog.inc
M /trunk/packages/fcl-base/src/win/eventlog.inc

* Patch from Luiz Americo to put Const in front of string parameters
------------------------------------------------------------------------
------------------------------------------------------------------------
r15686 | blikblum | 2010-08-01 16:13:51 +0200 (Sun, 01 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-db/src/sqlite/customsqliteds.pas
M /trunk/packages/fcl-db/src/sqlite/sqlite3ds.pas
M /trunk/packages/fcl-db/src/sqlite/sqliteds.pas

* Do not change SQL property value internally. Use instead a separated field (FEffectiveSQL)
------------------------------------------------------------------------
------------------------------------------------------------------------
r15691 | marco | 2010-08-02 22:32:50 +0200 (Mon, 02 Aug 2010) | 1 line
Changed paths:
M /trunk/rtl/win/sysutils.pp

* getlocalformatsettings, Mantis 10389
------------------------------------------------------------------------
------------------------------------------------------------------------
r15696 | michael | 2010-08-03 09:57:20 +0200 (Tue, 03 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/jsonrpc/fpextdirect.pp

* Bugfix for case of more than one handler classname
------------------------------------------------------------------------
------------------------------------------------------------------------
r15698 | michael | 2010-08-03 10:39:55 +0200 (Tue, 03 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/custweb.pp

* Fixed never-ending CGI scripts
------------------------------------------------------------------------
------------------------------------------------------------------------
r15714 | michael | 2010-08-05 23:47:47 +0200 (Thu, 05 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/webdata/sqldbwebdata.pp

* Support for design-time parameters
------------------------------------------------------------------------
------------------------------------------------------------------------
r15719 | michael | 2010-08-06 11:04:40 +0200 (Fri, 06 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/webdata/extjsjson.pp

* Null values should be sent as NULL in json
------------------------------------------------------------------------
------------------------------------------------------------------------
r15720 | michael | 2010-08-06 11:06:44 +0200 (Fri, 06 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/websession.pp

* Correct check for Session in checksession, and do not create same session cookie twice
------------------------------------------------------------------------
------------------------------------------------------------------------
r15721 | michael | 2010-08-06 11:07:12 +0200 (Fri, 06 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/websession.pp

* Switch off debug define
------------------------------------------------------------------------
------------------------------------------------------------------------
r15722 | michael | 2010-08-06 11:07:44 +0200 (Fri, 06 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/custfcgi.pp

* Parse cookies after initializing request variables
------------------------------------------------------------------------
------------------------------------------------------------------------
r15763 | pierre | 2010-08-10 13:37:06 +0200 (Tue, 10 Aug 2010) | 1 line
Changed paths:
M /trunk/compiler/utils
M /trunk/compiler/utils/gppc386.pp

+ Always try to find Compiler in same directory first
------------------------------------------------------------------------
------------------------------------------------------------------------
r15793 | sekelsenmat | 2010-08-13 10:24:27 +0200 (Fri, 13 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fpvectorial/Makefile.fpc
A /trunk/packages/fpvectorial/examples
A /trunk/packages/fpvectorial/examples/cdr2svg_mainform.lfm
A /trunk/packages/fpvectorial/examples/cdr2svg_mainform.pas
A /trunk/packages/fpvectorial/examples/cdr2svg_visual.ico
A /trunk/packages/fpvectorial/examples/cdr2svg_visual.lpi
A /trunk/packages/fpvectorial/examples/cdr2svg_visual.lpr
A /trunk/packages/fpvectorial/src/cdrvectorialreader.pas
A /trunk/packages/fpvectorial/src/svgvectorialwriter.pas

Starts code to add support to cdr and svg to fpvectorial
------------------------------------------------------------------------
------------------------------------------------------------------------
r15799 | sekelsenmat | 2010-08-13 16:56:40 +0200 (Fri, 13 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fpvectorial/examples/cdr2svg_mainform.lfm
M /trunk/packages/fpvectorial/examples/cdr2svg_mainform.pas
M /trunk/packages/fpvectorial/examples/cdr2svg_visual.lpi
M /trunk/packages/fpvectorial/examples/cdr2svg_visual.lpr
M /trunk/packages/fpvectorial/src/fpvectorial.pas
M /trunk/packages/fpvectorial/src/fpvtocanvas.pas
M /trunk/packages/fpvectorial/src/pdfvrsemantico.pas
M /trunk/packages/fpvectorial/src/svgvectorialwriter.pas

Starts implementing svg writer and improves test app and pdf reader
------------------------------------------------------------------------
------------------------------------------------------------------------
r15800 | michael | 2010-08-13 17:19:46 +0200 (Fri, 13 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/jsonrpc/fpjsonrpc.pp

* Error object must be of type TJSOnErrorObject. Initialize Result to Nil in function TJSONRPCHandler.DoExecute (fixes access violation)
------------------------------------------------------------------------
------------------------------------------------------------------------
r15801 | sekelsenmat | 2010-08-13 17:32:03 +0200 (Fri, 13 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fpvectorial/src/fpvectorial.pas
M /trunk/packages/fpvectorial/src/fpvtocanvas.pas
M /trunk/packages/fpvectorial/src/svgvectorialwriter.pas

Now the SVG writer works for lines
------------------------------------------------------------------------
------------------------------------------------------------------------
r15802 | sekelsenmat | 2010-08-13 17:34:07 +0200 (Fri, 13 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fpvectorial/examples/cdr2svg_mainform.pas

small fix for the fpvectorial example
------------------------------------------------------------------------
------------------------------------------------------------------------
r15804 | marco | 2010-08-14 01:36:07 +0200 (Sat, 14 Aug 2010) | 2 lines
Changed paths:
M /trunk/rtl/objpas/dateutil.inc

* fix for 17123, rounding issues decodedatetime

------------------------------------------------------------------------
------------------------------------------------------------------------
r15808 | marco | 2010-08-14 10:56:16 +0200 (Sat, 14 Aug 2010) | 2 lines
Changed paths:
M /trunk/packages/x11/src/xlib.pp

* changed chararr32 to pchararr32, see bug #15845

------------------------------------------------------------------------
------------------------------------------------------------------------
r15815 | michael | 2010-08-15 16:22:52 +0200 (Sun, 15 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/examples/webdata/demo/extgrid.lpr

* Removed resource linking
------------------------------------------------------------------------
------------------------------------------------------------------------
r15816 | michael | 2010-08-15 16:23:59 +0200 (Sun, 15 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/examples/webdata/demo/wmusers.pp

* Saving of response is now configurable
------------------------------------------------------------------------
------------------------------------------------------------------------
r15817 | michael | 2010-08-15 16:56:37 +0200 (Sun, 15 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-web/examples/webdata/demo/wmusers.pp

* Fixed and simplified example
------------------------------------------------------------------------
------------------------------------------------------------------------
r15826 | sekelsenmat | 2010-08-16 10:18:21 +0200 (Mon, 16 Aug 2010) | 1 line
Changed paths:
D /trunk/packages/fpvectorial/examples/cdr2svg_mainform.lfm
D /trunk/packages/fpvectorial/examples/cdr2svg_mainform.pas
D /trunk/packages/fpvectorial/examples/cdr2svg_visual.ico
D /trunk/packages/fpvectorial/examples/cdr2svg_visual.lpi
D /trunk/packages/fpvectorial/examples/cdr2svg_visual.lpr
A /trunk/packages/fpvectorial/examples/fpvc_mainform.lfm
A /trunk/packages/fpvectorial/examples/fpvc_mainform.pas
A /trunk/packages/fpvectorial/examples/fpvectorialconverter.ico
A /trunk/packages/fpvectorial/examples/fpvectorialconverter.lpi
A /trunk/packages/fpvectorial/examples/fpvectorialconverter.lpr
M /trunk/packages/fpvectorial/src/fpvectorial.pas

Renames the main fpvectorial example and adds a routine to detect the format from the extension.
------------------------------------------------------------------------
------------------------------------------------------------------------
r15827 | sekelsenmat | 2010-08-16 11:25:46 +0200 (Mon, 16 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-image/src/freetype.pp
M /trunk/packages/fcl-image/src/freetypeh.pp

Patch from Dirk Fellenberg to fix freetype font output, see bug #17156. Also other improvements made by me to improve how freetype linking and font searching under Mac OS X
------------------------------------------------------------------------
------------------------------------------------------------------------
r15829 | sekelsenmat | 2010-08-16 17:00:54 +0200 (Mon, 16 Aug 2010) | 1 line
Changed paths:
A /trunk/packages/fpvectorial/examples/fpce_mainform.lfm
A /trunk/packages/fpvectorial/examples/fpce_mainform.pas
A /trunk/packages/fpvectorial/examples/fpcorelexplorer.ico
A /trunk/packages/fpvectorial/examples/fpcorelexplorer.lpi
A /trunk/packages/fpvectorial/examples/fpcorelexplorer.lpr
M /trunk/packages/fpvectorial/examples/fpvc_mainform.lfm
M /trunk/packages/fpvectorial/src/cdrvectorialreader.pas
M /trunk/packages/fpvectorial/src/fpvectorial.pas

Adds a Corel Draw file format explorer and starts implementing the CDR reader in fpvectorial
------------------------------------------------------------------------

git-svn-id: branches/fixes_2_4@16401 -

marco 14 years ago
parent
commit
b4e9a218da
54 changed files with 2320 additions and 511 deletions
  1. 17 0
      .gitattributes
  2. 4 2
      compiler/utils/gppc386.pp
  3. 2 2
      packages/fcl-base/src/custapp.pp
  4. 1 1
      packages/fcl-base/src/dummy/eventlog.inc
  5. 27 27
      packages/fcl-base/src/eventlog.pp
  6. 1 1
      packages/fcl-base/src/os2/eventlog.inc
  7. 1 1
      packages/fcl-base/src/unix/eventlog.inc
  8. 1 1
      packages/fcl-base/src/win/eventlog.inc
  9. 10 8
      packages/fcl-db/src/sqlite/customsqliteds.pas
  10. 2 2
      packages/fcl-db/src/sqlite/sqlite3ds.pas
  11. 2 2
      packages/fcl-db/src/sqlite/sqliteds.pas
  12. 4 4
      packages/fcl-extra/src/daemonapp.pp
  13. 11 1
      packages/fcl-image/src/freetype.pp
  14. 27 6
      packages/fcl-image/src/freetypeh.pp
  15. 0 2
      packages/fcl-web/examples/webdata/demo/extgrid.lpr
  16. 44 80
      packages/fcl-web/examples/webdata/demo/wmusers.pp
  17. 121 92
      packages/fcl-web/src/base/custcgi.pp
  18. 79 12
      packages/fcl-web/src/base/custfcgi.pp
  19. 241 54
      packages/fcl-web/src/base/custweb.pp
  20. 60 44
      packages/fcl-web/src/base/fcgigate.pp
  21. 183 36
      packages/fcl-web/src/base/fpapache.pp
  22. 4 1
      packages/fcl-web/src/base/fpcgi.pp
  23. 6 0
      packages/fcl-web/src/base/fpfcgi.pp
  24. 8 4
      packages/fcl-web/src/base/websession.pp
  25. 89 38
      packages/fcl-web/src/jsonrpc/Makefile
  26. 1 1
      packages/fcl-web/src/jsonrpc/Makefile.fpc
  27. 28 2
      packages/fcl-web/src/jsonrpc/fpextdirect.pp
  28. 48 25
      packages/fcl-web/src/jsonrpc/fpjsonrpc.pp
  29. 3 0
      packages/fcl-web/src/webdata/extjsjson.pp
  30. 26 0
      packages/fcl-web/src/webdata/sqldbwebdata.pp
  31. 1 1
      packages/fpvectorial/Makefile.fpc
  32. 80 0
      packages/fpvectorial/examples/cdr2svg_mainform.lfm
  33. 66 0
      packages/fpvectorial/examples/cdr2svg_mainform.pas
  34. BIN
      packages/fpvectorial/examples/cdr2svg_visual.ico
  35. 85 0
      packages/fpvectorial/examples/cdr2svg_visual.lpi
  36. 20 0
      packages/fpvectorial/examples/cdr2svg_visual.lpr
  37. 54 0
      packages/fpvectorial/examples/fpce_mainform.lfm
  38. 85 0
      packages/fpvectorial/examples/fpce_mainform.pas
  39. BIN
      packages/fpvectorial/examples/fpcorelexplorer.ico
  40. 91 0
      packages/fpvectorial/examples/fpcorelexplorer.lpi
  41. 20 0
      packages/fpvectorial/examples/fpcorelexplorer.lpr
  42. 96 0
      packages/fpvectorial/examples/fpvc_mainform.lfm
  43. 97 0
      packages/fpvectorial/examples/fpvc_mainform.pas
  44. BIN
      packages/fpvectorial/examples/fpvectorialconverter.ico
  45. 91 0
      packages/fpvectorial/examples/fpvectorialconverter.lpi
  46. 20 0
      packages/fpvectorial/examples/fpvectorialconverter.lpr
  47. 180 0
      packages/fpvectorial/src/cdrvectorialreader.pas
  48. 44 1
      packages/fpvectorial/src/fpvectorial.pas
  49. 20 6
      packages/fpvectorial/src/fpvtocanvas.pas
  50. 38 15
      packages/fpvectorial/src/pdfvrsemantico.pas
  51. 127 0
      packages/fpvectorial/src/svgvectorialwriter.pas
  52. 4 3
      packages/x11/src/xlib.pp
  53. 7 1
      rtl/objpas/dateutil.inc
  54. 43 35
      rtl/win/sysutils.pp

+ 17 - 0
.gitattributes

@@ -1854,10 +1854,26 @@ packages/fpmkunit/fpmake.pp svneol=native#text/plain
 packages/fpmkunit/src/fpmkunit.pp svneol=native#text/plain
 packages/fpmkunit/src/fpmkunit.pp svneol=native#text/plain
 packages/fpvectorial/Makefile svneol=native#text/plain
 packages/fpvectorial/Makefile svneol=native#text/plain
 packages/fpvectorial/Makefile.fpc svneol=native#text/plain
 packages/fpvectorial/Makefile.fpc svneol=native#text/plain
+packages/fpvectorial/examples/cdr2svg_mainform.lfm svneol=native#text/plain
+packages/fpvectorial/examples/cdr2svg_mainform.pas svneol=native#text/plain
+packages/fpvectorial/examples/cdr2svg_visual.ico -text
+packages/fpvectorial/examples/cdr2svg_visual.lpi svneol=native#text/plain
+packages/fpvectorial/examples/cdr2svg_visual.lpr svneol=native#text/plain
+packages/fpvectorial/examples/fpce_mainform.lfm svneol=native#text/plain
+packages/fpvectorial/examples/fpce_mainform.pas svneol=native#text/plain
+packages/fpvectorial/examples/fpcorelexplorer.ico -text
+packages/fpvectorial/examples/fpcorelexplorer.lpi svneol=native#text/plain
+packages/fpvectorial/examples/fpcorelexplorer.lpr svneol=native#text/plain
+packages/fpvectorial/examples/fpvc_mainform.lfm svneol=native#text/plain
+packages/fpvectorial/examples/fpvc_mainform.pas svneol=native#text/plain
+packages/fpvectorial/examples/fpvectorialconverter.ico -text
+packages/fpvectorial/examples/fpvectorialconverter.lpi svneol=native#text/plain
+packages/fpvectorial/examples/fpvectorialconverter.lpr svneol=native#text/plain
 packages/fpvectorial/fpmake.pp svneol=native#text/plain
 packages/fpvectorial/fpmake.pp svneol=native#text/plain
 packages/fpvectorial/src/avisocncgcodereader.pas svneol=native#text/plain
 packages/fpvectorial/src/avisocncgcodereader.pas svneol=native#text/plain
 packages/fpvectorial/src/avisocncgcodewriter.pas svneol=native#text/plain
 packages/fpvectorial/src/avisocncgcodewriter.pas svneol=native#text/plain
 packages/fpvectorial/src/avisozlib.pas svneol=native#text/plain
 packages/fpvectorial/src/avisozlib.pas svneol=native#text/plain
+packages/fpvectorial/src/cdrvectorialreader.pas svneol=native#text/plain
 packages/fpvectorial/src/fpvectbuildunit.pas svneol=native#text/plain
 packages/fpvectorial/src/fpvectbuildunit.pas svneol=native#text/plain
 packages/fpvectorial/src/fpvectorial.pas svneol=native#text/plain
 packages/fpvectorial/src/fpvectorial.pas svneol=native#text/plain
 packages/fpvectorial/src/fpvtocanvas.pas svneol=native#text/plain
 packages/fpvectorial/src/fpvtocanvas.pas svneol=native#text/plain
@@ -1865,6 +1881,7 @@ packages/fpvectorial/src/pdfvectorialreader.pas svneol=native#text/plain
 packages/fpvectorial/src/pdfvrlexico.pas svneol=native#text/plain
 packages/fpvectorial/src/pdfvrlexico.pas svneol=native#text/plain
 packages/fpvectorial/src/pdfvrsemantico.pas svneol=native#text/plain
 packages/fpvectorial/src/pdfvrsemantico.pas svneol=native#text/plain
 packages/fpvectorial/src/pdfvrsintatico.pas svneol=native#text/plain
 packages/fpvectorial/src/pdfvrsintatico.pas svneol=native#text/plain
+packages/fpvectorial/src/svgvectorialwriter.pas svneol=native#text/plain
 packages/fuse/Makefile svneol=native#text/plain
 packages/fuse/Makefile svneol=native#text/plain
 packages/fuse/Makefile.fpc svneol=native#text/plain
 packages/fuse/Makefile.fpc svneol=native#text/plain
 packages/fuse/fpmake_disabled.pp svneol=native#text/plain
 packages/fuse/fpmake_disabled.pp svneol=native#text/plain

+ 4 - 2
compiler/utils/gppc386.pp

@@ -44,10 +44,12 @@ const
   GDBExeName = 'gdbpas';
   GDBExeName = 'gdbpas';
   GDBIniName = '.gdbinit';
   GDBIniName = '.gdbinit';
   DefaultCompilerName = 'ppc386';
   DefaultCompilerName = 'ppc386';
+  PathSep=':';
 {$else}
 {$else}
   GDBExeName = 'gdbpas.exe';
   GDBExeName = 'gdbpas.exe';
   GDBIniName = 'gdb.ini';
   GDBIniName = 'gdb.ini';
   DefaultCompilerName = 'ppc386.exe';
   DefaultCompilerName = 'ppc386.exe';
+  PathSep=';';
 {$endif not linux}
 {$endif not linux}
 
 
   { If you add a gdb.fpc file in a given directory }
   { If you add a gdb.fpc file in a given directory }
@@ -72,7 +74,7 @@ begin
   { support for info functions directly : used in makefiles }
   { support for info functions directly : used in makefiles }
   if (paramcount=1) and (pos('-i',Paramstr(1))=1) then
   if (paramcount=1) and (pos('-i',Paramstr(1))=1) then
     begin
     begin
-      Exec(fsearch(CompilerName,GetEnv('PATH')),Paramstr(1));
+      Exec(fsearch(CompilerName,Dir+PathSep+GetEnv('PATH')),Paramstr(1));
       exit;
       exit;
     end;
     end;
 
 
@@ -114,7 +116,7 @@ begin
   Writeln(fpcgdbini,'end');
   Writeln(fpcgdbini,'end');
   Close(fpcgdbini);
   Close(fpcgdbini);
 
 
-  Exec(fsearch(GDBExeName,GetEnv('PATH')),
+  Exec(fsearch(GDBExeName,Dir+PathSep+GetEnv('PATH')),
 {$ifdef win32}
 {$ifdef win32}
     '--nw '+
     '--nw '+
 {$endif win32}
 {$endif win32}

+ 2 - 2
packages/fcl-base/src/custapp.pp

@@ -63,7 +63,7 @@ Type
     Function CheckOptions(Const ShortOptions : String; Const LongOpts : String) : String;
     Function CheckOptions(Const ShortOptions : String; Const LongOpts : String) : String;
     Procedure GetEnvironmentList(List : TStrings;NamesOnly : Boolean);
     Procedure GetEnvironmentList(List : TStrings;NamesOnly : Boolean);
     Procedure GetEnvironmentList(List : TStrings);
     Procedure GetEnvironmentList(List : TStrings);
-    Procedure Log(EventType : TEventType; Msg : String); virtual;
+    Procedure Log(EventType : TEventType; const Msg : String); virtual;
     // Delphi properties
     // Delphi properties
     property ExeName: string read GetExeName;
     property ExeName: string read GetExeName;
     property HelpFile: string read FHelpFile write FHelpFile;
     property HelpFile: string read FHelpFile write FHelpFile;
@@ -223,7 +223,7 @@ begin
   // Do nothing. Override in descendent classes.
   // Do nothing. Override in descendent classes.
 end;
 end;
 
 
-Procedure TCustomApplication.Log(EventType : TEventType; Msg : String);
+Procedure TCustomApplication.Log(EventType : TEventType; const Msg : String);
 
 
 begin
 begin
   // Do nothing. Override in descendent classes.
   // Do nothing. Override in descendent classes.

+ 1 - 1
packages/fcl-base/src/dummy/eventlog.inc

@@ -32,7 +32,7 @@ begin
   DeActivateFileLog;
   DeActivateFileLog;
 end;
 end;
 
 
-procedure TEventLog.WriteSystemLog(EventType : TEventType; Msg : String);
+procedure TEventLog.WriteSystemLog(EventType : TEventType; const Msg : String);
 
 
 begin
 begin
   WriteFileLog(EventType,Msg);
   WriteFileLog(EventType,Msg);

+ 27 - 27
packages/fcl-base/src/eventlog.pp

@@ -52,8 +52,8 @@ Type
     procedure SetFileName(const Value: String);
     procedure SetFileName(const Value: String);
     procedure ActivateSystemLog;
     procedure ActivateSystemLog;
     function DefaultFileName: String;
     function DefaultFileName: String;
-    procedure WriteFileLog(EventType : TEventType; Msg: String);
-    procedure WriteSystemLog(EventType: TEventType; Msg: String);
+    procedure WriteFileLog(EventType : TEventType; const Msg: String);
+    procedure WriteSystemLog(EventType: TEventType; const Msg: String);
     procedure DeActivateFileLog;
     procedure DeActivateFileLog;
     procedure DeActivateSystemLog;
     procedure DeActivateSystemLog;
     procedure CheckIdentification;
     procedure CheckIdentification;
@@ -71,18 +71,18 @@ Type
     Function EventTypeToString(E : TEventType) : String;
     Function EventTypeToString(E : TEventType) : String;
     Function RegisterMessageFile(AFileName : String) : Boolean; virtual;
     Function RegisterMessageFile(AFileName : String) : Boolean; virtual;
     Function UnRegisterMessageFile : Boolean; virtual;
     Function UnRegisterMessageFile : Boolean; virtual;
-    Procedure Log (EventType : TEventType; Msg : String); {$ifndef fpc }Overload;{$endif}
-    Procedure Log (EventType : TEventType; Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
-    Procedure Log (Msg : String); {$ifndef fpc }Overload;{$endif}
-    Procedure Log (Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
-    Procedure Warning (Msg : String); {$ifndef fpc }Overload;{$endif}
-    Procedure Warning (Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
-    Procedure Error (Msg : String); {$ifndef fpc }Overload;{$endif}
-    Procedure Error (Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
-    Procedure Debug (Msg : String); {$ifndef fpc }Overload;{$endif}
-    Procedure Debug (Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
-    Procedure Info (Msg : String); {$ifndef fpc }Overload;{$endif}
-    Procedure Info (Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
+    Procedure Log (EventType : TEventType; const Msg : String); {$ifndef fpc }Overload;{$endif}
+    Procedure Log (EventType : TEventType; const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
+    Procedure Log (const Msg : String); {$ifndef fpc }Overload;{$endif}
+    Procedure Log (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
+    Procedure Warning (const Msg : String); {$ifndef fpc }Overload;{$endif}
+    Procedure Warning (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
+    Procedure Error (const Msg : String); {$ifndef fpc }Overload;{$endif}
+    Procedure Error (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
+    Procedure Debug (const Msg : String); {$ifndef fpc }Overload;{$endif}
+    Procedure Debug (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
+    Procedure Info (const Msg : String); {$ifndef fpc }Overload;{$endif}
+    Procedure Info (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
   Published
   Published
     Property Identification : String Read FIdentification Write SetIdentification;
     Property Identification : String Read FIdentification Write SetIdentification;
     Property LogType : TLogType Read Flogtype Write SetlogType;
     Property LogType : TLogType Read Flogtype Write SetlogType;
@@ -126,12 +126,12 @@ begin
     Raise ELogError.Create(SErrOperationNotAllowed);
     Raise ELogError.Create(SErrOperationNotAllowed);
 end;
 end;
 
 
-procedure TEventLog.Debug(Fmt: String; Args: array of const);
+procedure TEventLog.Debug(const Fmt: String; Args: array of const);
 begin
 begin
    Debug(Format(Fmt,Args));
    Debug(Format(Fmt,Args));
 end;
 end;
 
 
-procedure TEventLog.Debug(Msg: String);
+procedure TEventLog.Debug(const Msg: String);
 begin
 begin
   Log(etDebug,Msg);
   Log(etDebug,Msg);
 end;
 end;
@@ -142,38 +142,38 @@ begin
     Active:=True;
     Active:=True;
 end;
 end;
 
 
-procedure TEventLog.Error(Fmt: String; Args: array of const);
+procedure TEventLog.Error(const Fmt: String; Args: array of const);
 begin
 begin
   Error(Format(Fmt,Args));
   Error(Format(Fmt,Args));
 end;
 end;
 
 
-procedure TEventLog.Error(Msg: String);
+procedure TEventLog.Error(const Msg: String);
 begin
 begin
   Log(etError,Msg);
   Log(etError,Msg);
 end;
 end;
 
 
-procedure TEventLog.Info(Fmt: String; Args: array of const);
+procedure TEventLog.Info(const Fmt: String; Args: array of const);
 begin
 begin
   Info(Format(Fmt,Args));
   Info(Format(Fmt,Args));
 end;
 end;
 
 
-procedure TEventLog.Info(Msg: String);
+procedure TEventLog.Info(const Msg: String);
 begin
 begin
   Log(etInfo,Msg);
   Log(etInfo,Msg);
 end;
 end;
 
 
-procedure TEventLog.Log(Msg: String);
+procedure TEventLog.Log(const Msg: String);
 begin
 begin
   Log(DefaultEventType,msg);
   Log(DefaultEventType,msg);
 end;
 end;
 
 
-procedure TEventLog.Log(EventType: TEventType; Fmt: String;
+procedure TEventLog.Log(EventType: TEventType; const Fmt: String;
   Args: array of const);
   Args: array of const);
 begin
 begin
   Log(EventType,Format(Fmt,Args));
   Log(EventType,Format(Fmt,Args));
 end;
 end;
 
 
-procedure TEventLog.Log(EventType: TEventType; Msg: String);
+procedure TEventLog.Log(EventType: TEventType; const Msg: String);
 begin
 begin
   EnsureActive;
   EnsureActive;
   Case FlogType of
   Case FlogType of
@@ -182,7 +182,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TEventLog.WriteFileLog(EventType : TEventType; Msg : String);
+procedure TEventLog.WriteFileLog(EventType : TEventType; const Msg : String);
 
 
 Var
 Var
   S,TS,T : String;
   S,TS,T : String;
@@ -204,7 +204,7 @@ begin
     Raise ELogError.CreateFmt(SErrLogFailedMsg,[S]);
     Raise ELogError.CreateFmt(SErrLogFailedMsg,[S]);
 end;
 end;
 
 
-procedure TEventLog.Log(Fmt: String; Args: array of const);
+procedure TEventLog.Log(const Fmt: String; Args: array of const);
 begin
 begin
   Log(Format(Fmt,Args));
   Log(Format(Fmt,Args));
 end;
 end;
@@ -267,12 +267,12 @@ begin
   Flogtype := Value;
   Flogtype := Value;
 end;
 end;
 
 
-procedure TEventLog.Warning(Fmt: String; Args: array of const);
+procedure TEventLog.Warning(const Fmt: String; Args: array of const);
 begin
 begin
   Warning(Format(Fmt,Args));
   Warning(Format(Fmt,Args));
 end;
 end;
 
 
-procedure TEventLog.Warning(Msg: String);
+procedure TEventLog.Warning(const Msg: String);
 begin
 begin
   Log(etWarning,Msg);
   Log(etWarning,Msg);
 end;
 end;

+ 1 - 1
packages/fcl-base/src/os2/eventlog.inc

@@ -164,7 +164,7 @@ begin
 end;
 end;
 
 
 
 
-procedure TEventLog.WriteSystemLog (EventType: TEventType; Msg: string);
+procedure TEventLog.WriteSystemLog (EventType: TEventType; const Msg: string);
 
 
 const
 const
   WinET: array [TEventType] of Str3 = ('USR', 'INF', 'WRN', 'ERR', 'DBG');
   WinET: array [TEventType] of Str3 = ('USR', 'INF', 'WRN', 'ERR', 'DBG');

+ 1 - 1
packages/fcl-base/src/unix/eventlog.inc

@@ -76,7 +76,7 @@ begin
   CloseLog;
   CloseLog;
 end;
 end;
 
 
-procedure TEventLog.WriteSystemLog(EventType : TEventType; Msg : String);
+procedure TEventLog.WriteSystemLog(EventType : TEventType; const Msg : String);
 
 
 Var
 Var
   P,PT : PChar;
   P,PT : PChar;

+ 1 - 1
packages/fcl-base/src/win/eventlog.inc

@@ -49,7 +49,7 @@ function ReportEvent(hEventLog: THandle; wType, wCategory: Word;
   dwDataSize: DWORD; lpStrings, lpRawData: Pointer): BOOL; stdcall;
   dwDataSize: DWORD; lpStrings, lpRawData: Pointer): BOOL; stdcall;
 }
 }
 
 
-procedure TEventLog.WriteSystemLog(EventType : TEventType; Msg : String);
+procedure TEventLog.WriteSystemLog(EventType : TEventType; const Msg : String);
 
 
 Var
 Var
   P : PChar;
   P : PChar;

+ 10 - 8
packages/fcl-db/src/sqlite/customsqliteds.pas

@@ -128,6 +128,7 @@ type
     FPrimaryKeyNo: Integer;
     FPrimaryKeyNo: Integer;
     FFileName: String;
     FFileName: String;
     FSQL: String;
     FSQL: String;
+    FEffectiveSQL: String;
     FTableName: String;
     FTableName: String;
     FSqlFilterTemplate: String;
     FSqlFilterTemplate: String;
     FAutoIncFieldNo: Integer;
     FAutoIncFieldNo: Integer;
@@ -924,8 +925,10 @@ begin
   begin
   begin
     if FTablename = '' then
     if FTablename = '' then
       DatabaseError('Tablename not set', Self);
       DatabaseError('Tablename not set', Self);
-    FSQL := 'Select * from ' + FTableName + ';';
-  end;
+    FEffectiveSQL := 'Select * from ' + FTableName + ';';
+  end
+  else
+    FEffectiveSQL := FSQL;
 
 
   if FSqliteHandle = nil then
   if FSqliteHandle = nil then
     GetSqliteHandle;
     GetSqliteHandle;
@@ -1218,7 +1221,7 @@ begin
     FSqlFilterTemplate := FSqlFilterTemplate + FieldDefs[FieldDefs.Count - 1].Name +
     FSqlFilterTemplate := FSqlFilterTemplate + FieldDefs[FieldDefs.Count - 1].Name +
       ' FROM ' + FTableName;
       ' FROM ' + FTableName;
   end;
   end;
-  //set FSQL considering MasterSource active record
+  //set FEffectiveSQL considering MasterSource active record
   SetDetailFilter;
   SetDetailFilter;
 end;
 end;
 
 
@@ -1435,7 +1438,7 @@ var
   i: Integer;
   i: Integer;
 begin
 begin
   if (FMasterLink.Dataset.RecordCount = 0) or not FMasterLink.Active then //Retrieve all data
   if (FMasterLink.Dataset.RecordCount = 0) or not FMasterLink.Active then //Retrieve all data
-    FSQL := FSqlFilterTemplate
+    FEffectiveSQL := FSqlFilterTemplate
   else
   else
   begin
   begin
     AFilter := ' where ';
     AFilter := ' where ';
@@ -1445,7 +1448,7 @@ begin
       if i <> FMasterLink.Fields.Count - 1 then
       if i <> FMasterLink.Fields.Count - 1 then
         AFilter := AFilter + ' and ';
         AFilter := AFilter + ' and ';
     end;
     end;
-    FSQL := FSqlFilterTemplate + AFilter;
+    FEffectiveSQL := FSqlFilterTemplate + AFilter;
   end;
   end;
 end;
 end;
 
 
@@ -1455,7 +1458,7 @@ begin
   {$ifdef DEBUG_SQLITEDS}
   {$ifdef DEBUG_SQLITEDS}
   WriteLn('##TCustomSqliteDataset.MasterChanged##');
   WriteLn('##TCustomSqliteDataset.MasterChanged##');
   WriteLn('  SQL used to filter detail dataset:');
   WriteLn('  SQL used to filter detail dataset:');
-  WriteLn('  ', FSQL);
+  WriteLn('  ', FEffectiveSQL);
   {$endif}
   {$endif}
   RefetchData;
   RefetchData;
 end;
 end;
@@ -1537,8 +1540,7 @@ begin
   ExecSQL(SQLList);
   ExecSQL(SQLList);
 end;
 end;
 
 
-function TCustomSqliteDataset.GetSQLValue(Values: PPChar; FieldIndex: Integer
-  ): String;
+function TCustomSqliteDataset.GetSQLValue(Values: PPChar; FieldIndex: Integer): String;
 begin
 begin
   if (State = dsInactive) or (FieldIndex < 0) or (FieldIndex >= FieldDefs.Count) then
   if (State = dsInactive) or (FieldIndex < 0) or (FieldIndex >= FieldDefs.Count) then
     DatabaseError('Error retrieving SQL value: dataset inactive or field out of range', Self);
     DatabaseError('Error retrieving SQL value: dataset inactive or field out of range', Self);

+ 2 - 2
packages/fcl-db/src/sqlite/sqlite3ds.pas

@@ -163,7 +163,7 @@ begin
   {$endif}
   {$endif}
   FAutoIncFieldNo := -1;
   FAutoIncFieldNo := -1;
   FieldDefs.Clear;
   FieldDefs.Clear;
-  FReturnCode := sqlite3_prepare(FSqliteHandle, PChar(FSQL), -1, @vm, nil);
+  FReturnCode := sqlite3_prepare(FSqliteHandle, PChar(FEffectiveSQL), -1, @vm, nil);
   if FReturnCode <> SQLITE_OK then
   if FReturnCode <> SQLITE_OK then
     DatabaseError(ReturnString, Self);
     DatabaseError(ReturnString, Self);
   sqlite3_step(vm);
   sqlite3_step(vm);
@@ -281,7 +281,7 @@ begin
     sqlite3_exec(FSqliteHandle, PChar('Select Max(' + Fields[FAutoIncFieldNo].FieldName +
     sqlite3_exec(FSqliteHandle, PChar('Select Max(' + Fields[FAutoIncFieldNo].FieldName +
       ') from ' + FTableName), @GetAutoIncValue, @FNextAutoInc, nil);
       ') from ' + FTableName), @GetAutoIncValue, @FNextAutoInc, nil);
 
 
-  FReturnCode := sqlite3_prepare(FSqliteHandle, PChar(FSQL), -1, @vm, nil);
+  FReturnCode := sqlite3_prepare(FSqliteHandle, PChar(FEffectiveSQL), -1, @vm, nil);
   if FReturnCode <> SQLITE_OK then
   if FReturnCode <> SQLITE_OK then
     DatabaseError(ReturnString, Self);
     DatabaseError(ReturnString, Self);
 
 

+ 2 - 2
packages/fcl-db/src/sqlite/sqliteds.pas

@@ -119,7 +119,7 @@ var
 begin
 begin
   FieldDefs.Clear;
   FieldDefs.Clear;
   FAutoIncFieldNo := -1;
   FAutoIncFieldNo := -1;
-  FReturnCode := sqlite_compile(FSqliteHandle, PChar(FSQL), nil, @vm, nil);
+  FReturnCode := sqlite_compile(FSqliteHandle, PChar(FEffectiveSQL), nil, @vm, nil);
   if FReturnCode <> SQLITE_OK then
   if FReturnCode <> SQLITE_OK then
     DatabaseError(ReturnString, Self);
     DatabaseError(ReturnString, Self);
   sqlite_step(vm, @ColumnCount, @ColumnValues, @ColumnNames);
   sqlite_step(vm, @ColumnCount, @ColumnValues, @ColumnNames);
@@ -231,7 +231,7 @@ begin
     sqlite_exec(FSqliteHandle, PChar('Select Max(' + Fields[FAutoIncFieldNo].FieldName + ') from ' + FTableName),
     sqlite_exec(FSqliteHandle, PChar('Select Max(' + Fields[FAutoIncFieldNo].FieldName + ') from ' + FTableName),
       @GetAutoIncValue, @FNextAutoInc, nil);
       @GetAutoIncValue, @FNextAutoInc, nil);
 
 
-  FReturnCode := sqlite_compile(FSqliteHandle, PChar(FSQL), nil, @vm, nil);
+  FReturnCode := sqlite_compile(FSqliteHandle, PChar(FEffectiveSQL), nil, @vm, nil);
   if FReturnCode <> SQLITE_OK then
   if FReturnCode <> SQLITE_OK then
     DatabaseError(ReturnString, Self);
     DatabaseError(ReturnString, Self);
 
 

+ 4 - 4
packages/fcl-extra/src/daemonapp.pp

@@ -57,7 +57,7 @@ Type
     Function UnInstall: boolean; virtual;
     Function UnInstall: boolean; virtual;
     Function HandleCustomCode(ACode : DWord) : Boolean; Virtual;
     Function HandleCustomCode(ACode : DWord) : Boolean; Virtual;
   Public
   Public
-    Procedure LogMessage(Msg : String);
+    Procedure LogMessage(const Msg : String);
     Procedure ReportStatus;
     Procedure ReportStatus;
     
     
     // Filled in at runtime by controller
     // Filled in at runtime by controller
@@ -370,7 +370,7 @@ Type
     procedure UnInstallDaemons;
     procedure UnInstallDaemons;
     procedure ShowHelp;
     procedure ShowHelp;
     procedure CreateForm(InstanceClass: TComponentClass; var Reference); virtual;
     procedure CreateForm(InstanceClass: TComponentClass; var Reference); virtual;
-    procedure Log(EventType: TEventType; Msg: String); override;
+    procedure Log(EventType: TEventType; const Msg: String); override;
     Property  OnRun : TNotifyEvent Read FOnRun Write FOnRun;
     Property  OnRun : TNotifyEvent Read FOnRun Write FOnRun;
     Property EventLog : TEventLog Read GetEventLog;
     Property EventLog : TEventLog Read GetEventLog;
     Property GUIMainLoop : TGuiLoopEvent Read FGUIMainLoop Write FGuiMainLoop;
     Property GUIMainLoop : TGuiLoopEvent Read FGUIMainLoop Write FGuiMainLoop;
@@ -652,7 +652,7 @@ end;
 
 
 
 
 
 
-procedure TCustomDaemon.LogMessage(Msg: String);
+procedure TCustomDaemon.LogMessage(const Msg: String);
 begin
 begin
   Application.Log(etInfo,Msg);
   Application.Log(etInfo,Msg);
 end;
 end;
@@ -848,7 +848,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TCustomDaemonApplication.Log(EventType: TEventType; Msg: String);
+procedure TCustomDaemonApplication.Log(EventType: TEventType; const Msg: String);
 begin
 begin
   EventLog.Log(EventType,Msg);
   EventLog.Log(EventType,Msg);
 end;
 end;

+ 11 - 1
packages/fcl-image/src/freetype.pp

@@ -162,7 +162,14 @@ const
   sErrDestroying : string = 'finalizing FreeType';
   sErrDestroying : string = 'finalizing FreeType';
 
 
   DefaultFontExtention : string = '.ttf';
   DefaultFontExtention : string = '.ttf';
+
+  // Standard location for fonts in the Operating System
+  {$ifdef Darwin}
+  DefaultSearchPath : string = '/Library/Fonts/';
+  {$else}
   DefaultSearchPath : string = '';
   DefaultSearchPath : string = '';
+  {$endif}
+
   {$IFDEF MAC}
   {$IFDEF MAC}
   DefaultResolution : integer = 72;
   DefaultResolution : integer = 72;
   {$ELSE}
   {$ELSE}
@@ -729,7 +736,10 @@ begin
         end;
         end;
       end;
       end;
     // place position for next glyph
     // place position for next glyph
-    pos.x := pos.x + (gl^.advance.x shr 10);
+    // The previous code in this place used shr 10, which
+    // produces wrongly spaced text and looks very ugly
+    // for more information see: http://bugs.freepascal.org/view.php?id=17156
+    pos.x := pos.x + (gl^.advance.x shr 11);
     // pos.y := pos.y + (gl^.advance.y shr 6); // for angled texts also
     // pos.y := pos.y + (gl^.advance.y shr 6); // for angled texts also
     if prevx > pos.x then
     if prevx > pos.x then
       pos.x := prevx;
       pos.x := prevx;

+ 27 - 6
packages/fcl-image/src/freetypeh.pp

@@ -15,17 +15,38 @@
 {$mode objfpc}
 {$mode objfpc}
 unit freetypeh;
 unit freetypeh;
 
 
-{ These are not all the availlable calls from the dll, but only those
-  I needed for the TStringBitMaps }
+{ Note that these are not all the availlable calls from the dll yet.
+  This unit is used by TStringBitMaps and FTFont }
 
 
 interface
 interface
 
 
 const
 const
-{$ifdef win32}
+
+{$packrecords c}
+
+// Windows
+{$ifdef windows}
   freetypedll = 'freetype-6.dll';   // version 2.1.4
   freetypedll = 'freetype-6.dll';   // version 2.1.4
-  {$packrecords c}
-{$else}
-  // I don't know what it will be ??
+  {$define ft_found_platform}
+{$endif}
+// Mac OS X
+{$ifdef darwin}
+  freetypedll = 'libfreetype'; // Doesn't seam to matter much.
+  {$linklib freetype}          // This one is the important part,
+                               // but you also need to pass to fpc
+                               // the following command:
+                               // -k-L/usr/X11/lib
+                               // or another place where it can find
+                               // libfreetype.dylib
+  {$define ft_found_platform}
+{$endif}
+// LINUX
+{$if defined(UNIX) and not defined(darwin)}
+  freetypedll = 'freetype';
+  {$define ft_found_platform}
+{$endif}
+// Other platforms
+{$ifndef ft_found_platform}
   freetypedll = 'freetype';
   freetypedll = 'freetype';
 {$endif}
 {$endif}
 
 

+ 0 - 2
packages/fcl-web/examples/webdata/demo/extgrid.lpr

@@ -5,8 +5,6 @@ program extgrid;
 uses
 uses
   fpCGI, wmusers;
   fpCGI, wmusers;
 
 
-{$IFDEF WINDOWS}{$R extgrid.rc}{$ENDIF}
-
 begin
 begin
   Application.Initialize;
   Application.Initialize;
   Application.Run;
   Application.Run;

+ 44 - 80
packages/fcl-web/examples/webdata/demo/wmusers.pp

@@ -24,6 +24,7 @@ type
       AResponse: TResponse; var Handled: Boolean);
       AResponse: TResponse; var Handled: Boolean);
   private
   private
     { private declarations }
     { private declarations }
+    procedure GetAdaptorAndFormatter(P : TFPWebDataProvider; Var F :TExtJSDataFormatter; ARequest : TRequest; AResponse : TResponse);
   public
   public
     { public declarations }
     { public declarations }
   end; 
   end; 
@@ -31,6 +32,9 @@ type
 var
 var
   FPWebModule1: TFPWebModule1; 
   FPWebModule1: TFPWebModule1; 
 
 
+Var
+  ResponseFileName : String; // Set to non empty to write request responses to a file.
+
 implementation
 implementation
 {$define wmdebug}
 {$define wmdebug}
 
 
@@ -40,6 +44,38 @@ uses dbugintf;
 
 
 { TFPWebModule1 }
 { TFPWebModule1 }
 
 
+Procedure SaveResponse(M : TStream);
+
+begin
+  if (ResponseFileName<>'') then
+    With TFileStream.Create(ResponseFileName,fmCreate) do
+      try
+        CopyFrom(M,0);
+      finally
+        Free;
+      end;
+end;
+
+procedure TFPWebModule1.GetAdaptorAndFormatter(P : TFPWebDataProvider; Var F :TExtJSDataFormatter; ARequest : TRequest; AResponse : TResponse);
+
+begin
+  If Request.QueryFields.values['format']='xml' then
+    begin
+    F:=TExtJSXMLDataFormatter.Create(Self);
+    TExtJSXMLDataFormatter(F).TotalProperty:='total';
+    AResponse.ContentType:='text/xml';
+    P.Adaptor:=TExtJSXMLWebdataInputAdaptor.Create(Nil); 
+    end
+  else
+    begin
+    P.Adaptor:=TExtJSJSonWebdataInputAdaptor.Create(Nil); 
+    F:=TExtJSJSONDataFormatter.Create(Self);
+    end;
+  P.Adaptor.Request:=ARequest;
+  F.Adaptor:=P.Adaptor;
+  F.Provider:=P;
+end;
+
 procedure TFPWebModule1.TFPWebActions0Request(Sender: TObject;
 procedure TFPWebModule1.TFPWebActions0Request(Sender: TObject;
   ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
   ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
 
 
@@ -54,19 +90,9 @@ Var
 begin
 begin
   // Providername;
   // Providername;
   PN:=ARequest.GetNextPathInfo;
   PN:=ARequest.GetNextPathInfo;
-//  P:=GetWebDataProvider(PN);
   P:=TFPWebDataProvider.Create(Self);
   P:=TFPWebDataProvider.Create(Self);
   try
   try
-    P.Adaptor:=TWebDataInputAdaptor.Create(Self);
-    P.Adaptor.Request:=ARequest;
-    If Request.QueryFields.values['format']='xml' then
-      begin
-      F:=TExtJSXMLDataFormatter.Create(Self);
-      TExtJSXMLDataFormatter(F).TotalProperty:='total';
-      AResponse.ContentType:='text/xml';
-      end
-    else
-      F:=TExtJSJSONDataFormatter.Create(Self);
+    GetAdaptorAndFormatter(P,F,ARequest,AResponse);
     {$ifdef wmdebug} SendDebug(className+' '+F.ClassName);{$endif}
     {$ifdef wmdebug} SendDebug(className+' '+F.ClassName);{$endif}
     try
     try
       DS:=TDatasource.Create(Self);
       DS:=TDatasource.Create(Self);
@@ -75,11 +101,9 @@ begin
         DS.Dataset:=DBf1;
         DS.Dataset:=DBf1;
         DBF1.Open;
         DBF1.Open;
         try
         try
-          F.ADaptor:=P.Adaptor;
           P.Datasource:=DS;
           P.Datasource:=DS;
           P.Adaptor.Action:=wdaRead;
           P.Adaptor.Action:=wdaRead;
           P.ApplyParams;
           P.ApplyParams;
-          F.Provider:=P;
           M:=TMemoryStream.Create;
           M:=TMemoryStream.Create;
           try
           try
             F.GetContent(ARequest,M,Handled);
             F.GetContent(ARequest,M,Handled);
@@ -87,12 +111,7 @@ begin
             Response.ContentStream:=M;
             Response.ContentStream:=M;
             Response.SendResponse;
             Response.SendResponse;
             Response.ContentStream:=Nil;
             Response.ContentStream:=Nil;
-            With TFileStream.Create('/tmp/data.xml',fmCreate) do
-              try
-                CopyFrom(M,0);
-              finally
-                Free;
-              end;
+            SaveResponse(M);
           finally
           finally
             M.Free;
             M.Free;
           end;
           end;
@@ -127,18 +146,7 @@ begin
   P:=TFPWebDataProvider.Create(Self);
   P:=TFPWebDataProvider.Create(Self);
   try
   try
     P.IDFieldName:='ID';
     P.IDFieldName:='ID';
-    If Request.QueryFields.values['format']='xml' then
-      begin
-      F:=TExtJSXMLDataFormatter.Create(Self);
-      AResponse.ContentType:='text/xml';
-      P.Adaptor:=TWebDataInputAdaptor.Create(Self);
-      end
-    else
-      begin
-      F:=TExtJSJSONDataFormatter.Create(Self);
-      P.Adaptor:=TExtJSJSonWebdataInputAdaptor.Create(Self);
-      end;
-    P.Adaptor.Request:=ARequest;
+    GetAdaptorAndFormatter(P,F,ARequest,AResponse);
     {$ifdef wmdebug} SendDebug(className+' '+F.ClassName);{$endif}
     {$ifdef wmdebug} SendDebug(className+' '+F.ClassName);{$endif}
     try
     try
       DS:=TDatasource.Create(Self);
       DS:=TDatasource.Create(Self);
@@ -147,11 +155,9 @@ begin
         DS.Dataset:=DBf1;
         DS.Dataset:=DBf1;
         DBF1.Open;
         DBF1.Open;
         try
         try
-          F.ADaptor:=P.Adaptor;
           P.Datasource:=DS;
           P.Datasource:=DS;
           P.Adaptor.Action:=wdaInsert;
           P.Adaptor.Action:=wdaInsert;
           P.ApplyParams;
           P.ApplyParams;
-          F.Provider:=P;
           M:=TMemoryStream.Create;
           M:=TMemoryStream.Create;
           try
           try
             F.GetContent(ARequest,M,Handled);
             F.GetContent(ARequest,M,Handled);
@@ -159,12 +165,7 @@ begin
             Response.ContentStream:=M;
             Response.ContentStream:=M;
             Response.SendResponse;
             Response.SendResponse;
             Response.ContentStream:=Nil;
             Response.ContentStream:=Nil;
-            With TFileStream.Create('/tmp/data.xml',fmCreate) do
-              try
-                CopyFrom(M,0);
-              finally
-                Free;
-              end;
+            SaveResponse(M);
           finally
           finally
             M.Free;
             M.Free;
           end;
           end;
@@ -200,19 +201,7 @@ begin
   P:=TFPWebDataProvider.Create(Self);
   P:=TFPWebDataProvider.Create(Self);
   try
   try
     P.IDFieldName:='ID';
     P.IDFieldName:='ID';
-    If Request.QueryFields.values['format']='xml' then
-      begin
-      {$ifdef wmdebug} SendDebug('Update request received in XML');{$endif}
-      F:=TExtJSXMLDataFormatter.Create(Self);
-      AResponse.ContentType:='text/xml';
-      P.Adaptor:=TWebDataInputAdaptor.Create(Self);
-      end
-    else
-      begin
-      F:=TExtJSJSONDataFormatter.Create(Self);
-      P.Adaptor:=TExtJSJSonWebdataInputAdaptor.Create(Self);
-      end;
-    P.Adaptor.Request:=ARequest;
+    GetAdaptorAndFormatter(P,F,ARequest,AResponse);
     {$ifdef wmdebug} SendDebug(className+' '+F.ClassName);{$endif}
     {$ifdef wmdebug} SendDebug(className+' '+F.ClassName);{$endif}
     try
     try
       DS:=TDatasource.Create(Self);
       DS:=TDatasource.Create(Self);
@@ -221,11 +210,9 @@ begin
         DS.Dataset:=DBf1;
         DS.Dataset:=DBf1;
         DBF1.Open;
         DBF1.Open;
         try
         try
-          F.ADaptor:=P.Adaptor;
           P.Datasource:=DS;
           P.Datasource:=DS;
           P.Adaptor.Action:=wdaUpdate;
           P.Adaptor.Action:=wdaUpdate;
           P.ApplyParams;
           P.ApplyParams;
-          F.Provider:=P;
           M:=TMemoryStream.Create;
           M:=TMemoryStream.Create;
           try
           try
             F.GetContent(ARequest,M,Handled);
             F.GetContent(ARequest,M,Handled);
@@ -233,12 +220,7 @@ begin
             Response.ContentStream:=M;
             Response.ContentStream:=M;
             Response.SendResponse;
             Response.SendResponse;
             Response.ContentStream:=Nil;
             Response.ContentStream:=Nil;
-            With TFileStream.Create('/tmp/data.xml',fmCreate) do
-              try
-                CopyFrom(M,0);
-              finally
-                Free;
-              end;
+            SaveResponse(M);
           finally
           finally
             M.Free;
             M.Free;
           end;
           end;
@@ -274,18 +256,7 @@ begin
   P:=TFPWebDataProvider.Create(Self);
   P:=TFPWebDataProvider.Create(Self);
   try
   try
     P.IDFieldName:='ID';
     P.IDFieldName:='ID';
-    If Request.QueryFields.values['format']='xml' then
-      begin
-      F:=TExtJSXMLDataFormatter.Create(Self);
-      AResponse.ContentType:='text/xml';
-      P.Adaptor:=TWebDataInputAdaptor.Create(Self);
-      end
-    else
-      begin
-      F:=TExtJSJSONDataFormatter.Create(Self);
-      P.Adaptor:=TExtJSJSonWebdataInputAdaptor.Create(Self);
-      end;
-    P.Adaptor.Request:=ARequest;
+    GetAdaptorAndFormatter(P,F,ARequest,AResponse);
     {$ifdef wmdebug} SendDebug('className '+F.ClassName);{$endif}
     {$ifdef wmdebug} SendDebug('className '+F.ClassName);{$endif}
     try
     try
       DS:=TDatasource.Create(Self);
       DS:=TDatasource.Create(Self);
@@ -294,11 +265,9 @@ begin
         DS.Dataset:=DBf1;
         DS.Dataset:=DBf1;
         DBF1.Open;
         DBF1.Open;
         try
         try
-          F.ADaptor:=P.Adaptor;
           P.Datasource:=DS;
           P.Datasource:=DS;
           P.Adaptor.Action:=wdaDelete;
           P.Adaptor.Action:=wdaDelete;
           P.ApplyParams;
           P.ApplyParams;
-          F.Provider:=P;
           M:=TMemoryStream.Create;
           M:=TMemoryStream.Create;
           try
           try
             F.GetContent(ARequest,M,Handled);
             F.GetContent(ARequest,M,Handled);
@@ -306,12 +275,7 @@ begin
             Response.ContentStream:=M;
             Response.ContentStream:=M;
             Response.SendResponse;
             Response.SendResponse;
             Response.ContentStream:=Nil;
             Response.ContentStream:=Nil;
-            With TFileStream.Create('/tmp/data.xml',fmCreate) do
-              try
-                CopyFrom(M,0);
-              finally
-                Free;
-              end;
+            SaveResponse(M);
           finally
           finally
             M.Free;
             M.Free;
           end;
           end;

+ 121 - 92
packages/fcl-web/src/base/custcgi.pp

@@ -25,18 +25,18 @@ uses
 
 
 Type
 Type
   { TCGIRequest }
   { TCGIRequest }
-  TCustomCGIApplication = Class;
+  TCGIHandler = Class;
 
 
   TCGIRequest = Class(TRequest)
   TCGIRequest = Class(TRequest)
   Private
   Private
-    FCGI : TCustomCGIApplication;
+    FCGI : TCGIHandler;
     function GetCGIVar(Index: integer): String;
     function GetCGIVar(Index: integer): String;
   Protected
   Protected
     Function GetFieldValue(Index : Integer) : String; override;
     Function GetFieldValue(Index : Integer) : String; override;
     Procedure InitFromEnvironment;
     Procedure InitFromEnvironment;
     procedure ReadContent; override;
     procedure ReadContent; override;
   Public
   Public
-    Constructor CreateCGI(ACGI : TCustomCGIApplication);
+    Constructor CreateCGI(ACGI : TCGIHandler);
     Property GatewayInterface : String Index 1 Read GetCGIVar;
     Property GatewayInterface : String Index 1 Read GetCGIVar;
     Property RemoteIdent : String Index 2 read GetCGIVar;
     Property RemoteIdent : String Index 2 read GetCGIVar;
     Property RemoteUser : String Index 3 read GetCGIVar;
     Property RemoteUser : String Index 3 read GetCGIVar;
@@ -50,24 +50,22 @@ Type
 
 
   TCGIResponse = Class(TResponse)
   TCGIResponse = Class(TResponse)
   private
   private
-    FCGI : TCustomCGIApplication;
+    FCGI : TCGIHandler;
     FOutput : TStream;
     FOutput : TStream;
   Protected
   Protected
     Procedure DoSendHeaders(Headers : TStrings); override;
     Procedure DoSendHeaders(Headers : TStrings); override;
     Procedure DoSendContent; override;
     Procedure DoSendContent; override;
   Public
   Public
-    Constructor CreateCGI(ACGI : TCustomCGIApplication; AStream : TStream);
+    Constructor CreateCGI(ACGI : TCGIHandler; AStream : TStream);
   end;
   end;
 
 
   { TCustomCgiApplication }
   { TCustomCgiApplication }
 
 
-  TCustomCGIApplication = Class(TCustomWebApplication)
+  TCgiHandler = Class(TWebHandler)
   Private
   Private
     FResponse : TCGIResponse;
     FResponse : TCGIResponse;
     FRequest : TCGIRequest;
     FRequest : TCGIRequest;
     FOutput : TStream;
     FOutput : TStream;
-    Function GetRequestVariable(Const VarName : String) : String;
-    Function GetRequestVariableCount : Integer;
   protected
   protected
     Function GetEmail : String; override;
     Function GetEmail : String; override;
     Function GetAdministrator : String; override;
     Function GetAdministrator : String; override;
@@ -76,20 +74,37 @@ Type
     function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; override;
     function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; override;
     procedure EndRequest(ARequest : TRequest;AResponse : TResponse); override;
     procedure EndRequest(ARequest : TRequest;AResponse : TResponse); override;
   Public
   Public
+    Procedure GetCGIVarList(List : TStrings);
     Property Request : TCGIRequest read FRequest;
     Property Request : TCGIRequest read FRequest;
     Property Response: TCGIResponse Read FResponse;
     Property Response: TCGIResponse Read FResponse;
+  end;
+
+  { TCustomCgiApplication }
+
+  TCustomCGIApplication = Class(TCustomWebApplication)
+  private
+    function GetRequest: TCGIRequest;
+    function GetRequestVariable(VarName : String): String;
+    function GetRequestVariableCount: Integer;
+    function GetResponse: TCGIResponse;
+  protected
+    function InitializeWebHandler: TWebHandler; override;
+  public
+    Procedure ShowException(E: Exception);override;
+    Property Request : TCGIRequest read GetRequest;
+    Property Response: TCGIResponse Read GetResponse;
     Procedure AddResponse(Const S : String);
     Procedure AddResponse(Const S : String);
     Procedure AddResponse(Const Fmt : String; Args : Array of const);
     Procedure AddResponse(Const Fmt : String; Args : Array of const);
     Procedure AddResponseLn(Const S : String);
     Procedure AddResponseLn(Const S : String);
     Procedure AddResponseLn(Const Fmt : String; Args : Array of const);
     Procedure AddResponseLn(Const Fmt : String; Args : Array of const);
     Procedure GetCGIVarList(List : TStrings);
     Procedure GetCGIVarList(List : TStrings);
-    Procedure ShowException(E: Exception);override;
     Function VariableIsUploadedFile(Const VarName : String) : boolean;
     Function VariableIsUploadedFile(Const VarName : String) : boolean;
     Function UploadedFileName(Const VarName : String) : String;
     Function UploadedFileName(Const VarName : String) : String;
     Property RequestVariables[VarName : String] : String Read GetRequestVariable;
     Property RequestVariables[VarName : String] : String Read GetRequestVariable;
     Property RequestVariableCount : Integer Read GetRequestVariableCount;
     Property RequestVariableCount : Integer Read GetRequestVariableCount;
   end;
   end;
 
 
+
 ResourceString
 ResourceString
   SWebMaster = 'webmaster';
   SWebMaster = 'webmaster';
   SErrNoContentLength = 'No content length passed from server!';
   SErrNoContentLength = 'No content length passed from server!';
@@ -143,7 +158,7 @@ Const
     { 36: 'XHTTPREQUESTEDWITH'     } ''
     { 36: 'XHTTPREQUESTEDWITH'     } ''
   );
   );
 
 
-Procedure TCustomCGIApplication.GetCGIVarList(List : TStrings);
+Procedure TCgiHandler.GetCGIVarList(List : TStrings);
 
 
 Var
 Var
   I : Integer;
   I : Integer;
@@ -154,16 +169,7 @@ begin
     List.Add(CGIVarNames[i]+'='+GetEnvironmentVariable(CGIVarNames[i]));
     List.Add(CGIVarNames[i]+'='+GetEnvironmentVariable(CGIVarNames[i]));
 end;
 end;
 
 
-
-Procedure TCustomCGIApplication.ShowException(E: Exception);
-begin
-  if assigned(FResponse) then
-    ShowRequestException(FResponse,E)
-  else
-    inherited ShowException(E);
-end;
-
-Function TCustomCGIApplication.GetEmail : String;
+Function TCgiHandler.GetEmail : String;
 
 
 Var
 Var
   H : String;
   H : String;
@@ -178,7 +184,7 @@ begin
     end;
     end;
 end;
 end;
 
 
-Function TCustomCGIApplication.GetAdministrator : String;
+Function TCgiHandler.GetAdministrator : String;
 
 
 begin
 begin
   Result:=Inherited GetAdministrator;
   Result:=Inherited GetAdministrator;
@@ -186,17 +192,17 @@ begin
     Result:=SWebMaster;
     Result:=SWebMaster;
 end;
 end;
 
 
-function TCustomCGIApplication.CreateResponse(AOutput : TStream): TCGIResponse;
+function TCgiHandler.CreateResponse(AOutput : TStream): TCGIResponse;
 begin
 begin
-  TCGIResponse.CreateCGI(Self,AOutput);
+  result := TCGIResponse.CreateCGI(Self,AOutput);
 end;
 end;
 
 
-function TCustomCGIApplication.CreateRequest: TCGIRequest;
+function TCgiHandler.CreateRequest: TCGIRequest;
 begin
 begin
   Result:=TCGIRequest.CreateCGI(Self);
   Result:=TCGIRequest.CreateCGI(Self);
 end;
 end;
 
 
-function TCustomCGIApplication.WaitForRequest(out ARequest: TRequest; out AResponse: TResponse): boolean;
+function TCgiHandler.WaitForRequest(out ARequest: TRequest; out AResponse: TResponse): boolean;
 begin
 begin
   FRequest:=CreateRequest;
   FRequest:=CreateRequest;
   FRequest.InitFromEnvironment;
   FRequest.InitFromEnvironment;
@@ -208,83 +214,19 @@ begin
   Result := True;
   Result := True;
 end;
 end;
 
 
-procedure TCustomCGIApplication.EndRequest(ARequest: TRequest;
-  AResponse: TResponse);
+procedure TCgiHandler.EndRequest(ARequest: TRequest; AResponse: TResponse);
 begin
 begin
   inherited;
   inherited;
   FreeAndNil(FOutPut);
   FreeAndNil(FOutPut);
   Terminate;
   Terminate;
 end;
 end;
 
 
-constructor TCGIRequest.CreateCGI(ACGI: TCustomCGIApplication);
+constructor TCgiRequest.CreateCGI(ACGI: TCgiHandler);
 begin
 begin
   Inherited Create;
   Inherited Create;
   FCGI:=ACGI;
   FCGI:=ACGI;
 end;
 end;
 
 
-Function TCustomCGIApplication.GetRequestVariable(Const VarName : String) : String;
-
-begin
- If Assigned(Request) then
-   Result:=FRequest.QueryFields.Values[VarName]
- else
-   Result:='';
-end;
-
-Function TCustomCGIApplication.GetRequestVariableCount : Integer;
-
-begin
- If Assigned(Request) then
-    Result:=FRequest.QueryFields.Count
-  else
-    Result:=0;
-end;
-
-Procedure TCustomCGIApplication.AddResponse(Const S : String);
-
-Var
-  L : Integer;
-
-begin
-  L:=Length(S);
-  If L>0 then
-    Response.Content:=Response.Content+S;
-end;
-
-Procedure TCustomCGIApplication.AddResponse(Const Fmt : String; Args : Array of const);
-
-begin
-  AddResponse(Format(Fmt,Args));
-end;
-
-Procedure TCustomCGIApplication.AddResponseLN(Const S : String);
-
-
-begin
-  AddResponse(S+LineEnding);
-end;
-
-Procedure TCustomCGIApplication.AddResponseLN(Const Fmt : String; Args : Array of const);
-
-begin
-  AddResponseLN(Format(Fmt,Args));
-end;
-
-Function TCustomCGIApplication.VariableIsUploadedFile(Const VarName : String) : boolean;
-
-begin
-  Result:=FRequest.Files.IndexOfFile(VarName)<>-1;
-end;
-
-Function TCustomCGIApplication.UploadedFileName(Const VarName : String) : String;
-
-begin
-  If VariableIsUploadedFile(VarName) then
-    Result:=FRequest.Files.FileByName(VarName).LocalFileName
-  else
-    Result:='';
-end;
-
 { TCGIHTTPRequest }
 { TCGIHTTPRequest }
 
 
 function TCGIRequest.GetCGIVar(Index: integer): String;
 function TCGIRequest.GetCGIVar(Index: integer): String;
@@ -433,13 +375,100 @@ begin
 {$endif}
 {$endif}
 end;
 end;
 
 
-constructor TCGIResponse.CreateCGI(ACGI: TCustomCGIApplication; AStream: TStream);
+constructor TCGIResponse.CreateCGI(ACGI: TCgiHandler; AStream: TStream);
 begin
 begin
   inherited Create(ACGI.Request);
   inherited Create(ACGI.Request);
   FCGI:=ACGI;
   FCGI:=ACGI;
   FOutput:=AStream;
   FOutput:=AStream;
 end;
 end;
 
 
+{ TCustomCGIApplication }
+
+function TCustomCGIApplication.GetRequest: TCGIRequest;
+begin
+  result := TCgiHandler(WebHandler).Request;
+end;
+
+function TCustomCGIApplication.GetRequestVariable(VarName : String): String;
+begin
+  If Assigned(Request) then
+    Result:=Request.QueryFields.Values[VarName]
+  else
+    Result:='';
+end;
+
+function TCustomCGIApplication.GetRequestVariableCount: Integer;
+begin
+  If Assigned(Request) then
+     Result:=Request.QueryFields.Count
+   else
+     Result:=0;
+end;
+
+function TCustomCGIApplication.GetResponse: TCGIResponse;
+begin
+
+end;
+
+function TCustomCGIApplication.InitializeWebHandler: TWebHandler;
+begin
+  Result:=TCgiHandler.Create(self);
+end;
+
+Procedure TCustomCGIApplication.ShowException(E: Exception);
+var
+  CgiHandler: TCgiHandler;
+begin
+  CgiHandler := WebHandler as TCgiHandler;
+  if assigned(CgiHandler.FResponse) then
+    CgiHandler.ShowRequestException(CgiHandler.FResponse,E)
+  else
+    inherited ShowException(E);
+end;
+
+procedure TCustomCGIApplication.AddResponse(const S: String);
+Var
+  L : Integer;
+
+begin
+  L:=Length(S);
+  If L>0 then
+    Response.Content:=Response.Content+S;
+end;
+
+procedure TCustomCGIApplication.AddResponse(const Fmt: String; Args: array of const);
+begin
+  AddResponse(Format(Fmt,Args));
+end;
+
+procedure TCustomCGIApplication.AddResponseLn(const S: String);
+begin
+  AddResponse(S+LineEnding);
+end;
+
+procedure TCustomCGIApplication.AddResponseLn(const Fmt: String; Args: array of const);
+begin
+  AddResponseLN(Format(Fmt,Args));
+end;
+
+procedure TCustomCGIApplication.GetCGIVarList(List: TStrings);
+begin
+  TCgiHandler(WebHandler).GetCGIVarList(list);
+end;
+
+function TCustomCGIApplication.VariableIsUploadedFile(const VarName: String): boolean;
+begin
+  Result:=Request.Files.IndexOfFile(VarName)<>-1;
+end;
+
+function TCustomCGIApplication.UploadedFileName(const VarName: String): String;
+begin
+  If VariableIsUploadedFile(VarName) then
+    Result:=Request.Files.FileByName(VarName).LocalFileName
+  else
+    Result:='';
+end;
+
 initialization
 initialization
 
 
 finalization
 finalization

+ 79 - 12
packages/fcl-web/src/base/custfcgi.pp

@@ -75,9 +75,7 @@ Type
              Response : TFCgiResponse;
              Response : TFCgiResponse;
              end;
              end;
 
 
-  { TCustomFCgiApplication }
-
-  TCustomFCgiApplication = Class(TCustomWebApplication)
+  TFCgiHandler = class(TWebHandler)
   Private
   Private
     FOnUnknownRecord: TUnknownRecordEvent;
     FOnUnknownRecord: TUnknownRecordEvent;
     FPO: TProtoColOptions;
     FPO: TProtoColOptions;
@@ -100,6 +98,27 @@ Type
     Property OnUnknownRecord : TUnknownRecordEvent Read FOnUnknownRecord Write FOnUnknownRecord;
     Property OnUnknownRecord : TUnknownRecordEvent Read FOnUnknownRecord Write FOnUnknownRecord;
   end;
   end;
 
 
+  { TCustomFCgiApplication }
+
+  TCustomFCgiApplication = Class(TCustomWebApplication)
+  private
+    function GetAddress: string;
+    function GetFPO: TProtoColOptions;
+    function GetOnUnknownRecord: TUnknownRecordEvent;
+    function GetPort: integer;
+    procedure SetAddress(const AValue: string);
+    procedure SetOnUnknownRecord(const AValue: TUnknownRecordEvent);
+    procedure SetPort(const AValue: integer);
+    procedure SetPO(const AValue: TProtoColOptions);
+  protected
+    function InitializeWebHandler: TWebHandler; override;
+  Public
+    property Port: integer read GetPort write SetPort;
+    property Address: string read GetAddress write SetAddress;
+    Property ProtocolOptions : TProtoColOptions Read GetFPO Write SetPO;
+    Property OnUnknownRecord : TUnknownRecordEvent Read GetOnUnknownRecord Write SetOnUnknownRecord;
+  end;
+
 ResourceString
 ResourceString
   SNoInputHandle = 'Failed to open input-handle passed from server. Socket Error: %d';
   SNoInputHandle = 'Failed to open input-handle passed from server. Socket Error: %d';
   SNoSocket      = 'Failed to open socket. Socket Error: %d';
   SNoSocket      = 'Failed to open socket. Socket Error: %d';
@@ -157,6 +176,7 @@ begin
                           begin
                           begin
                           Result := True;
                           Result := True;
                           InitRequestVars;
                           InitRequestVars;
+                          ParseCookies;
                           end
                           end
                         else
                         else
                           begin
                           begin
@@ -372,9 +392,9 @@ begin
   Write_FCGIRecord(PFCGI_Header(@EndRequest));
   Write_FCGIRecord(PFCGI_Header(@EndRequest));
 end;
 end;
 
 
-{ TCustomFCgiApplication }
+{ TFCgiHandler }
 
 
-constructor TCustomFCgiApplication.Create(AOwner: TComponent);
+constructor TFCgiHandler.Create(AOwner: TComponent);
 begin
 begin
   Inherited Create(AOwner);
   Inherited Create(AOwner);
   FRequestsAvail:=5;
   FRequestsAvail:=5;
@@ -382,7 +402,7 @@ begin
   FHandle := THandle(-1);
   FHandle := THandle(-1);
 end;
 end;
 
 
-destructor TCustomFCgiApplication.Destroy;
+destructor TFCgiHandler.Destroy;
 begin
 begin
   SetLength(FRequestsArray,0);
   SetLength(FRequestsArray,0);
   if (Socket<>0) then
   if (Socket<>0) then
@@ -393,7 +413,7 @@ begin
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
-procedure TCustomFCgiApplication.EndRequest(ARequest: TRequest; AResponse: TResponse);
+procedure TFCgiHandler.EndRequest(ARequest: TRequest; AResponse: TResponse);
 begin
 begin
   with FRequestsArray[TFCGIRequest(ARequest).RequestID] do
   with FRequestsArray[TFCGIRequest(ARequest).RequestID] do
     begin
     begin
@@ -411,7 +431,7 @@ begin
   Inherited;
   Inherited;
 end;
 end;
 
 
-function TCustomFCgiApplication.Read_FCGIRecord : PFCGI_Header;
+function TFCgiHandler.Read_FCGIRecord : PFCGI_Header;
 
 
 var Header : FCGI_Header;
 var Header : FCGI_Header;
     BytesRead : integer;
     BytesRead : integer;
@@ -453,7 +473,7 @@ begin
   Result := ResRecord;
   Result := ResRecord;
 end;
 end;
 
 
-function TCustomFCgiApplication.WaitForRequest(out ARequest: TRequest; out AResponse: TResponse): boolean;
+function TFCgiHandler.WaitForRequest(out ARequest: TRequest; out AResponse: TResponse): boolean;
 var
 var
   IAddress      : TInetSockAddr;
   IAddress      : TInetSockAddr;
   AddressLength : tsocklen;
   AddressLength : tsocklen;
@@ -495,10 +515,10 @@ begin
       Socket:=StdInputHandle;
       Socket:=StdInputHandle;
     end;
     end;
 
 
-  if FHandle=-1 then
+  if FHandle=THandle(-1) then
     begin
     begin
     FHandle:=fpaccept(Socket,psockaddr(@IAddress),@AddressLength);
     FHandle:=fpaccept(Socket,psockaddr(@IAddress),@AddressLength);
-    if FHandle=-1 then
+    if FHandle=THandle(-1) then
       raise Exception.CreateFmt(SNoInputHandle,[socketerror]);
       raise Exception.CreateFmt(SNoInputHandle,[socketerror]);
     end;
     end;
 
 
@@ -534,7 +554,54 @@ begin
       Break;
       Break;
       end;
       end;
     end;
     end;
-  until Terminated;
+  until (1<>1);
+end;
+
+{ TCustomFCgiApplication }
+
+function TCustomFCgiApplication.GetAddress: string;
+begin
+  result := TFCgiHandler(WebHandler).Address;
+end;
+
+function TCustomFCgiApplication.GetFPO: TProtoColOptions;
+begin
+  result := TFCgiHandler(WebHandler).ProtocolOptions;
+end;
+
+function TCustomFCgiApplication.GetOnUnknownRecord: TUnknownRecordEvent;
+begin
+  result := TFCgiHandler(WebHandler).OnUnknownRecord;
+end;
+
+function TCustomFCgiApplication.GetPort: integer;
+begin
+  result := TFCgiHandler(WebHandler).Port;
+end;
+
+procedure TCustomFCgiApplication.SetAddress(const AValue: string);
+begin
+  TFCgiHandler(WebHandler).Address := AValue;
+end;
+
+procedure TCustomFCgiApplication.SetOnUnknownRecord(const AValue: TUnknownRecordEvent);
+begin
+  TFCgiHandler(WebHandler).OnUnknownRecord := AValue;
+end;
+
+procedure TCustomFCgiApplication.SetPort(const AValue: integer);
+begin
+  TFCgiHandler(WebHandler).Port := AValue;
+end;
+
+procedure TCustomFCgiApplication.SetPO(const AValue: TProtoColOptions);
+begin
+  TFCgiHandler(WebHandler).ProtocolOptions := AValue;
+end;
+
+function TCustomFCgiApplication.InitializeWebHandler: TWebHandler;
+begin
+  Result:=TFCgiHandler.Create(self);
 end;
 end;
 
 
 end.
 end.

+ 241 - 54
packages/fcl-web/src/base/custweb.pp

@@ -71,13 +71,19 @@ Const
     );
     );
 
 
 Type
 Type
+
   { TCustomWebApplication }
   { TCustomWebApplication }
+
   TGetModuleEvent = Procedure (Sender : TObject; ARequest : TRequest;
   TGetModuleEvent = Procedure (Sender : TObject; ARequest : TRequest;
                                Var ModuleClass : TCustomHTTPModuleClass) of object;
                                Var ModuleClass : TCustomHTTPModuleClass) of object;
   TOnShowRequestException = procedure(AResponse: TResponse; AnException: Exception; var handled: boolean);
   TOnShowRequestException = procedure(AResponse: TResponse; AnException: Exception; var handled: boolean);
 
 
-  TCustomWebApplication = Class(TCustomApplication)
-  Private
+  { TWebHandler }
+
+  TWebHandler = class(TComponent)
+  private
+    FOnIdle: TNotifyEvent;
+    FTerminated: boolean;
     FAdministrator: String;
     FAdministrator: String;
     FAllowDefaultModule: Boolean;
     FAllowDefaultModule: Boolean;
     FApplicationURL: String;
     FApplicationURL: String;
@@ -89,28 +95,24 @@ Type
     FHandleGetOnPost : Boolean;
     FHandleGetOnPost : Boolean;
     FRedirectOnError : Boolean;
     FRedirectOnError : Boolean;
     FRedirectOnErrorURL : String;
     FRedirectOnErrorURL : String;
-    FEventLog: TEventLog;
-    function GetEventLog: TEventLog;
+    FTitle: string;
+    FOnTerminate : TNotifyEvent;
   protected
   protected
+    procedure Terminate;
     Function GetModuleName(Arequest : TRequest) : string;
     Function GetModuleName(Arequest : TRequest) : string;
     function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; virtual; abstract;
     function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; virtual; abstract;
     procedure EndRequest(ARequest : TRequest;AResponse : TResponse); virtual;
     procedure EndRequest(ARequest : TRequest;AResponse : TResponse); virtual;
     function FindModule(ModuleClass : TCustomHTTPModuleClass): TCustomHTTPModule;
     function FindModule(ModuleClass : TCustomHTTPModuleClass): TCustomHTTPModule;
     Procedure SetBaseURL(AModule : TCustomHTTPModule; Const AModuleName : String; ARequest : TRequest); virtual;
     Procedure SetBaseURL(AModule : TCustomHTTPModule; Const AModuleName : String; ARequest : TRequest); virtual;
     function GetApplicationURL(ARequest : TRequest): String; virtual;
     function GetApplicationURL(ARequest : TRequest): String; virtual;
-    Procedure DoRun; override;
     procedure ShowRequestException(R: TResponse; E: Exception); virtual;
     procedure ShowRequestException(R: TResponse; E: Exception); virtual;
     Function GetEmail : String; virtual;
     Function GetEmail : String; virtual;
     Function GetAdministrator : String; virtual;
     Function GetAdministrator : String; virtual;
   Public
   Public
     constructor Create(AOwner: TComponent); override;
     constructor Create(AOwner: TComponent); override;
-    destructor Destroy; override;
-    Procedure CreateForm(AClass : TComponentClass; out Reference);
-    Procedure Initialize; override;
-    Procedure ShowException(E: Exception);override;
+    Procedure Run; virtual;
     Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse);
     Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse);
     Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); virtual;
     Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); virtual;
-    Procedure Log(EventType: TEventType; Msg: String); override;
     Property HandleGetOnPost : Boolean Read FHandleGetOnPost Write FHandleGetOnPost;
     Property HandleGetOnPost : Boolean Read FHandleGetOnPost Write FHandleGetOnPost;
     Property RedirectOnError : boolean Read FRedirectOnError Write FRedirectOnError;
     Property RedirectOnError : boolean Read FRedirectOnError Write FRedirectOnError;
     Property RedirectOnErrorURL : string Read FRedirectOnErrorURL Write FRedirectOnErrorURL;
     Property RedirectOnErrorURL : string Read FRedirectOnErrorURL Write FRedirectOnErrorURL;
@@ -120,8 +122,60 @@ Type
     Property ModuleVariable : String Read FModuleVar Write FModuleVar;
     Property ModuleVariable : String Read FModuleVar Write FModuleVar;
     Property OnGetModule : TGetModuleEvent Read FOnGetModule Write FOnGetModule;
     Property OnGetModule : TGetModuleEvent Read FOnGetModule Write FOnGetModule;
     Property Email : String Read GetEmail Write FEmail;
     Property Email : String Read GetEmail Write FEmail;
+    property Title: string read FTitle write FTitle;
     Property Administrator : String Read GetAdministrator Write FAdministrator;
     Property Administrator : String Read GetAdministrator Write FAdministrator;
     property OnShowRequestException: TOnShowRequestException read FOnShowRequestException write FOnShowRequestException;
     property OnShowRequestException: TOnShowRequestException read FOnShowRequestException write FOnShowRequestException;
+    property OnIdle: TNotifyEvent read FOnIdle write FOnIdle;
+  end;
+
+  TCustomWebApplication = Class(TCustomApplication)
+  Private
+    FEventLog: TEventLog;
+    FWebHandler: TWebHandler;
+    function GetAdministrator: String;
+    function GetAllowDefaultModule: Boolean;
+    function GetApplicationURL: String;
+    function GetEmail: String;
+    function GetEventLog: TEventLog;
+    function GetHandleGetOnPost: Boolean;
+    function GetModuleVar: String;
+    function GetOnGetModule: TGetModuleEvent;
+    function GetOnShowRequestException: TOnShowRequestException;
+    function GetRedirectOnError: boolean;
+    function GetRedirectOnErrorURL: string;
+    procedure SetAdministrator(const AValue: String);
+    procedure SetAllowDefaultModule(const AValue: Boolean);
+    procedure SetApplicationURL(const AValue: String);
+    procedure SetEmail(const AValue: String);
+    procedure SetHandleGetOnPost(const AValue: Boolean);
+    procedure SetModuleVar(const AValue: String);
+    procedure SetOnGetModule(const AValue: TGetModuleEvent);
+    procedure SetOnShowRequestException(const AValue: TOnShowRequestException);
+    procedure SetRedirectOnError(const AValue: boolean);
+    procedure SetRedirectOnErrorURL(const AValue: string);
+    procedure DoOnTerminate(Sender : TObject);
+  protected
+    Procedure DoRun; override;
+    function InitializeWebHandler: TWebHandler; virtual; abstract;
+    procedure SetTitle(const AValue: string); override;
+    property WebHandler: TWebHandler read FWebHandler write FWebHandler;
+  Public
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+    Procedure CreateForm(AClass : TComponentClass; out Reference);
+    Procedure Initialize; override;
+    Procedure Log(EventType: TEventType; const Msg: String); override;
+    procedure Terminate; override;
+    Property HandleGetOnPost : Boolean Read GetHandleGetOnPost Write SetHandleGetOnPost;
+    Property RedirectOnError : boolean Read GetRedirectOnError Write SetRedirectOnError;
+    Property RedirectOnErrorURL : string Read GetRedirectOnErrorURL Write SetRedirectOnErrorURL;
+    Property ApplicationURL : String Read GetApplicationURL Write SetApplicationURL;
+    Property AllowDefaultModule : Boolean Read GetAllowDefaultModule Write SetAllowDefaultModule;
+    Property ModuleVariable : String Read GetModuleVar Write SetModuleVar;
+    Property OnGetModule : TGetModuleEvent Read GetOnGetModule Write SetOnGetModule;
+    Property Email : String Read GetEmail Write SetEmail;
+    Property Administrator : String Read GetAdministrator Write SetAdministrator;
+    property OnShowRequestException: TOnShowRequestException read GetOnShowRequestException write SetOnShowRequestException;
     Property EventLog: TEventLog read GetEventLog;
     Property EventLog: TEventLog read GetEventLog;
   end;
   end;
 
 
@@ -173,18 +227,20 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure TCustomWebApplication.DoRun;
+procedure TWebHandler.Run;
 var ARequest : TRequest;
 var ARequest : TRequest;
     AResponse : TResponse;
     AResponse : TResponse;
 begin
 begin
-  while not Terminated do
+  while not FTerminated do
     begin
     begin
     if WaitForRequest(ARequest,AResponse) then
     if WaitForRequest(ARequest,AResponse) then
       DoHandleRequest(ARequest,AResponse);
       DoHandleRequest(ARequest,AResponse);
+    if assigned(OnIdle) then
+      OnIdle(Self);
     end;
     end;
 end;
 end;
 
 
-procedure TCustomWebApplication.ShowRequestException(R: TResponse; E: Exception);
+procedure TWebHandler.ShowRequestException(R: TResponse; E: Exception);
 Var
 Var
  S : TStrings;
  S : TStrings;
  handled: boolean;
  handled: boolean;
@@ -221,27 +277,17 @@ begin
     end;
     end;
 end;
 end;
 
 
-function TCustomWebApplication.GetEmail: String;
+function TWebHandler.GetEmail: String;
 begin
 begin
   Result := FEmail;
   Result := FEmail;
 end;
 end;
 
 
-function TCustomWebApplication.GetAdministrator: String;
+function TWebHandler.GetAdministrator: String;
 begin
 begin
   Result := FAdministrator;
   Result := FAdministrator;
 end;
 end;
 
 
-procedure TCustomWebApplication.ShowException(E: Exception);
-var Buf:ShortString;
-begin
-{$ifdef CGIDEBUG}
-  SetLength(Buf,ExceptionErrorMessage(ExceptObject,ExceptAddr,@Buf[1],255));
-  senddebug('Exception: ' + Buf);
-{$endif CGIDEBUG}
-  inherited ShowException(E);
-end;
-
-procedure TCustomWebApplication.HandleRequest(ARequest: TRequest; AResponse: TResponse);
+procedure TWebHandler.HandleRequest(ARequest: TRequest; AResponse: TResponse);
 Var
 Var
   MC : TCustomHTTPModuleClass;
   MC : TCustomHTTPModuleClass;
   M  : TCustomHTTPModule;
   M  : TCustomHTTPModule;
@@ -285,33 +331,21 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TCustomWebApplication.Log(EventType: TEventType; Msg: String);
-begin
-  EventLog.log(EventType,Msg);
-end;
-
-Procedure TCustomWebApplication.Initialize;
-
-begin
-  StopOnException:=True;
-  Inherited;
-end;
-
-function TCustomWebApplication.GetEventLog: TEventLog;
-begin
-  if not assigned(FEventLog) then
-    FEventLog := TEventLog.Create(self);
-  Result := FEventLog;
-end;
-
-function TCustomWebApplication.GetApplicationURL(ARequest: TRequest): String;
+function TWebHandler.GetApplicationURL(ARequest: TRequest): String;
 begin
 begin
   Result:=FApplicationURL;
   Result:=FApplicationURL;
   If (Result='') then
   If (Result='') then
     Result:=ARequest.ScriptName;
     Result:=ARequest.ScriptName;
 end;
 end;
 
 
-function TCustomWebApplication.GetModuleName(Arequest: TRequest): string;
+procedure TWebHandler.Terminate;
+begin
+  FTerminated := true;
+  If Assigned(FOnTerminate) then 
+    FOnTerminate(Self);
+end;
+
+function TWebHandler.GetModuleName(Arequest: TRequest): string;
 
 
    Function GetDefaultModuleName : String;
    Function GetDefaultModuleName : String;
 
 
@@ -344,13 +378,13 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure TCustomWebApplication.EndRequest(ARequest: TRequest; AResponse: TResponse);
+procedure TWebHandler.EndRequest(ARequest: TRequest; AResponse: TResponse);
 begin
 begin
   AResponse.Free;
   AResponse.Free;
   ARequest.Free;
   ARequest.Free;
 end;
 end;
 
 
-function TCustomWebApplication.FindModule(ModuleClass: TCustomHTTPModuleClass): TCustomHTTPModule;
+function TWebHandler.FindModule(ModuleClass: TCustomHTTPModuleClass): TCustomHTTPModule;
 Var
 Var
   I : Integer;
   I : Integer;
 begin
 begin
@@ -363,7 +397,7 @@ begin
     Result:=Nil;
     Result:=Nil;
 end;
 end;
 
 
-procedure TCustomWebApplication.SetBaseURL(AModule: TCustomHTTPModule;
+procedure TWebHandler.SetBaseURL(AModule: TCustomHTTPModule;
   Const AModuleName : String; ARequest: TRequest);
   Const AModuleName : String; ARequest: TRequest);
 
 
 Var
 Var
@@ -382,7 +416,7 @@ begin
   AModule.BaseURL:=S+P;
   AModule.BaseURL:=S+P;
 end;
 end;
 
 
-procedure TCustomWebApplication.DoHandleRequest(ARequest: TRequest; AResponse: TResponse);
+procedure TWebHandler.DoHandleRequest(ARequest: TRequest; AResponse: TResponse);
 begin
 begin
   HandleRequest(ARequest,AResponse);
   HandleRequest(ARequest,AResponse);
   If Not AResponse.ContentSent then
   If Not AResponse.ContentSent then
@@ -390,7 +424,7 @@ begin
   EndRequest(ARequest,AResponse);
   EndRequest(ARequest,AResponse);
 end;
 end;
 
 
-constructor TCustomWebApplication.Create(AOwner: TComponent);
+constructor TWebHandler.Create(AOwner:TComponent);
 begin
 begin
   inherited Create(AOwner);
   inherited Create(AOwner);
   FModuleVar:='Module'; // Do not localize
   FModuleVar:='Module'; // Do not localize
@@ -400,16 +434,169 @@ begin
   FRedirectOnErrorURL := '';
   FRedirectOnErrorURL := '';
 end;
 end;
 
 
+{ TCustomWebApplication }
+
+function TCustomWebApplication.GetAdministrator: String;
+begin
+  result := FWebHandler.Administrator;
+end;
+
+function TCustomWebApplication.GetAllowDefaultModule: Boolean;
+begin
+  result := FWebHandler.AllowDefaultModule;
+end;
+
+function TCustomWebApplication.GetApplicationURL: String;
+begin
+  result := FWebHandler.ApplicationURL;
+end;
+
+function TCustomWebApplication.GetEmail: String;
+begin
+  result := FWebHandler.Email;
+end;
+
+function TCustomWebApplication.GetEventLog: TEventLog;
+begin
+  if not assigned(FEventLog) then
+    FEventLog := TEventLog.Create(self);
+  Result := FEventLog;
+end;
+
+function TCustomWebApplication.GetHandleGetOnPost: Boolean;
+begin
+  result := FWebHandler.HandleGetOnPost;
+end;
+
+function TCustomWebApplication.GetModuleVar: String;
+begin
+  result := FWebHandler.ModuleVariable;
+end;
+
+function TCustomWebApplication.GetOnGetModule: TGetModuleEvent;
+begin
+  result := FWebHandler.OnGetModule;
+end;
+
+function TCustomWebApplication.GetOnShowRequestException: TOnShowRequestException;
+begin
+  result := FWebHandler.OnShowRequestException;
+end;
+
+function TCustomWebApplication.GetRedirectOnError: boolean;
+begin
+  result := FWebHandler.RedirectOnError;
+end;
+
+function TCustomWebApplication.GetRedirectOnErrorURL: string;
+begin
+  result := FWebHandler.RedirectOnErrorURL;
+end;
+
+procedure TCustomWebApplication.SetAdministrator(const AValue: String);
+begin
+  FWebHandler.Administrator := AValue;
+end;
+
+procedure TCustomWebApplication.SetAllowDefaultModule(const AValue: Boolean);
+begin
+  FWebHandler.AllowDefaultModule := AValue;
+end;
+
+procedure TCustomWebApplication.SetApplicationURL(const AValue: String);
+begin
+  FWebHandler.ApplicationURL := AValue;
+end;
+
+procedure TCustomWebApplication.SetEmail(const AValue: String);
+begin
+  FWebHandler.Email := AValue;
+end;
+
+procedure TCustomWebApplication.SetHandleGetOnPost(const AValue: Boolean);
+begin
+  FWebHandler.HandleGetOnPost := AValue;
+end;
+
+procedure TCustomWebApplication.SetModuleVar(const AValue: String);
+begin
+  FWebHandler.ModuleVariable := AValue;
+end;
+
+procedure TCustomWebApplication.SetOnGetModule(const AValue: TGetModuleEvent);
+begin
+  FWebHandler.OnGetModule := AValue;
+end;
+
+procedure TCustomWebApplication.SetOnShowRequestException(const AValue: TOnShowRequestException);
+begin
+  FWebHandler.OnShowRequestException := AValue;
+end;
+
+procedure TCustomWebApplication.SetRedirectOnError(const AValue: boolean);
+begin
+  FWebHandler.RedirectOnError := AValue;
+end;
+
+procedure TCustomWebApplication.SetRedirectOnErrorURL(const AValue: string);
+begin
+  FWebHandler.RedirectOnErrorURL :=AValue;
+end;
+
+procedure TCustomWebApplication.DoRun;
+begin
+  FWebHandler.Run;
+end;
+
+procedure TCustomWebApplication.SetTitle(const AValue: string);
+begin
+  inherited SetTitle(AValue);
+  FWebHandler.Title := Title;
+end;
+
+constructor TCustomWebApplication.Create(AOwner: TComponent);
+begin
+  FWebHandler := InitializeWebHandler;
+  FWebHandler.FOnTerminate:=@DoOnTerminate;
+end;
+
+procedure TCustomWebApplication.DoOnTerminate(Sender : TObject);
+begin
+  If Not Terminated then
+    Terminate;
+end;
+
 destructor TCustomWebApplication.Destroy;
 destructor TCustomWebApplication.Destroy;
 begin
 begin
+  FWebHandler.Free;
   if assigned(FEventLog) then
   if assigned(FEventLog) then
     FEventLog.Free;
     FEventLog.Free;
-  inherited Destroy;
 end;
 end;
 
 
 procedure TCustomWebApplication.CreateForm(AClass: TComponentClass; out Reference);
 procedure TCustomWebApplication.CreateForm(AClass: TComponentClass; out Reference);
 begin
 begin
-  TComponent(Reference):=AClass.Create(Self);
+  TComponent(Reference):=AClass.Create(FWebHandler);
+end;
+
+procedure TCustomWebApplication.Initialize;
+begin
+  StopOnException:=True;
+  Inherited;
 end;
 end;
 
 
+procedure TCustomWebApplication.Log(EventType: TEventType; const Msg: String);
+begin
+  EventLog.log(EventType,Msg);
+end;
+
+Procedure TCustomWebApplication.Terminate;
+
+begin
+  Inherited;
+  If Not Webhandler.FTerminated then
+    WebHandler.Terminate;
+end;
+
+
 end.
 end.
+

+ 60 - 44
packages/fcl-web/src/base/fcgigate.pp

@@ -54,7 +54,7 @@ uses
 {$IFDEF CGIGDEBUG}
 {$IFDEF CGIGDEBUG}
   dbugintf,
   dbugintf,
 {$endif}
 {$endif}
-  Classes, SysUtils,httpDefs,custcgi,fastcgi,ssockets,inifiles;
+  Classes, SysUtils,httpDefs,custcgi,fastcgi,ssockets,inifiles,custweb;
 
 
 Type
 Type
 
 
@@ -67,7 +67,9 @@ Type
 
 
   { TFastCGIGatewayApplication }
   { TFastCGIGatewayApplication }
 
 
-  TFastCGIGatewayApplication = Class(TCustomCGIApplication)
+  { TFastCGIGatewayHandler }
+
+  TFastCGIGatewayHandler = Class(TCgiHandler)
   private
   private
     FConfigFile: String;
     FConfigFile: String;
     FFastCGIBinary: String;
     FFastCGIBinary: String;
@@ -123,7 +125,7 @@ Type
     Constructor Create(AOwner : TComponent); override;
     Constructor Create(AOwner : TComponent); override;
     Destructor Destroy; override;
     Destructor Destroy; override;
     Procedure HandleRequest(ARequest : Trequest; AResponse : TResponse); override;
     Procedure HandleRequest(ARequest : Trequest; AResponse : TResponse); override;
-    Procedure Initialize; override;
+    Procedure Initialize;
     Property ConfigFileName : String Read FConfigFile Write SetConfigFile;
     Property ConfigFileName : String Read FConfigFile Write SetConfigFile;
     Property FastCGIBinary : String Read FFastCGIBinary Write FFastCGIBinary;
     Property FastCGIBinary : String Read FFastCGIBinary Write FFastCGIBinary;
     Property HostName : String Read FHostName Write SetHostname;
     Property HostName : String Read FHostName Write SetHostname;
@@ -132,6 +134,13 @@ Type
     Property Environment : TStrings Read FEnvironment Write SetEnvironment;
     Property Environment : TStrings Read FEnvironment Write SetEnvironment;
   end;
   end;
 
 
+  TFastCGIGatewayApplication = Class(TCustomCGIApplication)
+  protected
+    function InitializeWebHandler: TWebHandler; override;
+  public
+    Procedure Initialize; override;
+  end;
+
 Resourcestring
 Resourcestring
   SErrCouldNotConnectToFCGI = 'Could not connect to FastCGI server.';
   SErrCouldNotConnectToFCGI = 'Could not connect to FastCGI server.';
   SErrNoConnectionData      = 'No FastCGI connection data available.';
   SErrNoConnectionData      = 'No FastCGI connection data available.';
@@ -157,51 +166,51 @@ implementation
 
 
 { TCGIGateWayResponse }
 { TCGIGateWayResponse }
 
 
-procedure TCGIGateWayResponse.DoSendHeaders(Headers: TStrings);
+procedure TCGIGatewayResponse.DoSendHeaders(Headers: TStrings);
 
 
 begin
 begin
   // Do nothing. Headers are in response from FastCGI and are sent as content;
   // Do nothing. Headers are in response from FastCGI and are sent as content;
 end;
 end;
 
 
-procedure TFastCGIGatewayApplication.SetConfigFile(const AValue: String);
+procedure TFastCGIGatewayHandler.SetConfigFile(const AValue: String);
 begin
 begin
   if FConfigFile=AValue then exit;
   if FConfigFile=AValue then exit;
   CheckInitDone;
   CheckInitDone;
   FConfigFile:=AValue;
   FConfigFile:=AValue;
 end;
 end;
 
 
-procedure TFastCGIGatewayApplication.SetEnvironment(const AValue: TStrings);
+procedure TFastCGIGatewayHandler.SetEnvironment(const AValue: TStrings);
 begin
 begin
   FEnvironment.Assign(AValue);
   FEnvironment.Assign(AValue);
 end;
 end;
 
 
-procedure TFastCGIGatewayApplication.SetHostname(const AValue: String);
+procedure TFastCGIGatewayHandler.SetHostname(const AValue: String);
 begin
 begin
   if FHostName=AValue then exit;
   if FHostName=AValue then exit;
   CheckInitDone;
   CheckInitDone;
   FHostName:=AValue;
   FHostName:=AValue;
 end;
 end;
 
 
-procedure TFastCGIGatewayApplication.CheckInitDone;
+procedure TFastCGIGatewayHandler.CheckInitDone;
 begin
 begin
   If FInitDone then
   If FInitDone then
     RaiseError(SErrInitDone);
     RaiseError(SErrInitDone);
 end;
 end;
 
 
-function TFastCGIGatewayApplication.CreateResponse(AOutput: TStream): TCGIResponse;
+function TFastCGIGatewayHandler.CreateResponse(AOutput: TStream): TCGIResponse;
 begin
 begin
 {$IFDEF CGIGDEBUG}SendMethodEnter('CreateResponse');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodEnter('CreateResponse');{$ENDIF}
   Result:=TCGIGatewayResponse.CreateCGI(Self,AOutput);
   Result:=TCGIGatewayResponse.CreateCGI(Self,AOutput);
 {$IFDEF CGIGDEBUG}SendMethodExit('CreateResponse');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('CreateResponse');{$ENDIF}
 end;
 end;
 
 
-Procedure TFastCGIGatewayApplication.StartFCGIBinary;
+Procedure TFastCGIGatewayHandler.StartFCGIBinary;
 
 
 begin
 begin
   ExecuteProcess(FastCGIBinary,'',[]);
   ExecuteProcess(FastCGIBinary,'',[]);
 end;
 end;
 
 
-Procedure TFastCGIGatewayApplication.ConnectToFCGI;
+Procedure TFastCGIGatewayHandler.ConnectToFCGI;
 
 
 begin
 begin
   try
   try
@@ -237,7 +246,7 @@ begin
       Result:=Result+Format('#%.3d',[Ord(S[i])]);
       Result:=Result+Format('#%.3d',[Ord(S[i])]);
 end;
 end;
 
 
-Function TFastCGIGatewayApplication.EncodeFastCGIParam(N,V : AnsiString) : String;
+Function TFastCGIGatewayHandler.EncodeFastCGIParam(N,V : AnsiString) : String;
 
 
   Function CalcJump(ALen : Integer) : Integer;
   Function CalcJump(ALen : Integer) : Integer;
   begin
   begin
@@ -291,19 +300,19 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodExit('EncodeFastCGIParam');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('EncodeFastCGIParam');{$ENDIF}
 end;
 end;
 
 
-constructor TFastCGIGatewayApplication.Create(AOwner: TComponent);
+constructor TFastCGIGatewayHandler.Create(AOwner: TComponent);
 begin
 begin
   inherited Create(AOwner);
   inherited Create(AOwner);
   FEnvironment:=TStringList.Create;
   FEnvironment:=TStringList.Create;
 end;
 end;
 
 
-destructor TFastCGIGatewayApplication.Destroy;
+destructor TFastCGIGatewayHandler.Destroy;
 begin
 begin
   FreeAndNil(FEnvironment);
   FreeAndNil(FEnvironment);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
-Function TFastCGIGatewayApplication.TransformRequestVars : String;
+Function TFastCGIGatewayHandler.TransformRequestVars : String;
 
 
 Var
 Var
   L : TStringList;
   L : TStringList;
@@ -328,7 +337,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-Procedure TFastCGIGatewayApplication.SendFastCGIRecord(P : PFCGI_Header);
+Procedure TFastCGIGatewayHandler.SendFastCGIRecord(P : PFCGI_Header);
 
 
 Var
 Var
   Len : Integer;
   Len : Integer;
@@ -341,7 +350,7 @@ begin
 end;
 end;
 
 
 
 
-Procedure TFastCGIGatewayApplication.InitFastCGIRecord(P : PFCGI_Header; Const AContentLength, APadLength : Word);
+Procedure TFastCGIGatewayHandler.InitFastCGIRecord(P : PFCGI_Header; Const AContentLength, APadLength : Word);
 
 
 begin
 begin
 {$IFDEF CGIGDEBUG}SendMethodEnter('InitFastCGIRecord');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodEnter('InitFastCGIRecord');{$ENDIF}
@@ -353,7 +362,7 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodExit('InitFastCGIRecord');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('InitFastCGIRecord');{$ENDIF}
 end;
 end;
 
 
-function TFastCGIGatewayApplication.CreateFastCGIRecord(const AContentLength: Word) : PFCGI_Header;
+function TFastCGIGatewayHandler.CreateFastCGIRecord(const AContentLength: Word) : PFCGI_Header;
 
 
 Var
 Var
   L,PL : INteger;
   L,PL : INteger;
@@ -370,7 +379,7 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodExit('CreateFastCGIRecord');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('CreateFastCGIRecord');{$ENDIF}
 end;
 end;
 
 
-Procedure TFastCGIGatewayApplication.SendBeginRequest;
+Procedure TFastCGIGatewayHandler.SendBeginRequest;
 
 
 Var
 Var
   Req : FCGI_BeginRequestRecord;
   Req : FCGI_BeginRequestRecord;
@@ -386,7 +395,7 @@ begin
 end;
 end;
 
 
 
 
-Procedure TFastCGIGatewayApplication.SendRequestData(Const ARequest : Trequest);
+Procedure TFastCGIGatewayHandler.SendRequestData(Const ARequest : Trequest);
 
 
   Procedure SendString(S : String; RecType : Byte);
   Procedure SendString(S : String; RecType : Byte);
 
 
@@ -429,7 +438,7 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodExit('SendRequestData');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('SendRequestData');{$ENDIF}
 end;
 end;
 
 
-Function TFastCGIGatewayApplication.ReadFastCGIRecord : PFCGI_Header;
+Function TFastCGIGatewayHandler.ReadFastCGIRecord : PFCGI_Header;
 
 
 var
 var
   Header : FCGI_Header;
   Header : FCGI_Header;
@@ -468,7 +477,7 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodExit('ReadFastCGIRecord');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('ReadFastCGIRecord');{$ENDIF}
 end;
 end;
 
 
-Procedure TFastCGIGatewayApplication.ProcessUnknownRecord(Const Rec : PFCGI_Header; Const AResponse : TResponse; Var EOR : Boolean);
+Procedure TFastCGIGatewayHandler.ProcessUnknownRecord(Const Rec : PFCGI_Header; Const AResponse : TResponse; Var EOR : Boolean);
 
 
 begin
 begin
 {$IFDEF CGIGDEBUG}SendMethodEnter('ProcessUnknownRecord');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodEnter('ProcessUnknownRecord');{$ENDIF}
@@ -477,7 +486,7 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodEnter('ProcessUnknownRecord');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodEnter('ProcessUnknownRecord');{$ENDIF}
 end;
 end;
 
 
-Procedure TFastCGIGatewayApplication.ReadResponse(AResponse : TResponse);
+Procedure TFastCGIGatewayHandler.ReadResponse(AResponse : TResponse);
 
 
 Var
 Var
   Rec : PFCGI_Header;
   Rec : PFCGI_Header;
@@ -518,7 +527,7 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodExit('ReadResponse');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('ReadResponse');{$ENDIF}
 end;
 end;
 
 
-Procedure TFastCGIGatewayApplication.DisconnectfromFCGI;
+Procedure TFastCGIGatewayHandler.DisconnectfromFCGI;
 
 
 begin
 begin
 {$IFDEF CGIGDEBUG}SendMethodEnter('DisconnectfromFCGI');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodEnter('DisconnectfromFCGI');{$ENDIF}
@@ -526,7 +535,7 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodExit('DisconnectfromFCGI');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('DisconnectfromFCGI');{$ENDIF}
 end;
 end;
 
 
-Procedure TFastCGIGatewayApplication.HandleRequest(ARequest : Trequest; AResponse : TResponse);
+Procedure TFastCGIGatewayHandler.HandleRequest(ARequest : Trequest; AResponse : TResponse);
 
 
 begin
 begin
 {$IFDEF CGIGDEBUG}SendMethodEnter('Handle request');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodEnter('Handle request');{$ENDIF}
@@ -541,15 +550,32 @@ begin
 {$IFDEF CGIGDEBUG}SendMethodExit('Handle request');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('Handle request');{$ENDIF}
 end;
 end;
 
 
-procedure TFastCGIGatewayApplication.RaiseError(Const Msg : String);
+procedure TFastCGIGatewayHandler.Initialize;
+Var
+  Ini : TIniFile;
+begin
+  If (FConfigFile<>'') and FileExists(FConfigFile) then
+    begin
+    Ini:=TIniFile.Create(FConfigFile);
+    try
+      ReadConfigFile(Ini);
+    finally
+      Ini.Free;
+    end;
+    end;
+  if (Hostname='') or (Port=0) then
+    RaiseError(SErrNoConnectionData);
+  FInitDone:=True;
+end;
+
+procedure TFastCGIGatewayHandler.RaiseError(Const Msg : String);
 
 
 begin
 begin
   Raise HTTPError.Create(Msg);
   Raise HTTPError.Create(Msg);
 end;
 end;
 
 
 
 
-procedure TFastCGIGatewayApplication.ReadConfigFile(Ini : TIniFile);
-
+procedure TFastCGIGatewayHandler.ReadConfigFile(Ini : TIniFile);
 begin
 begin
   With Ini do
   With Ini do
     begin
     begin
@@ -564,28 +590,18 @@ begin
 end;
 end;
 
 
 procedure TFastCGIGatewayApplication.Initialize;
 procedure TFastCGIGatewayApplication.Initialize;
-
-Var
-  Ini : TIniFile;
-
 begin
 begin
 {$IFDEF CGIGDEBUG}SendMethodEnter('Initialize');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodEnter('Initialize');{$ENDIF}
   inherited Initialize;
   inherited Initialize;
-  If (FConfigFile<>'') and FileExists(FConfigFile) then
-    begin
-    Ini:=TIniFile.Create(FConfigFile);
-    try
-      ReadConfigFile(Ini);
-    finally
-      Ini.Free;
-    end;
-    end;
-  if (Hostname='') or (Port=0) then
-    RaiseError(SErrNoConnectionData);
-  FInitDone:=True;
+  TFastCGIGatewayHandler(WebHandler).Initialize;
 {$IFDEF CGIGDEBUG}SendMethodExit('Initialize');{$ENDIF}
 {$IFDEF CGIGDEBUG}SendMethodExit('Initialize');{$ENDIF}
 end;
 end;
 
 
+function TFastCGIGatewayApplication.InitializeWebHandler: TWebHandler;
+begin
+  Result:=TFastCGIGatewayHandler.Create(self);
+end;
+
 Procedure InitCGIGateWay; // Initializes Application.
 Procedure InitCGIGateWay; // Initializes Application.
 
 
 begin
 begin

+ 183 - 36
packages/fcl-web/src/base/fpapache.pp

@@ -22,29 +22,29 @@ uses
 
 
 Type
 Type
 
 
-  TCustomApacheApplication = Class;
+  TApacheHandler = Class;
 
 
   { TApacheRequest }
   { TApacheRequest }
 
 
   TApacheRequest = Class(TRequest)
   TApacheRequest = Class(TRequest)
   Private
   Private
-    FApache : TCustomApacheApplication;
+    FApache : TApacheHandler;
     FRequest : PRequest_rec;
     FRequest : PRequest_rec;
   Protected
   Protected
     Function GetFieldValue(Index : Integer) : String; override;
     Function GetFieldValue(Index : Integer) : String; override;
     Procedure InitFromRequest;
     Procedure InitFromRequest;
     procedure ReadContent; override;
     procedure ReadContent; override;
   Public
   Public
-    Constructor CreateReq(App : TCustomApacheApplication; ARequest : PRequest_rec);
+    Constructor CreateReq(App : TApacheHandler; ARequest : PRequest_rec);
     Property ApacheRequest : Prequest_rec Read FRequest;
     Property ApacheRequest : Prequest_rec Read FRequest;
-    Property ApacheApp : TCustomApacheApplication Read FApache;
+    Property ApacheApp : TApacheHandler Read FApache;
   end;
   end;
 
 
   { TApacheResponse }
   { TApacheResponse }
 
 
   TApacheResponse = Class(TResponse)
   TApacheResponse = Class(TResponse)
   private
   private
-    FApache : TCustomApacheApplication;
+    FApache : TApacheHandler;
     FRequest : PRequest_rec;
     FRequest : PRequest_rec;
     procedure SendStream(S: TStream);
     procedure SendStream(S: TStream);
   Protected
   Protected
@@ -53,7 +53,7 @@ Type
   Public
   Public
     Constructor CreateApache(Req : TApacheRequest);
     Constructor CreateApache(Req : TApacheRequest);
     Property ApacheRequest : Prequest_rec Read FRequest;
     Property ApacheRequest : Prequest_rec Read FRequest;
-    Property ApacheApp : TCustomApacheApplication Read FApache;
+    Property ApacheApp : TApacheHandler Read FApache;
   end;
   end;
 
 
   { TCustomApacheApplication }
   { TCustomApacheApplication }
@@ -61,7 +61,7 @@ Type
   TBeforeRequestEvent = Procedure(Sender : TObject; Const AHandler : String;
   TBeforeRequestEvent = Procedure(Sender : TObject; Const AHandler : String;
                                   Var AllowRequest : Boolean) of object;
                                   Var AllowRequest : Boolean) of object;
 
 
-  TCustomApacheApplication = Class(TCustomWebApplication)
+  TApacheHandler = Class(TWebHandler)
   private
   private
     FMaxRequests: Integer;             //Maximum number of simultaneous web module requests (default=64, if set to zero no limit)
     FMaxRequests: Integer;             //Maximum number of simultaneous web module requests (default=64, if set to zero no limit)
     FWorkingWebModules: TList;         //List of currently running web modules handling requests
     FWorkingWebModules: TList;         //List of currently running web modules handling requests
@@ -80,16 +80,15 @@ Type
     function GetWorkingModuleCount : Integer;
     function GetWorkingModuleCount : Integer;
   Protected
   Protected
     Function ProcessRequest(P : PRequest_Rec) : Integer; virtual;
     Function ProcessRequest(P : PRequest_Rec) : Integer; virtual;
-    Procedure DoRun; override;
     function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; override;
     function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; override;
     Function AllowRequest(P : PRequest_Rec) : Boolean; virtual;
     Function AllowRequest(P : PRequest_Rec) : Boolean; virtual;
     function GetApplicationURL(ARequest : TRequest): String; override;
     function GetApplicationURL(ARequest : TRequest): String; override;
   Public
   Public
     Constructor Create(AOwner : TComponent); override;
     Constructor Create(AOwner : TComponent); override;
     Destructor Destroy; override;
     Destructor Destroy; override;
+    Procedure Run; override;
     Procedure SetModuleRecord(Var ModuleRecord : Module);
     Procedure SetModuleRecord(Var ModuleRecord : Module);
-    Procedure Initialize; override;
-    Procedure ShowException(E : Exception); override;
+    Procedure Initialize;
     Procedure LogErrorMessage(Msg : String; LogLevel : integer = APLOG_INFO); virtual;
     Procedure LogErrorMessage(Msg : String; LogLevel : integer = APLOG_INFO); virtual;
     Procedure handleRequest(ARequest : TRequest; AResponse : TResponse); override;
     Procedure handleRequest(ARequest : TRequest; AResponse : TResponse); override;
     Property HandlerPriority : THandlerPriority Read FPriority Write FPriority default hpMiddle;
     Property HandlerPriority : THandlerPriority Read FPriority Write FPriority default hpMiddle;
@@ -104,6 +103,43 @@ Type
     Property WorkingWebModuleCount: Integer read GetWorkingModuleCount;
     Property WorkingWebModuleCount: Integer read GetWorkingModuleCount;
   end;
   end;
 
 
+  TCustomApacheApplication = Class(TCustomWebApplication)
+  private
+    function GetAfterModules: TStrings;
+    function GetBaseLocation: String;
+    function GetBeforeModules: TStrings;
+    function GetBeforeRequest: TBeforeRequestEvent;
+    function GetHandlerName: String;
+    function GetIdleModuleCount: Integer;
+    function GetMaxRequests: Integer;
+    function GetModuleName: String;
+    function GetPriority: THandlerPriority;
+    function GetWorkingModuleCount: Integer;
+    procedure SetAfterModules(const AValue: TStrings);
+    procedure SetBaseLocation(const AValue: String);
+    procedure SetBeforeModules(const AValue: TStrings);
+    procedure SetBeforeRequest(const AValue: TBeforeRequestEvent);
+    procedure SetHandlerName(const AValue: String);
+    procedure SetMaxRequests(const AValue: Integer);
+    procedure SetModuleName(const AValue: String);
+    procedure SetPriority(const AValue: THandlerPriority);
+  public
+    function InitializeWebHandler: TWebHandler; override;
+    procedure ShowException(E: Exception); override;
+    Function ProcessRequest(P : PRequest_Rec) : Integer; virtual;
+    Function AllowRequest(P : PRequest_Rec) : Boolean; virtual;
+    Property HandlerPriority : THandlerPriority Read GetPriority Write SetPriority default hpMiddle;
+    Property BeforeModules : TStrings Read GetBeforeModules Write SetBeforeModules;
+    Property AfterModules : TStrings Read GetAfterModules Write SetAfterModules;
+    Property BaseLocation : String Read GetBaseLocation Write SetBaseLocation;
+    Property ModuleName : String Read GetModuleName Write SetModuleName;
+    Property HandlerName : String Read GetHandlerName Write SetHandlerName;
+    Property BeforeRequest : TBeforeRequestEvent Read GetBeforeRequest Write SetBeforeRequest;
+    Property MaxRequests: Integer read GetMaxRequests write SetMaxRequests;
+    Property IdleWebModuleCount: Integer read GetIdleModuleCount;
+    Property WorkingWebModuleCount: Integer read GetWorkingModuleCount;
+  end;
+
   TApacheApplication = Class(TCustomApacheApplication)
   TApacheApplication = Class(TCustomApacheApplication)
   Public
   Public
     Property HandlerPriority;
     Property HandlerPriority;
@@ -128,6 +164,8 @@ Var
 
 
 Implementation
 Implementation
 
 
+uses CustApp;
+
 resourcestring
 resourcestring
   SErrNoModuleNameForRequest = 'Could not determine HTTP module name for request';
   SErrNoModuleNameForRequest = 'Could not determine HTTP module name for request';
   SErrNoModuleForRequest = 'Could not determine HTTP module for request "%s"';
   SErrNoModuleForRequest = 'Could not determine HTTP module for request "%s"';
@@ -144,12 +182,16 @@ Procedure InitApache;
 
 
 begin
 begin
   Application:=TCustomApacheApplication.Create(Nil);
   Application:=TCustomApacheApplication.Create(Nil);
+  if not assigned(CustomApplication) then
+    CustomApplication := Application;
 end;
 end;
 
 
 Procedure DoneApache;
 Procedure DoneApache;
 
 
 begin
 begin
   Try
   Try
+    if CustomApplication=Application then
+      CustomApplication := nil;
     FreeAndNil(Application);
     FreeAndNil(Application);
   except
   except
     if ShowCleanUpErrors then
     if ShowCleanUpErrors then
@@ -184,16 +226,16 @@ begin
   ap_hook_handler(H,PP1,PP2,HPRIO[Application.HandlerPriority]);
   ap_hook_handler(H,PP1,PP2,HPRIO[Application.HandlerPriority]);
 end;
 end;
 
 
-{ TCustomApacheApplication }
+{ TApacheHandler }
 
 
-function TCustomApacheApplication.GetModules(Index: integer): TStrings;
+function TApacheHandler.GetModules(Index: integer): TStrings;
 begin
 begin
   If (FModules[Index]=Nil) then
   If (FModules[Index]=Nil) then
     FModules[Index]:=TStringList.Create;
     FModules[Index]:=TStringList.Create;
   Result:=FModules[Index];
   Result:=FModules[Index];
 end;
 end;
 
 
-procedure TCustomApacheApplication.SetModules(Index: integer;
+procedure TApacheHandler.SetModules(Index: integer;
   const AValue: TStrings);
   const AValue: TStrings);
 begin
 begin
   If (FModules[Index]=Nil) then
   If (FModules[Index]=Nil) then
@@ -201,7 +243,7 @@ begin
   FModules[Index].Assign(AValue);
   FModules[Index].Assign(AValue);
 end;
 end;
 
 
-Function TCustomApacheApplication.ProcessRequest(P: PRequest_Rec) : Integer;
+Function TApacheHandler.ProcessRequest(P: PRequest_Rec) : Integer;
 
 
 Var
 Var
   Req : TApacheRequest;
   Req : TApacheRequest;
@@ -225,18 +267,18 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TCustomApacheApplication.DoRun;
+procedure TApacheHandler.Run;
 begin
 begin
   // Do nothing. This is a library
   // Do nothing. This is a library
+  Initialize;
 end;
 end;
 
 
-function TCustomApacheApplication.WaitForRequest(out ARequest: TRequest;
-  out AResponse: TResponse): boolean;
+function TApacheHandler.WaitForRequest(out ARequest: TRequest; out AResponse: TResponse): boolean;
 begin
 begin
   // Do nothing. Requests are triggered by Apache
   // Do nothing. Requests are triggered by Apache
 end;
 end;
 
 
-function TCustomApacheApplication.AllowRequest(P: PRequest_Rec): Boolean;
+function TApacheHandler.AllowRequest(P: PRequest_Rec): Boolean;
 
 
 Var
 Var
   Hn : String;
   Hn : String;
@@ -248,15 +290,14 @@ begin
     FBeforeRequest(Self,HN,Result);
     FBeforeRequest(Self,HN,Result);
 end;
 end;
 
 
-function TCustomApacheApplication.GetApplicationURL(ARequest: TRequest
-  ): String;
+function TApacheHandler.GetApplicationURL(ARequest: TRequest): String;
 begin
 begin
   Result:=inherited GetApplicationURL(ARequest);
   Result:=inherited GetApplicationURL(ARequest);
   If (Result='') then
   If (Result='') then
     Result:=BaseLocation;
     Result:=BaseLocation;
 end;
 end;
 
 
-constructor TCustomApacheApplication.Create(AOwner: TComponent);
+constructor TApacheHandler.Create(AOwner: TComponent);
 begin
 begin
   inherited Create(AOwner);
   inherited Create(AOwner);
   FPriority:=hpMiddle;
   FPriority:=hpMiddle;
@@ -266,7 +307,7 @@ begin
   FCriticalSection:=TCriticalSection.Create;
   FCriticalSection:=TCriticalSection.Create;
 end;
 end;
 
 
-destructor TCustomApacheApplication.Destroy;
+destructor TApacheHandler.Destroy;
 var I:Integer;
 var I:Integer;
 begin
 begin
   FCriticalSection.Free;
   FCriticalSection.Free;
@@ -280,13 +321,13 @@ begin
 end;
 end;
 
 
 
 
-procedure TCustomApacheApplication.SetModuleRecord(var ModuleRecord: Module);
+procedure TApacheHandler.SetModuleRecord(var ModuleRecord: Module);
 begin
 begin
   FModuleRecord:=@ModuleRecord;
   FModuleRecord:=@ModuleRecord;
   FillChar(ModuleRecord,SizeOf(ModuleRecord),0);
   FillChar(ModuleRecord,SizeOf(ModuleRecord),0);
 end;
 end;
 
 
-procedure TCustomApacheApplication.Initialize;
+procedure TApacheHandler.Initialize;
 
 
 begin
 begin
   If (FModuleRecord=nil) then
   If (FModuleRecord=nil) then
@@ -299,18 +340,12 @@ begin
   FModuleRecord^.register_hooks:=@RegisterApacheHooks;
   FModuleRecord^.register_hooks:=@RegisterApacheHooks;
 end;
 end;
 
 
-procedure TCustomApacheApplication.ShowException(E: Exception);
-begin
-  ap_log_error(pchar(FModuleName),0,APLOG_ERR,0,Nil,'module: %s',[Pchar(E.Message)]);
-end;
-
-procedure TCustomApacheApplication.LogErrorMessage(Msg: String;
-  LogLevel: integer);
+procedure TApacheHandler.LogErrorMessage(Msg: String; LogLevel: integer);
 begin
 begin
   ap_log_error(pchar(FModuleName),0,LogLevel,0,Nil,'module: %s',[pchar(Msg)]);
   ap_log_error(pchar(FModuleName),0,LogLevel,0,Nil,'module: %s',[pchar(Msg)]);
 end;
 end;
 
 
-function TCustomApacheApplication.GetIdleModuleCount : Integer;
+function TApacheHandler.GetIdleModuleCount : Integer;
 begin
 begin
   FCriticalSection.Enter;
   FCriticalSection.Enter;
   try
   try
@@ -320,7 +355,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TCustomApacheApplication.GetWorkingModuleCount : Integer;
+function TApacheHandler.GetWorkingModuleCount : Integer;
 begin
 begin
   FCriticalSection.Enter;
   FCriticalSection.Enter;
   try
   try
@@ -330,7 +365,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TCustomApacheApplication.HandleRequest(ARequest: TRequest; AResponse: TResponse);
+procedure TApacheHandler.HandleRequest(ARequest: TRequest; AResponse: TResponse);
 
 
 Var
 Var
   MC : TCustomHTTPModuleClass;
   MC : TCustomHTTPModuleClass;
@@ -399,7 +434,7 @@ begin
   except
   except
     On E : Exception do
     On E : Exception do
       begin
       begin
-      ShowException(E);
+      LogErrorMessage(E.Message,APLOG_ERR);
       ShowRequestException(AResponse,E);
       ShowRequestException(AResponse,E);
       end;
       end;
   end;
   end;
@@ -497,7 +532,7 @@ begin
   ParseCookies;
   ParseCookies;
 end;
 end;
 
 
-Constructor TApacheRequest.CreateReq(App : TCustomApacheApplication; ARequest : PRequest_rec);
+Constructor TApacheRequest.CreateReq(App : TApacheHandler; ARequest : PRequest_rec);
 
 
 begin
 begin
   FApache:=App;
   FApache:=App;
@@ -584,6 +619,118 @@ begin
 //empty
 //empty
 end;
 end;
 
 
+{ TCustomApacheApplication }
+
+function TCustomApacheApplication.GetAfterModules: TStrings;
+begin
+  result := TApacheHandler(WebHandler).AfterModules;
+end;
+
+function TCustomApacheApplication.GetBaseLocation: String;
+begin
+  result := TApacheHandler(WebHandler).BaseLocation;
+end;
+
+function TCustomApacheApplication.GetBeforeModules: TStrings;
+begin
+  result := TApacheHandler(WebHandler).BeforeModules;
+end;
+
+function TCustomApacheApplication.GetBeforeRequest: TBeforeRequestEvent;
+begin
+  result := TApacheHandler(WebHandler).BeforeRequest;
+end;
+
+function TCustomApacheApplication.GetHandlerName: String;
+begin
+  result := TApacheHandler(WebHandler).HandlerName;
+end;
+
+function TCustomApacheApplication.GetIdleModuleCount: Integer;
+begin
+  result := TApacheHandler(WebHandler).IdleWebModuleCount;
+end;
+
+function TCustomApacheApplication.GetMaxRequests: Integer;
+begin
+  result := TApacheHandler(WebHandler).MaxRequests;
+end;
+
+function TCustomApacheApplication.GetModuleName: String;
+begin
+  result := TApacheHandler(WebHandler).ModuleName;
+end;
+
+function TCustomApacheApplication.GetPriority: THandlerPriority;
+begin
+  result := TApacheHandler(WebHandler).HandlerPriority;
+end;
+
+function TCustomApacheApplication.GetWorkingModuleCount: Integer;
+begin
+  result := TApacheHandler(WebHandler).WorkingWebModuleCount;
+end;
+
+procedure TCustomApacheApplication.SetAfterModules(const AValue: TStrings);
+begin
+  TApacheHandler(WebHandler).AfterModules := AValue;
+end;
+
+procedure TCustomApacheApplication.SetBaseLocation(const AValue: String);
+begin
+  TApacheHandler(WebHandler).BaseLocation := AValue;
+end;
+
+procedure TCustomApacheApplication.SetBeforeModules(const AValue: TStrings);
+begin
+  TApacheHandler(WebHandler).BeforeModules := AValue;
+end;
+
+procedure TCustomApacheApplication.SetBeforeRequest(const AValue: TBeforeRequestEvent);
+begin
+  TApacheHandler(WebHandler).BeforeRequest := AValue;
+end;
+
+procedure TCustomApacheApplication.SetHandlerName(const AValue: String);
+begin
+  TApacheHandler(WebHandler).HandlerName := AValue;
+end;
+
+procedure TCustomApacheApplication.SetMaxRequests(const AValue: Integer);
+begin
+  TApacheHandler(WebHandler).MaxRequests := AValue;
+end;
+
+procedure TCustomApacheApplication.SetModuleName(const AValue: String);
+begin
+  TApacheHandler(WebHandler).ModuleName := AValue;
+end;
+
+procedure TCustomApacheApplication.SetPriority(const AValue: THandlerPriority);
+begin
+  TApacheHandler(WebHandler).HandlerPriority := AValue;
+end;
+
+function TCustomApacheApplication.InitializeWebHandler: TWebHandler;
+begin
+  Result:=TApacheHandler.Create(self);
+end;
+
+procedure TCustomApacheApplication.ShowException(E: Exception);
+begin
+  ap_log_error(pchar(TApacheHandler(WebHandler).ModuleName),0,APLOG_ERR,0,Nil,'module: %s',[Pchar(E.Message)]);
+end;
+
+function TCustomApacheApplication.ProcessRequest(P: PRequest_Rec): Integer;
+begin
+  result := TApacheHandler(WebHandler).ProcessRequest(p);
+end;
+
+function TCustomApacheApplication.AllowRequest(P: PRequest_Rec): Boolean;
+begin
+  result := TApacheHandler(WebHandler).AllowRequest(p);
+end;
+
 Initialization
 Initialization
   BeginThread(@__dummythread);//crash prevention for simultaneous requests
   BeginThread(@__dummythread);//crash prevention for simultaneous requests
   sleep(300);
   sleep(300);

+ 4 - 1
packages/fcl-web/src/base/fpcgi.pp

@@ -38,13 +38,16 @@ Procedure InitCGI;
 
 
 begin
 begin
   Application:=TCGIApplication.Create(Nil);
   Application:=TCGIApplication.Create(Nil);
-  CustomApplication:=Application;
+  if not assigned(CustomApplication) then
+    CustomApplication := Application;
 end;
 end;
 
 
 Procedure DoneCGI;
 Procedure DoneCGI;
 
 
 begin
 begin
   Try
   Try
+    if CustomApplication=Application then
+      CustomApplication := nil;
     FreeAndNil(Application);
     FreeAndNil(Application);
   except
   except
     if ShowCleanUpErrors then
     if ShowCleanUpErrors then

+ 6 - 0
packages/fcl-web/src/base/fpfcgi.pp

@@ -31,16 +31,22 @@ Var
   
   
 Implementation
 Implementation
 
 
+uses CustApp;
+
 Procedure InitFCGI;
 Procedure InitFCGI;
 
 
 begin
 begin
   Application:=TFCGIApplication.Create(Nil);
   Application:=TFCGIApplication.Create(Nil);
+  if not assigned(CustomApplication) then
+    CustomApplication := Application;
 end;
 end;
 
 
 Procedure DoneFCGI;
 Procedure DoneFCGI;
 
 
 begin
 begin
   Try
   Try
+    if CustomApplication=Application then
+      CustomApplication := nil;
     FreeAndNil(Application);
     FreeAndNil(Application);
   except
   except
     if ShowCleanUpErrors then
     if ShowCleanUpErrors then

+ 8 - 4
packages/fcl-web/src/base/websession.pp

@@ -283,8 +283,12 @@ begin
   If FSessionStarted then
   If FSessionStarted then
     begin
     begin
 {$ifdef cgidebug}SendDebug('Session started');{$endif}
 {$ifdef cgidebug}SendDebug('Session started');{$endif}
-    C:=AResponse.Cookies.Add;
-    C.Name:=SessionCookie;
+    C:=AResponse.Cookies.FindCookie(SessionCookie);
+    If (C=Nil) then
+      begin
+      C:=AResponse.Cookies.Add;
+      C.Name:=SessionCookie;
+      end;
     C.Value:=SID;
     C.Value:=SID;
     C.Path:=FSessionCookiePath;
     C.Path:=FSessionCookiePath;
     end
     end
@@ -350,8 +354,8 @@ begin
     begin
     begin
     If (FSession=Nil) then
     If (FSession=Nil) then
       FSession:=GetDefaultSession;
       FSession:=GetDefaultSession;
-    if Assigned(Session) then
-      Session.InitSession(ARequest,FOnNewSession,FOnSessionExpired);
+    if Assigned(FSession) then
+      FSession.InitSession(ARequest,FOnNewSession,FOnSessionExpired);
     end;
     end;
 {$ifdef cgidebug}SendMethodExit('SessionHTTPModule('+Name+').CheckSession');{$endif}
 {$ifdef cgidebug}SendMethodExit('SessionHTTPModule('+Name+').CheckSession');{$endif}
 end;
 end;

+ 89 - 38
packages/fcl-web/src/jsonrpc/Makefile

@@ -4,7 +4,7 @@
 default: all
 default: all
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-solaris x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-solaris x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
 BSDs = freebsd netbsd openbsd darwin
 BSDs = freebsd netbsd openbsd darwin
-UNIXs = linux $(BSDs) solaris qnx haiku
+UNIXs = linux $(BSDs) solaris qnx
 LIMIT83fs = go32v2 os2 emx watcom
 LIMIT83fs = go32v2 os2 emx watcom
 OSNeedsComspecToRunBatch = go32v2 watcom
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 FORCE:
@@ -59,11 +59,9 @@ endif
 endif
 endif
 ifdef COMSPEC
 ifdef COMSPEC
 ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
 ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
-ifndef RUNBATCH
 RUNBATCH=$(COMSPEC) /C
 RUNBATCH=$(COMSPEC) /C
 endif
 endif
 endif
 endif
-endif
 ifdef inUnix
 ifdef inUnix
 PATHSEP=/
 PATHSEP=/
 else
 else
@@ -390,9 +388,6 @@ endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 override TARGET_UNITS+=fpjsonrpc  webjsonrpc fpextdirect
 override TARGET_UNITS+=fpjsonrpc  webjsonrpc fpextdirect
 endif
 endif
-ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_UNITS+=fpjsonrpc  webjsonrpc fpextdirect
-endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
 override TARGET_UNITS+=fpjsonrpc  webjsonrpc fpextdirect
 override TARGET_UNITS+=fpjsonrpc  webjsonrpc fpextdirect
 endif
 endif
@@ -444,9 +439,6 @@ endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
 override TARGET_UNITS+=fpjsonrpc  webjsonrpc fpextdirect
 override TARGET_UNITS+=fpjsonrpc  webjsonrpc fpextdirect
 endif
 endif
-ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_UNITS+=fpjsonrpc  webjsonrpc fpextdirect
-endif
 override INSTALL_FPCPACKAGE=y
 override INSTALL_FPCPACKAGE=y
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
@@ -571,9 +563,6 @@ endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
-ifeq ($(FULL_TARGET),x86_64-solaris)
-override COMPILER_OPTIONS+=-S2h
-endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
@@ -625,9 +614,6 @@ endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
-ifeq ($(FULL_TARGET),mipsel-linux)
-override COMPILER_OPTIONS+=-S2h
-endif
 ifdef REQUIRE_UNITSDIR
 ifdef REQUIRE_UNITSDIR
 override UNITSDIR+=$(REQUIRE_UNITSDIR)
 override UNITSDIR+=$(REQUIRE_UNITSDIR)
 endif
 endif
@@ -1425,31 +1411,35 @@ else
 TAROPT=vz
 TAROPT=vz
 TAREXT=.tar.gz
 TAREXT=.tar.gz
 endif
 endif
-override REQUIRE_PACKAGES=rtl fcl-base fcl-xml fcl-json
+override REQUIRE_PACKAGES=rtl fcl-base fcl-xml fcl-json fcl-process
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1457,6 +1447,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1464,6 +1455,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1471,42 +1463,49 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1515,42 +1514,49 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1558,6 +1564,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1565,42 +1572,49 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1608,24 +1622,28 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1634,18 +1652,21 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1653,24 +1674,28 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1678,6 +1703,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1685,12 +1711,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
-endif
-ifeq ($(FULL_TARGET),x86_64-solaris)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_FCL-BASE=1
-REQUIRE_PACKAGES_FCL-XML=1
-REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1699,18 +1720,21 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1718,12 +1742,14 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1732,36 +1758,42 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1769,6 +1801,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1777,18 +1810,21 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
@@ -1796,19 +1832,14 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
-endif
-ifeq ($(FULL_TARGET),mipsel-linux)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_FCL-BASE=1
-REQUIRE_PACKAGES_ICONVENC=1
-REQUIRE_PACKAGES_FCL-XML=1
-REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 endif
 endif
 ifdef REQUIRE_PACKAGES_RTL
 ifdef REQUIRE_PACKAGES_RTL
 PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
 PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
@@ -1819,9 +1850,9 @@ else
 UNITDIR_RTL=$(PACKAGEDIR_RTL)
 UNITDIR_RTL=$(PACKAGEDIR_RTL)
 endif
 endif
 ifdef CHECKDEPEND
 ifdef CHECKDEPEND
-$(PACKAGEDIR_RTL)/$(OS_TARGET)/$(FPCMADE):
-	$(MAKE) -C $(PACKAGEDIR_RTL)/$(OS_TARGET) $(FPCMADE)
-override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(OS_TARGET)/$(FPCMADE)
+$(PACKAGEDIR_RTL)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_RTL) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(FPCMADE)
 endif
 endif
 else
 else
 PACKAGEDIR_RTL=
 PACKAGEDIR_RTL=
@@ -1940,6 +1971,32 @@ ifdef UNITDIR_FCL-JSON
 override COMPILER_UNITDIR+=$(UNITDIR_FCL-JSON)
 override COMPILER_UNITDIR+=$(UNITDIR_FCL-JSON)
 endif
 endif
 endif
 endif
+ifdef REQUIRE_PACKAGES_FCL-PROCESS
+PACKAGEDIR_FCL-PROCESS:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-process/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-PROCESS),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-PROCESS)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-PROCESS) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-PROCESS)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-PROCESS=
+UNITDIR_FCL-PROCESS:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-process/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-PROCESS),)
+UNITDIR_FCL-PROCESS:=$(firstword $(UNITDIR_FCL-PROCESS))
+else
+UNITDIR_FCL-PROCESS=
+endif
+endif
+ifdef UNITDIR_FCL-PROCESS
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-PROCESS)
+endif
+endif
 ifdef REQUIRE_PACKAGES_UNIVINT
 ifdef REQUIRE_PACKAGES_UNIVINT
 PACKAGEDIR_UNIVINT:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /univint/Makefile.fpc,$(PACKAGESDIR))))))
 PACKAGEDIR_UNIVINT:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /univint/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_UNIVINT),)
 ifneq ($(PACKAGEDIR_UNIVINT),)
@@ -2286,9 +2343,6 @@ endif
 ifdef EXEFILES
 ifdef EXEFILES
 override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
 override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
 endif
 endif
-ifdef CLEAN_PROGRAMS
-override CLEANEXEFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(EXEEXT), $(CLEAN_PROGRAMS)))
-endif
 ifdef CLEAN_UNITS
 ifdef CLEAN_UNITS
 override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
 override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
 endif
 endif
@@ -2335,9 +2389,6 @@ endif
 ifdef CLEANRSTFILES
 ifdef CLEANRSTFILES
 	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
 	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
 endif
 endif
-endif
-ifdef CLEAN_FILES
-	-$(DEL) $(CLEAN_FILES)
 endif
 endif
 	-$(DELTREE) units
 	-$(DELTREE) units
 	-$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
 	-$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)

+ 1 - 1
packages/fcl-web/src/jsonrpc/Makefile.fpc

@@ -10,7 +10,7 @@ version=2.5.1
 units=fpjsonrpc  webjsonrpc fpextdirect
 units=fpjsonrpc  webjsonrpc fpextdirect
 
 
 [require]
 [require]
-packages=fcl-base fcl-xml fcl-json
+packages=fcl-base fcl-xml fcl-json fcl-process
 
 
 [compiler]
 [compiler]
 options=-S2h
 options=-S2h

+ 28 - 2
packages/fcl-web/src/jsonrpc/fpextdirect.pp

@@ -34,6 +34,8 @@ Type
     Class Function ParamsProperty : String; override;
     Class Function ParamsProperty : String; override;
     // Add session support
     // Add session support
     Function FindHandler(Const AClassName,AMethodName : TJSONStringType;AContext : TJSONRPCCallContext; Out FreeObject : TComponent) : TCustomJSONRPCHandler; override;
     Function FindHandler(Const AClassName,AMethodName : TJSONStringType;AContext : TJSONRPCCallContext; Out FreeObject : TComponent) : TCustomJSONRPCHandler; override;
+    // Add type field
+    function CreateJSON2Error(Const AMessage : String; Const ACode : Integer; ID : TJSONData = Nil; idname : TJSONStringType = 'id' ) : TJSONObject; override;
     // Create API
     // Create API
     Function DoAPI : TJSONData; virtual;
     Function DoAPI : TJSONData; virtual;
     // Namespace for API description. Must be set. Default 'FPWeb'
     // Namespace for API description. Must be set. Default 'FPWeb'
@@ -92,6 +94,7 @@ Type
   private
   private
     FAPIPath: String;
     FAPIPath: String;
     FDispatcher: TCustomExtDirectDispatcher;
     FDispatcher: TCustomExtDirectDispatcher;
+    FNameSpace: String;
     FOptions: TJSONRPCDispatchOptions;
     FOptions: TJSONRPCDispatchOptions;
     FRequest: TRequest;
     FRequest: TRequest;
     FResponse: TResponse;
     FResponse: TResponse;
@@ -110,6 +113,8 @@ Type
     Property APIPath : String Read FAPIPath Write FAPIPath;
     Property APIPath : String Read FAPIPath Write FAPIPath;
     // Router path/action. Append to baseURL to get router. Default 'router'
     // Router path/action. Append to baseURL to get router. Default 'router'
     Property RouterPath : String Read FRouterPath Write FRouterPath;
     Property RouterPath : String Read FRouterPath Write FRouterPath;
+    // Namespace
+    Property NameSpace : String Read FNameSpace Write FNameSpace;
   Public
   Public
     Constructor CreateNew(AOwner : TComponent; CreateMode : Integer); override;
     Constructor CreateNew(AOwner : TComponent; CreateMode : Integer); override;
     Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); override;
     Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); override;
@@ -125,6 +130,7 @@ Type
     Property DispatchOptions;
     Property DispatchOptions;
     Property APIPath;
     Property APIPath;
     Property RouterPath;
     Property RouterPath;
+    Property NameSpace;
   end;
   end;
 
 
 implementation
 implementation
@@ -193,6 +199,13 @@ begin
   {$ifdef extdebug}SendDebugFmt('Done with searching for %s %s : %d',[AClassName,AMethodName,Ord(Assigned(Result))]);{$endif}
   {$ifdef extdebug}SendDebugFmt('Done with searching for %s %s : %d',[AClassName,AMethodName,Ord(Assigned(Result))]);{$endif}
 end;
 end;
 
 
+function TCustomExtDirectDispatcher.CreateJSON2Error(const AMessage: String;
+  const ACode: Integer; ID: TJSONData; idname: TJSONStringType): TJSONObject;
+begin
+  Result:=inherited CreateJSON2Error(AMessage,ACode,ID,idname);
+  TJSONObject(Result).Add('type','rpc');
+end;
+
 function TCustomExtDirectDispatcher.DoAPI: TJSONData;
 function TCustomExtDirectDispatcher.DoAPI: TJSONData;
 
 
 Var
 Var
@@ -205,6 +218,7 @@ Var
   HD : TJSONRPCHandlerDef;
   HD : TJSONRPCHandlerDef;
 
 
 begin
 begin
+  {$ifdef extdebug}SendDebugFmt('Creating API entries',[]);{$endif}
   D:=TJSONObject.Create;
   D:=TJSONObject.Create;
   try
   try
     D.Add('url',URL);
     D.Add('url',URL);
@@ -234,17 +248,20 @@ begin
       For I:=M.HandlerCount-1 downto 0 do
       For I:=M.HandlerCount-1 downto 0 do
         begin
         begin
         HD:=M.HandlerDefs[i];
         HD:=M.HandlerDefs[i];
+  {$ifdef extdebug}SendDebugFmt('Creating API entry for %s.%s',[HD.HandlerClassName,HD.HandlerMethodName]);{$endif}
         If (R=Nil) or (CompareText(N,HD.HandlerClassName)<>0) then
         If (R=Nil) or (CompareText(N,HD.HandlerClassName)<>0) then
           begin
           begin
+  {$ifdef extdebug}SendDebugFmt('Seems like new action entry : %s<> %s',[HD.HandlerClassName,N]);{$endif}
           N:=HD.HandlerClassName;
           N:=HD.HandlerClassName;
-          J:=A.IndexOf(R);
+          J:=A.IndexOfName(N);
           If (J=-1) then
           If (J=-1) then
             begin
             begin
+  {$ifdef extdebug}SendDebugFmt('Creating new action entry : %s ',[N]);{$endif}
             R:=TJSONArray.Create;
             R:=TJSONArray.Create;
             A.Add(N,R);
             A.Add(N,R);
             end
             end
           else
           else
-            R:=A.Items[i] as TJSONArray;
+            R:=A.Items[J] as TJSONArray;
           end;
           end;
         R.Add(TJSONObject.Create(['name',HD.HandlerMethodName,'len',HD.ArgumentCount]));
         R.Add(TJSONObject.Create(['name',HD.HandlerMethodName,'len',HD.ArgumentCount]));
         end;
         end;
@@ -360,6 +377,7 @@ begin
   E:=TExtDirectDispatcher.Create(Self);
   E:=TExtDirectDispatcher.Create(Self);
   E.Options:=DispatchOptions;
   E.Options:=DispatchOptions;
   E.URL:=IncludeHTTPPathDelimiter(BaseURL)+RouterPath;
   E.URL:=IncludeHTTPPathDelimiter(BaseURL)+RouterPath;
+  E.NameSpace:=NameSpace;
   Result:=E
   Result:=E
 end;
 end;
 
 
@@ -398,8 +416,14 @@ Var
   R : String;
   R : String;
 
 
 begin
 begin
+  {$ifdef extdebug}SendDebug('Ext.Direct handlerequest: checking session');{$endif}
+  CheckSession(ARequest);
+  {$ifdef extdebug}SendDebug('Ext.Direct handlerequest: init session ');{$endif}
+  InitSession(AResponse);
+  {$ifdef extdebug}SendDebug('Ext.Direct creating dispatcher');{$endif}
   If (Dispatcher=Nil) then
   If (Dispatcher=Nil) then
     Dispatcher:=CreateDispatcher;
     Dispatcher:=CreateDispatcher;
+  {$ifdef extdebug}SendDebugFmt('Ext.Direct handlerequest: dispatcher class is "%s"',[Dispatcher.Classname]);{$endif}
   Disp:=Dispatcher as TCustomExtDirectDispatcher;
   Disp:=Dispatcher as TCustomExtDirectDispatcher;
   R:=ARequest.QueryFields.Values['action'];
   R:=ARequest.QueryFields.Values['action'];
   If (R='') then
   If (R='') then
@@ -408,12 +432,14 @@ begin
   If (CompareText(R,APIPath)=0) then
   If (CompareText(R,APIPath)=0) then
     begin
     begin
     CreateAPI(Disp,ARequest,AResponse);
     CreateAPI(Disp,ARequest,AResponse);
+    UpdateSession(AResponse);
     AResponse.SendResponse;
     AResponse.SendResponse;
     end
     end
   else if (CompareText(R,RouterPath)=0) then
   else if (CompareText(R,RouterPath)=0) then
     begin
     begin
     Res:=DispatchRequest(ARequest,Disp);
     Res:=DispatchRequest(ARequest,Disp);
     try
     try
+      UpdateSession(AResponse);
       If Assigned(Res) then
       If Assigned(Res) then
         AResponse.Content:=Res.AsJSON;
         AResponse.Content:=Res.AsJSON;
       AResponse.SendResponse;
       AResponse.SendResponse;

+ 48 - 25
packages/fcl-web/src/jsonrpc/fpjsonrpc.pp

@@ -133,6 +133,7 @@ Type
     FOnStartBatch: TNotifyEvent;
     FOnStartBatch: TNotifyEvent;
     FOptions: TJSONRPCDispatchOptions;
     FOptions: TJSONRPCDispatchOptions;
   Protected
   Protected
+
     // Find handler. If none found, nil is returned. Executes OnFindHandler if needed.
     // Find handler. If none found, nil is returned. Executes OnFindHandler if needed.
     // On return 'DoFree' must be set to indicate that the hand
     // On return 'DoFree' must be set to indicate that the hand
     Function FindHandler(Const AClassName,AMethodName : TJSONStringType;AContext : TJSONRPCCallContext; Out FreeObject : TComponent) : TCustomJSONRPCHandler; virtual;
     Function FindHandler(Const AClassName,AMethodName : TJSONStringType;AContext : TJSONRPCCallContext; Out FreeObject : TComponent) : TCustomJSONRPCHandler; virtual;
@@ -151,6 +152,9 @@ Type
     Function CheckRequests(Requests : TJSONData) : TJSONData; virtual;
     Function CheckRequests(Requests : TJSONData) : TJSONData; virtual;
     // Format result of a single request. Result is returned to the client, possibly in an array if multiple requests were received in batch.
     // Format result of a single request. Result is returned to the client, possibly in an array if multiple requests were received in batch.
     Function FormatResult(const AClassName, AMethodName: TJSONStringType;  const Params, ID, Return: TJSONData) : TJSONData; virtual;
     Function FormatResult(const AClassName, AMethodName: TJSONStringType;  const Params, ID, Return: TJSONData) : TJSONData; virtual;
+    // Format error of a single request.
+    function CreateJSON2Error(Const AMessage : String; Const ACode : Integer; ID : TJSONData = Nil; idname : TJSONStringType = 'id' ) : TJSONObject; virtual;
+    function CreateJSON2Error(Const AFormat : String; Args : Array of const; Const ACode : Integer; ID : TJSONData = Nil; idname : TJSONStringType = 'id') : TJSONObject;
     // Hooks for user.
     // Hooks for user.
     Property OnStartBatch : TNotifyEvent Read FOnStartBatch Write FOnStartBatch;
     Property OnStartBatch : TNotifyEvent Read FOnStartBatch Write FOnStartBatch;
     Property OnDispatchRequest : TDispatchRequestEvent Read FOnDispatchRequest Write FOnDispatchRequest;
     Property OnDispatchRequest : TDispatchRequestEvent Read FOnDispatchRequest Write FOnDispatchRequest;
@@ -352,7 +356,7 @@ implementation
 function CreateJSONErrorObject(Const AMessage : String; Const ACode : Integer) : TJSONObject;
 function CreateJSONErrorObject(Const AMessage : String; Const ACode : Integer) : TJSONObject;
 
 
 begin
 begin
-  Result:=TJSONObject.Create(['code',ACode,'message',AMessage])
+  Result:=TJSONErrorObject.Create(['code',ACode,'message',AMessage])
 end;
 end;
 
 
 function CreateJSON2ErrorResponse(Const AMessage : String; Const ACode : Integer; ID : TJSONData = Nil; idname : TJSONStringType = 'id' ) : TJSONObject;
 function CreateJSON2ErrorResponse(Const AMessage : String; Const ACode : Integer; ID : TJSONData = Nil; idname : TJSONStringType = 'id' ) : TJSONObject;
@@ -414,11 +418,18 @@ end;
 { TJSONParamDef }
 { TJSONParamDef }
 
 
 procedure TJSONParamDef.SetName(const AValue: TJSONStringType);
 procedure TJSONParamDef.SetName(const AValue: TJSONStringType);
+
+Var
+  D: TJSONParamDef;
+
 begin
 begin
   if FName=AValue then exit;
   if FName=AValue then exit;
   If Assigned(Collection) and (Collection is TJSONParamDefs) then
   If Assigned(Collection) and (Collection is TJSONParamDefs) then
-    if (Collection as TJSONParamDefs).FindParamDef(AValue)<>Nil then
+    begin
+    D:=(Collection as TJSONParamDefs).FindParamDef(AValue);
+    If (D<>Nil) and (D<>Self) then
       JSONRPCError(SErrDuplicateParam,[AValue]);
       JSONRPCError(SErrDuplicateParam,[AValue]);
+    end;
   FName:=AValue;
   FName:=AValue;
 end;
 end;
 
 
@@ -572,6 +583,7 @@ end;
 
 
 function TJSONRPCHandler.DoExecute(const Params: TJSONData;AContext : TJSONRPCCallContext): TJSONData;
 function TJSONRPCHandler.DoExecute(const Params: TJSONData;AContext : TJSONRPCCallContext): TJSONData;
 begin
 begin
+  Result:=Nil;
   If Assigned(FOnExecute) then
   If Assigned(FOnExecute) then
     FOnExecute(Self,Params,Result);
     FOnExecute(Self,Params,Result);
 end;
 end;
@@ -646,9 +658,9 @@ begin
   H:=FindHandler(AClassName,AMethodName,AContext,FreeObject);
   H:=FindHandler(AClassName,AMethodName,AContext,FreeObject);
   If (H=Nil) then
   If (H=Nil) then
     if (AClassName='') then
     if (AClassName='') then
-      Exit(CreateJSON2ErrorResponse(SErrInvalidMethodName,[AMethodName],EJSONRPCMethodNotFound,ID.Clone,transactionProperty))
+      Exit(CreateJSON2Error(SErrInvalidMethodName,[AMethodName],EJSONRPCMethodNotFound,ID.Clone,transactionProperty))
     else
     else
-      Exit(CreateJSON2ErrorResponse(SErrInvalidClassMethodName,[AClassName,AMethodName],EJSONRPCMethodNotFound,ID.Clone,transactionProperty));
+      Exit(CreateJSON2Error(SErrInvalidClassMethodName,[AClassName,AMethodName],EJSONRPCMethodNotFound,ID.Clone,transactionProperty));
   try
   try
     If Assigned(FOndispatchRequest) then
     If Assigned(FOndispatchRequest) then
       FOndispatchRequest(Self,AClassName,AMethodName,Params);
       FOndispatchRequest(Self,AClassName,AMethodName,Params);
@@ -668,6 +680,19 @@ begin
     TJSONObject(Result).Add('jsonrpc','2.0');
     TJSONObject(Result).Add('jsonrpc','2.0');
 end;
 end;
 
 
+function TCustomJSONRPCDispatcher.CreateJSON2Error(const AMessage: String;
+  const ACode: Integer; ID: TJSONData; idname: TJSONStringType): TJSONObject;
+begin
+  Result:=CreateJSON2ErrorResponse(AMessage,ACode,ID,IDName);
+end;
+
+function TCustomJSONRPCDispatcher.CreateJSON2Error(const AFormat: String;
+  Args: array of const; const ACode: Integer; ID: TJSONData;
+  idname: TJSONStringType): TJSONObject;
+begin
+  Result:=CreateJSON2Error(Format(AFormat,Args),ACode,ID,IDName);
+end;
+
 function TCustomJSONRPCDispatcher.ExecuteRequest(ARequest: TJSONData;AContext : TJSONRPCCallContext): TJSONData;
 function TCustomJSONRPCDispatcher.ExecuteRequest(ARequest: TJSONData;AContext : TJSONRPCCallContext): TJSONData;
 
 
 Var
 Var
@@ -687,21 +712,19 @@ begin
         begin
         begin
         // No response, and a response was expected.
         // No response, and a response was expected.
         if (ID<>Nil) or not (jdoNotifications in Options) then
         if (ID<>Nil) or not (jdoNotifications in Options) then
-          Result:=CreateJSON2ErrorResponse(SErrNoResponse,[M],EJSONRPCInternalError,ID,transactionProperty);
+          Result:=CreateJSON2Error(SErrNoResponse,[M],EJSONRPCInternalError,ID,transactionProperty);
         end
         end
       else
       else
         begin
         begin
         // A response was received, and no response was expected.
         // A response was received, and no response was expected.
         if ((ID=Nil) or (ID is TJSONNull))  and (jdoStrictNotifications in Options) then
         if ((ID=Nil) or (ID is TJSONNull))  and (jdoStrictNotifications in Options) then
-          Result:=CreateJSON2ErrorResponse(SErrResponseFromNotification,[M],EJSONRPCInternalError,ID,transactionProperty);
+          Result:=CreateJSON2Error(SErrResponseFromNotification,[M],EJSONRPCInternalError,ID,transactionProperty);
         If (ID=Nil) or (ID is TJSONNull) then // Notification method, discard result.
         If (ID=Nil) or (ID is TJSONNull) then // Notification method, discard result.
           FreeAndNil(Result);
           FreeAndNil(Result);
         end;
         end;
       end;
       end;
     If Assigned(Result) and not (Result is TJSONErrorObject) then
     If Assigned(Result) and not (Result is TJSONErrorObject) then
-      begin
-      Result:=FormatResult(C,M,P,ID,Result);
-      end;
+        Result:=FormatResult(C,M,P,ID,Result)
   except
   except
     // Something went really wrong if we end up here.
     // Something went really wrong if we end up here.
     On E : Exception do
     On E : Exception do
@@ -709,9 +732,9 @@ begin
       If (Result<>Nil) then
       If (Result<>Nil) then
         FreeAndNil(Result);
         FreeAndNil(Result);
       If Assigned(ID) then
       If Assigned(ID) then
-        Result:=CreateJSON2ErrorResponse(E.Message,EJSONRPCInternalError,ID.Clone,transactionproperty)
+        Result:=CreateJSON2Error(E.Message,EJSONRPCInternalError,ID.Clone,transactionproperty)
       else
       else
-        Result:=CreateJSON2ErrorResponse(E.Message,EJSONRPCInternalError,Nil,transactionproperty)
+        Result:=CreateJSON2Error(E.Message,EJSONRPCInternalError,Nil,transactionproperty);
       end;
       end;
   end;
   end;
 end;
 end;
@@ -757,7 +780,7 @@ begin
   Params:=Nil;
   Params:=Nil;
   Result:=Nil;
   Result:=Nil;
   If Not (Request is TJSONObject) then
   If Not (Request is TJSONObject) then
-    Exit(CreateJSON2ErrorResponse(SErrRequestMustBeObject,EJSONRPCInvalidRequest,Nil,transactionproperty));
+    Exit(CreateJSON2Error(SErrRequestMustBeObject,EJSONRPCInvalidRequest,Nil,transactionproperty));
   O:=TJSONObject(Request);
   O:=TJSONObject(Request);
   // Get ID object, if it exists.
   // Get ID object, if it exists.
   I:=O.IndexOfName(TransactionProperty);
   I:=O.IndexOfName(TransactionProperty);
@@ -765,31 +788,31 @@ begin
     ID:=O.Items[i];
     ID:=O.Items[i];
   // Check ID
   // Check ID
   If (ID=Nil) and not (jdoNotifications in Options) then
   If (ID=Nil) and not (jdoNotifications in Options) then
-    Exit(CreateJSON2ErrorResponse(SErrNoIDProperty,EJSONRPCInvalidRequest,Nil,transactionproperty));
+    Exit(CreateJSON2Error(SErrNoIDProperty,EJSONRPCInvalidRequest,Nil,transactionproperty));
   OJ2:=(jdoJSONRPC2 in Options) and not (jdoJSONRPC1 in Options);
   OJ2:=(jdoJSONRPC2 in Options) and not (jdoJSONRPC1 in Options);
   If OJ2 then
   If OJ2 then
     begin
     begin
     if Assigned(ID) and not (ID.JSONType in [jtNull,jtString,jtNumber]) then
     if Assigned(ID) and not (ID.JSONType in [jtNull,jtString,jtNumber]) then
-      Exit(CreateJSON2ErrorResponse(SErrINvalidIDProperty,EJSONRPCInvalidRequest,Nil,transactionproperty));
+      Exit(CreateJSON2Error(SErrINvalidIDProperty,EJSONRPCInvalidRequest,Nil,transactionproperty));
     // Check presence and value of jsonrpc property
     // Check presence and value of jsonrpc property
     I:=O.IndexOfName('jsonrpc');
     I:=O.IndexOfName('jsonrpc');
     If (I=-1) then
     If (I=-1) then
-      Exit(CreateJSON2ErrorResponse(SErrNoJSONRPCProperty,EJSONRPCInvalidRequest,ID,transactionproperty));
+      Exit(CreateJSON2Error(SErrNoJSONRPCProperty,EJSONRPCInvalidRequest,ID,transactionproperty));
     If (O.Items[i].JSONType<>jtString) or (O.Items[i].AsString<>'2.0') then
     If (O.Items[i].JSONType<>jtString) or (O.Items[i].AsString<>'2.0') then
-      Exit(CreateJSON2ErrorResponse(SErrInvalidJSONRPCProperty,EJSONRPCInvalidRequest,ID,transactionproperty));
+      Exit(CreateJSON2Error(SErrInvalidJSONRPCProperty,EJSONRPCInvalidRequest,ID,transactionproperty));
     end;
     end;
   // Get method name, if it exists.
   // Get method name, if it exists.
   I:=O.IndexOfName(MethodProperty);
   I:=O.IndexOfName(MethodProperty);
   If (I<>-1) then
   If (I<>-1) then
     D:=O.Items[i]
     D:=O.Items[i]
   else
   else
-    Exit(CreateJSON2ErrorResponse(SErrNoMethodName,[MethodProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
+    Exit(CreateJSON2Error(SErrNoMethodName,[MethodProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
   // Check if it is a string
   // Check if it is a string
   if Not (D is TJSONString) then
   if Not (D is TJSONString) then
-    Exit(CreateJSON2ErrorResponse(SErrInvalidMethodType,[MethodProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
+    Exit(CreateJSON2Error(SErrInvalidMethodType,[MethodProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
   AMethodName:=D.AsString;
   AMethodName:=D.AsString;
   If (AMethodName='') then
   If (AMethodName='') then
-    Exit(CreateJSON2ErrorResponse(SErrNoMethodName,[MethodProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
+    Exit(CreateJSON2Error(SErrNoMethodName,[MethodProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
   // Get class name, if it exists and is required
   // Get class name, if it exists and is required
   If (ClassNameProperty<>'') then
   If (ClassNameProperty<>'') then
     begin
     begin
@@ -797,31 +820,31 @@ begin
     If (I<>-1) then
     If (I<>-1) then
       D:=O.Items[i]
       D:=O.Items[i]
     else if (jdoRequireClass in options) then
     else if (jdoRequireClass in options) then
-      Exit(CreateJSON2ErrorResponse(SErrNoClassName,[ClassNameProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
+      Exit(CreateJSON2Error(SErrNoClassName,[ClassNameProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
     // Check if it is a string
     // Check if it is a string
     if Not (D is TJSONString) then
     if Not (D is TJSONString) then
-      Exit(CreateJSON2ErrorResponse(SErrInvalidClassNameType,[ClassNameProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
+      Exit(CreateJSON2Error(SErrInvalidClassNameType,[ClassNameProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
     AClassName:=D.AsString;
     AClassName:=D.AsString;
     If (AMethodName='') and (jdoRequireClass in options)  then
     If (AMethodName='') and (jdoRequireClass in options)  then
-      Exit(CreateJSON2ErrorResponse(SErrNoClassName,[ClassNameProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
+      Exit(CreateJSON2Error(SErrNoClassName,[ClassNameProperty],EJSONRPCInvalidRequest,ID,transactionproperty));
     end;
     end;
   // Get params, if they exist
   // Get params, if they exist
   I:=O.IndexOfName(ParamsProperty);
   I:=O.IndexOfName(ParamsProperty);
   If (I<>-1) then
   If (I<>-1) then
     D:=O.Items[i]
     D:=O.Items[i]
   else
   else
-    Exit(CreateJSON2ErrorResponse(SErrNoParams,[ParamsProperty],EJSONRPCInvalidParams,ID,transactionproperty));
+    Exit(CreateJSON2Error(SErrNoParams,[ParamsProperty],EJSONRPCInvalidParams,ID,transactionproperty));
   if OJ2 then
   if OJ2 then
     begin
     begin
     // Allow array or object
     // Allow array or object
     If Not (D.JSONType in [jtArray,jtObject]) then
     If Not (D.JSONType in [jtArray,jtObject]) then
-      Exit(CreateJSON2ErrorResponse(SErrParamsMustBeArrayorObject,EJSONRPCInvalidParams,ID,transactionproperty));
+      Exit(CreateJSON2Error(SErrParamsMustBeArrayorObject,EJSONRPCInvalidParams,ID,transactionproperty));
     end
     end
   else if not (jdoJSONRPC2 in Options) then
   else if not (jdoJSONRPC2 in Options) then
     begin
     begin
     // Allow only array
     // Allow only array
     If Not (D.JSONType in [jtArray]) then
     If Not (D.JSONType in [jtArray]) then
-      Exit(CreateJSON2ErrorResponse(SErrParamsMustBeArray,EJSONRPCInvalidParams,ID,transactionproperty));
+      Exit(CreateJSON2Error(SErrParamsMustBeArray,EJSONRPCInvalidParams,ID,transactionproperty));
     end;
     end;
   Params:=D;
   Params:=D;
 end;
 end;

+ 3 - 0
packages/fcl-web/src/webdata/extjsjson.pp

@@ -80,6 +80,9 @@ end;
 function TExtJSJSONDataFormatter.AddFieldToJSON(O : TJSONObject; AFieldName : String; F : TField): TJSONData;
 function TExtJSJSONDataFormatter.AddFieldToJSON(O : TJSONObject; AFieldName : String; F : TField): TJSONData;
 
 
 begin
 begin
+ if F.IsNull then
+   Result:=O.Items[O.Add(AFieldName)]
+ else
   Case F.DataType of
   Case F.DataType of
     ftSmallint,
     ftSmallint,
     ftInteger,
     ftInteger,

+ 26 - 0
packages/fcl-web/src/webdata/sqldbwebdata.pp

@@ -19,13 +19,16 @@ Type
     FIDFieldName: String;
     FIDFieldName: String;
     FOnGetNewID: TNewIDEvent;
     FOnGetNewID: TNewIDEvent;
     FOnGetParamValue: TGetParamValueEvent;
     FOnGetParamValue: TGetParamValueEvent;
+    FParams: TParams;
     FSQLS : Array[0..3] of TStringList;
     FSQLS : Array[0..3] of TStringList;
     FConnection: TSQLConnection;
     FConnection: TSQLConnection;
     FQuery : TSQLQuery;
     FQuery : TSQLQuery;
     FLastNewID : String;
     FLastNewID : String;
     FOnGetParamType : TGetParamTypeEvent;
     FOnGetParamType : TGetParamTypeEvent;
     function GetS(AIndex: integer): TStrings;
     function GetS(AIndex: integer): TStrings;
+    procedure RegenerateParams;
     procedure SetConnection(const AValue: TSQLConnection);
     procedure SetConnection(const AValue: TSQLConnection);
+    procedure SetParams(const AValue: TParams);
     procedure SetS(AIndex: integer; const AValue: TStrings);
     procedure SetS(AIndex: integer; const AValue: TStrings);
   Protected
   Protected
     function CheckDataset : Boolean; virtual;
     function CheckDataset : Boolean; virtual;
@@ -52,6 +55,7 @@ Type
     Property OnGetNewID : TNewIDEvent Read FOnGetNewID Write FOnGetNewID;
     Property OnGetNewID : TNewIDEvent Read FOnGetNewID Write FOnGetNewID;
     property OnGetParameterType : TGetParamTypeEvent Read FOnGetParamType Write FOnGetParamType;
     property OnGetParameterType : TGetParamTypeEvent Read FOnGetParamType Write FOnGetParamType;
     property OnGetParameterValue : TGetParamValueEvent Read FOnGetParamValue Write FOnGetParamValue;
     property OnGetParameterValue : TGetParamValueEvent Read FOnGetParamValue Write FOnGetParamValue;
+    Property Params : TParams Read FParams Write SetParams;
   Public
   Public
     Constructor Create(AOwner : TComponent); override;
     Constructor Create(AOwner : TComponent); override;
     Destructor Destroy; override;
     Destructor Destroy; override;
@@ -69,6 +73,7 @@ Type
     property OnGetParameterType;
     property OnGetParameterType;
     property OnGetParameterValue;
     property OnGetParameterValue;
     Property Options;
     Property Options;
+    Property Params;
   end;
   end;
 
 
 implementation
 implementation
@@ -107,6 +112,12 @@ begin
     FConnection.FreeNotification(Self);
     FConnection.FreeNotification(Self);
 end;
 end;
 
 
+procedure TCustomSQLDBWebDataProvider.SetParams(const AValue: TParams);
+begin
+  if FParams=AValue then exit;
+  FParams.Assign(AValue);
+end;
+
 procedure TCustomSQLDBWebDataProvider.SetS(AIndex: integer;
 procedure TCustomSQLDBWebDataProvider.SetS(AIndex: integer;
   const AValue: TStrings);
   const AValue: TStrings);
 begin
 begin
@@ -119,9 +130,22 @@ begin
     begin
     begin
     FQuery.Close;
     FQuery.Close;
     FQuery.SQL.Assign(SelectSQL);
     FQuery.SQL.Assign(SelectSQL);
+    If Not (csLoading in ComponentState) then
+      RegenerateParams;
     end;
     end;
 end;
 end;
 
 
+procedure TCustomSQLDBWebDataProvider.RegenerateParams;
+
+Var
+  S : String;
+
+begin
+  S:=SelectSQL.Text;
+  Params.Clear;
+  Params.ParseSQL(S,True);
+end;
+
 procedure TCustomSQLDBWebDataProvider.ExecuteSQL(ASQL : TStrings; Msg : String = ''; DoNewID : Boolean = False);
 procedure TCustomSQLDBWebDataProvider.ExecuteSQL(ASQL : TStrings; Msg : String = ''; DoNewID : Boolean = False);
 
 
 Var
 Var
@@ -407,6 +431,7 @@ begin
     L.OnChange:=@SQLChanged;
     L.OnChange:=@SQLChanged;
     FSQLS[i]:=L;
     FSQLS[i]:=L;
     end;
     end;
+  FParams:=TParams.Create(TParam);
 end;
 end;
 
 
 destructor TCustomSQLDBWebDataProvider.Destroy;
 destructor TCustomSQLDBWebDataProvider.Destroy;
@@ -419,6 +444,7 @@ begin
    FreeAndNil(FSQLS[i]);
    FreeAndNil(FSQLS[i]);
   Connection:=Nil;
   Connection:=Nil;
   FreeAndNil(FQuery);
   FreeAndNil(FQuery);
+  FreeAndNil(FParams);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 

+ 1 - 1
packages/fpvectorial/Makefile.fpc

@@ -15,7 +15,7 @@ units=fpvectbuildunit
 exampledirs=
 exampledirs=
 implicitunits= avisocncgcodereader avisocncgcodewriter avisozlib fpvectorial \
 implicitunits= avisocncgcodereader avisocncgcodewriter avisozlib fpvectorial \
 	       fpvtocanvas  pdfvectorialreader pdfvrlexico pdfvrsemantico \
 	       fpvtocanvas  pdfvectorialreader pdfvrlexico pdfvrsemantico \
-	       pdfvrsintatico
+	       pdfvrsintatico cdrvectorialreader svgvectorialwriter
 
 
 [compiler]
 [compiler]
 includedir=src
 includedir=src

+ 80 - 0
packages/fpvectorial/examples/cdr2svg_mainform.lfm

@@ -0,0 +1,80 @@
+object Form1: TForm1
+  Left = 216
+  Height = 240
+  Top = 192
+  Width = 240
+  Caption = 'cdr2svg'
+  ClientHeight = 240
+  ClientWidth = 240
+  LCLVersion = '0.9.29'
+  object Label1: TLabel
+    Left = 8
+    Height = 14
+    Top = 80
+    Width = 215
+    Caption = 'Location of the Input Corel Draw (*.cdr) file:'
+    ParentColor = False
+  end
+  object Label2: TLabel
+    Left = 8
+    Height = 59
+    Top = 8
+    Width = 224
+    AutoSize = False
+    Caption = 'This example project uses fpvectorial to convert a Corel Draw file (*.cdr) to an SVG (*.svg) vectorial graphics file.'
+    ParentColor = False
+    WordWrap = True
+  end
+  object editInput: TFileNameEdit
+    Left = 8
+    Height = 21
+    Top = 104
+    Width = 192
+    DialogOptions = []
+    FilterIndex = 0
+    HideDirectories = False
+    ButtonWidth = 23
+    NumGlyphs = 0
+    MaxLength = 0
+    TabOrder = 0
+  end
+  object Label3: TLabel
+    Left = 8
+    Height = 14
+    Top = 138
+    Width = 154
+    Caption = 'Full path of the Output SVG file:'
+    ParentColor = False
+  end
+  object editOutput: TFileNameEdit
+    Left = 8
+    Height = 21
+    Top = 160
+    Width = 192
+    DialogOptions = []
+    FilterIndex = 0
+    HideDirectories = False
+    ButtonWidth = 23
+    NumGlyphs = 0
+    MaxLength = 0
+    TabOrder = 1
+  end
+  object buttonConvert: TButton
+    Left = 32
+    Height = 25
+    Top = 200
+    Width = 75
+    Caption = 'Convert'
+    OnClick = buttonConvertClick
+    TabOrder = 2
+  end
+  object buttonQuit: TButton
+    Left = 136
+    Height = 25
+    Top = 200
+    Width = 75
+    Caption = 'Quit'
+    OnClick = buttonQuitClick
+    TabOrder = 3
+  end
+end

+ 66 - 0
packages/fpvectorial/examples/cdr2svg_mainform.pas

@@ -0,0 +1,66 @@
+unit cdr2svg_mainform;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  EditBtn;
+
+type
+
+  { TForm1 }
+
+  TForm1 = class(TForm)
+    buttonConvert: TButton;
+    buttonQuit: TButton;
+    editInput: TFileNameEdit;
+    editOutput: TFileNameEdit;
+    Label1: TLabel;
+    Label2: TLabel;
+    Label3: TLabel;
+    procedure buttonConvertClick(Sender: TObject);
+    procedure buttonQuitClick(Sender: TObject);
+  private
+    { private declarations }
+  public
+    { public declarations }
+  end; 
+
+var
+  Form1: TForm1; 
+
+implementation
+
+uses
+  fpvectorial, cdrvectorialreader, svgvectorialwriter;
+
+{$R *.lfm}
+
+{ TForm1 }
+
+procedure TForm1.buttonQuitClick(Sender: TObject);
+begin
+  Close;
+end;
+
+procedure TForm1.buttonConvertClick(Sender: TObject);
+var
+  Vec: TvVectorialDocument;
+begin
+  // First check the in input
+  // todo...
+
+  // Now convert
+  Vec := TvVectorialDocument.Create;
+  try
+    Vec.ReadFromFile(editInput.FileName, vfPDF);
+    Vec.WriteToFile(editOutPut.FileName, vfGCodeAvisoCNCPrototipoV5);
+  finally
+    Vec.Free;
+  end;
+end;
+
+end.
+

BIN
packages/fpvectorial/examples/cdr2svg_visual.ico


+ 85 - 0
packages/fpvectorial/examples/cdr2svg_visual.lpi

@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="cdr2svg_visual"/>
+      <UseXPManifest Value="True"/>
+      <Icon Value="0"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="LCL"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="cdr2svg_visual.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="cdr2svg_visual"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="cdr2svg_mainform.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="Form1"/>
+        <ResourceBaseClass Value="Form"/>
+        <UnitName Value="cdr2svg_mainform"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <Target>
+      <Filename Value="cdr2svg_visual"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)\"/>
+      <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <Win32>
+          <GraphicApplication Value="True"/>
+        </Win32>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 20 - 0
packages/fpvectorial/examples/cdr2svg_visual.lpr

@@ -0,0 +1,20 @@
+program cdr2svg_visual;
+
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}{$IFDEF UseCThreads}
+  cthreads,
+  {$ENDIF}{$ENDIF}
+  Interfaces, // this includes the LCL widgetset
+  Forms, cdr2svg_mainform
+  { you can add units after this };
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.CreateForm(TForm1, Form1);
+  Application.Run;
+end.
+

+ 54 - 0
packages/fpvectorial/examples/fpce_mainform.lfm

@@ -0,0 +1,54 @@
+object formCorelExplorer: TformCorelExplorer
+  Left = 216
+  Height = 345
+  Top = 192
+  Width = 466
+  Caption = 'FP Corel Explorer'
+  ClientHeight = 345
+  ClientWidth = 466
+  LCLVersion = '0.9.29'
+  object Label1: TLabel
+    Left = 8
+    Height = 14
+    Top = 40
+    Width = 123
+    Caption = 'Location of the Input file:'
+    ParentColor = False
+  end
+  object Label2: TLabel
+    Left = 8
+    Height = 32
+    Top = 8
+    Width = 224
+    AutoSize = False
+    Caption = 'This application helps us explore the internal structure of Corel Draw files (*.cdr).'
+    ParentColor = False
+    WordWrap = True
+  end
+  object shellInput: TShellTreeView
+    Left = 8
+    Height = 272
+    Top = 64
+    Width = 224
+    FileSortType = fstFoldersFirst
+    TabOrder = 0
+    OnSelectionChanged = shellInputSelectionChanged
+    ObjectTypes = [otFolders, otNonFolders]
+  end
+  object labelFilename: TLabel
+    Left = 256
+    Height = 14
+    Top = 65
+    Width = 47
+    Caption = 'Filename:'
+    ParentColor = False
+  end
+  object labelVersion: TLabel
+    Left = 256
+    Height = 14
+    Top = 88
+    Width = 40
+    Caption = 'Version:'
+    ParentColor = False
+  end
+end

+ 85 - 0
packages/fpvectorial/examples/fpce_mainform.pas

@@ -0,0 +1,85 @@
+unit fpce_mainform;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  EditBtn, ExtCtrls, ComCtrls, ShellCtrls;
+
+type
+
+  { TformCorelExplorer }
+
+  TformCorelExplorer = class(TForm)
+    Label1: TLabel;
+    Label2: TLabel;
+    labelVersion: TLabel;
+    labelFilename: TLabel;
+    shellInput: TShellTreeView;
+    procedure buttonQuitClick(Sender: TObject);
+    procedure shellInputSelectionChanged(Sender: TObject);
+  private
+    { private declarations }
+    function CheckInput(): Boolean;
+  public
+    { public declarations }
+  end; 
+
+var
+  formCorelExplorer: TformCorelExplorer;
+
+implementation
+
+uses
+  fpvectorial, cdrvectorialreader, svgvectorialwriter, pdfvectorialreader,
+  fpvtocanvas;
+
+{$R *.lfm}
+
+{ TformCorelExplorer }
+
+procedure TformCorelExplorer.buttonQuitClick(Sender: TObject);
+begin
+  Close;
+end;
+
+procedure TformCorelExplorer.shellInputSelectionChanged(Sender: TObject);
+var
+  Vec: TvVectorialDocument;
+  Reader: TvCDRVectorialReader;
+  lFormat: TvVectorialFormat;
+  lChunk, lCurChunk: TCDRChunk;
+  Str: string;
+begin
+  // First check the in input
+  if not CheckInput() then Exit;
+
+  // Now read the data from the input file
+  Reader := TvCDRVectorialReader.Create;
+  try
+    Reader.ExploreFromFile(shellInput.GetSelectedNodePath(), lChunk);
+
+    labelFilename.Caption := 'Filename: ' + shellInput.GetSelectedNodePath();
+    if (lChunk.ChildChunks <> nil) and (lChunk.ChildChunks.First <> nil) then
+    begin
+      lCurChunk := TCDRChunk(lChunk.ChildChunks.First);
+      Str := TCDRChunkVRSN(lCurChunk).VersionStr;
+      labelVersion.Caption := 'Version: ' + Str;
+    end;
+  finally
+    Reader.Free;
+  end;
+end;
+
+function TformCorelExplorer.CheckInput(): Boolean;
+var
+  lPath: String;
+begin
+  lPath := shellInput.GetSelectedNodePath();
+  Result := (ExtractFileExt(lPath) = STR_CORELDRAW_EXTENSION);
+end;
+
+end.
+

BIN
packages/fpvectorial/examples/fpcorelexplorer.ico


+ 91 - 0
packages/fpvectorial/examples/fpcorelexplorer.lpi

@@ -0,0 +1,91 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <AlwaysBuild Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="fpcorelexplorer"/>
+      <UseXPManifest Value="True"/>
+      <Icon Value="0"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="LCL"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="fpcorelexplorer.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fpcorelexplorer"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="fpce_mainform.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="formCorelExplorer"/>
+        <ResourceBaseClass Value="Form"/>
+        <UnitName Value="fpce_mainform"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <Target>
+      <Filename Value="fpcorelexplorer"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)\"/>
+      <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <Win32>
+          <GraphicApplication Value="True"/>
+        </Win32>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="4">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+      <Item4>
+        <Name Value="EConvertError"/>
+      </Item4>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 20 - 0
packages/fpvectorial/examples/fpcorelexplorer.lpr

@@ -0,0 +1,20 @@
+program fpcorelexplorer;
+
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}{$IFDEF UseCThreads}
+  cthreads,
+  {$ENDIF}{$ENDIF}
+  Interfaces, // this includes the LCL widgetset
+  Forms, fpce_mainform
+  { you can add units after this };
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.CreateForm(TformCorelExplorer, formCorelExplorer);
+  Application.Run;
+end.
+

+ 96 - 0
packages/fpvectorial/examples/fpvc_mainform.lfm

@@ -0,0 +1,96 @@
+object formVectorialConverter: TformVectorialConverter
+  Left = 216
+  Height = 439
+  Top = 192
+  Width = 240
+  BorderStyle = bsSingle
+  Caption = 'FP Vectorial Converter'
+  ClientHeight = 439
+  ClientWidth = 240
+  LCLVersion = '0.9.29'
+  object Label1: TLabel
+    Left = 8
+    Height = 14
+    Top = 104
+    Width = 123
+    Caption = 'Location of the Input file:'
+    ParentColor = False
+  end
+  object Label2: TLabel
+    Left = 11
+    Height = 96
+    Top = 8
+    Width = 224
+    AutoSize = False
+    Caption = 'This converter application use the fpvectorial library to convert between various different vectorial graphics formats. The type is detected from the extension and the supported types are: PDF (*.pdf), SVG (*.svg) and Corel Draw file (*.cdr).'
+    ParentColor = False
+    WordWrap = True
+  end
+  object editInput: TFileNameEdit
+    Left = 8
+    Height = 21
+    Top = 120
+    Width = 192
+    DialogOptions = []
+    FilterIndex = 0
+    HideDirectories = False
+    ButtonWidth = 23
+    NumGlyphs = 0
+    MaxLength = 0
+    TabOrder = 0
+  end
+  object Label3: TLabel
+    Left = 8
+    Height = 14
+    Top = 144
+    Width = 132
+    Caption = 'Full path of the Output file:'
+    ParentColor = False
+  end
+  object editOutput: TFileNameEdit
+    Left = 8
+    Height = 21
+    Top = 160
+    Width = 192
+    DialogOptions = []
+    FilterIndex = 0
+    HideDirectories = False
+    ButtonWidth = 23
+    NumGlyphs = 0
+    MaxLength = 0
+    TabOrder = 1
+  end
+  object buttonConvert: TButton
+    Left = 87
+    Height = 25
+    Top = 192
+    Width = 67
+    Caption = 'Convert'
+    OnClick = buttonConvertClick
+    TabOrder = 2
+  end
+  object buttonQuit: TButton
+    Left = 176
+    Height = 25
+    Top = 192
+    Width = 59
+    Caption = 'Quit'
+    OnClick = buttonQuitClick
+    TabOrder = 3
+  end
+  object imagePreview: TImage
+    Left = 8
+    Height = 210
+    Top = 224
+    Width = 224
+  end
+  object buttonVisualize: TButton
+    Left = 8
+    Height = 25
+    Top = 192
+    Width = 59
+    Caption = 'Visualize'
+    OnClick = buttonVisualizeClick
+    TabOrder = 4
+  end
+end

+ 97 - 0
packages/fpvectorial/examples/fpvc_mainform.pas

@@ -0,0 +1,97 @@
+unit fpvc_mainform;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  EditBtn, ExtCtrls;
+
+type
+
+  { TformVectorialConverter }
+
+  TformVectorialConverter = class(TForm)
+    buttonVisualize: TButton;
+    buttonConvert: TButton;
+    buttonQuit: TButton;
+    editInput: TFileNameEdit;
+    editOutput: TFileNameEdit;
+    imagePreview: TImage;
+    Label1: TLabel;
+    Label2: TLabel;
+    Label3: TLabel;
+    procedure buttonConvertClick(Sender: TObject);
+    procedure buttonQuitClick(Sender: TObject);
+    procedure buttonVisualizeClick(Sender: TObject);
+  private
+    { private declarations }
+    function CheckInput(): Boolean;
+  public
+    { public declarations }
+  end; 
+
+var
+  formVectorialConverter: TformVectorialConverter;
+
+implementation
+
+uses
+  fpvectorial, cdrvectorialreader, svgvectorialwriter, pdfvectorialreader,
+  fpvtocanvas;
+
+{$R *.lfm}
+
+{ TformVectorialConverter }
+
+procedure TformVectorialConverter.buttonQuitClick(Sender: TObject);
+begin
+  Close;
+end;
+
+procedure TformVectorialConverter.buttonVisualizeClick(Sender: TObject);
+var
+  Vec: TvVectorialDocument;
+begin
+  // First check the in input
+  if not CheckInput() then Exit;
+
+  Vec := TvVectorialDocument.Create;
+  try
+    Vec.ReadFromFile(editInput.FileName, vfPDF);
+    imagePreview.Canvas.Brush.Color := clWhite;
+    imagePreview.Canvas.FillRect(0, 0, imagePreview.Width, imagePreview.Height);
+    DrawFPVectorialToCanvas(Vec, imagePreview.Canvas);
+  finally
+    Vec.Free;
+  end;
+end;
+
+function TformVectorialConverter.CheckInput(): Boolean;
+begin
+  // todo...
+end;
+
+procedure TformVectorialConverter.buttonConvertClick(Sender: TObject);
+var
+  Vec: TvVectorialDocument;
+  lFormat: TvVectorialFormat;
+begin
+  // First check the in input
+  if not CheckInput() then Exit;
+
+  // Now convert
+  Vec := TvVectorialDocument.Create;
+  try
+    lFormat := TvVectorialDocument.GetFormatFromExtension(editInput.FileName);
+    Vec.ReadFromFile(editInput.FileName, lFormat);
+    lFormat := TvVectorialDocument.GetFormatFromExtension(editOutPut.FileName);
+    Vec.WriteToFile(editOutPut.FileName, lFormat);
+  finally
+    Vec.Free;
+  end;
+end;
+
+end.
+

BIN
packages/fpvectorial/examples/fpvectorialconverter.ico


+ 91 - 0
packages/fpvectorial/examples/fpvectorialconverter.lpi

@@ -0,0 +1,91 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <AlwaysBuild Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="fpvectorialconverter"/>
+      <UseXPManifest Value="True"/>
+      <Icon Value="0"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="LCL"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="fpvectorialconverter.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fpvectorialconverter"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="fpvc_mainform.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="formVectorialConverter"/>
+        <ResourceBaseClass Value="Form"/>
+        <UnitName Value="fpvc_mainform"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <Target>
+      <Filename Value="fpvectorialconverter"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)\"/>
+      <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <Win32>
+          <GraphicApplication Value="True"/>
+        </Win32>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="4">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+      <Item4>
+        <Name Value="EConvertError"/>
+      </Item4>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 20 - 0
packages/fpvectorial/examples/fpvectorialconverter.lpr

@@ -0,0 +1,20 @@
+program fpvectorialconverter;
+
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}{$IFDEF UseCThreads}
+  cthreads,
+  {$ENDIF}{$ENDIF}
+  Interfaces, // this includes the LCL widgetset
+  Forms, fpvc_mainform
+  { you can add units after this };
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.CreateForm(TformVectorialConverter, formVectorialConverter);
+  Application.Run;
+end.
+

+ 180 - 0
packages/fpvectorial/src/cdrvectorialreader.pas

@@ -0,0 +1,180 @@
+{
+cdrvectorialreader.pas
+
+Reads a Corel Draw vectorial file
+
+CDR file format specification obtained from:
+
+ADOBE SYSTEMS INCORPORATED. PDF Reference: Adobe®
+Portable Document Format. San Jose, 2006. (Sixth edition).
+
+AUTHORS: Felipe Monteiro de Carvalho
+
+License: The same modified LGPL as the Free Pascal RTL
+         See the file COPYING.modifiedLGPL for more details
+}
+unit cdrvectorialreader;
+
+{$ifdef fpc}
+  {$mode delphi}
+{$endif}
+
+interface
+
+uses
+  Classes, SysUtils,
+  pdfvrlexico, pdfvrsintatico, pdfvrsemantico, avisozlib,
+  fpvectorial;
+
+type
+
+  TCDRChunk = class
+    Name: array[0..3] of Char;
+    Size: Cardinal;
+    ChildChunks: TFPList;
+  end;
+
+  TCDRChunkClass = class of TCDRChunk;
+
+  TvCDRInternalData = TCDRChunk;
+
+  TCDRChunkVRSN = class(TCDRChunk)
+    VersionStr: string;
+    VersionNum: Integer;
+  end;
+
+  { TvCDRVectorialReader }
+
+  TvCDRVectorialReader = class(TvCustomVectorialReader)
+  private
+    procedure ReadVersionChunk(AStream: TStream; var AData: TCDRChunk);
+    function AddNewChunk(var AData: TCDRChunk; AClass: TCDRChunkClass): TCDRChunk;
+  public
+    { General reading methods }
+    procedure ReadFromStream(AStream: TStream; AData: TvVectorialDocument); override;
+    { File format exploring methods }
+    procedure ExploreFromFile(AFilename: string; out AData: TvCDRInternalData);
+    procedure ExploreFromStream(AStream: TStream; out AData: TvCDRInternalData);
+  end;
+
+implementation
+
+{ TvPDFVectorialReader }
+
+procedure TvCDRVectorialReader.ReadVersionChunk(AStream: TStream;
+  var AData: TCDRChunk);
+var
+  lDWord: DWord;
+  lChunk: TCDRChunkVRSN absolute AData;
+  lVerBytes: array[0..1] of Byte;
+begin
+  // Read the Chunk name
+  lDWord := AStream.ReadDWord();
+
+  // Read the Chunk size
+  lDWord := AStream.ReadDWord();
+
+  // Read the version
+  AStream.Read(lVerBytes, 2);
+
+  if (lVerBytes[0] = $BC) and (lVerBytes[1] = $02) then
+  begin
+    lChunk.VersionNum := 7;
+    lChunk.VersionStr := 'CorelDraw 7';
+  end
+  else if (lVerBytes[0] = $20) and (lVerBytes[1] = $03) then
+  begin
+    lChunk.VersionNum := 8;
+    lChunk.VersionStr := 'CorelDraw 8';
+  end
+  else if (lVerBytes[0] = $21) and (lVerBytes[1] = $03) then
+  begin
+    lChunk.VersionNum := 8;
+    lChunk.VersionStr := 'CorelDraw 8bidi';
+  end
+  else if (lVerBytes[0] = $84) and (lVerBytes[1] = $03) then
+  begin
+    lChunk.VersionNum := 9;
+    lChunk.VersionStr := 'CorelDraw 9';
+  end
+  else if (lVerBytes[0] = $E8) and (lVerBytes[1] = $03) then
+  begin
+    lChunk.VersionNum := 10;
+    lChunk.VersionStr := 'CorelDraw 10';
+  end
+  else if (lVerBytes[0] = $4C) and (lVerBytes[1] = $04) then
+  begin
+    lChunk.VersionNum := 11;
+    lChunk.VersionStr := 'CorelDraw 11';
+  end
+  else if (lVerBytes[0] = $B0) and (lVerBytes[1] = $04) then
+  begin
+    lChunk.VersionNum := 12;
+    lChunk.VersionStr := 'CorelDraw 12';
+  end
+  else if (lVerBytes[0] = $14) and (lVerBytes[1] = $05) then
+  begin
+    lChunk.VersionNum := 13;
+    lChunk.VersionStr := 'CorelDraw X3';
+  end;
+end;
+
+function TvCDRVectorialReader.AddNewChunk(var AData: TCDRChunk; AClass: TCDRChunkClass): TCDRChunk;
+begin
+  if AData.ChildChunks = nil then AData.ChildChunks := TFPList.Create;
+
+  Result := AClass.Create;
+
+  AData.ChildChunks.Add(Result);
+end;
+
+procedure TvCDRVectorialReader.ReadFromStream(AStream: TStream;
+  AData: TvVectorialDocument);
+begin
+end;
+
+procedure TvCDRVectorialReader.ExploreFromFile(AFilename: string;
+  out AData: TvCDRInternalData);
+var
+  FileStream: TFileStream;
+begin
+  FileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
+  try
+    ExploreFromStream(FileStream, AData);
+  finally
+    FileStream.Free;
+  end;
+end;
+
+procedure TvCDRVectorialReader.ExploreFromStream(AStream: TStream;
+  out AData: TvCDRInternalData);
+var
+  lRIFF: array[0..3] of Char;
+  lDocSize, lDWord: Cardinal;
+  lChild: TCDRChunk;
+begin
+  // Create the data object
+  AData := TCDRChunk.Create;
+
+  // All CorelDraw files starts with "RIFF"
+  AStream.Read(lRIFF, 4);
+  if lRIFF <> 'RIFF' then
+    raise Exception.Create('[TvCDRVectorialReader.ExploreFromStream] The Corel Draw RIFF file marker wasn''t found.');
+
+  // And then 4 bytes for the document size
+  lDocSize := AStream.ReadDWord();
+
+  // And mroe 4 bytes of other stuff
+  lDWord := AStream.ReadDWord();
+
+  // Now comes the version
+  lChild := AddNewChunk(AData, TCDRChunkVRSN);
+  ReadVersionChunk(AStream, lChild);
+end;
+
+initialization
+
+  RegisterVectorialReader(TvCDRVectorialReader, vfCorelDrawCDR);
+
+end.
+

+ 44 - 1
packages/fpvectorial/src/fpvectorial.pas

@@ -31,13 +31,23 @@ type
 
 
 const
 const
   { Default extensions }
   { Default extensions }
+  { Multi-purpose document formats }
   STR_PDF_EXTENSION = '.pdf';
   STR_PDF_EXTENSION = '.pdf';
+  STR_POSTSCRIPT_EXTENSION = '.ps';
+  STR_SVG_EXTENSION = '.svg';
+  STR_CORELDRAW_EXTENSION = '.cdr';
+  STR_WINMETAFILE_EXTENSION = '.wmf';
 
 
 type
 type
   TSegmentType = (
   TSegmentType = (
     st2DLine, st2DBezier,
     st2DLine, st2DBezier,
     st3DLine, st3DBezier);
     st3DLine, st3DBezier);
 
 
+  {@@
+    The coordinates in fpvectorial are given in millimiters and
+    the starting point is in the bottom-left corner of the document.
+    The X grows to the right and the Y grows to the top.
+  }
   TPathSegment = record
   TPathSegment = record
     SegmentType: TSegmentType;
     SegmentType: TSegmentType;
     X, Y, Z: Double; // Z is ignored in 2D segments
     X, Y, Z: Double; // Z is ignored in 2D segments
@@ -79,6 +89,8 @@ type
     procedure ReadFromFile(AFileName: string; AFormat: TvVectorialFormat);
     procedure ReadFromFile(AFileName: string; AFormat: TvVectorialFormat);
     procedure ReadFromStream(AStream: TStream; AFormat: TvVectorialFormat);
     procedure ReadFromStream(AStream: TStream; AFormat: TvVectorialFormat);
     procedure ReadFromStrings(AStrings: TStrings; AFormat: TvVectorialFormat);
     procedure ReadFromStrings(AStrings: TStrings; AFormat: TvVectorialFormat);
+    class function GetFormatFromExtension(AFileName: string): TvVectorialFormat;
+    function  GetDetailedFileFormat(): string;
     { Data reading methods }
     { Data reading methods }
     function  GetPath(ANum: Cardinal): TPath;
     function  GetPath(ANum: Cardinal): TPath;
     function  GetPathCount: Integer;
     function  GetPathCount: Integer;
@@ -522,6 +534,26 @@ begin
   end;
   end;
 end;
 end;
 
 
+class function TvVectorialDocument.GetFormatFromExtension(AFileName: string
+  ): TvVectorialFormat;
+var
+  lExt: string;
+begin
+  lExt := ExtractFileExt(AFileName);
+  if AnsiCompareText(lExt, STR_PDF_EXTENSION) = 0 then Result := vfPDF
+  else if AnsiCompareText(lExt, STR_POSTSCRIPT_EXTENSION) = 0 then Result := vfPostScript
+  else if AnsiCompareText(lExt, STR_SVG_EXTENSION) = 0 then Result := vfSVG
+  else if AnsiCompareText(lExt, STR_CORELDRAW_EXTENSION) = 0 then Result := vfCorelDrawCDR
+  else if AnsiCompareText(lExt, STR_WINMETAFILE_EXTENSION) = 0 then Result := vfWindowsMetafileWMF
+  else
+    raise Exception.Create('TvVectorialDocument.GetFormatFromExtension: The extension (' + lExt + ') doesn''t match any supported formats.');
+end;
+
+function  TvVectorialDocument.GetDetailedFileFormat(): string;
+begin
+
+end;
+
 function TvVectorialDocument.GetPath(ANum: Cardinal): TPath;
 function TvVectorialDocument.GetPath(ANum: Cardinal): TPath;
 begin
 begin
   if ANum >= FPaths.Count then raise Exception.Create('TvVectorialDocument.GetPath: Path number out of bounds');
   if ANum >= FPaths.Count then raise Exception.Create('TvVectorialDocument.GetPath: Path number out of bounds');
@@ -617,10 +649,21 @@ begin
   end;
   end;
 end;
 end;
 
 
+{@@
+  The default stream writer just uses WriteToStrings
+}
 procedure TvCustomVectorialWriter.WriteToStream(AStream: TStream;
 procedure TvCustomVectorialWriter.WriteToStream(AStream: TStream;
   AData: TvVectorialDocument);
   AData: TvVectorialDocument);
+var
+  lStringList: TStringList;
 begin
 begin
-
+  lStringList := TStringList.Create;
+  try
+    WriteToStrings(lStringList, AData);
+    lStringList.SaveToStream(AStream);
+  finally
+    lStringList.Free;
+  end;
 end;
 end;
 
 
 procedure TvCustomVectorialWriter.WriteToStrings(AStrings: TStrings;
 procedure TvCustomVectorialWriter.WriteToStrings(AStrings: TStrings;

+ 20 - 6
packages/fpvectorial/src/fpvtocanvas.pas

@@ -10,12 +10,26 @@ uses
   fpvectorial;
   fpvectorial;
 
 
 procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas;
 procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas;
-  ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Integer = 1; AMulY: Integer = 1);
+  ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
 
 
 implementation
 implementation
 
 
+{@@
+  This function draws a FPVectorial vectorial image to a TFPCustomCanvas
+  descendent, such as TCanvas from the LCL.
+
+  Be careful that by default this routine does not execute coordinate transformations,
+  and that FPVectorial works with a start point in the bottom-left corner, with
+  the X growing to the right and the Y growing to the top. This will result in
+  an image in TFPCustomCanvas mirrored in the Y axis in relation with the document
+  as seen in a PDF viewer, for example. This can be easily changed with the
+  provided parameters. To have the standard view of an image viewer one could
+  use this function like this:
+
+  DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
+}
 procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas;
 procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas;
-  ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Integer = 1; AMulY: Integer = 1);
+  ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
 var
 var
   i, j, k: Integer;
   i, j, k: Integer;
   PosX, PosY: Integer; // Not modified by ADestX, etc
   PosX, PosY: Integer; // Not modified by ADestX, etc
@@ -47,8 +61,8 @@ begin
         PosX := Round(CurSegment.X);
         PosX := Round(CurSegment.X);
         PosY := Round(CurSegment.Y);
         PosY := Round(CurSegment.Y);
         ADest.LineTo(
         ADest.LineTo(
-          ADestX + AMulX * PosX,
-          ADestY + AMulY * PosY
+          Round(ADestX + AMulX * PosX),
+          Round(ADestY + AMulY * PosY)
           );
           );
       end;
       end;
       { To draw a bezier we need to divide the interval in parts and make
       { To draw a bezier we need to divide the interval in parts and make
@@ -66,8 +80,8 @@ begin
           CurX := Round(sqr(1 - t) * (1 - t) * PosX + 3 * t * sqr(1 - t) * CurSegment.X2 + 3 * t * t * (1 - t) * CurSegment.X3 + t * t * t * CurSegment.X);
           CurX := Round(sqr(1 - t) * (1 - t) * PosX + 3 * t * sqr(1 - t) * CurSegment.X2 + 3 * t * t * (1 - t) * CurSegment.X3 + t * t * t * CurSegment.X);
           CurY := Round(sqr(1 - t) * (1 - t) * PosY + 3 * t * sqr(1 - t) * CurSegment.Y2 + 3 * t * t * (1 - t) * CurSegment.Y3 + t * t * t * CurSegment.Y);
           CurY := Round(sqr(1 - t) * (1 - t) * PosY + 3 * t * sqr(1 - t) * CurSegment.Y2 + 3 * t * t * (1 - t) * CurSegment.Y3 + t * t * t * CurSegment.Y);
           ADest.LineTo(
           ADest.LineTo(
-            ADestX + AMulX * CurX,
-            ADestY + AMulY * CurY);
+            Round(ADestX + AMulX * CurX),
+            Round(ADestY + AMulY * CurY));
         end;
         end;
         PosX := Round(CurSegment.X);
         PosX := Round(CurSegment.X);
         PosY := Round(CurSegment.Y);
         PosY := Round(CurSegment.Y);

+ 38 - 15
packages/fpvectorial/src/pdfvrsemantico.pas

@@ -8,11 +8,16 @@ uses
   Classes, SysUtils, pdfvrlexico, fpvectorial;
   Classes, SysUtils, pdfvrlexico, fpvectorial;
 
 
 type
 type
+
+  { AnSemantico }
+
   AnSemantico = class
   AnSemantico = class
   public
   public
+    FPointSeparator, FCommaSeparator: TFormatSettings;
     close_path_x: String;
     close_path_x: String;
     close_path_y: String;
     close_path_y: String;
     cm_a, cm_b, cm_c, cm_d, cm_e, cm_f: Real; // coordinate spaces constants
     cm_a, cm_b, cm_c, cm_d, cm_e, cm_f: Real; // coordinate spaces constants
+    function StringToFloat(AStr: string): Double;
     function generate(c: Command; AData: TvVectorialDocument): String;
     function generate(c: Command; AData: TvVectorialDocument): String;
     function convert(x: String; y: String; Axis: Char): String;
     function convert(x: String; y: String; Axis: Char): String;
     function startMachine(): String;
     function startMachine(): String;
@@ -22,6 +27,14 @@ type
 
 
 implementation
 implementation
 
 
+{ PDF doesn't seam very consistent when it comes to using commas or
+  points as decimal separator, so we just try both }
+function AnSemantico.StringToFloat(AStr: string): Double;
+begin
+  if Pos('.', AStr) > 0 then Result := StrToFloat(AStr, FPointSeparator)
+  else Result := StrToFloat(AStr, FCommaSeparator);
+end;
+
 function AnSemantico.generate(c: Command; AData: TvVectorialDocument): String;
 function AnSemantico.generate(c: Command; AData: TvVectorialDocument): String;
 var
 var
   enter_line : String;
   enter_line : String;
@@ -29,6 +42,7 @@ begin
   {$ifdef FPVECTORIALDEBUG}
   {$ifdef FPVECTORIALDEBUG}
   WriteLn(':> AnSemantico.generate');
   WriteLn(':> AnSemantico.generate');
   {$endif}
   {$endif}
+
   enter_line:= LineEnding; //chr(13) + chr(10); // CR and LF
   enter_line:= LineEnding; //chr(13) + chr(10); // CR and LF
 
 
   if ((c.code = cc_H_CLOSE_PATH) or (c.code = cc_hS_CLOSE_AND_END_PATH)) then // command h or s
   if ((c.code = cc_H_CLOSE_PATH) or (c.code = cc_hS_CLOSE_AND_END_PATH)) then // command h or s
@@ -69,7 +83,7 @@ begin
     // Correcao para programas de desenho que geram um novo inicio no
     // Correcao para programas de desenho que geram um novo inicio no
     // fim do desenho, terminamos qualquer desenho inacabado
     // fim do desenho, terminamos qualquer desenho inacabado
     AData.EndPath();
     AData.EndPath();
-    AData.StartPath(StrToFloat(c.cord_x), StrToFloat(c.cord_y));
+    AData.StartPath(StringToFloat(c.cord_x), StringToFloat(c.cord_y));
 
 
     close_path_x:=c.cord_x;
     close_path_x:=c.cord_x;
     close_path_y:=c.cord_y;
     close_path_y:=c.cord_y;
@@ -81,7 +95,7 @@ begin
     {$endif}
     {$endif}
     // Result:='G01' + ' ' + 'X' + c.cord_x + ' ' +  'Y' + c.cord_y;
     // Result:='G01' + ' ' + 'X' + c.cord_x + ' ' +  'Y' + c.cord_y;
 
 
-    AData.AddLineToPath(StrToFloat(c.cord_x), StrToFloat(c.cord_y));
+    AData.AddLineToPath(StringToFloat(c.cord_x), StringToFloat(c.cord_y));
   end;
   end;
   cc_h_CLOSE_PATH: // command h
   cc_h_CLOSE_PATH: // command h
   begin
   begin
@@ -90,7 +104,7 @@ begin
     {$endif}
     {$endif}
     //Result:='G01' + ' ' + 'X' + c.cord_x + ' ' +  'Y' + c.cord_y;
     //Result:='G01' + ' ' + 'X' + c.cord_x + ' ' +  'Y' + c.cord_y;
 
 
-    AData.AddLineToPath(StrToFloat(c.cord_x), StrToFloat(c.cord_y));
+    AData.AddLineToPath(StringToFloat(c.cord_x), StringToFloat(c.cord_y));
   end;
   end;
   cc_S_END_PATH: // command S
   cc_S_END_PATH: // command S
   begin
   begin
@@ -108,7 +122,7 @@ begin
     //Result:='G01' + ' ' + 'X' + c.cord_x + ' ' +  'Y' + c.cord_y + enter_line
     //Result:='G01' + ' ' + 'X' + c.cord_x + ' ' +  'Y' + c.cord_y + enter_line
     //       +'G01 Z0 // Sobe a cabeça de gravação' + enter_line;
     //       +'G01 Z0 // Sobe a cabeça de gravação' + enter_line;
 
 
-    AData.AddLineToPath(StrToFloat(c.cord_x), StrToFloat(c.cord_y));
+    AData.AddLineToPath(StringToFloat(c.cord_x), StringToFloat(c.cord_y));
     AData.EndPath();
     AData.EndPath();
   end;
   end;
   cc_c_BEZIER_TO_X_Y_USING_X2_Y2_AND_X3_Y3: // command c
   cc_c_BEZIER_TO_X_Y_USING_X2_Y2_AND_X3_Y3: // command c
@@ -120,9 +134,9 @@ begin
     //       +'G01 Z0 // Sobe a cabeça de gravação' + enter_line;
     //       +'G01 Z0 // Sobe a cabeça de gravação' + enter_line;
 
 
     AData.AddBezierToPath(
     AData.AddBezierToPath(
-      StrToFloat(c.cord_x3), StrToFloat(c.cord_y3),
-      StrToFloat(c.cord_x2), StrToFloat(c.cord_y2),
-      StrToFloat(c.cord_x), StrToFloat(c.cord_y)
+      StringToFloat(c.cord_x3), StringToFloat(c.cord_y3),
+      StringToFloat(c.cord_x2), StringToFloat(c.cord_y2),
+      StringToFloat(c.cord_x), StringToFloat(c.cord_y)
       );
       );
   end;
   end;
   cc_CONCATENATE_MATRIX: // command cm
   cc_CONCATENATE_MATRIX: // command cm
@@ -131,12 +145,12 @@ begin
     WriteLn(':> AnSemantico.cc_CONCATENATE_MATRIX');
     WriteLn(':> AnSemantico.cc_CONCATENATE_MATRIX');
     {$endif}
     {$endif}
 
 
-    cm_a := StrToFloat(c.cord_x3);
-    cm_b := StrToFloat(c.cord_y3);
-    cm_c := StrToFloat(c.cord_x2);
-    cm_d := StrToFloat(c.cord_y2);
-    cm_e := StrToFloat(c.cord_x);
-    cm_f := StrToFloat(c.cord_y);
+    cm_a := StringToFloat(c.cord_x3);
+    cm_b := StringToFloat(c.cord_y3);
+    cm_c := StringToFloat(c.cord_x2);
+    cm_d := StringToFloat(c.cord_y2);
+    cm_e := StringToFloat(c.cord_x);
+    cm_f := StringToFloat(c.cord_y);
   end;
   end;
   cc_RESTORE_MATRIX: // command Q
   cc_RESTORE_MATRIX: // command Q
   begin
   begin
@@ -169,13 +183,13 @@ begin
   if (Axis = 'y') then
   if (Axis = 'y') then
   begin
   begin
        // y' = b * x + d * y + f
        // y' = b * x + d * y + f
-       Result:=FloatToStr((cm_b*StrToFloat(x)+cm_d*StrToFloat(y)+cm_f)*(25.40/72));
+       Result:=FloatToStr((cm_b*StringToFloat(x)+cm_d*StringToFloat(y)+cm_f)*(25.40/72));
   end
   end
   else
   else
   // Axis = 'x'
   // Axis = 'x'
   begin
   begin
        // x' = a * x + c * y + e
        // x' = a * x + c * y + e
-       Result:=FloatToStr((cm_a*StrToFloat(x)+cm_c*StrToFloat(y)+cm_e)*(25.40/72));
+       Result:=FloatToStr((cm_a*StringToFloat(x)+cm_c*StringToFloat(y)+cm_e)*(25.40/72));
   end;
   end;
 end;
 end;
 
 
@@ -209,12 +223,21 @@ end;
 constructor AnSemantico.Create;
 constructor AnSemantico.Create;
 begin
 begin
   inherited Create;
   inherited Create;
+
   cm_a:=1;
   cm_a:=1;
   cm_b:=0;
   cm_b:=0;
   cm_c:=0;
   cm_c:=0;
   cm_d:=1;
   cm_d:=1;
   cm_e:=0;
   cm_e:=0;
   cm_f:=0;
   cm_f:=0;
+
+  // Format seetings to convert a string to a float
+  FPointSeparator := DefaultFormatSettings;
+  FPointSeparator.DecimalSeparator := '.';
+  FPointSeparator.ThousandSeparator := '#';// disable the thousand separator
+  FCommaSeparator := DefaultFormatSettings;
+  FCommaSeparator.DecimalSeparator := ',';
+  FCommaSeparator.ThousandSeparator := '#';// disable the thousand separator
 end;
 end;
 
 
 end.
 end.

+ 127 - 0
packages/fpvectorial/src/svgvectorialwriter.pas

@@ -0,0 +1,127 @@
+{
+Writes an SVG Document
+
+License: The same modified LGPL as the Free Pascal RTL
+         See the file COPYING.modifiedLGPL for more details
+
+AUTHORS: Felipe Monteiro de Carvalho
+}
+unit svgvectorialwriter;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils,
+  fpvectorial;
+
+type
+  { TvSVGVectorialWriter }
+
+  TvSVGVectorialWriter = class(TvCustomVectorialWriter)
+  private
+    FPointSeparator, FCommaSeparator: TFormatSettings;
+    procedure WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
+    procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
+    procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
+  public
+    { General reading methods }
+    procedure WriteToStrings(AStrings: TStrings; AData: TvVectorialDocument); override;
+  end;
+
+implementation
+
+{ TvSVGVectorialWriter }
+
+procedure TvSVGVectorialWriter.WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
+begin
+  AStrings.Add('  width="' + FloatToStr(AData.Width, FPointSeparator) + 'mm"');
+  AStrings.Add('  height="' + FloatToStr(AData.Height, FPointSeparator) + 'mm"');
+end;
+
+procedure TvSVGVectorialWriter.WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
+begin
+  AStrings.Add('  sodipodi:docname="New document 1">');
+end;
+
+{@@
+  SVG Coordinate system measures things in whatever unit we pass to it, so we
+  choose to pass in millimiters (mm), like FPVectorial uses.
+
+  The initial point is in the bottom-left corner of the document and it grows
+  to the top and to the right, just like in FPVectorial.
+
+  SVG uses commas "," to separate the X,Y coordinates, so it always uses points
+  "." as decimal separators and uses no thousand separators
+}
+procedure TvSVGVectorialWriter.WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
+var
+  i, j: Integer;
+  PathStr: string;
+  lPath: TPath;
+  PtX, PtY: double;
+begin
+  for i := 0 to AData.GetPathCount() - 1 do
+  begin
+    PathStr := 'm ';
+    lPath := AData.GetPath(i);
+    for j := 0 to lPath.Len - 1 do
+    begin
+      if lPath.Points[j].SegmentType <> st2DLine then Break; // unsupported line type
+
+      PtX := lPath.Points[j].X;
+      PtY := lPath.Points[j].Y;
+      PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + 'mm,'
+        + FloatToStr(PtY, FPointSeparator) + 'mm ';
+    end;
+
+    AStrings.Add('  <path');
+    AStrings.Add('    style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"');
+    AStrings.Add('    d="' + PathStr + '"');
+    AStrings.Add('  id="path' + IntToStr(i) + '" />');
+  end;
+end;
+
+procedure TvSVGVectorialWriter.WriteToStrings(AStrings: TStrings;
+  AData: TvVectorialDocument);
+begin
+  // Format seetings to convert a string to a float
+  FPointSeparator := DefaultFormatSettings;
+  FPointSeparator.DecimalSeparator := '.';
+  FPointSeparator.ThousandSeparator := '#';// disable the thousand separator
+  FCommaSeparator := DefaultFormatSettings;
+  FCommaSeparator.DecimalSeparator := ',';
+  FCommaSeparator.ThousandSeparator := '#';// disable the thousand separator
+
+  // Headers
+  AStrings.Add('<?xml version="1.0" encoding="UTF-8" standalone="no"?>');
+  AStrings.Add('<!-- Created with fpVectorial (http://wiki.lazarus.freepascal.org/fpvectorial) -->');
+  AStrings.Add('');
+  AStrings.Add('<svg');
+  AStrings.Add('  xmlns:dc="http://purl.org/dc/elements/1.1/"');
+  AStrings.Add('  xmlns:cc="http://creativecommons.org/ns#"');
+  AStrings.Add('  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"');
+  AStrings.Add('  xmlns:svg="http://www.w3.org/2000/svg"');
+  AStrings.Add('  xmlns="http://www.w3.org/2000/svg"');
+  AStrings.Add('  xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"');
+  WriteDocumentSize(AStrings, AData);
+  AStrings.Add('  id="svg2"');
+  AStrings.Add('  version="1.1"');
+  WriteDocumentName(AStrings, AData);
+
+  // Now data
+  AStrings.Add('  <g id="layer1">');
+  WritePaths(AStrings, AData);
+  AStrings.Add('  </g>');
+
+  // finalization
+  AStrings.Add('</svg>');
+end;
+
+initialization
+
+  RegisterVectorialWriter(TvSVGVectorialWriter, vfSVG);
+
+end.
+

+ 4 - 3
packages/x11/src/xlib.pp

@@ -1252,9 +1252,10 @@ type
      _Xdebug : cint;cvar;external;
      _Xdebug : cint;cvar;external;
 {$endif}
 {$endif}
 type
 type
-  funcdisp = function(display:PDisplay):cint;cdecl;
+  funcdisp    = function(display:PDisplay):cint;cdecl;
   funcifevent = function(display:PDisplay; event:PXEvent; p : TXPointer):TBoolResult;cdecl;
   funcifevent = function(display:PDisplay; event:PXEvent; p : TXPointer):TBoolResult;cdecl;
-  chararr32 = array[0..31] of char;
+  chararr32   = array[0..31] of char;
+  pchararr32  = chararr32;
 
 
 const
 const
   AllPlanes : culong = culong(not 0);
   AllPlanes : culong = culong(not 0);
@@ -1571,7 +1572,7 @@ function XQueryColor(para1:PDisplay; para2:TColormap; para3:PXColor):cint;cdecl;
 function XQueryColors(para1:PDisplay; para2:TColormap; para3:PXColor; para4:cint):cint;cdecl;external libX11;
 function XQueryColors(para1:PDisplay; para2:TColormap; para3:PXColor; para4:cint):cint;cdecl;external libX11;
 function XQueryExtension(para1:PDisplay; para2:Pchar; para3:Pcint; para4:Pcint; para5:Pcint):TBoolResult;cdecl;external libX11;
 function XQueryExtension(para1:PDisplay; para2:Pchar; para3:Pcint; para4:Pcint; para5:Pcint):TBoolResult;cdecl;external libX11;
 {?}
 {?}
-function XQueryKeymap(para1:PDisplay; para2:chararr32):cint;cdecl;external libX11;
+function XQueryKeymap(para1:PDisplay; para2:pchararr32):cint;cdecl;external libX11;
 function XQueryPointer(para1:PDisplay; para2:TWindow; para3:PWindow; para4:PWindow; para5:Pcint;
 function XQueryPointer(para1:PDisplay; para2:TWindow; para3:PWindow; para4:PWindow; para5:Pcint;
            para6:Pcint; para7:Pcint; para8:Pcint; para9:Pcuint):TBoolResult;cdecl;external libX11;
            para6:Pcint; para7:Pcint; para8:Pcint; para9:Pcuint):TBoolResult;cdecl;external libX11;
 function XQueryTextExtents(para1:PDisplay; para2:TXID; para3:Pchar; para4:cint; para5:Pcint;
 function XQueryTextExtents(para1:PDisplay; para2:TXID; para3:Pchar; para4:cint; para5:Pcint;

+ 7 - 1
rtl/objpas/dateutil.inc

@@ -1530,8 +1530,14 @@ end;
 
 
 Procedure DecodeDateTime(const AValue: TDateTime; out AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);
 Procedure DecodeDateTime(const AValue: TDateTime; out AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);
 begin
 begin
-  DecodeDate(AValue,AYear,AMonth,ADay);
   DecodeTime(AValue,AHour,AMinute,ASecond,AMilliSecond);
   DecodeTime(AValue,AHour,AMinute,ASecond,AMilliSecond);
+  if AHour=24 then // can happen due rounding issues mantis 17123
+    begin
+      AHour:=0; // rest is already zero
+      DecodeDate(round(AValue),AYear,AMonth,ADay);
+    end
+  else
+    DecodeDate(AValue,AYear,AMonth,ADay);
 end;
 end;
 
 
 
 

+ 43 - 35
rtl/win/sysutils.pp

@@ -60,6 +60,7 @@ Procedure RaiseLastWin32Error;
 function GetFileVersion(const AFileName: string): Cardinal;
 function GetFileVersion(const AFileName: string): Cardinal;
 
 
 procedure GetFormatSettings;
 procedure GetFormatSettings;
+procedure GetLocaleFormatSettings(LCID: Integer; var FormatSettings: TFormatSettings); platform;
 
 
 implementation
 implementation
 
 
@@ -651,49 +652,56 @@ Begin
 End;
 End;
 
 
 
 
-procedure GetFormatSettings;
+procedure GetLocaleFormatSettings(LCID: Integer; var FormatSettings: TFormatSettings); 
 var
 var
   HF  : Shortstring;
   HF  : Shortstring;
-  LID : LCID;
+  LID : Windows.LCID;
   I,Day : longint;
   I,Day : longint;
 begin
 begin
-  LID := GetThreadLocale;
-  { Date stuff }
-  for I := 1 to 12 do
-    begin
-    ShortMonthNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVMONTHNAME1+I-1,ShortMonthNames[i]);
-    LongMonthNames[I]:=GetLocaleStr(LID,LOCALE_SMONTHNAME1+I-1,LongMonthNames[i]);
-    end;
-  for I := 1 to 7 do
+  LID := LCID;
+  with FormatSettings do
     begin
     begin
-    Day := (I + 5) mod 7;
-    ShortDayNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVDAYNAME1+Day,ShortDayNames[i]);
-    LongDayNames[I]:=GetLocaleStr(LID,LOCALE_SDAYNAME1+Day,LongDayNames[i]);
+  { Date stuff }
+      for I := 1 to 12 do
+        begin
+        ShortMonthNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVMONTHNAME1+I-1,ShortMonthNames[i]);
+        LongMonthNames[I]:=GetLocaleStr(LID,LOCALE_SMONTHNAME1+I-1,LongMonthNames[i]);
+        end;
+      for I := 1 to 7 do
+        begin
+        Day := (I + 5) mod 7;
+        ShortDayNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVDAYNAME1+Day,ShortDayNames[i]);
+        LongDayNames[I]:=GetLocaleStr(LID,LOCALE_SDAYNAME1+Day,LongDayNames[i]);
+        end;
+      DateSeparator := GetLocaleChar(LID, LOCALE_SDATE, '/');
+      ShortDateFormat := GetLocaleStr(LID, LOCALE_SSHORTDATE, 'm/d/yy');
+      LongDateFormat := GetLocaleStr(LID, LOCALE_SLONGDATE, 'mmmm d, yyyy');
+      { Time stuff }
+      TimeSeparator := GetLocaleChar(LID, LOCALE_STIME, ':');
+      TimeAMString := GetLocaleStr(LID, LOCALE_S1159, 'AM');
+      TimePMString := GetLocaleStr(LID, LOCALE_S2359, 'PM');
+      if StrToIntDef(GetLocaleStr(LID, LOCALE_ITLZERO, '0'), 0) = 0 then
+        HF:='h'
+      else
+        HF:='hh';
+      // No support for 12 hour stuff at the moment...
+      ShortTimeFormat := HF+':nn';
+      LongTimeFormat := HF + ':nn:ss';
+      { Currency stuff }
+      CurrencyString:=GetLocaleStr(LID, LOCALE_SCURRENCY, '');
+      CurrencyFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRENCY, '0'), 0);
+      NegCurrFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_INEGCURR, '0'), 0);
+      { Number stuff }
+      ThousandSeparator:=GetLocaleChar(LID, LOCALE_STHOUSAND, ',');
+      DecimalSeparator:=GetLocaleChar(LID, LOCALE_SDECIMAL, '.');
+      CurrencyDecimals:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRDIGITS, '0'), 0);
     end;
     end;
-  DateSeparator := GetLocaleChar(LID, LOCALE_SDATE, '/');
-  ShortDateFormat := GetLocaleStr(LID, LOCALE_SSHORTDATE, 'm/d/yy');
-  LongDateFormat := GetLocaleStr(LID, LOCALE_SLONGDATE, 'mmmm d, yyyy');
-  { Time stuff }
-  TimeSeparator := GetLocaleChar(LID, LOCALE_STIME, ':');
-  TimeAMString := GetLocaleStr(LID, LOCALE_S1159, 'AM');
-  TimePMString := GetLocaleStr(LID, LOCALE_S2359, 'PM');
-  if StrToIntDef(GetLocaleStr(LID, LOCALE_ITLZERO, '0'), 0) = 0 then
-    HF:='h'
-  else
-    HF:='hh';
-  // No support for 12 hour stuff at the moment...
-  ShortTimeFormat := HF+':nn';
-  LongTimeFormat := HF + ':nn:ss';
-  { Currency stuff }
-  CurrencyString:=GetLocaleStr(LID, LOCALE_SCURRENCY, '');
-  CurrencyFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRENCY, '0'), 0);
-  NegCurrFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_INEGCURR, '0'), 0);
-  { Number stuff }
-  ThousandSeparator:=GetLocaleChar(LID, LOCALE_STHOUSAND, ',');
-  DecimalSeparator:=GetLocaleChar(LID, LOCALE_SDECIMAL, '.');
-  CurrencyDecimals:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRDIGITS, '0'), 0);
 end;
 end;
 
 
+procedure GetFormatSettings;
+begin
+  GetlocaleFormatSettings(GetThreadLocale, DefaultFormatSettings);
+end;
 
 
 Procedure InitInternational;
 Procedure InitInternational;
 var
 var