CONTENTS

  API documentation

COPYIGHT

  1999 Dietmar Eilert. All Rights Reserved.

  Dietmar Eilert
  Mies-v-d-Rohe-Str.31, 52074 Aachen, Germany
  Phone: +49-(0)179-5987061 German/English
  E-Mail: Dietmar.Eilert@post.rwth-aachen.de
  E-Mail: dietmar_eilert@yahoo.de (alternative address)
  WWW:    http://members.tripod.com/golded
  Mirror: http://members.xoom.com/golded

INTRODUCTION

  GoldED  offers  a  fast  interface  for  plug-ins:  the  API  interface  or
  "Application  Programmer  Interface". This interface can be used to add new
  commands to the editor and to implement plug-ins  showing  up  directly  in
  editor windows with their own graphical user interface. It is a synchronous
  library-based interface, ie. plug-ins are shared libraries  loaded  by  the
  host  application (typically GoldED). You must be familiar with the concept
  of programming shared  libraries  -  which  to  some  extent  are  compiler
  specific - if you want to write API plug-ins.

HOW TO RUN CLIENTS

  Plug-ins  ("API  clients")  are  added  to   GoldED   using   the   plug-in
  configuration  requester.  The  editor  will start all plug-ins associacted
  with a filetype when a text using that filetype  is  loaded.  Plug-ins  are
  started  on  a  per-text  basis. Some plug-ins require startup options (for
  example the name of a configuration file). The startup-options can  be  set
  in the API configuration requester of GoldED: doubleclick on a plug-in name
  to set its command string.

INTERFACE DESCRIPTION

  It is important to  understand  that  plug-ins  are  libraries.  Libraries,
  (unlike  normal  programs)  have  no  life of their own. They do not "run":
  Libraries are simply a collection of functions. The code in these functions
  is executed only if and when the program using the library starts executing
  them. Plug-in libraries developed for GoldED  are  expected  to  provide  a
  specific  set  of  four  functions  as described in the autodoc file. These
  functions are called by the editor on an as-needed basis, ie.  the  plug-in
  code  does  not  run  parallel  to  GoldED  but  is  executed  directly and
  synchronously by the main editor thread (task). Experienced programmers can
  of  course add asynchronous capabilities by running portions of the plug-in
  code in a second thread.

PLUG-IN PROTOCOL

  The first function of a plug-in executed by GoldED after  the  plug-in  has
  been  loaded is the APIMountClient() function. This function is expected to
  return a description of the client. The details on  how  this  function  is
  called  by GoldED and what it should return as a result is described in the
  autodoc file. GoldED will use the result of this function - especially  the
  api_Classes  field  -  to  determine if and when the other functions of the
  plug-in   should   be   called.   The   api_Classes   value   returned   by
  APIMountClient()  is  a  mask  field:  It  describes  the event classes the
  plug-in wants to see as input.  For  example,  some  plug-ins  want  to  be
  notified  every  time  the  user  presses  a  key.  These  clients  set the
  API_CLASS_KEY flag in  the  api_Classes  field.  GoldED  will  execute  the
  APIBriefClient()  function  of  the  plug-in every time it detects an event
  matching one of the requested event flags. The plug-in can then do whatever
  it  needs  to  do in its APIBriefClient() function to process the event. It
  must set a return code before it returns control  to  GoldED.  GoldED  will
  continue  to execute the APIBriefClient() function on an as-needed basis as
  events occur until the user closes the text.  At  this  time,  GoldED  will
  execute  the APICloseClient() function of the plug-in before it unloads the
  plug-in so that the plug-in can free local resources.

WHAT CAN API CLIENTS DO ?

  The APIBriefClient() function of the plug-in is called synchronously by the
  editor. The editor passes information about its internal state as arguments
  to the plug-in when executing this function (see  autodoc.h  for  details).
  The  API  client is free to read all internal configuration details as they
  are exposed by these arguments. This  information  is  guaranteed  to  stay
  valid  during the execution time of the APIBriefClient() function. However,
  all configuration details are  read-only.  API  clients  can  not  directly
  modify the configuration of GoldED with three exceptions:

  a) plug-ins can set the cursor to a new position

     Plug-ins  may  directly  set  the  cursor  position  in  the  EditConfig
     structure  provided  that  they  set  the  API_REFRESH_SYNC  flag in the
     api_Refresh field returned by APIBriefClient() so that GoldED knows that
     the cursor position has been changed.

  b) plug-ins can mark text

     Plug-ins may directly change  the  position  of  block  markers  in  the
     EditConfig  structure provided that they set the API_REFRESH_MARKER flag
     in the api_Refresh field returned by  APIBriefClient()  so  that  GoldED
     knows that the marker has been changed.

  c) plug-ins can change text

     Plug-ins can change  the  text  by  attaching  a  list  of  modification
     "orders"  to  the  api_Order  field  returned by APIBriefClient(). These
     orders contain the new text to be inserted  and  a  description  of  the
     insertion  point.  GoldED  will call the APIFreeClient() function of the
     plug-in after processing the orders so that the plug-in can free  memory
     allocated for the orders.

WHAT API CLIENTS MAY NOT DO

  All other operations affecting the configuration of GoldED are  unsupported
  by  the  plug-in  interface and require usage of the normal Rexx interface.
  Using the Rexx interface in plug-ins can however be very  tricky:  Remember
  that  the  plug-in  code is executed synchronously: GoldED would be sending
  messages to itself while it is executing plug-in code. That's why  plug-ins
  may   send   asynchronous   rexx  messages  to  GoldED  but  they  may  not
  synchronously Wait() for a reply because  GoldED  can  not  reply  to  rexx
  messages  while  excuting  the  plug-in  code.  Unfortunately, sending rexx
  messages asynchronously does not always make sense (if you need the  result
  code  or  plan  to send a sequence of rexx commands). The best solution for
  this problem is to run portions of the plug-in code, specifically the  rexx
  communication - asynchronously and synchronize this thread with the rest of
  the plug-in code via semaphores or signals.

