
If you write any code which you feel you may one day deign to send to the
DeskLib moderator for possible inclusion in the library, then please read
through the following text. It is also suggested that you familiarise
yourself with the way most of the library structures have been laid out, and
the naming conventions used, so that you can make your codes' external
interface as consistent with the rest of DeskLib as possible

The following is not mandatory, but it will help, and it'll save me
re-writing your code before it goes in!


Programming conventions
=======================

 There are various conventions which I have tried to impose upon the DeskLib
 code to retain as much consistency as possible. If writing generic code
 that you might add to DeskLib for all to use in the future, then please try
 to write it in the same style as the current code (even if you don't
 personally like this style, it is *very* bad to have inconsistencies, and I
 will be forced to re-write all your code to comply, which is a lot of
 wasted bother...)

 The main aims of the following conventions are:
   -Naming consistency. I have chosen to echo the style used in Acorn's SWI
    names (see below).
   -Readability. Although "event.type" means more typing work than "e->e",
    it is far better in a global library such as this for the following
    reasons:
      - Anyone reading some source code will be able to work out fairly
        easily what is going on, even if they haven't seen the library
        naming before.
      - You don't need to memorise huge gobs of ASCII encodings just to
        program with the library - if you want an event type, it is most
        likely called an event type, not an e->e.
      - Learning the ins and outs of a new library is far quicker and less
        painful if things have meaningful names - especially if they tally
        with similar names used in other languages people are used to.
      - Debugging is easier, as remembering what an "event->type" is tends
        to be easier than remembering what the "e->e" was.
      - Readability is improved, so other people can more easily understand
        your code, and if you leave some code alone for a few weeks and then
        come back to it, you will be able to work out what you had done more
        easily.
      - Portability is increased, as it is easier to translate code full of
        meaningful names than code full of random ASCII symbols.

 Anyone who does not like the names of types and functions in the library
 can always use #defines or alter their copy of the sources to make the
 names meaningless again if they so wish. (Though it is recommended that you
 use #defines, so that the code remains compatible with future releases of
 the Library.)

 function names:
   I have opted to use the same style as Acorn standardised with their SWI
   names. That is,  module-name underline function-name, where module-name
   and function-name are all lowercase except for the initial letters of
   words:
   
 i.e. Wimp_OpenWindow();
      Dialog_SaveAs();
      Icon_PlaceCaret();

 (Note that for the libraries I have defined SWI names as SWI_Wimp_OpenWindow
 so that there is no clash between the #defined SWI name and the funcion name)

 DeskLib uses a policy of splitting code up into the smallest reasonable
 segments so that a minimum of code is included if the user only calls one
 function. The result of this is that it is necessary to supply some
 internal-use functions (and variables) to external callers (other parts of
 DeskLib).
 These are to be named as above, but use a double underline to make it clear
 that they are internal routines that should generally not be used unless by
 a new routine for inclusion into DeskLib itself...


 variable/type names:
   The LAST thing that we want is 1-letter variable names. Undeniably they
   are faster to type, but they render code far more difficult to read, even
   for people who are fluent with them, and they make learning the use of a
   library a long and arduous task. Also, working out what an "m" is from
   its context is an undesirable thing.
   (i.e. "w", "i", "m", "m", and "e" are definitely out!)

   The second to last thing that we want is a really long variable name, as
   it is an annoyance to have to type exceedingly long names over and over.
   Thus, some things are gong to have to be abbreviated.
   (i.e. "saveas_read_leafname_during_send" is also not too good)

   Abbreviations should be 4 to 6 characters long where possible. e.g.
      icon          ->  icon
      window        ->  window
      menu          ->  menu
      button        ->  button
      mouse         ->  mouse
      dialogue      ->  dialog
      outline       ->  outline
      rectangle     ->  rect

   -most names fit nicely into 4 or 5 characters without much abbreviation,
   and this seems to be a nice compromise between readability and typing
   effort.

   The third important thing is that naming should be consistent: If you
   look through the wimp library data structures, for example, you will find
   that a window handle (type window_handle) is ALWAYS called a window in
   external interfaces.
   An icon_handle is always called an icon
   An icon definition block (type icon_block) is always called an iconblock
   A flag word is always accessed as flagword.value or flagword.data.xxx
   (i.e. "value" and "data" names for flags are consistent throughout the
   library, even though they might not be the "best" names under all
   circumstances)
   etc.

   Variables and types should be entirely lowercase to differentiate them
   more easily from function names. They should contain underlines to
   seperate groups from individuals (e.g. wimp_window, wimp_icon), but NO
   MORE than ONE underline.
   Although multiple-word variables look bad (wimp_openwindowstructure)
   if things are abbreviated well and the words are carefully chosen, names
   can still be quite readable all lowercased. (window_openblock)

   Where Acorn's naming fits within these guidelines, you should use
   Acorn-compatible names. For example, I don't wholly like Acorns
   "nameisname", but I have kept it as it is not too bad, still adequately
   describes its function, and is not a silly name like "nin" which I would
   find meaningless. (Thus, Acorn's w becomes window, and i becomes icon)
   This will help to ease the job of moving from use of Acorn's library to
   this one, as well as making it as easy as possible to integrate parts of
   the two libraries together where necessary.
                                              
   constants should be named with lowercased module/group name, followed by
   an underline and uppercased constant name. (i.e. the same as a variable,
   but with the second half uppercased). e.g.
     icon_SELECTED
     colour_GREEN

   Notice how I have seperated many data constants into groups like
     icon, iconborder, iconbtype, etc.
   rather than just the module name (Acorn use wimp_ for *everything*)
   because this makes it much easier to understand what a constant is for...
   e.g.
        wimp_ISELECTED    ->     icon_SELECTED
        wimp_MOVE_WIND    ->     drag_MOVEWINDOW
        wimp_BRIGHT       ->     button_RIGHT
        wimp_WMOVEABLE    ->     window_MOVEABLE

   (In fact, DeskLib goes one step further, and defines variable structures
   so that you can simply use icon.data.selected to retrieve a flag etc.)

   which not only makes the function of the constant far more meaningful and
   far less ambiguous, but in many cases makes the constant name shorter as
   well. It also removes the possibility of using (for example) an icon flag
   in a window_flagword by accident because you misread/misinterpreted one
   character in its name.

   From a programming point of view, it also reduces the chance of you
   defining all your icon flags as wimp_Ixxxx, and then realising that you
   defined one as wimp_INDIRECT instead of wimp_IINDIRECT (as Acorn did)

   When in doubt about naming things, look at the source code in this
   library for hints.

   The main thing is to get the name as readable, meaningful, consistent,
   and unambiguous as possible, with a secondary consideration to length of
   variable/constant name.


   header files/function group names:
   ==================================

   Try to divide any functions up into distinct groups. Acorn decided on
   modules, for example "wimp", but I feel this should be further subdivided
   into modules for windows, icons, drags, pointers, etc. - basically put
   one "functional group" into its own .c file (or group of files).

   My intent for a module such as "wimp" is to provide a low-level interface
   to all wimp SWI calls (Wimp_OpenWindow(), Wimp_CloseWindow(), etc.), with
   a higher-level (or levels) of interfacing which is named according to
   WHAT the function AFFECTS, for example:
     Window_Open()
   might be the high-level call which does:
     Wimp_GetWindowState(&windowstate);
     windowstate.open.behind = -1; /* Open on top of all other windows */
     Wimp_OpenWindow(&windowstate.open);

   For each .c file, there should be a .h file of the same name prototyping
   all external function and variable names, plus any constants that should
   be used in data passed in to those functions. This .h file will go into
   the main .h directory.
   An additional .h file (generally <name>defs.h or similar) can be used for
   internal constant and structure definitions. This usually goes in the .h
   directory local to a sublibrary directory.
   e.g. "Template" has a "Template.h" file detailing the externally visible
   functions, variables, and structures/types. It also has an internal header
   file (Template.h.TempDefs - TempDefs.h) which defines internal-use-only
   definitions.

   EVERY header file should guard against multiple-inclusion by using the
   following format:

     #ifndef __dl_<filename>_h
     #define __dl_<filename>_h

     ... insert your .h code in here ...

     #endif

   (I know #pragma include_only_once is better, but this will work with ANY
   C compiler, rather than just Acorn's one...)

   Note that this is similar to the method used in Acorn's own libraries,
   except for the addition of the dl_ portion: this is so that DeskLib
   libraries can be used in conjunctipon with Acorn libraries (e.g. so there
   is no clash between __dl_error_h and __error_h, for example)

   This is also useful, as other files can check #ifdef __dl_<filename>_h...


   Generic design
   ==============

   Please try to design your code in as generic a manner as possible. For
   example, if you write code that automatically malloc's space for a
   window's indirected data, then include a function that can be called to
   free the memory when necessary. (And possibly also include a call to this
   code in the Window_Delete() function). Note that this should be a seperate
   function, so that programmers using the libraries can call it themselves
   if they want to do things slightly differently to the way you envisaged it.

   Some code is intended as a sort of template or prototype. For example, you
   might produce routines to draw a single circle, line, etc. in a given
   window. Of course, this means that if two circles are to be drawn my code
   will call GetWindowState twice, which is inefficient. In this case, the
   user can copy the code to draw the circle into his/her own redraw loop,
   and simply use the library routine as a source of useful code fragments.

   Another example is the code for SaveAs and other "standard" windows... I
   have endeavoured to allow the user to do anything (e.g. 3-d icons,
   pointer-shape changing) while a save-as window is up, but if necessary
   they should have access to the full source code for SaveAs (so they can
   alter anything), but also if possible to the dialogue-box or window data
   used, so that slight alterations may be made if necessary while the code
   is running. (Thus, I provide a standard functionality for a save-as
   window, which provides consistency between different applications all
   using the same code library, yet the programmer still has the power to
   alter things if they really want to)

   
   Error (and other) messages
   If ALL strings in the libraries use "msgs" format, then it will be
   easier to replace default messages with different languages, etc.
   e.g. instead of returning an error message "not found", you should return
   the message "E.CantFind:Not found", so that if the message "E.CantFind" is
   defined in a "msgs" message file, the whole error message can be replaced.

   Currently, I have gone about 50% of the way to this, by defining all
   output text in #defined constants at the top of .c files or in
   local .h files... thus, the messages can be more easily changed to
   use msgtrans tags or whatever... In the future these messages may be
   collected into a central .h file to enable quick and easy conversion
   of the entire library to a different language.

   This also allows selected messages to be removed from your final
   application (how many times have you needed the error message "Templates
   file is not loaded for use with dialog boxes" after your application is
   developed: If the templates aren't loaded, another error will already
   have occurred (thus the message is never seen) or you don't get the 
   error (thus the message is never seen)...

   Also, I find it annoying when I know my messages file is loaded OK to
   have text in my program (the default message) wasting space once again,
   when it has been replaced by a message in my messages file. In these
   cases I would like to replace the message with just the msgtrans tag.
   So having all (most) constant strings used by a bit of code actually
   defined at the top in one lump would be very useful.


   Defaults
   ========

   The last point is to always use sensible defaults: If the user doesn't
   supply a non-vital piece of information, your code should handle it (even
   if *you* know *you* will always supply the full information). For
   example, in *ANY* situation where a function-pointer is supplied, you
   should check if it is NULL, and not try to call it if it is! (Even if
   this renders the effect of your routine down to nothing whatsoever)
   Anywhere that you return values to a variable passed by reference
     ReturnAnInteger(&integer_variable);
   if the variable pointer passed in is NULL, then that return-value should
   be ignored if possible. (checking if something == 0 usually takes only
   one instruction, so very little efficiency is lost due to this, but it is
   VERY useful if you don't want all the return values)

   At the very least, if your function DOESN'T do this, then WARN the user
   of this fact in the .h and .c files with comments!

   eg In the icon-handling code, it always *checks* that icons are of the right
   types for things to be done to them... For example, an attempt to set the
   text in *any* icon will not fail, even if the icon was not a text icon or
   an indirected text icon. An attempt to place the caret in an icon will
   not always succeed, but no errors or problems should be caused by
   allowing the caret to be placed in "illegal" places such as non-writeable
   icons...



Types
=====

Try to define nicely structured types. For example, in the Wimp header, I
have defined a point (x, y), from which a rectangle can be formed (min, max).
This leads to names in use:
  screenrect.min.x
  screenrect.min.y
  screenrect.max.x
  screenrect.max.y

which is far nicer than "screenrect.maxx" or "box.x0" etc.

It also allows the user to pull out data more easily:
  int         left_x_position    = screenrect.min.x;
  wimp_point  bottom_left_corner = screenrect.min;
  wimp_rect   rectangle          = screenrect;

(Note that the point cannot be easily pulled out or copied in Acorn's scheme
in one C instruction)

Another example is my scroll positions:
  scroll.x                  (Acorn: scx or x)
  scroll.y                  (       scy or y)

and caret offset:
  offset.x                  (Acorn: x)
  offset.y                  (       y)

-As you can see, this structure also helps to control inconsistencies - when
programming, you suddenly notice that part of a structure can be replaced by
a predefined substructure, and so your new structure becomes more consistent
with other structure definitions.

Basically, the rule of thumb here is:
If part of a data type would make a useful data type in its own right, DO IT


FlagWords
=========

For consistency, these should be made into structures as follows:

union
{
  int value;        /* A straight 32-bit flag word */

  struct
  {
    unsigned int bit0   : 1;  /* Note: the number of bits here must be <= 32 */
    unsigned int bit2   : 1;
    ...
    unsigned int nybble : 4;
    ...
    unsigned int byte   : 8;
  } data;
} flagword;


This gives the programmer the choice of:

  flagword.value;
(Exactly the same as current flagwords: a 32-bit integer)

or
  flagword.data.nybble (etc.)

Note that the two parts "value" and "data" should ALWAYS have these names,
for consistency throughout the library. These names are not always the "best"
to use, but due to the fact that they are consistent, they become easy
to remember.

This has the advantage of being able to replace:
  buttontype = (iconflags & BUTTONTYPEMASK) >> BUTTONTYPESHIFT;
  gribble    = (frobbleflags & 0x00f70000) >> 16;

with:
  buttontype = iconflags.data.buttontype;
  gribble    = frobbleflags.data.thingy;

  (note though, that it is *still* possible to say:
    buttontype = (iconflags.value & BUTTONTYPEMASK) >> BUTTONTYPESHIFT;
   if you really want to?!)


and replace:
  if (iconflags & icon_SELECTED)

with:
  if (iconflags.data.selected)

-- A much more pleasant way of thinking about things.


Misc
====

Writing of basic functions is well underway. What we really need to make
DeskLib better is a lot of little, useful functions.
  e.g. Fake a click on an icon
       Place the caret at the end of an icon
       Shade an icon (ensuring that the caret is removed from the icon)
       Open a window in a portion of "free space" on the desktop
       Bring a window to the front
       Change the colour of an icon
       Change the sprite in an icon
-Most of these things are *very* simple to write, and most of us have the
ability to write most of the functions for ourselves... but it is still very
nice to have them *predefined*, so you can spend your time on actual editing
functions or whatever...

  Also, I want a host of functions to handle writable icons: You give your
  writable a validation string of "A" to allow NO characters to be entered,
  and then call the Icon handlers when you get keypress events. They will
  then vet entry of values properly:
    Numbers where you can't type a 0 as the first digit.
    Any number taking up to (e.g.) 12 digits, but not valued less than 0.1
    and not more than 100.0
    Any (e.g.) 3-digit number smaller than (e.g.) 73
    Any number with a value between 0 and 7 (i.e. it will let you type only
     a single digit, then you can only type a ".", and then you can type
     up to x decimal places)
    Any character entered is automatically uppercased/lowercased (good for
     passwords etc.)
    Any valid ADFS filename can be entered: For example, if you try to enter
     a leafname only, you can't type more than 10 characters, but if you
     type a "." then another 10 characters can be typed... I really hate
     counting the number of characters in a save-as dialogue box to ensure I
     haven't used too many characters in the leafname!

  As you can probably see by now, there are an infinitude of little functions
that would come in useful to many programmers much of the time, and will be
very useful time/work savers for wimp programmers (it is amazing how much
you use these functions as soon as they become available)
  
You will notice that some of these functions are just useful or convenient
(e.g. Icon_Select, etc.) and others actually save a lot of work (e.g.
placing the cursor at the end of the text in a given icon takes a fair bit
of work) in really quite common cases.
(What annoys me with RISC OS Lib is Acorn's dbox_ obviously has code to
place the caret at the end of an icon's text, but it is HIDDEN inside dbox
so you can't use it generically for any icon - useful code is IN your
program, but YOU can't use it... I find that very wasteful, and this kind of
wanton pollution is killing our planet... ;-) ... (After having seen dbox, I
was also less than pleased to see that every time a caret is placed, the code
is repeated, rather than using a nice generic place_caret call...ugh)

-In fact, if you look carefully at the functionality in Acorn's dbox
routines, you will see that it could be split up into a set of slightly more
generic routines, and dbox will simply vanish - it isn't really needed, so
long as your window, icon, and event code is well designed!

dbox_show type functions   -> Window show type functions
dbox_event handling        -> default handlers used with Event()
dbox button click handling -> Icon button handlers + event handlers
dbox_set.../dbox_get...    -> Icon_Set/Get Integer/double/text/radios/etc
dbox caret handlers        -> generic caret handlers
dbox key handlers          -> generic key handlers/event handlers

Some more examples of the types of routines I intend to end up with:
(well, OK, so these are now implemented in DeskLib... what do you expect? I
wanted the code... it's been *days* since I thought of the idea... ;-)

  Window_Show    - Opens a window, allowing it to be opened wherever it was
                   defined in the template, or centered on screen, or
                   centered plus a small random displacement, or appearing
                   under the pointer or over the current caret position, or
                   centered over a given window or icon.
                   And if the window is being opened because of a menu
                   sublink warning message, it is opened instead in the
                   correct position in the menu tree.
                   (This replaces dbox_show, and does more on top)

  Window_Delete  - Closes and deletes a window, deallocating all its
                   handlers, memory, etc.
                   (say goodbye to dbox_dispose!)

  A series of functions you can connect in that are default event handlers
  for dialogue boxes. This replaces the dbox_fillin series of calls.

  Code for things like moving the caret to the next icon or the previous
  icon, which can be called by the dialog handlers when up-arrow,
  down-arrow, tab, and return keypresses are caught.

  And last but not least (as mentioned above), a set of icon calls that set
  and get icon values, radio button selection states, etc. (Not to mention
  icon-groups such as "volume sliders" that will be handled
  semi-automatically. (This is not a dream... the code has *already* been
  written! See Icon.h))


I also want to devise a method by which you can open two (or more) windows
and attach them to each other as panes. Then, whenever you call high-level
Window_ functions, the windows will be treated as one "window" (i.e. when
one window is dragged, the panes attached to it will move as if glued onto
it, completely automatically, so you don't need to worry about the fact that
they are seperate windows... This will probably mean indexing icons as
0..1..2 for the base window, and 512, 513, 514 for the pane, as if the whole
kaboodle is really only one window...
-This will probably be with Window_ calls, but the "handle" that you use
is actually only the "back" window handle - you will just have to use 
Window_ calls to access the pane as a "window".

Hopefully these things have helped to show you what *I* intend to do for
DeskLib... lots of useful "tack-on" facilities that are compatible with RISC
OS Lib and DeskLib low-level functions. Any useful functions any of you have
written will be gladly accepted and included into DeskLib (Even if your
function only works with RISC OS Lib, I can try to add support for DeskLib
as well, and the whole world can benefit from the usefulness of your
function. Let's share all the useful code we have sweated over for minutes
instead of hoarding it (which helps nobody)

If you think of some good things to write, it might be a good idea to
contact me before you start, and I'll hopefully be able to reduce clashes
where more than one person spends time writing basically the same code.

