home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: wx_ipc.cc
- * Purpose: Interprocess communication implementation
- *
- * wxWindows 1.40
- * Copyright (c) 1993 Artificial Intelligence Applications Institute,
- * The University of Edinburgh
- *
- * Author: Julian Smart
- * Date: 18-4-93
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice, author statement and this permission
- * notice appear in all copies of this software and related documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
- * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
- * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
- * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- #include <windows.h>
- #include <iostream.h>
- #include <stdio.h>
- #include <math.h>
-
- #include "common.h"
- #include "wx_main.h"
- #include "wx_frame.h"
- #include "wx_event.h"
- #include "wx_utils.h"
- #include "wx_ipc.h"
-
- #ifdef wx_x
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <sys/un.h>
- #include <netdb.h>
-
- #define wxFAMILY(s) s.addr.sa_family
- #define wxNAMELEN(s) (wxFAMILY(s) == AF_INET \
- ? sizeof(s.inaddr) \
- : strlen(s.unaddr.sun_path) + sizeof(s.unaddr) - sizeof(s.unaddr.sun_path))
-
- extern errno;
- int wx_socket_create(int port);
- // Add NULL-terminated string to buffer, returning next start point
- int wxAddString(int start, char *info, char *buffer, int size = -1);
-
- // Get next NULL-terminated string from buffer
- char *wxGetNextString(char *buffer);
- #endif
-
- #ifdef wx_xview
- #include <xview/xview.h>
- #include <xview/panel.h>
- Notify_value wx_input_ready(Notify_client client, int fd);
- Notify_value wx_accept_connection(Notify_client client, int fd);
- #endif
-
- #ifdef wx_motif
- Bool wx_input_ready(XtPointer client, int *fid, XtInputId *id);
- Bool wx_accept_connection(XtPointer client, int *fid, XtInputId *id);
- #endif
-
- #ifdef wx_msw
- #include <ddeml.h>
- wxConnection *wxFindConnection(HCONV hConv);
- void wxDeleteConnection(HCONV hConv);
- wxServer *wxFindServer(char *s);
-
- extern "C" HDDEDATA EXPENTRY _export wxDdeCallback(
- WORD wType,
- WORD wFmt,
- HCONV hConv,
- HSZ hsz1,
- HSZ hsz2,
- HDDEDATA hData,
- DWORD lData1,
- DWORD lData2);
- #endif
-
- // Add topic name to atom table before using in conversations
- void wxAddAtom(char *string);
-
- #ifdef wx_msw
- HSZ wxGetAtom(char *string);
- #endif
-
- #ifdef wx_msw
- #include <ddeml.h>
- DWORD wxIdInst = 0L;
- wxConnection *wxCurrentlyConnecting = NULL;
- #endif
-
- #ifdef wx_msw
- wxList wxAtomTable(wxKEY_STRING);
- wxList wxIPCObjects;
- #endif
-
- char *wxDefaultIPCBuffer = NULL;
- int wxDefaultIPCBufferSize = 4000;
-
- /*
- * Initialization
- *
- */
-
- static Bool wxIPCInitialized;
-
- void wxIPCInitialize(void)
- {
- if (wxIPCInitialized)
- return;
- wxIPCInitialized = TRUE;
- #ifdef wx_msw
- // Should insert filter flags
- DdeInitialize(&wxIdInst, (PFNCALLBACK)MakeProcInstance(
- (FARPROC)wxDdeCallback, wxTheApp->hInstance),
- APPCLASS_STANDARD,
- 0L);
- #endif
- }
-
- wxIPCObject::wxIPCObject(void)
- {
- service_name = NULL;
- #ifdef wx_msw
- wxIPCObjects.Append(this);
- #endif
- }
-
- wxIPCObject::~wxIPCObject(void)
- {
- if (service_name)
- delete service_name;
-
- wxNode *node = connections.First();
- while (node)
- {
- wxConnection *connection = (wxConnection *)node->Data();
- wxNode *next = node->Next();
- connection->OnDisconnect(); // May delete the node implicitly
- node = next;
- }
-
- // If any left after this, delete them
- node = connections.First();
- while (node)
- {
- wxConnection *connection = (wxConnection *)node->Data();
- delete connection;
- node = connections.First();
- }
- #ifdef wx_msw
- wxIPCObjects.DeleteObject(this);
- #endif
- }
-
- #ifdef wx_msw
- // Global find connection
- wxConnection *wxFindConnection(HCONV hConv)
- {
- wxNode *node = wxIPCObjects.First();
- wxConnection *found = NULL;
- while (node && !found)
- {
- wxIPCObject *object = (wxIPCObject *)node->Data();
- found = object->FindConnection(hConv);
- node = node->Next();
- }
- return found;
- }
-
- // Global delete connection
- void wxDeleteConnection(HCONV hConv)
- {
- wxNode *node = wxIPCObjects.First();
- Bool found = FALSE;
- while (node && !found)
- {
- wxIPCObject *object = (wxIPCObject *)node->Data();
- found = object->DeleteConnection(hConv);
- node = node->Next();
- }
- }
-
- wxConnection *wxIPCObject::FindConnection(HCONV conv)
- {
- wxNode *node = connections.First();
- wxConnection *found = NULL;
- while (node && !found)
- {
- wxConnection *connection = (wxConnection *)node->Data();
- if (connection->hConv == conv)
- found = connection;
- else node = node->Next();
- }
- return found;
- }
-
- Bool wxIPCObject::DeleteConnection(HCONV conv)
- {
- wxNode *node = connections.First();
- Bool found = FALSE;
- while (node && !found)
- {
- wxConnection *connection = (wxConnection *)node->Data();
- if (connection->hConv == conv)
- {
- found = TRUE;
- delete node;
- }
- else node = node->Next();
- }
- return found;
- }
-
- // Find a server from a service name
- wxServer *wxFindServer(char *s)
- {
- wxNode *node = wxIPCObjects.First();
- wxServer *found = NULL;
- while (node && !found)
- {
- wxIPCObject *object = (wxIPCObject *)node->Data();
- if (object->service_name && strcmp(object->service_name, s) == 0)
- found = (wxServer *)object;
- else node = node->Next();
- }
- return found;
- }
- #endif
-
- /*
- * Server
- *
- */
-
- wxServer::wxServer(void)
- {
- }
-
- Bool wxServer::Create(char *server_name)
- {
- service_name = copystring(server_name);
- #ifdef wx_x
- // Under UNIX, server should be an integer inside a string!
- int the_port = 0;
- sscanf(server_name, "%d", &the_port);
-
- /* Create a socket listening on specified port */
- server_socket = wx_socket_create(the_port);
- if (server_socket < 0)
- return FALSE;
-
- Bool notify_toplevel = FALSE;
- wxConnection *toplevel = this->OnAcceptConnection("STDIO");
- if (toplevel)
- {
- toplevel->input_fd = 0;
- toplevel->output_fd = 1;
- notify_toplevel = TRUE;
- toplevel->topic_name = copystring("STDIO");
- }
- else toplevel = new wxConnection(NULL, 0); // Create a dummy connection
-
- toplevel->server = this;
- connections.Append(toplevel);
-
- /* Register stdin (IF APP ALLOWS IT) and the socket with the notifier */
-
- #ifdef wx_xview
- // stdin
- if (notify_toplevel)
- notify_set_input_func((Notify_client)toplevel, &wx_input_ready, 0);
-
- // Top level port
- notify_set_input_func((Notify_client)toplevel, &wx_accept_connection, server_socket);
- #endif
- #ifdef wx_motif
- XtAppAddInput(wxTheApp->appContext, server_socket, XtInputReadMask, wx_accept_connection, toplevel);
- #endif
- return TRUE;
- #endif
- #ifdef wx_msw
- HSZ wxServiceName = DdeCreateStringHandle(wxIdInst, server_name, CP_WINANSI);
-
- DdeNameService(wxIdInst, wxServiceName, NULL, DNS_REGISTER);
- return TRUE;
- #endif
- }
-
- wxServer::~wxServer(void)
- {
- #ifdef wx_motif
- #endif
- #ifdef wx_xview
- close(server_socket);
- #endif
- }
-
- // Default behaviour for accepting a connection
- wxConnection *wxServer::OnAcceptConnection(char *topic)
- {
- return new wxConnection;
- }
-
-
- /*
- * Client
- *
- */
-
-
- wxClient::wxClient(void)
- {
- #ifdef wx_msw
- #endif
- }
-
- wxClient::~wxClient(void)
- {
- wxNode *node = connections.First();
- while (node)
- {
- wxConnection *connection = (wxConnection *)node->Data();
- delete connection; // Deletes the node implicitly (see ~wxConnection)
- node = connections.First();
- }
- }
-
- Bool wxClient::ValidHost(char *host)
- {
- #ifdef wx_x
- if (gethostbyname(host))
- return TRUE;
- else
- return FALSE;
- #endif
- #ifdef wx_msw
- return TRUE;
- #endif
- }
-
- wxConnection *wxClient::MakeConnection(char *host, char *server_name, char *topic)
- {
- #ifdef wx_x
- int port;
- sscanf(server_name, "%d", &port);
-
- union {struct sockaddr addr;
- struct sockaddr_un unaddr;
- struct sockaddr_in inaddr;} s;
-
- struct hostent *server;
-
- int fd;
-
- bzero(&s.inaddr, sizeof(s.inaddr));
- server = gethostbyname(host);
- if(server == (struct hostent *)0)
- {
- perror("sockio: gethostbyname failed");
- return NULL;
- }
- bcopy(server->h_addr, &s.inaddr.sin_addr, server->h_length);
- s.inaddr.sin_family = AF_INET;
- s.inaddr.sin_port = htons(port);
-
- fd = socket(wxFAMILY(s), SOCK_STREAM, 0);
- if(fd < 0)
- {
- perror("sockio: socket failed");
- return NULL;
- }
-
- if (connect(fd, &s.addr, wxNAMELEN(s)) == 0)
- {
- // Send topic name, and enquire whether this has succeeded
- char buf[200];
- buf[0] = wxCONNECT;
- strcpy(buf+1, topic);
- write(fd, buf, strlen(topic)+2);
- read(fd, buf, 200);
- // OK! Confirmation.
- if (buf[0] == wxCONNECT)
- {
- wxConnection *connection = OnMakeConnection();
- if (connection)
- {
- connections.Append(connection);
- connection->input_fd = fd;
- connection->output_fd = fd;
- connection->client = this;
-
- // Register with the notifier
- connection->Notify(TRUE);
- return connection;
- }
- else { close(fd); return NULL; }
- }
- else
- {
- close(fd);
- return NULL;
- }
- }
- else
- {
- close(fd);
- return NULL;
- }
- /*
- if(errno == ENOENT)
- {
- fprintf(stderr, "socket doesn't exist, retrying after 5 secs\n");
- sleep(5);
- }
- else
- {
- perror("sockio: connect failed");
- exit(1);
- }
- */
- #endif
- #ifdef wx_msw
- HSZ wxServiceName = DdeCreateStringHandle(wxIdInst, server_name, CP_WINANSI);
- HSZ topic_atom = DdeCreateStringHandle(wxIdInst, topic, CP_WINANSI);
-
- HCONV hConv = DdeConnect(wxIdInst, wxServiceName, topic_atom, (PCONVCONTEXT)NULL);
- if (hConv == NULL)
- return NULL;
- else
- {
- wxConnection *connection = OnMakeConnection();
- if (connection)
- {
- connection->hConv = hConv;
- connection->topic_name = copystring(topic);
- connections.Append(connection);
- return connection;
- }
- else return NULL;
- }
- #endif
- }
-
- wxConnection *wxClient::OnMakeConnection(void)
- {
- return new wxConnection;
- }
-
- /*
- * Connection
- */
-
- wxConnection::wxConnection(char *buffer, int size)
- {
- if (buffer == NULL)
- {
- if (wxDefaultIPCBuffer == NULL)
- wxDefaultIPCBuffer = new char[wxDefaultIPCBufferSize];
- buf_ptr = wxDefaultIPCBuffer;
- buf_size = wxDefaultIPCBufferSize;
- }
- else
- {
- buf_ptr = buffer;
- buf_size = size;
- }
-
- topic_name = NULL;
-
- client = NULL;
- server = NULL;
- #ifdef wx_x
- input_fd = 0;
- output_fd = 0;
- #endif
- #ifdef wx_msw
- hConv = NULL;
- sending_data = NULL;
- #endif
- }
-
- wxConnection::wxConnection(void)
- {
- if (wxDefaultIPCBuffer == NULL)
- wxDefaultIPCBuffer = new char[wxDefaultIPCBufferSize];
-
- buf_ptr = wxDefaultIPCBuffer;
- buf_size = wxDefaultIPCBufferSize;
-
- topic_name = NULL;
- client = NULL;
- server = NULL;
- #ifdef wx_x
- input_fd = 0;
- output_fd = 0;
- #endif
- #ifdef wx_motif
- xtInputId = 0;
- #endif
- #ifdef wx_msw
- hConv = NULL;
- sending_data = NULL;
- #endif
- }
-
- wxConnection::~wxConnection(void)
- {
- #ifdef wx_motif
- if (xtInputId > 0)
- XtRemoveInput(xtInputId);
- #endif
- #ifdef wx_xview
- notify_set_input_func((Notify_client)this, (Notify_func)0, input_fd);
- #endif
- #ifdef wx_x
- if (input_fd != 0)
- close(input_fd);
- if (output_fd != 0)
- close(output_fd);
-
- if (server)
- server->connections.DeleteObject(this);
- if (client)
- client->connections.DeleteObject(this);
- if (topic_name)
- delete topic_name;
- #endif
- }
-
- Bool wxConnection::OnDisconnect(void)
- {
- // Default action is to delete itself
- delete this;
- return TRUE;
- }
-
- // Callbacks to SERVER - override at will
- Bool wxConnection::OnExecute(char *topic, char *data, int size, int format)
- {
- return FALSE;
- }
-
- char *wxConnection::OnRequest(char *topic, char *item, int *size, int format)
- {
- return NULL;
- }
-
- Bool wxConnection::OnPoke(char *topic, char *item, char *data, int size, int format)
- {
- return FALSE;
- }
-
- Bool wxConnection::OnStartAdvise(char *topic, char *item)
- {
- return TRUE;
- }
-
- Bool wxConnection::OnStopAdvise(char *topic, char *item)
- {
- return TRUE;
- }
-
-
- // Callbacks to CLIENT - override at will
- Bool wxConnection::OnAdvise(char *topic, char *item, char *data, int size, int format)
- {
- return FALSE;
- }
-
- // Calls that CLIENT can make
- Bool wxConnection::Disconnect(void)
- {
- #ifdef wx_x
- buf_ptr[0] = wxDISCONNECT;
- write(output_fd, buf_ptr, 1);
- #endif
- #ifdef wx_motif
- if (xtInputId)
- XtRemoveInput(xtInputId);
- xtInputId = 0;
- #endif
- #ifdef wx_xview
- notify_set_input_func((Notify_client)this, (Notify_func)0, input_fd);
- #endif
- #ifdef wx_x
- if (input_fd != 0)
- close(input_fd);
- if (output_fd != 0)
- close(output_fd);
- input_fd = 0;
- output_fd = 0;
-
- return TRUE;
- #endif
- #ifdef wx_msw
- wxDeleteConnection(hConv);
- return DdeDisconnect(hConv);
- #endif
- }
-
- Bool wxConnection::Execute(char *data, int size, int format)
- {
- #ifdef wx_x
- if (size < 0)
- size = strlen(data);
-
- char format_buf[10];
- sprintf(format_buf, "%d", format);
-
- buf_ptr[0] = wxEXECUTE;
- int pos = wxAddString(1, format_buf, buf_ptr);
- pos = wxAddString(pos, data, buf_ptr, size);
-
- write(output_fd, buf_ptr, pos);
- return TRUE;
- #endif
- #ifdef wx_msw
- DWORD result;
- if (size < 0)
- size = strlen(data);
-
- size ++;
-
- DdeClientTransaction((void FAR *)data, size, hConv,
- NULL, format, XTYP_EXECUTE, 5000, &result);
-
- return TRUE;
- #endif
- }
-
- char *wxConnection::Request(char *item, int *size, int format)
- {
- #ifdef wx_x
- char format_buf[10];
- sprintf(format_buf, "%d", format);
-
- buf_ptr[0] = wxREQUEST;
- int pos = wxAddString(1, item, buf_ptr);
- pos = wxAddString(pos, format_buf, buf_ptr);
-
- #ifdef wx_xview
- Notify(FALSE);
- #endif
- write(output_fd, buf_ptr, pos);
- read(input_fd, buf_ptr, buf_size);
- #ifdef wx_xview
- Notify(TRUE);
- #endif
-
- if (buf_ptr[0] == wxFAIL)
- return NULL;
- else
- {
- char *new_item = buf_ptr + 1;
- char *data = wxGetNextString(new_item);
- if (size) *size = data-new_item;
- return data;
- }
- #endif
- #ifdef wx_msw
- DWORD result;
- HSZ atom = wxGetAtom(item);
-
- HDDEDATA returned_data = DdeClientTransaction(NULL, 0, hConv,
- atom, format, XTYP_REQUEST, 5000, &result);
-
- DWORD len = DdeGetData(returned_data, (LPBYTE)(buf_ptr), buf_size, 0);
-
- DdeFreeDataHandle(returned_data);
-
- if (size) *size = (int)len;
- if (len > 0)
- {
- return buf_ptr;
- }
- else return NULL;
- #endif
- }
-
- Bool wxConnection::Poke(char *item, char *data, int size, int format)
- {
- #ifdef wx_x
- char format_buf[10];
- sprintf(format_buf, "%d", format);
-
- if (size < 0)
- size = strlen(data);
-
- buf_ptr[0] = wxPOKE;
- int pos = wxAddString(1, item, buf_ptr);
- pos = wxAddString(pos, format_buf, buf_ptr);
- pos = wxAddString(pos, data, buf_ptr, size);
-
- write(output_fd, buf_ptr, pos);
- return TRUE;
- #endif
- #ifdef wx_msw
- DWORD result;
- if (size < 0)
- size = strlen(data);
-
- size ++;
-
- HSZ item_atom = wxGetAtom(item);
- DdeClientTransaction((void FAR *)data, size, hConv,
- item_atom, format, XTYP_POKE, 5000, &result);
-
- return TRUE;
- #endif
- }
-
- Bool wxConnection::StartAdvise(char *item)
- {
- #ifdef wx_x
- buf_ptr[0] = wxADVISE_START;
- int pos = wxAddString(1, item, buf_ptr);
-
- #ifdef wx_xview
- Notify(FALSE);
- #endif
-
- write(output_fd, buf_ptr, pos);
- read(input_fd, buf_ptr, buf_size);
-
- #ifdef wx_xview
- Notify(TRUE);
- #endif
-
- if (buf_ptr[0] != wxFAIL)
- return TRUE;
- else
- return FALSE;
- #endif
- #ifdef wx_msw
- DWORD result;
- HSZ atom = wxGetAtom(item);
-
- DdeClientTransaction(NULL, 0, hConv,
- atom, CF_TEXT, XTYP_ADVSTART, 5000, &result);
-
- return (Bool)result;
- #endif
- }
-
- Bool wxConnection::StopAdvise(char *item)
- {
- #ifdef wx_x
- buf_ptr[0] = wxADVISE_STOP;
- int pos = wxAddString(1, item, buf_ptr);
-
- #ifdef wx_xview
- Notify(FALSE);
- #endif
-
- write(output_fd, buf_ptr, pos);
- read(input_fd, buf_ptr, buf_size);
-
- #ifdef wx_xview
- Notify(TRUE);
- #endif
-
- if (buf_ptr[0] != wxFAIL)
- return TRUE;
- else
- return FALSE;
- #endif
- #ifdef wx_msw
- DWORD result;
- HSZ atom = wxGetAtom(item);
-
- DdeClientTransaction(NULL, 0, hConv,
- atom, CF_TEXT, XTYP_ADVSTOP, 5000, &result);
-
- return (Bool)result;
- #endif
- }
-
- // Calls that SERVER can make
- Bool wxConnection::Advise(char *item, char *data, int size, int format)
- {
- #ifdef wx_x
- char format_buf[10];
- sprintf(format_buf, "%d", format);
-
- buf_ptr[0] = wxADVISE;
- int pos = wxAddString(1, item, buf_ptr);
- pos = wxAddString(pos, format_buf, buf_ptr);
- pos = wxAddString(pos, data, buf_ptr, size);
-
- write(output_fd, buf_ptr, pos);
- return TRUE;
- #endif
- #ifdef wx_msw
- if (size < 0)
- size = strlen(data);
-
- size ++;
-
- HSZ item_atom = wxGetAtom(item);
- HSZ topic_atom = wxGetAtom(topic_name);
- sending_data = data;
- data_size = size;
- data_type = format;
- return DdePostAdvise(wxIdInst, topic_atom, item_atom);
- #endif
- }
-
- void wxConnection::Notify(Bool notify)
- {
- #ifdef wx_motif
- if (!notify)
- {
- if (xtInputId > 0)
- XtRemoveInput(xtInputId);
- }
- else
- xtInputId = XtAppAddInput(wxTheApp->appContext, input_fd, XtInputReadMask, wx_input_ready, this);
- #endif
- #ifdef wx_xview
- if (notify)
- notify_set_input_func((Notify_client)this, (Notify_func)wx_input_ready, input_fd);
- else
- notify_set_input_func((Notify_client)this, NOTIFY_FUNC_NULL, input_fd);
- #endif
- }
-
- #ifdef wx_x
-
- #ifdef wx_xview
- Notify_value wx_input_ready(Notify_client client, int fd)
- #endif
- #ifdef wx_motif
- Bool wx_input_ready(XtPointer client, int *fid, XtInputId *id)
- #endif
- {
- #ifdef wx_motif
- // int fd = *fid;
- #endif
- wxConnection *connection = (wxConnection *)client;
- int nread = read(connection->input_fd, connection->buf_ptr, connection->buf_size);
-
- if ((nread >= 0) && (nread < connection->buf_size))
- connection->buf_ptr[nread] = 0;
-
- switch(nread)
- {
- case -1: /* Error - give up */
- connection->OnDisconnect();
- return FALSE;
- break;
-
- case 0: /* EOF - de-register descriptor */
- {
- connection->OnDisconnect();
- return FALSE;
- break;
- }
- default:
- break;
- }
- switch (connection->buf_ptr[0])
- {
- case wxEXECUTE:
- {
- char *format_buf = connection->buf_ptr + 1;
- char *data = wxGetNextString(format_buf);
-
- int format = wxCF_TEXT;
- sscanf(format_buf, "%d", &format);
-
- int size = nread - (data - connection->buf_ptr);
- connection->OnExecute(connection->topic_name, data, size, format);
- break;
- }
- case wxADVISE:
- {
- char *item = connection->buf_ptr + 1;
- char *format_buf = wxGetNextString(item);;
- char *data = wxGetNextString(format_buf);
-
- int format = wxCF_TEXT;
- sscanf(format_buf, "%d", &format);
-
- int size = nread - (data - connection->buf_ptr);
- connection->OnAdvise(connection->topic_name, item, data, size, format);
- break;
- }
- case wxADVISE_START:
- {
- char *item = connection->buf_ptr + 1;
- Bool ok = connection->OnStartAdvise(connection->topic_name, item);
- if (ok)
- {
- connection->buf_ptr[0] = wxADVISE_START;
- connection->buf_ptr[1] = 0;
- write(connection->output_fd, connection->buf_ptr, 2);
- }
- else
- {
- connection->buf_ptr[0] = wxFAIL;
- connection->buf_ptr[1] = 0;
- write(connection->output_fd, connection->buf_ptr, 2);
- }
-
- break;
- }
- case wxADVISE_STOP:
- {
- char *item = connection->buf_ptr + 1;
- Bool ok = connection->OnStopAdvise(connection->topic_name, item);
- if (ok)
- {
- connection->buf_ptr[0] = wxADVISE_STOP;
- connection->buf_ptr[1] = 0;
- write(connection->output_fd, connection->buf_ptr, 2);
- }
- else
- {
- connection->buf_ptr[0] = wxFAIL;
- connection->buf_ptr[1] = 0;
- write(connection->output_fd, connection->buf_ptr, 2);
- }
-
- break;
- }
- case wxPOKE:
- {
- char *item = connection->buf_ptr + 1;
- char *format_buf = wxGetNextString(item);;
- char *data = wxGetNextString(format_buf);
-
- int format = wxCF_TEXT;
- sscanf(format_buf, "%d", &format);
-
- int size = nread - (data - connection->buf_ptr);
- connection->OnPoke(connection->topic_name, item, data, size, format);
- break;
- }
- case wxREQUEST:
- {
- char *item = connection->buf_ptr + 1;
- char *format_buf = wxGetNextString(item);;
-
- int format = wxCF_TEXT;
- sscanf(format_buf, "%d", &format);
-
- int user_size = -1;
- char *user_data = connection->OnRequest(connection->topic_name, item, &user_size, format);
- if (user_data)
- {
- connection->buf_ptr[0] = wxREQUEST_REPLY;
- int pos = wxAddString(1, item, connection->buf_ptr);
- pos = wxAddString(pos, user_data, connection->buf_ptr, user_size);
-
- write(connection->output_fd, connection->buf_ptr, pos);
- }
- else
- {
- connection->buf_ptr[0] = wxFAIL;
- connection->buf_ptr[1] = 0;
- write(connection->output_fd, connection->buf_ptr, 2);
- }
-
- break;
- }
- default:
- break;
- }
- return 0;
- }
-
- #ifdef wx_xview
- Notify_value wx_accept_connection(Notify_client client, int fd)
- #endif
- #ifdef wx_motif
- Bool wx_accept_connection(XtPointer client, int *fid, XtInputId *id)
- #endif
- {
- #ifdef wx_motif
- int fd = *fid;
- #endif
-
- struct sockaddr_in addr;
- int newsock, addrlen = sizeof(addr);
- wxConnection *top_connection = (wxConnection *)client;
-
- /* Accept the connection, getting a new socket */
-
- newsock = accept(fd, (struct sockaddr *)&addr, &addrlen);
- if(newsock == -1)
- printf("Error in accept\n");
- char buf[300];
-
- read(newsock, buf, 300);
-
- if (buf[0] == wxCONNECT)
- {
- char *topic_name = copystring(buf + 1);
-
- /* Register new socket with the notifier */
- wxConnection *new_connection = top_connection->server->OnAcceptConnection(topic_name);
- if (new_connection)
- {
- // Acknowledge success
- buf[0] = wxCONNECT;
- buf[1] = 0;
- write(newsock, buf, 2);
-
- new_connection->input_fd = newsock;
- new_connection->output_fd = newsock;
- new_connection->server = top_connection->server;
- new_connection->topic_name = topic_name;
- top_connection->server->connections.Append(new_connection);
-
- #ifdef wx_xview
- notify_set_input_func((Notify_client)new_connection, &wx_input_ready, newsock);
- #endif
- #ifdef wx_motif
- new_connection->xtInputId = XtAppAddInput(wxTheApp->appContext, newsock, XtInputReadMask, wx_input_ready, new_connection);
- #endif
- }
- else
- {
- // Send failure message
- buf[0] = wxFAIL;
- buf[1] = 0;
- write(newsock, buf, 2);
- }
- }
- return 0;
- }
-
- #endif
-
- /*
- * Create an internet socket listening on the specified port.
- */
-
- #ifdef wx_x
- int wx_socket_create(int port)
- {
- struct sockaddr_in addr; int sock;
-
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- addr.sin_port = htons(port);
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
- {
- printf("Error in bind\n");
- return -1;
- }
-
- listen(sock, 5);
-
- return sock;
- }
- #endif
-
- #ifdef wx_xview
- static Notify_value
- wx_child_died(Notify_client me, int pid, union wait *status, struct rusage *rusage)
- {
- if (WIFEXITED(*status))
- {
- wxChild *child = (wxChild *)me;
- child->OnDeath();
- delete child;
- return NOTIFY_DONE;
- } else
- return NOTIFY_IGNORED;
- }
- #endif
-
- // Pipes
- wxChild::wxChild(void)
- {
- the_pid = -1;
- }
-
- Bool wxChild::Create(char *command, char *argv[])
- {
- #ifdef wx_motif
- return FALSE;
- #endif
- #ifdef wx_xview
- int to_subprocess[2], from_subprocess[2];
-
- pipe(to_subprocess); pipe(from_subprocess);
-
- int pid = fork();
-
- the_pid = pid;
- switch(pid)
- {
- case -1:
- return FALSE;
-
- case 0: // child
-
- // Copy pipe descriptors to stdin and stdout
- dup2(to_subprocess[0], 0); dup2(from_subprocess[1], 1);
-
- // Close unwanted descriptors
-
- close(to_subprocess[0]); close(to_subprocess[1]);
- close(from_subprocess[0]); close(from_subprocess[1]);
-
- // Exec new process
-
- // execlp("prolog", "prolog", (char *)0); execvp(command, argv);
-
- // If we get here it failed; give up
-
- perror("exec");
- _exit(1); // Use _exit() not exit() after failed exec
-
- default: // parent
-
- break;
- }
-
- // Close unneeded descriptors
-
- close(to_subprocess[0]); close(from_subprocess[1]);
-
- (void)notify_set_wait3_func((Notify_client)this, (Notify_func)wx_child_died, pid);
-
- wxConnection *connection = this->OnSpawn(pid);
- connection->input_fd = from_subprocess[0];
- connection->output_fd = to_subprocess[1];
-
- if (connection)
- {
- connection->Notify(TRUE);
- return TRUE;
- }
- else
- { close(to_subprocess[1]);
- close(from_subprocess[0]);
- return FALSE;
- }
- #endif
- #ifdef wx_msw
- return FALSE;
- #endif
- }
-
- void wxChild::OnDeath(void)
- {
- }
-
- // Default behaviour
- wxConnection *wxChild::OnSpawn(int pid)
- {
- return new wxConnection;
- }
-
- #ifdef wx_msw
- HDDEDATA EXPENTRY _export wxDdeCallback(
- WORD wType,
- WORD wFmt,
- HCONV hConv,
- HSZ hsz1,
- HSZ hsz2,
- HDDEDATA hData,
- DWORD lData1,
- DWORD lData2)
- {
- switch (wType)
- {
- case XTYP_CONNECT:
- {
- char topic_buf[100];
- char server_buf[100];
- DdeQueryString(wxIdInst, hsz1, (LPSTR)topic_buf, sizeof(topic_buf),
- CP_WINANSI);
- DdeQueryString(wxIdInst, hsz2, (LPSTR)server_buf, sizeof(topic_buf),
- CP_WINANSI);
- wxServer *server = wxFindServer(server_buf);
- if (server)
- {
- wxConnection *connection =
- server->OnAcceptConnection(topic_buf);
- if (connection)
- {
- connection->server = server;
- server->connections.Append(connection);
- connection->hConv = 0;
- connection->topic_name = copystring(topic_buf);
- wxCurrentlyConnecting = connection;
- return TRUE;
- }
- }
- else return 0;
- break;
- }
-
- case XTYP_CONNECT_CONFIRM:
- {
- if (wxCurrentlyConnecting)
- {
- wxCurrentlyConnecting->hConv = hConv;
- wxCurrentlyConnecting = NULL;
- return TRUE;
- }
- else return 0;
- break;
- }
-
- case XTYP_DISCONNECT:
- {
- wxConnection *connection = wxFindConnection(hConv);
- if (connection && connection->OnDisconnect())
- {
- wxDeleteConnection(hConv); // Delete mapping: hConv => connection
- return TRUE;
- }
- else return 0;
- break;
- }
-
- case XTYP_EXECUTE:
- {
- wxConnection *connection = wxFindConnection(hConv);
-
- if (connection)
- {
- DWORD len = DdeGetData(hData, (LPBYTE)(connection->buf_ptr), connection->buf_size, 0);
- DdeFreeDataHandle(hData);
- if (connection->OnExecute(connection->topic_name, connection->buf_ptr, (int)len, wFmt))
- return DDE_FACK;
- else
- return DDE_FNOTPROCESSED;
- } else return DDE_FNOTPROCESSED;
- break;
- }
-
- case XTYP_REQUEST:
- {
- wxConnection *connection = wxFindConnection(hConv);
-
- if (connection)
- {
- char item_name[200];
- DdeQueryString(wxIdInst, hsz2, (LPSTR)item_name, sizeof(item_name),
- CP_WINANSI);
-
- int user_size = -1;
- char *data = connection->OnRequest(connection->topic_name, item_name, &user_size, wFmt);
- if (data)
- {
- if (user_size < 0) user_size = strlen(data);
-
- HDDEDATA handle = DdeCreateDataHandle(wxIdInst,
- data, user_size + 1, 0, hsz2, wFmt, 0);
- return handle;
- } else return 0;
- } else return 0;
- break;
- }
-
- case XTYP_POKE:
- {
- wxConnection *connection = wxFindConnection(hConv);
-
- if (connection)
- {
- char item_name[200];
- DdeQueryString(wxIdInst, hsz2, (LPSTR)item_name, sizeof(item_name),
- CP_WINANSI);
- DWORD len = DdeGetData(hData, (LPBYTE)(connection->buf_ptr), connection->buf_size, 0);
- DdeFreeDataHandle(hData);
- connection->OnPoke(connection->topic_name, item_name, connection->buf_ptr, (int)len, wFmt);
- return DDE_FACK;
- } else return DDE_FNOTPROCESSED;
- break;
- }
-
- case XTYP_ADVSTART:
- {
- wxConnection *connection = wxFindConnection(hConv);
-
- if (connection)
- {
- char item_name[200];
- DdeQueryString(wxIdInst, hsz2, (LPSTR)item_name, sizeof(item_name),
- CP_WINANSI);
-
- return connection->OnStartAdvise(connection->topic_name, item_name);
- } else return 0;
- break;
- }
-
- case XTYP_ADVSTOP:
- {
- wxConnection *connection = wxFindConnection(hConv);
-
- if (connection)
- {
- char item_name[200];
- DdeQueryString(wxIdInst, hsz2, (LPSTR)item_name, sizeof(item_name),
- CP_WINANSI);
- return connection->OnStopAdvise(connection->topic_name, item_name);
- } else return 0;
- break;
- }
-
- case XTYP_ADVREQ:
- {
- wxConnection *connection = wxFindConnection(hConv);
-
- if (connection && connection->sending_data)
- {
- HDDEDATA data = DdeCreateDataHandle(wxIdInst, connection->sending_data,
- connection->data_size, 0, hsz2, connection->data_type, 0);
- connection->sending_data = NULL;
- return data;
- } else return NULL;
- break;
- }
-
- case XTYP_ADVDATA:
- {
- wxConnection *connection = wxFindConnection(hConv);
-
- if (connection)
- {
- char item_name[200];
- DdeQueryString(wxIdInst, hsz2, (LPSTR)item_name, sizeof(item_name),
- CP_WINANSI);
-
- DWORD len = DdeGetData(hData, (LPBYTE)(connection->buf_ptr), connection->buf_size, 0);
- DdeFreeDataHandle(hData);
- if (connection->OnAdvise(connection->topic_name, item_name, connection->buf_ptr, (int)len, wFmt))
- return DDE_FACK;
- else
- return DDE_FNOTPROCESSED;
- } else return DDE_FNOTPROCESSED;
- break;
- }
- }
- return 0;
- }
-
- #endif
-
- // Add NULL-terminated string to buffer, returning next start point
- int wxAddString(int start, char *info, char *buffer, int size)
- {
- if (size < 0)
- size = strlen(info);
-
- int i;
- for (i = start; i < (start + size); i++)
- buffer[i] = info[i-start];
- buffer[i] = 0;
- return i+1;
- }
-
- // Get next position of NULL-terminated string from buffer
- char *wxGetNextString(char *buffer)
- {
- int i = 0;
- int ch = -1;
- Bool flag = FALSE;
- while (!flag)
- {
- ch = (int)buffer[i];
- if (ch == 0)
- {
- flag = TRUE;
- }
- else
- {
- i ++;
- }
- }
- return buffer + i + 1;
- }
-
- // Atom table stuff
- void wxAddAtom(char *string)
- {
- #ifdef wx_msw
- HSZ atom = DdeCreateStringHandle(wxIdInst, string, CP_WINANSI);
- wxAtomTable.Append(string, (wxObject *)atom);
- #endif
- }
-
- #ifdef wx_msw
- HSZ wxGetAtom(char *string)
- {
- wxNode *node = wxAtomTable.Find(string);
- if (node)
- return (HSZ)node->Data();
- else
- {
- wxAddAtom(string);
- return (HSZ)(wxAtomTable.Find(string)->Data());
- }
- }
- #endif
-
-