CONTAINER CLIENTS

  Plug-ins can request rendering space in editor windows and directly  render
  to  these  areas,  display  buttons, etc. This feature has been inspired by
  ActiveX controls from the Windows world. Embedded plug-ins could be used to
  implement  a  VisualC-style  development  environment, a HEX editor, a HTML
  preview area in editor windows, a class  browser,  visual  feedback  areas,
  virtual shells, toolbars, smart online help systems, etc.

IMPLEMENTING CONTAINER CLIENTS

  Container  clients  are  implemented  as  normal  API  plug-ins.  The  only
  difference  is that the APIMountClient function - the first function called
  by the host - additionally returns a pointer to an APIArea structure  which
  describes the container (width, height, alignment) requested by the client.
  GoldED automatically overrides the dimensions with the user preferences  if
  the  plug-in  has  been  used before and then continues with allocating the
  container and initializing the output area. Subsequent  notifications  sent
  to  the plug-in (technically speaking calls to the APIBriefClient function)
  contain a pointer to the allocated APIContainer structure  which  describes
  the  container  (position,  rastport,  etc).  One  of  these  calls  is the
  API_ACTION_PAINT notification which is the host's  request  to  redraw  the
  container  contents.  A  few  other  container-related  notifications  help
  clients to cope with window resizing and window refreshing; please see  the
  include files for details.

IDCMP MESSAGES AND MESSAGE PORTS

  Container clients may allocate their own signals and message ports (e.g.  a
  timer)  and  request IDCMP messages (required for gadget handling) but they
  may not directly Wait() for ports and signals because clients are  libaries
  and  as  such must return control to the program using the libary. Instead,
  they   pass   the   signals   and   the   IDCMP   mask    to    the    host
  (APIClient->api_Signals  and  APIArea->api_IDCMP)  which  will  notify  the
  client if an  event  of  the  specified  type  occurs.  Another  difference
  compared to normal application programming is that due to the fact that all
  plug-ins share the same window, plug-ins are not free to choose gadget  IDs
  freely: the host provides a namespace for gadgets to be used by the plug-in
  (APIContainer->api_Namespace is the first free ID; each client may allocate
  up  to 255 gadgets). Clients may not add gadgets or detach gadgets on their
  own using the normal Intuition functions for the same reason. Instead, they
  have   to  pass  the  gadget  list  as  "order"  of  type  API_ORDER_ATTACH
  respectively API_ORDER_DETACH to the host which will then add  the  gadgets
  to  the  window  or  detach them. These orders usually are sent to the host
  when responding to API_ACTION_ATTACH notifications which is the host's  way
  of telling plug-in that it's time to create gadgets.

IDCMP messages

  Plug-ins can receive IDCMP messages by setting the corresponding bits (e.g.
  IDCMP_GADGETUP) in APIArea->IDCMP as mentioned in the last paragraph. It is
  important to understand that clients receive all  IDCMP  messages  arriving
  for the host program. For example, clients listening to IDCMP_GADGETUP will
  see these messages not only for their own gadgets but for  all  gadgets  in
  the host's windows. It is the sole responsibility of each plug-in to filter
  out messages meant for the plug-in and to pass all other events back to the
  host  program  (which  will  send  them  to  other  plug-ins before finally
  processing the events on its own). The following IDCMP classes can be used:

                IDCMP_ACTIVEWINDOW    IDCMP_MOUSEBUTTONS
                IDCMP_CLOSEWINDOW     IDCMP_MOUSEMOVE
                IDCMP_GADGETDOWN      IDCMP_NEWSIZE
                IDCMP_GADGETUP        IDCMP_RAWKEY
                IDCMP_INACTIVEWINDOW  IDCMP_REFRESHWINDOW
                IDCMP_MENUHELP        IDCMP_SIZEVERIFY
                IDCMP_MENUPICK        IDCMP_VANILLAKEY

  Plug-Ins may not interfere with the host's IDCMP handling. They specificaly
  may  not  modify the window's IDCMP mask nor use the ReportMouse() function
  (to disable or enable IDCMP_MOUSEMOVE  events)  nor  may  they  modify  the
  Window  structure or the windows's Rastport structure. Each client receives
  its own Rastport structure (APIContainer->RPort) to be used for rendering.

EXAMPLES

  Several example API clients are shipped with GoldED (golded:developer/api).
  Have  a  look  at the provided source code to understand how plug-ins work.
  You may have to adjust the source code before you can  compile  it  because
  the  compilation  of  libraries  is  to  some extend compiler-specific (the
  examples have been developed with DICE).

THE FILES

  All plug-in related code is  kept  in  the  file  "func.c".  Some  examples
  additonally have initialization code in "init.c" which is executed when the
  library is used for the first time respectively before it is expunged  from
  memory.  You  can use the Init()/Exit() functions in this module for global
  initialization. The other files are mostly library glue code. You can leave
  these files untouched except that you may want to edit the plug-in name for
  you own projects which can be  found  in  "tag.a"  and  of  course  in  the
  makefile  (note  that  you  must use exactly the same name in both files or
  your library will fail to load). You may also want to add code  to  "lib.c"
  to  open  the  shared  libraries  you  need;  most  examples  already  open
  "dos.library", "exec.library" and "intuition.library".
