File: API_Description

package info (click to toggle)
tkchooser 2.0652-7
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 432 kB
  • ctags: 272
  • sloc: tcl: 3,344; makefile: 76; sh: 13
file content (225 lines) | stat: -rw-r--r-- 9,972 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
-- Ethan Gold <etgold@cs.vassar.edu> --
-- last modified 3/30/98 --

Separation
----------
Tkchooser is divided into 3 main pieces:
	Main Browser
	Major protocol modules
	Minor protocol plugins
	
All three parts provide API's which will hopefully
remain somewhat fixed.

Description of protocol architecture
------------------------------------

Major protocols such as appletalk, smb, and ipx are supported
via sourced protocol modules. These modules provide a simple API
to the main browser in the form of start and stop functions. The
modules are closely coupled to the main browser and internal non-API
changes to the browser may affect the protocol modules. The modules
also provide and API to their client plugins. The plugin API's for
the modules may differ from each other, but if someone were to write
a CAP appletalk module to replace the current Netatalk appletalk
module the API's to both the plugins and main browser would have to
stay the same. This would ensure seamless drop-in replacement of
the existing protocol module.
Modules may set and have access to the main global variables. Because
they have the potential to muck things up badly, they must be
written carefully. Adding new (as opposed to replacing) major protocol
modules will require internal modification of the main browser. This
MAY change, but will require some reworking of the main<->protocol
API's to provide some of the functions that are required from the
plugins.


Description of plugin architecture
----------------------------------
The plugin architecture allows new functionality to be added just
by copying a new plugin into the $libdir/plugins directory and
it's associated icon into the $libdir/icons directory. Generally
plugins will associate themselves with only one major protocol, but
they should be able to register themselves with more than one if
they do not need protocol specific functionality. The plugins do NOT
have access to the main browser global scope and thus cannot save
state in global variables. This makes textentry widgets in the main
browser window kind of tough. The plugins MUST provide a set of functions
as an API for the major protocol and main browser to call. Plugins
are easily added and removed without changing any of the main or module
code.


Description of main browser API
-------------------------------
The main browser provides two mostly separated API's - one to the
major protocols in addition to some nasty global stuff, and one to
the plugins.

	API to modules:
	---------------
All widgets are available, but the only ones that should be used
are the zones listbox. This may be genericized in the future so
main browser internals can be changed more easily.
All global data is available, but should NOT be modified except
very very carefully.
The main browser provides directories to module specific external
programs (getzones, nbplkup, smbmount, etc.) via global variables
set in the chooser.cfg file or overridden in the user's
~/.chooser/chooser.cfg file.

	API to plugins:
	---------------
The plugins do not have direct access to the global scope. Ok, that's
not really true. I've written the Enscript plugin to use the plug_globals
array directly instead of using the normal access functions. So consider
that global array fair game.
The following functions and procedures are available to the plugins:

	* plug_frame: returns the name of the frame widget that the
	  plugin may use to pack its widgets into. This frame is the
	  bottom right corner of the main browser window.
	* plug_list: returns the name of the listbox widget that the
	  plugin can write its entity listings into.
	* plug_list_label: returns the name of the label widget that
	  sits above the plugin listbox.
	* get_curr_item: returns the current plugin listbox item.
	* get_propfont: returns the name of the configured proportional
	  font.
	* get_fixedfont: returns the name of the configured fixed width
	  font.
	* tilde {filename}: performs tilde expansion of a filename if
	  necessary and returns the resulting string. Might not work
	  in strange setups, but should be fine for most vanilla
	  configurations.

	- these two functions allow some global state to be stored
	* set_glob {name value}: sets the global array element "name"
	  to "value"
	* get_glob {name}: returns the value stored in the global
	  array indexed by "name." Returns a null string if the
	  variable does not exist.
	* debug {}: returns a boolean value for turning on and off
	  debugging information
	
	* check_deps {dependancies}: procedure to test for the
	  existance of a list of commands. The elements of the list
	  may be either command names alone or absolute paths.
	  Plugins and/or protocol modules should use this function
	  before full registration to determine if everything they
	  need is available. Returns 0 if any element can't be found,
	  otherwise 1. It is stateless and may be called many times
	  to test different conditions. Protocol modules will disable
	  themselves if they can't find programs they need and thus
	  plugins requiring only the same programs that their parent
	  module does need not test for them again.

	* register_plugin {major plugname plugpubname}: procedure to
	  register the plugin with the main browser. This function may
	  be called more than once per plugin. Arguments are as
	  follows:	major = major protocol name
				must be one of "appletalk", "smb", "ipx"
				or other supported major protocol.
			plugname = internal plugin name
			plugpubname = user visible plugin name
	* error {caller message}: displays "message" in a dialog window
	  labeled with "caller."

	* toggleentries {window checkboxvariablename}: toggles username
	  and password entries on and off when the guest checkbutton
          controlled by the variable named "checkbotvariablename" is
	  clicked. The entry widgets must follow the name form:
          $window.nameframe.name and $window.passframe.pass


