-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathlibtw.txt
585 lines (447 loc) · 20.9 KB
/
libtw.txt
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
libtw 2.0.0 tutorial
libtw is the library that talks to `twin' server. Since the parallel between
X11 server and twin server comes out so often, we could say libtw is the
equivalent of libX11.
One thing that has been asked many times is porting applications from ncurses
to libtw. Unlickily, things are not so straightforward as the two libraries
have quite different approaches: libtw is a network transparent, multi window,
multi headed, event driven, mouse aware library, while ncurses is full-screen,
single-headed library without mouse support and without events.
If all you want is to have a ncurses program run inside a SINGLE twin window,
you could just let it run unmodified inside twterm, or, if you like hacking
programs, you could substitute printf(), write(), etc. calls to standard output
with TwWriteCharsetWindow() and read() from standard input with TwReadMsg().
Yet, what you will get will still be a program displaying in a single window:
converting an application that uses ncurses windows to use multiple libtw
windows is usually much more difficult as with libtw any open window can
generate events at any time, while with ncurses the "focused" window that
generates events (user input) is decided by the application.
the libtw API
1. Types and defines
To access libtw functions, you need to
#include <Tw/Tw.h>
This include file defines various data types used by all libtw functions.
The types, together with their usual definition, are:
typedef signed char num;
typedef unsigned char byte;
typedef signed short dat;
typedef unsigned short udat;
typedef signed int ldat;
typedef unsigned int uldat;
Anyway, except for `num' and `byte' (which are always 1 byte long)
you must NEVER assume to know a type's size as it may change between
releases of libtw. You should instead use either sizeof(<type>)
or the defines
MINDAT
MAXDAT
MAXUDAT
MINLDAT
MAXLDAT
MAXULDAT
for the minimum and maximum values of the various types.
Other defines coming from the include are:
TW_NOID : a numeric value meaning `no object'. Used to indicate
an invalid window, screen, msgport, etc. (see below)
TW_NOFD : a negative number meaning `no file descriptor' (-1)
FALSE, TRUE : the obvious meaning
TW_INET_PORT: the base TCP port used by libtw/twin server (7754)
TW_SMALLBUFF : the size for a small data buffer
TW_BIGBUFF : the size for a bigger data buffer
To represent colors, there are some dedicated types and defines:
trune;
tcolor;
tcell;
Don't assume you know the sizes of these types, always use
sizeof(<type>) if you need it.
trune can hold a single character. This means it surely can contain
an ASCII character, but depending on libtw configuration, it may even
contain a UNICODE character.
tcolor can hold a single foreground color + background color combination
This is loosely based on VGA colors, with 8 different colors
tblack, tblue, tgreen, tcyan, tred, tmagenta, tyellow, twhite
and a special thigh flag. The maximum possible color value is tmaxcol.
to convert between this representation and ANSI colors, there are two macros:
TANSI2VGA(col) and TVGA2ANSI(col)
To compose and decompose a tcolor from fg/bg pair, you have the macros
TFG(fg), TBG(bg) and TCOL(fg,bg) to compose a tcolor
TCOL(fg,bg) is simply TFG(fg)|TBG(bg)
TCOLBG(col) and TCOLFG(col) to decompose it
To compose and decompose a tcell from tcolor/trune pair, you have the macros
TCELL(col,rune) to compose and TCOLOR(cell), TRUNE(cell) to decompose.
Examples:
a blue `f' on white background is TCELL( TCOL(tblue,twhite), 'f')
a cyan foreground on red background is TCOL(tcyan,tred)
and so on...
WARNING:
TRUNE(), TCOLOR() and TCELL() are macros that can evaluate their
arguments more than once. Don't use arguments that have side effects
(like increments) inside them.
For example, this causes unpredictable results because of the `h++'
increment inside the TCELL() macro:
tcell a[2];
trune buf[2], *h = buf;
a[0] = TCELL(TCOL(twhite,tblack), *h++);
a[1] = TCELL(TCOL(twhite,tblack), *h++);
(types for time intervals: TODO)
Mouse events masks
HOLD_LEFT, HOLD_MIDDLE, HOLD_RIGHT, HOLD_ANY
PRESS_LEFT, PRESS_RIGHT, PRESS_MIDDLE, PRESS_ANY
#define DOWN_LEFT (HOLD_LEFT|PRESS_LEFT)
#define DOWN_RIGHT (HOLD_RIGHT|PRESS_RIGHT)
#define DOWN_MIDDLE (HOLD_MIDDLE|PRESS_MIDDLE)
#define DOWN_ANY (HOLD_ANY|PRESS_ANY)
RELEASE_LEFT, RELEASE_RIGHT, RELEASE_MIDDLE, RELEASE_ANY
DRAG_MOUSE
MOTION_MOUSE
#define ANY_ACTION_MOUSE (PRESS_ANY | RELEASE_ANY | DRAG_MOUSE)
isPRESS(code), isDRAG(code), isRELEASE(code), isMOTION(code)
Finally, the types for the various libtw objects:
tobj (generic), twidget (generic), tgadget, trow, twindow,
tmenuitem, tmenu, tscreen, tmsgport
The following are instead pointers to various structures:
tevent_common, tevent_keyboard, tevent_keyboard, tevent_mouse,
tevent_display, tevent_window, tevent_gadget, tevent_menu,
tevent_selection, tevent_selectionnotify, tevent_selectionrequest,
tevent_any
tmsg
/* msg ->Type : */
TW_MSG_DISPLAY, TW_MSG_WINDOW_KEY, TW_MSG_WINDOW_MOUSE,
TW_MSG_WINDOW_CHANGE, TW_MSG_WINDOW_GADGET, TW_MSG_MENU_ROW
TW_MSG_SELECTION, TW_MSG_SELECTIONNOTIFY, TW_MSG_SELECTIONREQUEST
TW_MSG_SELECTIONCLEAR
tdisplay
/* Gadget Flags : */
TW_GADGETFL_DISABLED, TW_GADGETFL_TOGGLE
/* Row Flags : */
TW_ROW_INACTIVE, TW_ROW_ACTIVE, TW_ROW_IGNORE
/* Window Attr : */
TW_WINDOW_WANT_KEYS, TW_WINDOW_WANT_MOUSE, TW_WINDOW_WANT_MOUSE_MOTION
TW_WINDOW_WANT_CHANGES, TW_WINDOW_DRAG, TW_WINDOW_RESIZE, TW_WINDOW_CLOSE
TW_WINDOW_ROLLED_UP, TW_WINDOW_X_BAR, TW_WINDOW_Y_BAR
/* Window Flags: */
TW_WINDOWFL_USEROWS, TW_WINDOWFL_USECONTENTS, TW_WINDOWFL_USEEXPOSE
TW_WINDOWFL_USEFILL, TW_WINDOWFL_CURSOR_ON, TW_WINDOWFL_MENU,
TW_WINDOWFL_DISABLED, TW_WINDOWFL_BORDERLESS,
TW_WINDOWFL_ROWS_INSERT, TW_WINDOWFL_ROWS_DEFCOL, TW_WINDOWFL_ROWS_SELCURRENT
/* Window CursorType : */
TW_NOCURSOR, TW_LINECURSOR, TW_SOLIDCURSOR
/* Buttons on window borders: */
TW_MAX_BUTTONS
2. Functions
When no connections are open, you can call
byte Tw_CheckMagic(byte Magic[]);
to ensure sizeof() of the various types are the same in the client
and in the library, and you can call
void Tw_ConfigMalloc(void *(*my_malloc)(size_t),
void *(*my_realloc)(void *, size_t),
void (*my_free)(void *));
to set the functions
extern void *(*Tw_AllocMem)(size_t);
extern void *(*Tw_ReAllocMem)(void *, size_t);
extern void (*Tw_FreeMem)(void *);
extern byte *(*Tw_CloneStr)(byte *);
to your custom malloc/free routines.
To open a connection to a twin server, call (Tw_Display is optional)
byte TwOpen(byte *Tw_Display);
or
tdisplay Tw_Open(byte *Tw_Display);
To close,
void TwClose(void);
or
void Tw_Close(tdisplay TwD);
The file descriptor of a connection is returned by
int TwConnectionFd(void);
or
int Tw_ConnectionFd(tdisplay TwD);
As you may already have noticed, the functions starting with "Tw_"
are multiheaded, i.e. can handle multiple tdisplay:s
If all you want is to talk to a _single_ display, you can use the functions
starting with "Tw" only (they are actually macros) and save a little typing.
In case you need it, the "Tw" functions use the tdisplay Tw_DefaultD, so for
example, TwConnectionFd is defined as
#define TwConnectionFd() Tw_ConnectionFd(Tw_DefaultD)
/* the following four functions return FALSE only after libtw has paniced */
/* flush output buffer.
* if not all data can be written immediately, block, then write data when
* output becomes possible again. return only after all data has been written
*/
byte TwFlush(void);
byte Tw_Flush(tdisplay TwD);
/* flush output buffer and wait for all replies from server */
byte TwSync(void);
byte Tw_Sync(tdisplay TwD);
/* did the library panic on that display? */
byte TwInPanic(void);
byte Tw_InPanic(tdisplay TwD);
/*
* after a panic (i.e. a fatal error), the only useful thing
* you can do is to Tw_Close() the display and, if you need,
* to Tw_Open() again.
*/
/*
* try to write to the underlying socket.
* if not all data could be written immediately, write as much as possible,
* keep the rest queued, then return.
*
* returns FALSE only after libtw has paniced,
* returns TRUE if all data was written.
* returns TRUE+TRUE if not all data could be written.
*/
byte TwTimidFlush(void);
byte Tw_TimidFlush(tdisplay TwD);
/*
* This is the function you must call to get a tmsg from the server.
* If Wait is TRUE and no tmsg is available, it flushes output queue
* (with Tw_Flush()) then waits until a tmsg arrives.
* If Wait is FALSE and no tmsg is available, it flushes output queue
* non-blocking (with Tw_TimidFlush()), then it tries non-blocking
* to receive more Msgs.
*
* In both cases, if there are already received Msgs they are returned
* without waiting.
*/
tmsg TwReadMsg(byte Wait);
tmsg Tw_ReadMsg(tdisplay TwD, byte Wait);
/*
* this is just like Tw_ReadMsg(), but returns a Tw_AllocMem() copy
* of the message, to avoid concurrency problems with other threads.
* You must Tw_DeleteMsg() it when done!
*/
tmsg TwCloneReadMsg(byte Wait);
tmsg Tw_CloneReadMsg(tdisplay TwD, byte Wait);
/*
* This is the function you must call to check if there are pending Msgs.
* There may be messages to process even if there's nothig to read on
* (Fd = Tw_ConnectionFd()) as messages can be received also during any
* blocking function call like Tw_Sync(), Tw_CreateWindow(), etc.
* Look at the twterm sources for an example.
*
* This returns the first pending tmsg, or (tmsg)0 if none is available
* and none can be received non-blocking.
*/
tmsg TwPeekMsg(void);
tmsg Tw_PeekMsg(tdisplay TwD);
/*
* <*> B I G W A R N I N G <*>
*
* Tw_PeekMsg() and Tw_ReadMsg() return a (tmsg) pointer to data
* in a static buffer. The pointer becomes invalid after a call
* to any function of Tw/Tw.h with non-void return value,
* so that it sends something to the server and waits for the server
* to send the return value (i.e. it is blocking),
* in particular any of the following:
* (but calling one of these with an argument pointing to data
* inside a tmsg is allowed)
*
* Tw_Sync();
* Tw_PeekMsg();
* Tw_ReadMsg();
* Tw_CreateGadget();
* Tw_SearchGadget();
* Tw_CreateWindow();
* Tw_Create4MenuWindow();
* Tw_Create4MenuMenuItem();
* Tw_CreateMsgPort();
* Tw_CreateMenu();
* Tw_FirstScreen();
* Tw_FirstMsgPort();
* [...]
*
* If you are using threads, or just have a doubt that your code might
* reference the message returned Tw_PeekMsg() or Tw_ReadMsg()
* after a call to one of the above functions, use Tw_CloneReadMsg() :
* it's just like Tw_ReadMsg(), except that it returns a Tw_AllocMem() copy
* of the message, that you can use as long as you wish. Just remember to
* Tw_DeleteMsg() it when done!
*
*
* Other important notes:
* 1. Only ONE MsgPort can exists at max on each connection.
* 2. Tw_DeleteMsgPort() calls Tw_DeleteMenu() on all menus created by the client
* and Tw_DeleteWidget/Gadget/Window() on all gadgets/widgets/windows created by the client.
* 3. Tw_DeleteMenu() calls Tw_UnMapWindow() on all windows which use that menu.
* 4. Tw_DeleteWidget[/Gadget/Window]() calls Tw_UnMapWidget() on all sub-gadgets/widgets/windows
* of that widget, does NOT call Tw_DeleteWidget[/Gadget/Window]() recursively on them!
* If you wish to delete a widget and all sub-widgets inside it,
* use Tw_RecursiveDeleteWidget[/Gadget/Window]()
*
* also, if you exit() from your program without calling Tw_Flush(), Tw_Sync() or Tw_Close(),
* pending data will *NOT* be sent to the server.
*/
tmsgport Tw_CreateMsgPort(tdisplay TwD, byte NameLen, byte *ProgramName, time_t PauseSec, frac_t PauseFraction, byte WakeUp);
/* WakeUp: */
#define TW_TIMER_ALWAYS ((byte)1)
#define TW_TIMER_ONCE ((byte)2)
void Tw_DeleteMsgPort(tdisplay TwD, tmsgport MsgPort);
tgadget Tw_CreateGadget(tdisplay TwD, twidget Parent, dat Left, dat Up,
tcolor ColText, tcolor ColTextSelect, tcolor ColTextDisabled, tcolor ColTextSelectDisabled,
uldat Attr, uldat Flags, dat XWidth, dat YWidth);
void Tw_DeleteGadget(tdisplay TwD, tgadget Gadget);
tgadget Tw_SearchGadget(tdisplay TwD, twindow Window, dat i, dat j);
tgadget Tw_CreateButtonGadget(tdisplay TwD, twindow Window,
twindow Tw_CreateButtonGadget(tdisplay TwD, twidget Parent, dat XWidth, dat YWidth, TW_CONST byte *Title,
uldat Flags, udat Code, tcolor BgCol, tcolor Col, tcolor ColDisabled,
dat Left, dat Up);
void Tw_Create4MenuRow(tdisplay TwD, twindow Window, udat Code, byte FlagActive, uldat TextLen, byte *Text);
#define Tw_Row4Menu Tw_Create4MenuRow
twindow Tw_CreateWindow(tdisplay TwD, dat NameLen, TW_CONST byte *Name, TW_CONST tcolor *ColName, tmenu Menu,
tcolor ColText, uldat cursorType, uldat Attr, uldat Flags,
dat XWidth, dat YWidth, dat ScrollBackLines);
void Tw_DeleteWindow(tdisplay TwD, twindow Window);
twindow Tw_Create4MenuWindow(tdisplay TwD, tmenu Menu);
#define Tw_Win4Menu Tw_Create4MenuWindow
void Tw_MapWindow(tdisplay TwD, twindow Window, tscreen Screen);
void Tw_UnMapWindow(tdisplay TwD, twindow Window);
void Tw_WriteCharsetWindow(tdisplay TwD, twindow Window, uldat AsciiLen, TW_CONST char *charset_bytes);
void Tw_WriteUtf8Window(tdisplay TwD, twindow Window, ldat AsciiLen, TW_CONST char *utf8_bytes);
void Tw_WriteTCellWindow(tdisplay TwD, twindow Window, udat x, udat y, uldat Len, TW_CONST tcell *cells);
void Tw_WriteRowWindow(tdisplay TwD, twindow Window, uldat Len, byte *Text);
void Tw_SetColTextWindow(tdisplay TwD, twindow Window, tcolor ColText);
void Tw_SetColorsWindow(tdisplay TwD, twindow Window, udat Bitmap, tcolor ColGadgets, tcolor ColArrows, tcolor ColBars, tcolor ColTabs,
tcolor ColBorder, tcolor ColText, tcolor ColSelect, tcolor ColDisabled, tcolor ColSelectDisabled);
void Tw_ConfigureWindow(tdisplay TwD, twindow Window, byte Bitmap, dat Left, udat Up, udat MinXWidth, udat MinYWidth, udat MaxXWidth, udat MaxYWidth);
void Tw_ResizeWindow(tdisplay TwD, twindow Window, udat XWidth, udat YWidth);
void Tw_GotoXYWindow(tdisplay TwD, twindow Window, uldat X, uldat Y);
tgadget Tw_SearchGadgetWindow(tdisplay TwD, twindow Window, dat X, dat Y);
tmenuitem Tw_Create4MenuMenuItem(tdisplay TwD, tmenu Menu, twindow Window, byte Flags, udat NameLen, byte *Name);
#define Tw_Item4Menu Tw_Create4MenuMenuItem
tmenuitem Tw_Create4MenuCommonMenuItem(tdisplay TwD, tmenu Menu);
#define Tw_Item4MenuCommon Tw_Create4MenuCommonMenuItem
void Tw_DeleteMenuItem(tdisplay TwD, tmenuitem MenuItem);
tmenu Tw_CreateMenu(tdisplay TwD, tmsgport MsgPort, tcolor ColItem, tcolor ColSelect, tcolor ColDisabled,
tcolor ColSelectDisabled, tcolor ColShtCut, tcolor ColSelShtCut, byte FlagDefColInfo);
#define Tw_Grab Tw_CreateMutex
void Tw_SetInfoMenu(tdisplay TwD, tmenu Menu, byte Flags, uldat Len, byte *Text, tcolor *ColText);
#define Tw_Info4Menu Tw_SetInfoMenu
void Tw_DeleteMenu(tdisplay TwD, tmenu Menu);
void Tw_BgImageScreen(tdisplay TwD, tscreen Screen, udat BgWidth, udat BgHeight, tcell *BgImage);
tscreen Tw_FirstScreen(tdisplay TwD);
twindow Tw_FirstWindow(tdisplay TwD, tscreen Screen);
tgadget Tw_FirstGadget(tdisplay TwD, twindow Window);
tmsgport Tw_FirstMsgPort(tdisplay TwD);
tmenu Tw_FirstMenu(tdisplay TwD, tmsgport MsgPort);
tmenuitem Tw_FirstMenuItem(tdisplay TwD, tmenu Menu);
tobj Tw_PrevObj(tdisplay TwD, tobj Obj);
tobj Tw_NextObj(tdisplay TwD, tobj Obj);
tobj Tw_ParentObj(tdisplay TwD, tobj Obj);
udat Tw_GetDisplayWidth(tdisplay TwD);
udat Tw_GetDisplayHeight(tdisplay TwD);
tmsg Tw_CreateMsg(tdisplay TwD, udat Type, udat Len);
void Tw_DeleteMsg(tdisplay TwD, tmsg msg);
byte Tw_SendMsg(tdisplay TwD, tmsgport MsgPort, tmsg msg);
void Tw_BlindSendMsg(tdisplay TwD, tmsgport MsgPort, tmsg msg);
/*
* Selection handling. This is very similar to X11:
*
* if client <a> wants to know the contents of selection to paste it,
* it must find who is the Selection owner (say <b>) and ask him:
*
* Tw_RequestSelection(TwD, Tw_GetOwnerSelection(TwD), ReqPrivate);
*
* ReqPrivate is some opaque data that client <a> may specify,
* and it will be sent back later literally.
*
* after a while, a TW_MSG_SELECTIONNOTIFY will arrive with all the
* precious Selection data and also with ReqPrivate.
*
*
*
* Now the other half of the story: What The Selection Owner Must Do.
* (this is handled automagically by twin server if the client choosed
* not to receive mouse events)
*
* If the user just hilighted some data in a window of client <b>,
* client <b> will want to become the Selection owner, so that other
* clients may receive that data too. For this, client <b> must call
*
* Tw_SetOwnerSelection(TwD, myMsgPort, TW_SEL_CURRENTTIME, TW_SEL_CURRENTTIME);
*
* where myMsgPort is actually client <b> MsgPort. From now on, and until
* client <b> receives a TW_MSG_SELECTIONCLEAR event, client <b> must
* send its precious Selection to whoever asks for it: every time client <b>
* receives a TW_MSG_SELECTIONREQUEST event from libtw, it must call
*
* Tw_NotifySelection(TwD, Requestor, ReqPrivate, Magic, MIME, Len, Data);
*
* where Requestor and ReqPrivate come from the TW_MSG_SELECTIONREQUEST event,
* and the rest is the Selection data: its Magic type (usually TW_SEL_UTF8MAGIC),
* its MIME type ("text/plain", or whatever looks appropriate),
* its Len in bytes and finally, Data: a pointer to the actual data.
*
*
* There is a last thing: how can client <a> know that the user
* wants to paste the selection in one of its windows ?
* If the client keeps track of mouse movement and buttons, it can figure
* out by its own. Otherwise, twin automagically solves the problem sending
* a TW_MSG_SELECTION to the client when it should paste the selection
* in a window. Client should then call the first function said above,
*
* Tw_RequestSelection(TwD, Tw_GetOwnerSelection(TwD), ReqPrivate);
*
* and start the chain of communications just explained.
* Once client <a> got the Selection, it must paste it in the window
* in whatever way is appropriate for that window.
*
* P.S. hint: a possible use for ReqPrivate is to store the window
* that client <a> must paste into.
*
* Finally, the function prototypes:
*/
tobj Tw_GetOwnerSelection(tdisplay TwD);
void Tw_RequestSelection(tdisplay TwD, tobj Owner, uldat ReqPrivate);
void Tw_SetOwnerSelection(tdisplay TwD, tobj Owner, time_t Time, frac_t Frac);
#define TW_SEL_CURRENTTIME ((time_t)0)
void Tw_NotifySelection(tdisplay TwD, tobj Requestor, uldat ReqPrivate,
uldat Magic, char MIME[TW_MAX_MIMELEN], uldat Len, byte *Data);
/*
* a few string/memory related function macros:
*/
#define TwCopyStr(From,To) strcpy((To),(From))
#define TwCopyMem(From, To, Size) memcpy((To), (From), (size_t)(Size))
#define TwMoveMem(From, To, Size) memmove((To), (From), (size_t)(Size))
/*
* the "Tw_" versions of the above ones exist, and have exactly the same
* definition (no tdisplay argument here)
*/
/*
* Check if the server supports a function given its name
* (without the Tw/Tw_ prefix)
*/
uldat TwFindFunction(byte Len, byte *Name);
uldat Tw_FindFunction(tdisplay TwD, byte Len, byte *Name);
/*
* Check if the server supports a list of functions given its pointers
* (you must use the ones with Tw_ prefix as the other are macros)
* The list must be NULL terminated.
*/
byte Tw_FindFunctions(tdisplay TwD, void *Function, ...);
/*
* enable gzip compression on the socket
*/
byte TwEnableGzip(void);
byte Tw_EnableGzip(tdisplay TwD);
/*
* disable gzip compression on the socket
*/
byte TwDisableGzip(void);
byte Tw_DisableGzip(tdisplay TwD);
/*
* these are reserved for the programs "twattach" and "twdisplay" :
* manage attaching/detaching of display drivers inside twin core.
*/
void TwNeedResizeDisplay(void);
void Tw_NeedResizeDisplay(tdisplay TwD);
void TwAttachHW(uldat len, char *name, byte redirect);
void Tw_AttachHW(tdisplay TwD, uldat len, char *name, byte redirect);
char *TwAttachGetReply(uldat *len);
char *Tw_AttachGetReply(tdisplay TwD, uldat *len);
void TwAttachConfirm(void);
void Tw_AttachConfirm(tdisplay TwD);
byte TwDetachHW(uldat len, char *name);
byte Tw_DetachHW(tdisplay TwD, uldat len, char *name);
/*
* load a customizable translation table. "trans" points to a 128 byte
* translation table for the ASCII codes 0x80 - 0xff
*/
void TwSetFontTranslation(byte trans[0x80]);
void Tw_SetFontTranslation(tdisplay TwD, byte trans[0x80]);