#include "vim.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef INET_SOCKETS
#include <netdb.h>
#include <netinet/in.h>
#else
#include <sys/un.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/param.h>
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif
#include <unistd.h>
#include <string.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/AtomMgr.h>
#include <Xm/PushB.h>
#ifdef HAVE_X11_XPM_H
# include <X11/xpm.h>
#else
# ifdef HAVE_XM_XPMP_H
# include <Xm/XpmP.h>
# endif
#endif
#ifdef HAVE_UTIL_DEBUG_H
# include <util/debug.h>
#endif
#ifdef HAVE_UTIL_MSGI18N_H
# include <util/msgi18n.h>
#endif
#include "integration.h"
#ifdef HAVE_FRAME_H
# include <frame.h>
#endif
#ifndef MAX
# define MAX(a, b) (a) > (b) ? (a) : (b)
#endif
#ifndef NOCATGETS
# define NOCATGETS(x) x
#endif
static void workshop_connection_closed(void);
static void messageFromEserve(XtPointer clientData, int *dum1, XtInputId *dum2);
static void workshop_disconnect(void);
static void workshop_sensitivity(int num, char *table);
static void adjust_sign_name(char *filename);
static void process_menuItem(char *);
static void process_toolbarButton(char *);
static void workshop_set_option_first(char *name, char *value);
static size_t dummy;
#define CMDBUFSIZ 2048
#ifdef DEBUG
static FILE *dfd;
static void pldebug(char *, ...);
static void unrecognised_message(char *);
#define HANDLE_ERRORS(cmd) else unrecognised_message(cmd);
#else
#define HANDLE_ERRORS(cmd)
#endif
#define PROTOCOL_VERSION "4.0.0"
static int sd = -1;
static XtInputId inputHandler;
Boolean save_files = True;
void
workshop_connection_closed(void)
{
XtRemoveInput(inputHandler);
inputHandler = 0;
sd = -1;
}
static char *
getCommand(void)
{
int len;
char lenbuf[7];
char *newcb;
static char *cmdbuf;
static int cbsize;
if ((len = read(sd, &lenbuf, 6)) == 6) {
lenbuf[6] = 0;
len = atoi(lenbuf);
if (cbsize < (len + 1)) {
newcb = (char *) realloc(cmdbuf,
MAX((len + 256), CMDBUFSIZ));
if (newcb != NULL) {
cmdbuf = newcb;
cbsize = MAX((len + 256), CMDBUFSIZ);
}
}
if (cbsize >= len && (len = read(sd, cmdbuf, len)) > 0) {
cmdbuf[len] = 0;
return cmdbuf;
} else {
return NULL;
}
} else {
if (len == 0) {
workshop_connection_closed();
}
return NULL;
}
}
void
messageFromEserve(XtPointer clientData UNUSED,
int *dum1 UNUSED,
XtInputId *dum2 UNUSED)
{
char *cmd;
cmd = getCommand();
if (cmd == NULL) {
return;
}
#ifdef DEBUG
pldebug("%s\n", cmd);
#endif
switch (*cmd) {
case 'a':
if (cmd[1] == 'c' &&
strncmp(cmd, NOCATGETS("ack "), 4) == 0) {
int ackNum;
char buf[20];
ackNum = atoi(&cmd[4]);
vim_snprintf(buf, sizeof(buf),
NOCATGETS("ack %d\n"), ackNum);
dummy = write(sd, buf, strlen(buf));
} else if (strncmp(cmd,
NOCATGETS("addMarkType "), 12) == 0) {
int idx;
char *color;
char *sign;
idx = atoi(strtok(&cmd[12], " "));
color = strtok(NULL, NOCATGETS("\001"));
sign = strtok(NULL, NOCATGETS("\001"));
if (color) {
color++;
}
if (sign) {
sign++;
}
adjust_sign_name(sign);
workshop_add_mark_type(idx, color, sign);
}
HANDLE_ERRORS(cmd);
break;
case 'b':
if (strncmp(cmd,
NOCATGETS("balloon "), 8) == 0) {
char *tip;
tip = strtok(&cmd[8], NOCATGETS("\001"));
workshop_show_balloon_tip(tip);
}
HANDLE_ERRORS(cmd);
break;
case 'c':
if (strncmp(cmd,
NOCATGETS("changeMarkType "), 15) == 0) {
char *file;
int markId;
int type;
file = strtok(&cmd[15], " ");
markId = atoi(strtok(NULL, " "));
type = atoi(strtok(NULL, " "));
workshop_change_mark_type(file, markId, type);
}
HANDLE_ERRORS(cmd);
break;
case 'd':
if (strncmp(cmd, NOCATGETS("deleteMark "), 11) == 0) {
char *file;
int markId;
file = strtok(&cmd[11], " ");
markId = atoi(strtok(NULL, " "));
workshop_delete_mark(file, markId);
}
HANDLE_ERRORS(cmd);
break;
case 'f':
if (cmd[1] == 'o' &&
strncmp(cmd, NOCATGETS("footerMsg "), 10) == 0) {
int severity;
char *message;
severity =
atoi(strtok(&cmd[10], " "));
message = strtok(NULL, NOCATGETS("\001"));
workshop_footer_message(message, severity);
} else if (strncmp(cmd,
NOCATGETS("frontFile "), 10) == 0) {
char *file;
file = strtok(&cmd[10], " ");
workshop_front_file(file);
}
HANDLE_ERRORS(cmd);
break;
case 'g':
if (cmd[1] == 'e' &&
strncmp(cmd, NOCATGETS("getMarkLine "), 12) == 0) {
char *file;
int markid;
int line;
char buf[100];
file = strtok(&cmd[12], " ");
markid = atoi(strtok(NULL, " "));
line = workshop_get_mark_lineno(file, markid);
vim_snprintf(buf, sizeof(buf),
NOCATGETS("markLine %s %d %d\n"),
file, markid, line);
dummy = write(sd, buf, strlen(buf));
} else if (cmd[1] == 'o' && cmd[4] == 'L' &&
strncmp(cmd, NOCATGETS("gotoLine "), 9) == 0) {
char *file;
int lineno;
file = strtok(&cmd[9], " ");
lineno = atoi(strtok(NULL, " "));
workshop_goto_line(file, lineno);
} else if (strncmp(cmd,
NOCATGETS("gotoMark "), 9) == 0) {
char *file;
int markId;
char *message;
file = strtok(&cmd[9], " ");
markId = atoi(strtok(NULL, " "));
message = strtok(NULL, NOCATGETS("\001"));
workshop_goto_mark(file, markId, message);
#ifdef NOHANDS_SUPPORT_FUNCTIONS
} else if (strcmp(cmd, NOCATGETS("getCurrentFile")) == 0) {
char *f = workshop_test_getcurrentfile();
char buffer[2*MAXPATHLEN];
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("currentFile %d %s"),
f ? strlen(f) : 0, f ? f : "");
workshop_send_message(buffer);
} else if (strcmp(cmd, NOCATGETS("getCursorRow")) == 0) {
int row = workshop_test_getcursorrow();
char buffer[2*MAXPATHLEN];
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("cursorRow %d"), row);
workshop_send_message(buffer);
} else if (strcmp(cmd, NOCATGETS("getCursorCol")) == 0) {
int col = workshop_test_getcursorcol();
char buffer[2*MAXPATHLEN];
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("cursorCol %d"), col);
workshop_send_message(buffer);
} else if (strcmp(cmd, NOCATGETS("getCursorRowText")) == 0) {
char *t = workshop_test_getcursorrowtext();
char buffer[2*MAXPATHLEN];
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("cursorRowText %d %s"),
t ? strlen(t) : 0, t ? t : "");
workshop_send_message(buffer);
} else if (strcmp(cmd, NOCATGETS("getSelectedText")) == 0) {
char *t = workshop_test_getselectedtext();
char buffer[2*MAXPATHLEN];
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("selectedText %d %s"),
t ? strlen(t) : 0, t ? t : "");
workshop_send_message(buffer);
#endif
}
HANDLE_ERRORS(cmd);
break;
case 'l':
if (strncmp(cmd, NOCATGETS("loadFile "), 9) == 0) {
char *file;
int line;
char *frameid;
file = strtok(&cmd[9], " ");
line = atoi(strtok(NULL, " "));
frameid = strtok(NULL, " ");
workshop_load_file(file, line, frameid);
}
HANDLE_ERRORS(cmd);
break;
case 'm':
if (cmd[1] == 'e' && cmd[4] == 'B' &&
strncmp(cmd, NOCATGETS("menuBegin "), 10) == 0) {
workshop_menu_begin(&cmd[10]);
} else if (cmd[1] == 'e' && cmd[4] == 'I' &&
strncmp(cmd, NOCATGETS("menuItem "), 9) == 0) {
process_menuItem(cmd);
} else if (cmd[1] == 'e' && cmd[4] == 'E' &&
strcmp(cmd, NOCATGETS("menuEnd")) == 0) {
workshop_menu_end();
} else if (cmd[1] == 'a' &&
strcmp(cmd, NOCATGETS("maximize")) == 0) {
workshop_maximize();
} else if (strcmp(cmd, NOCATGETS("minimize")) == 0) {
workshop_minimize();
}
HANDLE_ERRORS(cmd);
break;
case 'o':
if (cmd[1] == 'p' &&
strcmp(cmd, NOCATGETS("option"))) {
char *name;
char *value;
name = strtok(&cmd[7], " ");
value = strtok(NULL, " ");
workshop_set_option_first(name, value);
}
HANDLE_ERRORS(cmd);
break;
case 'p':
if (strcmp(cmd, NOCATGETS("ping")) == 0) {
#if 0
int pingNum;
pingNum = atoi(&cmd[5]);
workshop_send_ack(ackNum);
#endif
}
HANDLE_ERRORS(cmd);
break;
case 'q':
if (strncmp(cmd, NOCATGETS("quit"), 4) == 0) {
workshop_disconnect();
workshop_quit();
}
HANDLE_ERRORS(cmd);
break;
case 'r':
if (cmd[1] == 'e' &&
strncmp(cmd, NOCATGETS("reloadFile "), 11) == 0) {
char *file;
int line;
file = strtok(&cmd[11], " ");
line = atoi(strtok(NULL, " "));
workshop_reload_file(file, line);
}
HANDLE_ERRORS(cmd);
break;
case 's':
if (cmd[1] == 'e' && cmd[2] == 't' &&
strncmp(cmd, NOCATGETS("setMark "), 8) == 0) {
char *file;
int line;
int markId;
int type;
file = strtok(&cmd[8], " ");
line = atoi(strtok(NULL, " "));
markId = atoi(strtok(NULL, " "));
type = atoi(strtok(NULL, " "));
workshop_set_mark(file, line, markId, type);
} else if (cmd[1] == 'h' &&
strncmp(cmd, NOCATGETS("showFile "), 9) == 0) {
workshop_show_file(&cmd[9]);
} else if (cmd[1] == 'u' &&
strncmp(cmd, NOCATGETS("subMenu "), 8) == 0) {
char *label;
label = strtok(&cmd[8], NOCATGETS("\001"));
workshop_submenu_begin(label);
} else if (cmd[1] == 'u' &&
strcmp(cmd, NOCATGETS("subMenuEnd")) == 0) {
workshop_submenu_end();
} else if (cmd[1] == 'e' && cmd[2] == 'n' &&
strncmp(cmd, NOCATGETS("sensitivity "), 12) == 0) {
int num;
char *bracket;
char *table;
num = atoi(strtok(&cmd[12], " "));
bracket = strtok(NULL, " ");
if (*bracket != '[') {
fprintf(stderr, NOCATGETS("Parsing "
"error for sensitivity\n"));
} else {
table = strtok(NULL, NOCATGETS("]"));
workshop_sensitivity(num, table);
}
} else if (cmd[1] == 'e' && cmd[2] == 'n' && cmd[3] == 'd' &&
strncmp(cmd, NOCATGETS("sendVerb "), 9) == 0) {
char *verb;
verb = strtok(&cmd[9], " ");
workshop_perform_verb(verb, NULL);
} else if (cmd[1] == 'a' &&
strncmp(cmd, NOCATGETS("saveFile "), 9) == 0) {
workshop_save_file(&cmd[9]);
#ifdef NOHANDS_SUPPORT_FUNCTIONS
} else if (strncmp(cmd, NOCATGETS("saveSensitivity "), 16) == 0) {
char *file;
file = strtok(&cmd[16], " ");
workshop_save_sensitivity(file);
#endif
}
HANDLE_ERRORS(cmd);
break;
case 't':
if (cmd[8] == 'e' &&
strncmp(cmd, NOCATGETS("toolbarBegin"), 12) == 0) {
workshop_toolbar_begin();
} else if (cmd[8] == 'u' &&
strncmp(cmd, NOCATGETS("toolbarButton"), 13) == 0) {
process_toolbarButton(cmd);
} else if (cmd[7] == 'E' &&
strcmp(cmd, NOCATGETS("toolbarEnd")) == 0) {
workshop_toolbar_end();
}
HANDLE_ERRORS(cmd);
break;
#ifdef DEBUG
default:
unrecognised_message(cmd);
break;
#endif
}
}
static void
process_menuItem(
char *cmd)
{
char *label = strtok(&cmd[9], NOCATGETS("\001"));
char *verb = strtok(NULL, NOCATGETS("\001"));
char *acc = strtok(NULL, NOCATGETS("\001"));
char *accText = strtok(NULL, NOCATGETS("\001"));
char *name = strtok(NULL, NOCATGETS("\001"));
char *sense = strtok(NULL, NOCATGETS("\n"));
char *filepos = strtok(NULL, NOCATGETS("\n"));
if (*acc == '-') {
acc = NULL;
}
if (*accText == '-') {
accText = NULL;
}
workshop_menu_item(label, verb, acc, accText, name, filepos, sense);
}
static void
process_toolbarButton(
char *cmd)
{
char *label = strtok(&cmd[14], NOCATGETS("\001"));
char *verb = strtok(NULL, NOCATGETS("\001"));
char *senseVerb = strtok(NULL, NOCATGETS("\001"));
char *filepos = strtok(NULL, NOCATGETS("\001"));
char *help = strtok(NULL, NOCATGETS("\001"));
char *sense = strtok(NULL, NOCATGETS("\001"));
char *file = strtok(NULL, NOCATGETS("\001"));
char *left = strtok(NULL, NOCATGETS("\n"));
if (!strcmp(label, NOCATGETS("-"))) {
label = NULL;
}
if (!strcmp(help, NOCATGETS("-"))) {
help = NULL;
}
if (!strcmp(file, NOCATGETS("-"))) {
file = NULL;
}
if (!strcmp(senseVerb, NOCATGETS("-"))) {
senseVerb = NULL;
}
workshop_toolbar_button(label, verb, senseVerb, filepos, help,
sense, file, left);
}
#ifdef DEBUG
void
unrecognised_message(
char *cmd)
{
pldebug("Unrecognised eserve message:\n\t%s\n", cmd);
}
#endif
void
adjust_sign_name(char *filename)
{
char *s;
static int fontSize = -1;
if (fontSize == -1)
fontSize = workshop_get_font_height();
if (fontSize == 0)
return;
if (filename[0] == '-')
return;
s = filename+strlen(filename)-5;
if (fontSize <= 11)
strcpy(s, "2.xpm");
else if (fontSize <= 15)
strcpy(s, "1.xpm");
else
strcpy(s, ".xpm");
}
#if 0
int
workshop_invoked(void)
{
static int result = -1;
if (result == -1) {
result = (getenv(NOCATGETS("SPRO_EDITOR_SOCKET")) != NULL);
}
return result;
}
#endif
void workshop_connect(XtAppContext context)
{
#ifdef INET_SOCKETS
struct sockaddr_in server;
struct hostent * host;
int port;
#else
struct sockaddr_un server;
#endif
char buf[32];
char * address;
#ifdef DEBUG
char *file;
#endif
address = getenv(NOCATGETS("SPRO_EDITOR_SOCKET"));
if (address == NULL) {
return;
}
#ifdef INET_SOCKETS
port = atoi(address);
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
PERROR(NOCATGETS("workshop_connect"));
return;
}
vim_memset((char *)&server, '\0', sizeof(server));
server.sin_family = AF_INET;
server.sin_port = port;
if ((host = gethostbyname(NOCATGETS("localhost"))) == NULL) {
PERROR(NOCATGETS("gethostbyname"));
sd = -1;
return;
}
memcpy((char *)&server.sin_addr, host->h_addr, host->h_length);
#else
if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
PERROR(NOCATGETS("workshop_connect"));
return;
}
server.sun_family = AF_UNIX;
strcpy(server.sun_path, address);
#endif
if (connect(sd, (struct sockaddr *)&server, sizeof(server))) {
if (errno == ECONNREFUSED) {
close(sd);
#ifdef INET_SOCKETS
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
PERROR(NOCATGETS("workshop_connect"));
return;
}
#else
if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
PERROR(NOCATGETS("workshop_connect"));
return;
}
#endif
if (connect(sd, (struct sockaddr *)&server,
sizeof(server))) {
PERROR(NOCATGETS("workshop_connect"));
return;
}
} else {
PERROR(NOCATGETS("workshop_connect"));
return;
}
}
inputHandler = XtAppAddInput(context, sd, (XtPointer) XtInputReadMask,
messageFromEserve, NULL);
#ifdef DEBUG
if ((file = getenv(NOCATGETS("SPRO_PLUGIN_DEBUG"))) != NULL) {
char buf[BUFSIZ];
unlink(file);
vim_snprintf(buf, sizeof(buf), "date > %s", file);
system(buf);
dfd = fopen(file, "a");
} else {
dfd = NULL;
}
#endif
vim_snprintf(buf, sizeof(buf), NOCATGETS("connected %s %s %s\n"),
workshop_get_editor_name(),
PROTOCOL_VERSION,
workshop_get_editor_version());
dummy = write(sd, buf, strlen(buf));
vim_snprintf(buf, sizeof(buf), NOCATGETS("ack 1\n"));
dummy = write(sd, buf, strlen(buf));
}
void workshop_disconnect(void)
{
XtRemoveInput(inputHandler);
close(sd);
inputHandler = 0;
sd = -1;
}
static Boolean
isWindowMapped(Display *display, Window win)
{
XWindowAttributes winAttrs;
XGetWindowAttributes(display,
win,
&winAttrs);
if (winAttrs.map_state == IsViewable) {
return(True);
} else {
return(False);
}
}
static Boolean
isMapped(Widget widget)
{
if (widget == NULL) {
return(False);
}
if (XtIsRealized(widget) == False) {
return(False);
}
return(isWindowMapped(XtDisplay(widget), XtWindow(widget)));
}
static Boolean
widgetIsIconified(
Widget w)
{
Atom wm_state;
Atom act_type;
int act_fmt;
u_long nitems_ret;
u_long bytes_after;
u_long *property;
wm_state = XmInternAtom(XtDisplay(w), NOCATGETS("WM_STATE"), False);
if (XtWindow(w) != 0) {
XGetWindowProperty(XtDisplay(w), XtWindow(w), wm_state, 0L, 2L,
False, AnyPropertyType, &act_type, &act_fmt, &nitems_ret,
&bytes_after, (char_u **) &property);
if (nitems_ret == 2 && property[0] == IconicState) {
return True;
}
}
return False;
}
void
workshop_minimize_shell(Widget shell)
{
if (shell != NULL &&
XtIsObject(shell) &&
XtIsRealized(shell) == True) {
if (isMapped(shell) == True) {
XIconifyWindow(XtDisplay(shell), XtWindow(shell),
XScreenNumberOfScreen(XtScreen(shell)));
}
XtVaSetValues(shell,
XmNiconic, True,
NULL);
}
}
void workshop_maximize_shell(Widget shell)
{
if (shell != NULL &&
XtIsRealized(shell) == True &&
widgetIsIconified(shell) == True &&
isMapped(shell) == False) {
XtMapWidget(shell);
}
}
Boolean workshop_get_width_height(int *width, int *height)
{
static int wid = 0;
static int hgt = 0;
static Boolean firstTime = True;
static Boolean success = False;
if (firstTime) {
char *settings;
settings = getenv(NOCATGETS("SPRO_GUI_WIDTH_HEIGHT"));
if (settings != NULL) {
wid = atoi(settings);
settings = strrchr(settings, ':');
if (settings++ != NULL) {
hgt = atoi(settings);
}
if (wid > 0 && hgt > 0) {
success = True;
}
firstTime = False;
}
}
if (success) {
*width = wid;
*height = hgt;
}
return success;
}
void workshop_sensitivity(int num, char *table)
{
VerbSense *vs;
int i;
char *s;
if ((num < 1) || (num > 500)) {
return;
}
vs = (VerbSense *)malloc((num+1)*sizeof(VerbSense));
s = table;
for (i = 0; i < num; i++) {
while (*s == ' ') {
s++;
}
vs[i].verb = s;
while (*s && (*s != ' ') && (*s != '\001')) {
s++;
}
if (*s == 0) {
vs[i].verb = NULL;
break;
}
if (*s == '\001') {
*s = 0;
s++;
}
*s = 0;
s++;
while (*s == ' ') {
s++;
}
if (*s == '1') {
vs[i].sense = 1;
} else {
vs[i].sense = 0;
}
s++;
}
vs[i].verb = NULL;
workshop_frame_sensitivities(vs);
free(vs);
}
void workshop_set_option_first(char *name, char *value)
{
Boolean on = !strcmp(value, "on");
if (!strcmp(name, "workshopkeys")) {
workshop_hotkeys(on);
} else if (!strcmp(name, "savefiles")) {
save_files = on;
} else if (!strcmp(name, "balloon")) {
workshop_balloon_mode(on);
} else if (!strcmp(name, "balloondelay")) {
int delay = atoi(value);
workshop_balloon_delay(delay);
} else {
workshop_set_option(name, value);
}
}
void workshop_file_closed_lineno(char *filename, int lineno)
{
char buffer[2*MAXPATHLEN];
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("deletedFile %s %d\n"), filename, lineno);
dummy = write(sd, buffer, strlen(buffer));
}
void workshop_file_opened(char *filename, int readOnly)
{
char buffer[2*MAXPATHLEN];
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("loadedFile %s %d\n"), filename, readOnly);
dummy = write(sd, buffer, strlen(buffer));
}
void workshop_file_saved(char *filename)
{
char buffer[2*MAXPATHLEN];
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("savedFile %s\n"), filename);
dummy = write(sd, buffer, strlen(buffer));
workshop_moved_marks(filename);
}
void workshop_frame_moved(int new_x, int new_y, int new_w, int new_h)
{
char buffer[200];
if (sd >= 0)
{
vim_snprintf(buffer, sizeof(buffer),
NOCATGETS("frameAt %d %d %d %d\n"),
new_x, new_y, new_w, new_h);
dummy = write(sd, buffer, strlen(buffer));
}
}
void workshop_perform_verb(char *verb, void *clientData)
{
char *filename;
int curLine;
int curCol;
int selStartLine;
int selStartCol;
int selEndLine;
int selEndCol;
int selLength;
char *selection;
char buf[2*MAXPATHLEN];
if (workshop_get_positions(clientData,
&filename,
&curLine,
&curCol,
&selStartLine,
&selStartCol,
&selEndLine,
&selEndCol,
&selLength,
&selection)) {
if (selection == NULL) {
selection = NOCATGETS("");
}
if (save_files) {
if (!strcmp(verb, "build.build") || !strcmp(verb, "build.build-file") ||
!strcmp(verb, "debug.fix") || !strcmp(verb, "debug.fix-all")) {
workshop_save_files();
}
}
vim_snprintf(buf, sizeof(buf),
NOCATGETS("toolVerb %s %s %d,%d %d,%d %d,%d %d %s\n"),
verb,
filename,
curLine, curCol,
selStartLine, selStartCol,
selEndLine, selEndCol,
selLength,
selection);
dummy = write(sd, buf, strlen(buf));
if (*selection) {
free(selection);
}
}
}
#if defined(NOHANDS_SUPPORT_FUNCTIONS) || defined(FEAT_BEVAL)
void workshop_send_message(char *buf)
{
dummy = write(sd, buf, strlen(buf));
}
#endif
#ifdef DEBUG
void
pldebug(
char *fmt,
...)
{
va_list ap;
if (dfd != NULL) {
va_start(ap, fmt);
vfprintf(dfd, fmt, ap);
va_end(ap);
fflush(dfd);
}
}
#endif