Description of protocol module API's
------------------------------------
The major protocol modules provide a simple API to the main browser
and a more complex one to the plugins. Additional API functions may
be added to these modules in the future, but hopefully none will
be taken away. Otherwise what's the point? All network/protocol
specific functions/procedures are supplied by the protocol module.
All protocol module functions names MUST have follow the form
"modulename.functionname" so the browser and plugins can properly
invoke them.

Modules MUST provide the following procedures to the main browser:

	* protocolname.start {}
	* protocolname.stop {}
	* protocolname.setcurrzone {newzone}

Modules MUST destroy all widgets they create (hopefully none) and
cancel ALL pending tasks (i.e. zone list updates) in the stop function.
See the appletalk module as an example.

Module specific API's are not going to be documented here because
that would be a pain for me. So you have to read the individual modules to
get the API for the moment. There should (or will) be a commented API
listing at the top of each module.
The Samba one is kinda ugly... feel free to email me if you want
to write any kind of plugin.


Description of plugin API and how to write one
----------------------------------------------
Each plugin must register itself by calling the register_plugin
procedure with the appropriate arguments. This is the only line
other than maybe some "puts" status statements that should appear
outside of procedures or functions. Plugins do NOT have access to
the global scope, so any variables set outside of functions will be
lost! All function/procedure names MUST follow the naming convention
pluginname.functionname, otherwise the protocol modules and main
browser will not be able to find anything. Non API functions technically
do not have to follow this convention, but you run the risk of conflicts
by doing otherwise.

Plugins have access to the frame under the plugins entity listbox
and the plugin listbox itself as well as it's associated label.
See the main browser API for how to get these widget names.
Plugins MUST delete all widgets they create when the stop function
is called.
The plugins MUST NOT delete any widgets that they do not create.
Plugins may schedule recurring tasks, but they MUST  be cleaned up
when the stop function is called. See any of the appletalk plugins
as an example. Global variables set thru the main browser's API will
be cleared every time a plugin is started.

The plugins must provide a set of functions to the main browser:

	* pluginname.geticon {}: called by the browser to get
	  the plugin's icon name. Hardcode the string value in
	  here instead of using a global.

	* pluginname.getpubname {}: called by the browser to get
	  the plugin's public name. Hardcode the string value in
	  here instead of using a global.

	* pluginname.getprotocol {}: called by the browser to get
	  the plugin's protocol name. Hardcode the string value in
	  here instead of using a global. - note, this is not
	  designed to handle multiple protocols... But function is
	  never called right now.

	* pluginname.start {}: called when the plugin's icon is
	  clicked in the browser. Build and pack widgets and start
	  recurring tasks such as listbox updates.

	* pluginname.stop {}: called when another plugin icon is
	  clicked on or another major protocol is selected. Destroy
	  all private widgets and cancel any pending tasks. Clear
	  the listbox too, just to be safe.

	* pluginname.doubleclick {}: function to be called when a
	  plugin listbox widget is double-clicked

	* pluginname.newzone {}: function called by the browser to
	  notify the plugin that a new zone has been selected.

Recommended function:
	I recommend using a pluginname.widgets {start|stop} function
	that knows the names of all the widgets it has to create and
	destroy. This keeps the starting and stopping stuff in one
	place, making the plugin widget management a little easier.