Skip to content

Commit 3d4d9ed

Browse files
committed
nxcomp: Duplicate NXTransDialog code as NXTransCallbacksDispatcher.
- As a starting point for newly implementing a callbacks dispatcher scenario that allows capturing various session events and execute external tools (like dialog boxes, pulldown menus, etc.). - The callbacks dispatch approach will finally deprecated the NX_CLIENT env var related code path in later releases of nxcomp/nxagent. For now, the callbacks dispatcher code path is taken if the env var NX_CALLBACKS_DISPATCHER is set, ideally to the applications that handles the dispatching of callbacks from nxagent.
1 parent 4b67d31 commit 3d4d9ed

File tree

3 files changed

+232
-2
lines changed

3 files changed

+232
-2
lines changed

nx-X11/programs/Xserver/hw/nxagent/Dialog.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ void nxagentLaunchDialog(DialogType dialogType)
180180
int local;
181181
const char *window = NULL;
182182

183+
char *cbDispatcherCmd;
184+
183185
switch (dialogType)
184186
{
185187
case DIALOG_KILL_SESSION:
@@ -319,9 +321,14 @@ void nxagentLaunchDialog(DialogType dialogType)
319321

320322
sigprocmask(SIG_BLOCK, &set, &oldSet);
321323

322-
*pid = NXTransDialog(nxagentDialogName, message, window,
323-
type, local, dialogDisplay);
324+
cbDispatcherCmd = getenv("NX_CALLBACKS_DISPATCHER");
324325

326+
if (cbDispatcherCmd == NULL)
327+
*pid = NXTransDialog(nxagentDialogName, message, window,
328+
type, local, dialogDisplay);
329+
else
330+
*pid = NXTransCallbacksDispatcher(nxagentDialogName, message, window,
331+
type, local, dialogDisplay);
325332
#ifdef TEST
326333
fprintf(stderr, "nxagentLaunchDialog: Launched dialog %s with pid [%d] on display %s.\n",
327334
DECODE_DIALOG_TYPE(dialogType), *pid, dialogDisplay);

nxcomp/Children.cpp

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,225 @@ static int NXTransKeeperHandler(int signal);
108108
static void NXTransKeeperCheck();
109109

110110

111+
int NXTransCallbacksDispatcher(const char *caption, const char *message,
112+
const char *window, const char *type, int local,
113+
const char* display)
114+
{
115+
//
116+
// Be sure log file is valid.
117+
//
118+
119+
if (logofs == NULL)
120+
{
121+
logofs = &cerr;
122+
}
123+
124+
int pid;
125+
126+
#ifdef TEST
127+
*logofs << "NXTransCallbacksDispatcher: Going to fork with NX pid '"
128+
<< getpid() << "'.\n" << logofs_flush;
129+
#endif
130+
131+
pid = Fork();
132+
133+
if (pid != 0)
134+
{
135+
if (pid < 0)
136+
{
137+
#ifdef TEST
138+
*logofs << "NXTransCallbacksDispatcher: WARNING! Function fork failed. "
139+
<< "Error is " << EGET() << " '" << ESTR()
140+
<< "'.\n" << logofs_flush;
141+
#endif
142+
143+
cerr << "Warning" << ": Function fork failed. "
144+
<< "Error is " << EGET() << " '" << ESTR()
145+
<< "'.\n";
146+
}
147+
#ifdef TEST
148+
else
149+
{
150+
*logofs << "NXTransCallbacksDispatcher: Created NX dialog process "
151+
<< "with pid '" << pid << "'.\n"
152+
<< logofs_flush;
153+
}
154+
#endif
155+
156+
return pid;
157+
}
158+
159+
#ifdef TEST
160+
*logofs << "NXTransCallbacksDispatcher: Executing child with pid '"
161+
<< getpid() << "' and parent '" << getppid()
162+
<< "'.\n" << logofs_flush;
163+
#endif
164+
165+
SystemCleanup("NXTransCallbacksDispatcher");
166+
167+
//
168+
// Copy the client command before
169+
// freeing up the control class.
170+
//
171+
172+
char command[DEFAULT_STRING_LIMIT];
173+
174+
if (control != NULL)
175+
{
176+
strcpy(command, control -> ClientPath);
177+
}
178+
else
179+
{
180+
char *path = GetClientPath();
181+
182+
strcpy(command, path);
183+
184+
delete [] path;
185+
}
186+
187+
//
188+
// Get rid of the unused resources.
189+
//
190+
191+
MemoryCleanup("NXTransCallbacksDispatcher");
192+
193+
#ifdef TEST
194+
*logofs << "NXTransCallbacksDispatcher: Running external NX dialog with caption '"
195+
<< caption << "' message '" << message << "' type '"
196+
<< type << "' local '" << local << "' display '"
197+
<< display << "'.\n"
198+
<< logofs_flush;
199+
#endif
200+
201+
int pulldown = (strcmp(type, "pulldown") == 0);
202+
203+
char parent[DEFAULT_STRING_LIMIT];
204+
205+
snprintf(parent, DEFAULT_STRING_LIMIT, "%d", getppid());
206+
207+
parent[DEFAULT_STRING_LIMIT - 1] = '\0';
208+
209+
UnsetEnv("LD_LIBRARY_PATH");
210+
211+
for (int i = 0; i < 2; i++)
212+
{
213+
if (local != 0)
214+
{
215+
if (pulldown)
216+
{
217+
execlp(command, command, "--dialog", type, "--caption", caption,
218+
"--window", window, "--local", "--parent", parent,
219+
"--display", display, NULL);
220+
}
221+
else
222+
{
223+
execlp(command, command, "--dialog", type, "--caption", caption,
224+
"--message", message, "--local", "--parent", parent,
225+
"--display", display, NULL);
226+
}
227+
}
228+
else
229+
{
230+
if (pulldown)
231+
{
232+
execlp(command, command, "--dialog", type, "--caption", caption,
233+
"--window", window, "--parent", parent,
234+
"--display", display, NULL);
235+
}
236+
else
237+
{
238+
execlp(command, command, "--dialog", type, "--caption", caption,
239+
"--message", message, "--parent", parent,
240+
"--display", display, NULL);
241+
}
242+
}
243+
244+
#ifdef WARNING
245+
*logofs << "NXTransCallbacksDispatcher: WARNING! Couldn't start '"
246+
<< command << "'. " << "Error is " << EGET()
247+
<< " '" << ESTR() << "'.\n" << logofs_flush;
248+
#endif
249+
250+
cerr << "Warning" << ": Couldn't start '" << command
251+
<< "'. Error is " << EGET() << " '" << ESTR()
252+
<< "'.\n";
253+
254+
//
255+
// Retry by looking for the default name
256+
// in the default NX path.
257+
//
258+
259+
if (i == 0)
260+
{
261+
262+
strcpy(command, "nxclient");
263+
264+
char newPath[DEFAULT_STRING_LIMIT];
265+
266+
strcpy(newPath, "/usr/NX/bin:/opt/NX/bin:/usr/local/NX/bin:");
267+
268+
#ifdef __APPLE__
269+
270+
strcat(newPath, "/Applications/NX Client for OSX.app/Contents/MacOS:");
271+
272+
#endif
273+
274+
#ifdef __CYGWIN32__
275+
276+
strcat(newPath, ".:");
277+
278+
#endif
279+
280+
int newLength = strlen(newPath);
281+
282+
char *oldPath = getenv("PATH");
283+
284+
strncpy(newPath + newLength, oldPath, DEFAULT_STRING_LIMIT - newLength - 1);
285+
286+
newPath[DEFAULT_STRING_LIMIT - 1] = '\0';
287+
288+
#ifdef WARNING
289+
*logofs << "NXTransCallbacksDispatcher: WARNING! Trying with path '"
290+
<< newPath << "'.\n" << logofs_flush;
291+
#endif
292+
293+
cerr << "Warning" << ": Trying with path '" << newPath
294+
<< "'.\n";
295+
296+
//
297+
// Solaris doesn't seem to have
298+
// function setenv().
299+
//
300+
301+
#ifdef __sun
302+
303+
char newEnv[DEFAULT_STRING_LIMIT + 5];
304+
305+
sprintf(newEnv,"PATH=%s", newPath);
306+
307+
putenv(newEnv);
308+
309+
#else
310+
311+
setenv("PATH", newPath, 1);
312+
313+
#endif
314+
315+
}
316+
}
317+
318+
//
319+
// Hopefully useless.
320+
//
321+
322+
exit(0);
323+
}
324+
325+
//
326+
// Start a nxclient process in dialog mode.
327+
//
328+
329+
111330
//
112331
// Start a nxclient process in dialog mode.
113332
//

nxcomp/NX.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,10 @@ extern int NXTransProxy(int fd, int mode, const char *display);
433433

434434
extern int NXTransClient(const char *display);
435435

436+
extern int NXTransCallbacksDispatcher(const char *caption, const char *message,
437+
const char *window, const char *type, int local,
438+
const char *display);
439+
436440
extern int NXTransDialog(const char *caption, const char *message,
437441
const char *window, const char *type, int local,
438442
const char *display);

0 commit comments

Comments
 (0)