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 586 587 588 589 590 591
|
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 TwWriteAsciiWindow() 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:
hwfont;
hwcol;
hwattr;
Don't assume you know the sizes of these types, always use
sizeof(<type>) if you need it.
hwfont 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.
hwcol can hold a single foreground color + background color combination
This is loosely based on VGA colors, with 8 different colors
BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE
and a special HIGH flag. The maximum possible color value is MAXCOL.
to convert between this representation and ANSI colors, there are two macros:
ANSI2VGA(col) and VGA2ANSI(col)
To compose and decompose a hwcol from fg/bg pair, you have the macros
FG(fg), BG(bg) and COL(fg,bg) to compose a hwcol
COL(fg,bg) is simply FG(fg)|BG(bg)
COLBG(col) and COLFG(col) to decompose it
To compose and decompose a hwattr from hwcol/hwfont pair, you have the macros
HWATTR(col,font) to compose and HWCOL(attr), HWFONT(attr) to decompose.
Examples:
a blue `f' on white background is HWATTR( COL(BLUE,WHITE), 'f')
a cyan foreground on red background is COL(CYAN,RED)
and so on...
WARNING:
HWFONT(), HWCOL() and HWATTR() 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 HWATTR() macro:
hwattr a[2];
hwfont buf[2], *h = buf;
a[0] = HWATTR(COL(WHITE,BLACK), *h++);
a[1] = HWATTR(COL(WHITE,BLACK), *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 Attrib : */
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 Msg from the server.
* If Wait is TRUE and no Msg is available, it flushes output queue
* (with Tw_Flush()) then waits until a Msg arrives.
* If Wait is FALSE and no Msg 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_FreeMem() it when done!
*/
tmsg TwReadMsg_Clone(byte Wait);
tmsg Tw_ReadMsg_Clone(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 Msg, 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 libTw.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_ReadMsg_Clone() :
* 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_FreeMem() 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,
hwcol ColText, hwcol ColTextSelect, hwcol ColTextDisabled, hwcol ColTextSelectDisabled,
uldat Attrib, 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, hwcol BgCol, hwcol Col, hwcol 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 hwcol *ColName, tmenu Menu,
hwcol ColText, uldat cursorType, uldat Attrib, 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_WriteAsciiWindow(tdisplay TwD, twindow Window, uldat AsciiLen, TW_CONST byte *AsciiSeq);
void Tw_WriteTextWindow(tdisplay TwD, twindow Window, ldat AsciiLen, TW_CONST byte *Text);
void Tw_WriteUnicodeWindow(tdisplay TwD, twindow Window, ldat AsciiLen, TW_CONST udat *UnicodeSeq);
void Tw_WriteHWAttrWindow(tdisplay TwD, twindow Window, udat x, udat y, uldat Len, TW_CONST hwattr *Attr);
void Tw_WriteRowWindow(tdisplay TwD, twindow Window, uldat Len, byte *Text);
void Tw_SetColTextWindow(tdisplay TwD, twindow Window, hwcol ColText);
void Tw_SetColorsWindow(tdisplay TwD, twindow Window, udat Bitmap, hwcol ColGadgets, hwcol ColArrows, hwcol ColBars, hwcol ColTabs,
hwcol ColBorder, hwcol ColText, hwcol ColSelect, hwcol ColDisabled, hwcol 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, hwcol ColItem, hwcol ColSelect, hwcol ColDisabled,
hwcol ColSelectDisabled, hwcol ColShtCut, hwcol ColSelShtCut, byte FlagDefColInfo);
#define Tw_Grab Tw_CreateMutex
void Tw_SetInfoMenu(tdisplay TwD, tmenu Menu, byte Flags, uldat Len, byte *Text, hwcol *ColText);
#define Tw_Info4Menu Tw_SetInfoMenu
void Tw_DeleteMenu(tdisplay TwD, tmenu Menu);
void Tw_BgImageScreen(tdisplay TwD, tscreen Screen, udat BgWidth, udat BgHeight, hwattr *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_TEXTMAGIC),
* 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, byte MIME[TW_MAX_MIMELEN], uldat Len, byte *Data);
/*
* a few string/memory related function macros:
*/
#define TwLenStr(S) strlen(S)
#define TwCmpStr(S1, S2) strcmp((S1), (S2))
#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))
#define TwWriteMem(Mem, Char, Size) memset((Mem), (int)(Char), (size_t)(Size))
#define TwCmpMem(m1, m2, Size) memcmp((m1), (m2), (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, byte *name, byte redirect);
void Tw_AttachHW(tdisplay TwD, uldat len, byte *name, byte redirect);
byte *TwAttachGetReply(uldat *len);
byte *Tw_AttachGetReply(tdisplay TwD, uldat *len);
void TwAttachConfirm(void);
void Tw_AttachConfirm(tdisplay TwD);
byte TwDetachHW(uldat len, byte *name);
byte Tw_DetachHW(tdisplay TwD, uldat len, byte *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]);
|