2 static char *RCSid() { return RCSid("$Id: gpexecute.c,v 1.14.2.1 2009/02/19 21:17:54 sfeam Exp $"); }
5 /* GNUPLOT - gpexecute.c */
8 * Permission to use, copy, and distribute this software and its
9 * documentation for any purpose with or without fee is hereby granted,
10 * provided that the above copyright notice appear in all copies and
11 * that both that copyright notice and this permission notice appear
12 * in supporting documentation.
14 * Permission to modify the software is granted, but not the right to
15 * distribute the complete modified source code. Modifications are to
16 * be distributed as patches to the released version. Permission to
17 * distribute binaries produced by compiling modified sources is granted,
19 * 1. distribute the corresponding source modifications from the
20 * released version in the form of a patch file along with the binaries,
21 * 2. add special version identification to distinguish your version
22 * in addition to the base release version number,
23 * 3. provide your name and address as the primary contact for the
24 * support of your modified version, and
25 * 4. retain our contact information in regard to use of the base
27 * Permission to distribute the released version of the source code along
28 * with corresponding source modifications in the form of a patch file is
29 * granted with same provisions 2 through 4 for binary distributions.
31 * This software is provided "as is" without express or implied warranty
32 * to the extent permitted by applicable law.
38 * Original Software (October 1999 - January 2000):
39 * Pieter-Tjerk de Boer <ptdeboer@cs.utwente.nl>
40 * Petr Mikulik <mikulik@physics.muni.cz>
41 * Johannes Zellner <johannes@zellner.org>
44 #include "gpexecute.h"
53 # include <unistd.h> /* open(), write() */
63 # include "mouse.h" /* do_event() */
66 #if defined(PIPE_IPC) /* || defined(WIN_IPC) */
67 static gpe_fifo_t *gpe_init __PROTO((void));
68 static void gpe_push __PROTO((gpe_fifo_t ** base, struct gp_event_t * ge));
69 static struct gp_event_t *gpe_front __PROTO((gpe_fifo_t ** base));
70 static int gpe_pop __PROTO((gpe_fifo_t ** base));
71 #endif /* PIPE_IPC || WIN_IPC */
74 * gp_execute functions
78 char mouseShareMemName[40];
79 PVOID input_from_PM_Terminal;
80 /* pointer to shared memory for storing the command to be executed */
81 HEV semInputReady = 0;
82 /* handle to event semaphore (post an event to gnuplot that the shared
83 memory contains a command to be executed) */
85 /* avoid passing data back to gnuplot in `pause' mode */
91 * Let the command in the shared memory be executed.
97 if (semInputReady == 0) { /* but it must be open for the first time */
98 char semInputReadyName[40];
99 sprintf(semInputReadyName, "\\SEM32\\GP%i_Input_Ready", (int) ppidGnu);
100 DosOpenEventSem(semInputReadyName, &semInputReady);
102 rc = DosPostEventSem(semInputReady);
104 /* dirty trick: wait a little bit; otherwise problems to
105 * distinguish mouse button down and up, for instance
106 * (info sent to shared memory was too fast; maybe a blocking
107 * semaphore would help, but no fun to implement it...)
111 /* Copy the command (given by the input string) to the shared memory
112 * and let gnuplot execute it.
113 * If this routine is called during a 'pause', then the command is
114 * ignored (shared memory is cleared). Needed for actions launched by a
116 * Firstly, the command is copied from shared memory to clipboard
117 * if this option is set on.
118 * Secondly, gnuplot is informed that shared memory contains a command
119 * by posting semInputReady event semaphore.
121 * OS/2 specific: if (!s), then the command has been already sprintf'ed to
127 if (input_from_PM_Terminal == NULL)
129 if (s) /* copy the command to shared memory */
130 strcpy(input_from_PM_Terminal, s);
131 if (((char *) input_from_PM_Terminal)[0] == 0)
133 if (pausing) { /* no communication during pause */
134 /* DosBeep(440,111); */
135 ((char *) input_from_PM_Terminal)[0] = 0;
139 /* write the command to clipboard */
140 if (bSend2gp == TRUE)
141 TextToClipboard(input_from_PM_Terminal);
143 gp_post_shared_mem();
148 #if defined(PIPE_IPC) /* || defined(WIN_IPC) */
150 int buffered_output_pending = 0;
155 gpe_fifo_t *base = malloc(sizeof(gpe_fifo_t));
156 /* fprintf(stderr, "(gpe_init) \n"); */
158 base->next = (gpe_fifo_t *) 0;
159 base->prev = (gpe_fifo_t *) 0;
164 gpe_push(gpe_fifo_t ** base, struct gp_event_t *ge)
166 buffered_output_pending++;
168 gpe_fifo_t *new = malloc(sizeof(gpe_fifo_t));
169 /* fprintf(stderr, "(gpe_push) \n"); */
171 (*base)->prev->next = new;
172 new->prev = (*base)->prev;
174 new->next = (gpe_fifo_t *) 0;
176 /* first element, this is the case, if the pipe isn't clogged */
177 (*base)->next = (gpe_fifo_t *) 0; /* tail */
178 (*base)->prev = (*base); /* points to itself */
180 (*base)->prev->ge = *ge;
183 static struct gp_event_t *
184 gpe_front(gpe_fifo_t ** base)
186 return &((*base)->ge);
190 gpe_pop(gpe_fifo_t ** base)
192 buffered_output_pending--;
193 if ((*base)->prev == (*base)) {
194 (*base)->prev = (gpe_fifo_t *) 0;
197 gpe_fifo_t *save = *base;
198 /* fprintf(stderr, "(gpe_pop) \n"); */
199 (*base)->next->prev = (*base)->prev;
200 (*base) = (*base)->next;
205 #endif /* PIPE_IPC || WIN_IPC */
209 pipe_died_handler(int signum)
211 (void) signum; /* avoid -Wunused warning. */
212 /* fprintf(stderr, "\n*******(pipe_died_handler)*******\n"); */
216 #endif /* PIPE_IPC */
219 gp_exec_event(char type, int mx, int my, int par1, int par2, int winid)
221 struct gp_event_t ge;
222 #if defined(PIPE_IPC) /* || defined(WIN_IPC) */
223 static struct gpe_fifo_t *base = (gpe_fifo_t *) 0;
236 /* HBB 20010218: commented this out for WIN_IPC. We don't actually use the stack,
238 #if defined(PIPE_IPC) /* || defined(WIN_IPC) */
242 if (GE_pending != type) {
243 gpe_push(&base, &ge);
244 } else if (!buffered_output_pending) {
249 /* FIXME HBB 20010216: this breaks the wgnuplot.exe+wgnuplot.dll type of
250 * compilation (for Win16). do_event is in the main program(mouse.c), but
251 * gpexecute is in the DLL --> can't reach it, from here. */
257 int status = write(1, gpe_front(&base), sizeof(ge));
268 } while (gpe_pop(&base));
269 #endif /* PIPE_IPC */
271 #ifdef OS2_IPC /* OS/2 communication via shared memory; coded according to gp_execute() */
272 if (input_from_PM_Terminal == NULL)
274 ((char *) input_from_PM_Terminal)[0] = '%'; /* flag that passing gp_event_t */
275 memcpy(((char *) input_from_PM_Terminal) + 1, &ge, sizeof(ge)); /* copy the command to shared memory */
276 if (pausing) { /* no communication during pause */
277 /* DosBeep(440,111); */
278 ((char *) input_from_PM_Terminal)[0] = 0;
281 gp_post_shared_mem();