home *** CD-ROM | disk | FTP | other *** search
/ com!online 2005 April / com_0405_1.iso / opensource / SynergyInstaller.exe / $INSTDIR / PORTING < prev    next >
Encoding:
Text File  |  2005-01-01  |  17.0 KB  |  420 lines

  1. Synergy Developer and Porting Guide
  2. ===================================
  3.  
  4. This document is under development.
  5.  
  6. Code Organization
  7. -----------------
  8.  
  9. The synergy source code organization is:
  10.  
  11. .               -- root makefiles, some standard documentation
  12. cmd             -- program source code
  13.   launcher      -- synergy launcher for Windows
  14.   synergyc      -- synergy client
  15.   synergys      -- synergy server
  16. config          -- stuff for autoconf/automake
  17. dist            -- files for creating distributions
  18.   nullsoft      -- files for creating Nullsoft NSIS installer (Windows)
  19.   rpm           -- files for creating RPMs
  20. doc             -- placeholder for documentation
  21. examples        -- example files
  22. lib             -- library source code
  23.   arch          -- platform dependent utility library
  24.   base          -- simple utilities
  25.   client        -- synergy client library
  26.   common        -- commonly needed header files
  27.   io            -- I/O
  28.   mt            -- multithreading
  29.   net           -- networking
  30.   platform      -- platform dependent display/window/event stuff
  31.   server        -- synergy server library
  32.   synergy       -- synergy shared client/server code library
  33.  
  34. Note how the utility code required by the programs is placed into
  35. separate library directories.  This makes the makefiles a little
  36. more awkward but makes for a cleaner organization.  The top level
  37. directory has only the standard documentation files and the files
  38. necessary to configure and build the rest of the project.
  39.  
  40.  
  41. Coding Style Guide
  42. ------------------
  43.  
  44. Synergy uses many coding conventions.  Contributed code should
  45. following these guidelines.
  46.  
  47. - Symbol Naming
  48.   Names always begin with a letter (never an underscore).  The first
  49.   letter of interior names are always capitalized.  Acronyms should
  50.   be all uppercase.  For example: myTextAsASCII.
  51.  
  52.   Names come it two flavors:  leading capital and leading lowercase.
  53.   The former have the first character capitalized and the latter
  54.   don't.  In the following table, leading capital names are indicated
  55.   by `Name' and leading lowercase names by `name'.
  56.  
  57.   The naming convention for various things are:
  58.  
  59.     * Exceptions       -- X + Name    XMyException
  60.     * Interfaces       -- I + Name    IMyInterface
  61.     * Template Classes -- T + Name    TMyTemplate<>
  62.     * Other Classes    -- C + Name    CMyClass
  63.     * Enumerations     -- E + Name    EMyEnumeration
  64.     * Constants        -- k + Name    kMyConstant
  65.     * Data Members     -- m_ + name   m_myDataMember
  66.     * Methods          -- name        myMethod
  67.     * Functions        -- name        myFunction
  68.     * Variables        -- name        myVariable
  69.  
  70.   Exceptions are types that get thrown and are generally derived
  71.   (possibly indirectly) from XBase.  Interfaces are derived (possibly
  72.   indirectly) from IInterface and have only pure virtual functions.
  73.   Other classes are classes that aren't exceptions or interfaces.
  74.   Constants include global constants and enumerants.
  75.  
  76.   Method names should usually have the form `verbObject'.  For example:
  77.     * isGameOn()
  78.     * getBeer()
  79.     * pressPowerButton()
  80.     * setChannel()
  81.   In general, use `get' and `set' to read and write state but use `is'
  82.   to read boolean state.  Note that classes that contain only `is',
  83.   `get', and `set' are probably plain old data;  you might want to
  84.   consider using public data members only or, better, refactor your
  85.   design to have classes that actually do something more than just
  86.   hold data.
  87.  
  88. - File Naming
  89.   Each class should have one source and one header file.  If the
  90.   class is named `CMyClass' then the source file should be named
  91.   `CMyClass.cpp' and the header file `CMyClass.h'.
  92.  
  93.   Headers files not containing a class should have some meaningful
  94.   name with a leading capital (e.g. `Version.h').
  95.  
  96.   Source files without a header file have a leading lowercase name.
  97.   Only files containing the entry point for an application should
  98.   lack a header file.
  99.  
  100. - Dependencies
  101.   * No circular library dependencies
  102.     Library dependencies form an acyclic graph.  Conceptually
  103.     libraries can be arranged in layers where each library only
  104.     references libraries in layers below it, not in the same layer
  105.     or layers above it.  The makefiles build the lowest layer
  106.     libraries first and work upwards.
  107.  
  108.   * Avoid circular uses-a relationships
  109.     When possible, design classes with one-way uses-a relationships
  110.     and avoid cycles.  This makes it easier to understand the code.
  111.     However, sometimes it's not always practical so it is permitted.
  112.  
  113.   * Included files in headers
  114.     Headers should #include only the necessary headers.  In
  115.     particular, if a class is referenced in a header file only as a
  116.     pointer or a reference then use `class COtherClass;' instead of
  117.     `#include "COtherClass.h".'
  118.  
  119.   * #include syntax
  120.     Non-synergy header files must be included using angle brackets
  121.     while synergy header files must be included using double quotes.
  122.       #include "CSynergyHeader.h"
  123.       #include <systemheader.h>
  124.     The file name in a #include must not be a relative path unless
  125.     it's a system header file and it's customary to use a relative
  126.     path, e.g. `#include <sys/types.h>'.  Use compiler options to
  127.     add necessary directories to the include search path.
  128.  
  129.   * Included file ordering
  130.     Files should be included in the following order:
  131.     * Header for source file
  132.       The first include for CMyClass.cpp must be CMyClass.h. 
  133.     * Other headers in directory, sorted alphabetically
  134.     * Headers for each library, sorted alphabetically per library
  135.       Include headers from the library closest in the dependency graph
  136.         first, then the next farthest, etc.  Sort alphabetically within
  137.         each library.
  138.     * System headers
  139.  
  140. - C++
  141.   * C++ features
  142.     Synergy uses the following more recent C++ features:
  143.     * bool
  144.     * templates
  145.     * exceptions
  146.     * mutable
  147.     * new scoping rules
  148.     * the standard C++ library
  149.  
  150.     Do not use the following C++ features:
  151.     * dynamic_cast
  152.     * run time type information
  153.     * namespaces and using (use std:: where necessary)
  154.  
  155.     The new scoping rules say that the scope of a variable declared
  156.     in a for statement is limited to the for loop.  For example:
  157.  
  158.       for (int i = 0; i < 10; ++i) {
  159.         // i is in scope here
  160.       }
  161.       // i is not in scope here
  162.  
  163.       for (int i = -10; i < 0; ++i) {
  164.         // an entirely new i is in scope here
  165.       }
  166.       // i is not in scope here
  167.  
  168.     This is used routinely in synergy, but only in for loops.  There
  169.     is a macro for `for' in lib/base/common.h when building under
  170.     Microsoft Visual C++ that works around the fact that that compiler
  171.     doesn't follow the new scoping rules.  Use the macro if your
  172.     compiler uses the old scoping rules.
  173.  
  174.   * Standard C++ library
  175.     The standard C++ library containers should always be used in favor
  176.     of custom containers wherever reasonable.  std::string is used
  177.     throughout synergy but only as the CString typedef;  always use
  178.     CString, never std::string except in the arch library.  Synergy
  179.     avoids using auto_ptr due to some portability problems.  Synergy
  180.     makes limited use of standard algorithms and streams but they can
  181.     be freely used in new code.
  182.  
  183.   * Limited multiple inheritance
  184.     Classes should inherit implementation from at most one superclass. 
  185.     Inheriting implementation from multiple classes can have unpleasant
  186.     consequences in C++ due to it's limited capabilities.  Classes can
  187.     inherit    from any number of interface classes.  An interface class
  188.     provides only pure virtual methods.  Synergy breaks this rule in
  189.     IInterface which implements the virtual destructor for convenience.
  190.  
  191.   * No globals
  192.     Avoid global variables.  All global variables must be static, making
  193.     it visible only with its source file.  Most uses of global variables
  194.     are better served by static data members of a class.  Global
  195.     constants are permitted in some circumstances.
  196.  
  197.     Also avoid global functions.  Use public static member functions in
  198.     a class instead.
  199.  
  200.     These rules are violated by the main source file for each program
  201.     (except that the globals are still static).  They could easily be
  202.     rewritten to put all the variables and functions into a class but
  203.     there's little to be gained by that.
  204.  
  205.   * Private data only
  206.     If a class is plain-old-data (i.e. it has no methods) all of its
  207.     data members should be public.  Otherwise all of its data members
  208.     should be private, not public or protected.  This makes it much
  209.     easier to track the use of a member when reading code.  Protected
  210.     data is not allowed because `protected' is a synonym for `public
  211.     to my subclasses' and public data is a Bad Thing.  While it might
  212.     seem okay in this limited situation, the situation is not at all
  213.     limited since an arbitrary number of classes can be derived,
  214.     directly or indirectly, from the class and any of those classes
  215.     have full access to the protected data.
  216.  
  217.   * Plain old data
  218.     A class that merely contains data and doesn't perform operations
  219.     on that data (other than reads and writes) is plain old data (POD).
  220.     POD should have only public data members and non-copy constructors.
  221.     It must not have any methods other than constructors, not even a
  222.     destructor or assignment operators, nor protected or private data.
  223.     Note that this definition of POD is not the definition used in the
  224.     C++ standard, which limits the contained data types to types that
  225.     have no constructors, destructors, or methods.
  226.  
  227.   * Avoid using friend
  228.     Avoid declaring friend functions or classes.  They're sometimes
  229.     necessary for operator overloading.  If you find it necessary to
  230.     add friends to some class C, consider creating a utility class U.
  231.     A utility class is declared as the only friend of C and provides
  232.     only static methods.  Each method forwards to a private method on
  233.     an object of C type (passed as a parameter to the U's method).
  234.     This makes maintenance easier since only U has friend access to C
  235.     and finding any call to U is trivial (they're prefixed by U::).
  236.  
  237.   * Don't test for NULL when using `delete' or `delete[]'
  238.     It's unnecessary since delete does it anyway.
  239.  
  240. - Makefiles
  241.   Automake's makefiles (named Makefile.am) have a few requirements:
  242.   * Define the following macro at the top of the file:
  243.       NULL =
  244.   * Lists should have one item per line and end in $(NULL).  For
  245.     example:
  246.       EXTRA_DIST =     \
  247.           kiwi.txt     \
  248.           mango.cpp    \
  249.           papaya.h     \
  250.           $(NULL)
  251.     Indentation must use tabs in a makefile.  Line continuations
  252.     (backslashes) should be aligned using tabs.
  253.   * Lists of files should be sorted alphabetically in groups (e..g
  254.     source files, header files, then other files).  Lists of
  255.     subdirectories must be in the desired build order.
  256.  
  257. - Source Formatting
  258.   Every project has its own formatting style and no style satisfies
  259.   everyone.  New code should be consistent with existing code:
  260.  
  261.   * All files should include the copyright and license notice
  262.   * Use tabs to indent
  263.   * Tabs are 4 columns
  264.   * Lines should not extend past the 80th column
  265.   * Open braces ({) go on same line as introducing statement
  266.     `for (i = 0; i < 10; ++i) {' not
  267.      for (i = 0; i < 10; ++i)
  268.      {
  269.   * Close braces line up with introducing statement
  270.   * Open brace for function is on a line by itself in first column
  271.   * Close brace for function lines up with open brace
  272.   * Always use braces on: if, else, for, while, do, switch
  273.   * `else {' goes on its own line
  274.   * Always explicitly test pointers against NULL
  275.     e.g. `if (ptr == NULL)' not `if (ptr)'
  276.   * Always explicitly test integral values against 0
  277.     e.g. `if (i == 0)' not `if (i)'
  278.   * Put spaces around binary operators and after statements
  279.     e.g. `if (a == b) {' not `if(a==b){'
  280.   * C'tor initializers are one per line, indented one tab stop
  281.   * Other indentation should follow existing practice
  282.   * Use Qt style comments for extraction by doxygen (i.e. //! and /*!)
  283.   * Mark incomplete or buggy code with `FIXME'
  284.  
  285. - Other
  286.   * calls to LOG() should always be all on one line (even past column 80)
  287.  
  288.  
  289. Class Relationships
  290. -------------------
  291.  
  292. The doxygen documentation can help in understanding the relationships
  293. between objects.  Use `make doxygen' in the top level directory to
  294. create the doxygen documentation into doc/doxygen/html.  You must have
  295. doxygen installed, of course.
  296.  
  297. FIXME -- high level overview of class relationships
  298.  
  299.  
  300. Portability
  301. -----------
  302.  
  303. Synergy is mostly platform independent code but necessarily has
  304. platform dependent parts.  The mundane platform dependent parts
  305. come from the usual suspects:  networking, multithreading, file
  306. system, high resolution clocks, system logging, etc.  Porting
  307. these parts is relatively straightforward.
  308.  
  309. Synergy also has more esoteric platform dependent code.  The
  310. functions for low-level event interception and insertion,
  311. warping the cursor position, character to keyboard event
  312. translation, clipboard manipulation, and screen saver control
  313. are often obscure and poorly documented.  Unfortunately, these
  314. are exactly the functions synergy requires to do its magic.
  315.  
  316. Porting synergy to a new platform requires the following steps:
  317.  
  318. - Setting up the build
  319. - Adjusting lib/common/common.h
  320. - Implementing lib/arch
  321. - Implementing lib/platform
  322. - Tweaks
  323.  
  324. Setting up the build:
  325.  
  326. The first phase is simply to create the files necessary to build the
  327. other files.  On Unix, synergy uses autoconf/automake which produces
  328. a `configure' script that generates makefiles.  On Windows, synergy
  329. uses Visual C++ workspace and project files.  If you're porting to
  330. another Unix variant, you may need to adjust `configure.in',
  331. `acinclude.m4', and Unix flavor dependent code in lib/arch.  Note
  332. especially the SYSAPI_* and WINAPI_* macro definitions in
  333. ARCH_CFLAGS.  Exactly one of each must be defined.  It should also
  334. add AM_CONDITIONALs if a new SYSAPI_* or WINAPI_* was added.
  335.  
  336. Adjusting lib/common/common.h:
  337.  
  338. The lib/common/common.h header file is included directly or indirectly
  339. by every other file.  Its primary job is to include config.h, which
  340. defines macros depending on what the 'configure' script discovered
  341. about the system.  If the platform does not use the 'configure' script
  342. it must define the appropriate SYSAPI_* and WINAPI_* macro.  It may
  343. also do other platform specific setup.
  344.  
  345. Adjusting lib/common/BasicTypes.h:
  346.  
  347. No changes should be necessary in BasicTypes.h.  However, if the
  348. platform's system header files define SInt8, et al. you may need
  349. to adjust the typedefs to match the system's definitions.
  350.  
  351. Implementing lib/arch:
  352.  
  353. Much platform dependent code lives in lib/arch.  There are several
  354. interface classes there and they must all be implemented for each
  355. platform.  See the interface header files for more information.
  356.  
  357. Platforms requiring special functions should create a class named
  358. CArchMiscXXX where XXX is the platform name.  The class should have
  359. only static methods.  Clients can include the appropriate header
  360. file and make calls directly, surrounded by a suitable #ifdef/#endif.
  361.  
  362. If using automake, the Makefile.am should list the system specific
  363. files in a XXX_SOURCE_FILES macro where XXX matches the appropriate
  364. AM_CONDITIONAL symbol.  XXX_SOURCE_FILES must be added to EXTRA_DIST
  365. and the following added above the INCLUDES macro:
  366.  
  367.     if XXX
  368.     libarch_a_SOURCES =            \
  369.         $(COMMON_SOURCE_FILES)    \
  370.         $(XXX_SOURCE_FILES)        \
  371.         $(NULL)
  372.     endif
  373.  
  374. Implementing lib/platform:
  375.  
  376. Most of the remaining platform dependent code lives in lib/platform.
  377. The code there implements platform dependent window, clipboard, keyboard
  378. and screen saver handling.  If a platform is named XXX then the following
  379. classes should be derived and implemented:
  380.  
  381.   * CXXXClipboard : IClipboard
  382.     Provides clipboard operations.  Typically, this class will
  383.     have helper classes for converting between various clipboard
  384.     data formats.
  385.  
  386.   * CXXXEventQueueBuffer : IEventQueueBuffer
  387.     Provides operations for waiting for, posting and retrieving events.
  388.     Also provides operations for creating and deleting timers.
  389.  
  390.   * CXXXKeyState : CKeyState
  391.     Provides operations for synthesizing key events and for mapping a
  392.     key ID to a sequence of events to generate that key.
  393.  
  394.   * CXXXScreen : IScreen, IPrimaryScreen, ISecondaryScreen, IPlatformScreen
  395.     Provides screen operations.
  396.  
  397.   * CXXXScreenSaver : IScreenSaver
  398.     Provides screen saver operations.
  399.  
  400. If using automake, the Makefile.am should list the window system
  401. specific files in a XXX_SOURCE_FILES macro where XXX matches the
  402. appropriate AM_CONDITIONAL symbol.  XXX_SOURCE_FILES must be added
  403. to EXTRA_DIST and the following added above the INCLUDES macro:
  404.  
  405.     if XXX
  406.     libplatform_a_SOURCES = $(XXX_SOURCE_FILES)
  407.     endif
  408.  
  409. Tweaks:
  410.  
  411. Finally, each platform typically requires various adjustments here
  412. and there.  In particular, synergyc.cpp and synergys.cpp usually
  413. require platform dependent code for the main entry point, parsing
  414. arguments, and reporting errors.  Also, some platforms may benefit
  415. from a graphical user interface front end.  These are generally
  416. not portable and synergy doesn't provide any infrastructure for
  417. the code common to any platform, though it may do so someday.
  418. There is, however, an implementation of a GUI front end for Windows
  419. that serves as an example.
  420.