1 /* Copyright (C) 2000 Damir Zucic */
2 
3 /*=============================================================================
4 
5 				key_press.c
6 
7 Purpose:
8 	Handle KeyPress events.
9 
10 Input:
11 	(1) Pointer to MolComplexS structure, with macromol. complexes.
12 	(2) Number of macromolecular complexes.
13 	(3) Pointer to the next macromolecular complex identifier.
14 	(4) Pointer to RuntimeS structure, with some runtime data.
15 	(5) Pointer to ConfigS structure, with configuration data.
16 	(6) Pointer to GUIS structure, with GUI data.
17 	(7) Pointer to pointer to NearestAtomS structure.
18 	(8) Pointer to the number of pixels in the main window free area.
19 	(9) Pointer to refreshI.
20        (10) Pointer to XKeyEvent structure.
21 
22 Output:
23 	(1) Some action performed.
24 	(2) Return value.
25 
26 Return value:
27 	(1) Positive or zero on success. If positive value is returned,
28 	    it should be  interpreted  as command code  returned by the
29 	    function ExecuteCommand1_ ().
30 	(2) Negative, if ExecuteCommand1_ () function failes. The value
31 	    should be interpreted as (internal) error code.
32 
33 Notes:
34 	(1) The value of refreshI  (*refreshIP)  may be changed in this
35 	    function.  It is checked in  EventLoop_ (see event_loop.c).
36 	    It is assumed that refreshI is updated no more than once in
37 	    each event handling function.  If this is not the case, the
38 	    care should be taken to avoid refreshI overflow.
39 
40 ========includes:============================================================*/
41 
42 #include <stdio.h>
43 
44 #include <ctype.h>
45 
46 #include <X11/Xlib.h>
47 #include <X11/Xutil.h>
48 #include <X11/Xos.h>
49 #include <X11/Xatom.h>
50 
51 #include <X11/keysym.h>
52 
53 #include "defines.h"
54 #include "typedefs.h"
55 
56 /*======function prototypes:=================================================*/
57 
58 double		RotationAngle_ (ConfigS *, GUIS *, double);
59 int		Rotate_ (MolComplexS *, int,
60 			 RuntimeS *, ConfigS *, double, int);
61 size_t		MainRefresh_ (MolComplexS *, int,
62 			      RuntimeS *, ConfigS *, GUIS *,
63 			      NearestAtomS *, size_t, unsigned int);
64 int		ControlRefresh_ (MolComplexS *, ConfigS *, GUIS *);
65 int		DockingRefresh_ (RuntimeS *, GUIS *);
66 double		TranslationShift_ (ConfigS *, GUIS *, double);
67 void		Translate_ (MolComplexS *, int,
68 			    RuntimeS *, ConfigS *, double, int);
69 double		SlabShift_ (ConfigS *, GUIS *, double);
70 void		MoveBackSlab_ (MolComplexS *, int, ConfigS *, double);
71 void		MoveFrontSlab_ (MolComplexS *, int, ConfigS *, double);
72 double		FadingShift_ (ConfigS *, GUIS *, double);
73 void		MoveBackFading_ (MolComplexS *, int, ConfigS *, double);
74 void		MoveFrontFading_ (MolComplexS *, int, ConfigS *, double);
75 int		AddCharToCommand_ (RuntimeS *, GUIS *, int);
76 int		InputRefresh_ (GUIS *, RuntimeS *);
77 int		EatLeftChar_ (RuntimeS *);
78 int		EatRightChar_ (RuntimeS *);
79 int		ExecuteCommand1_ (MolComplexS *, int *, int *,
80 				  RuntimeS *, ConfigS *, GUIS *,
81 				  NearestAtomS **, size_t *, unsigned int *);
82 int		TruncateCommand_ (RuntimeS *);
83 int		ReplaceCommand_ (RuntimeS *, int, GUIS *);
84 void		InitNearest_ (NearestAtomS *, size_t);
85 
86 /*======handle KeyPress events:==============================================*/
87 
KeyPress_(MolComplexS * mol_complexSP,int * mol_complexesNP,int * next_mol_complexIDP,RuntimeS * runtimeSP,ConfigS * configSP,GUIS * guiSP,NearestAtomS ** nearest_atomSPP,size_t * pixelsNP,unsigned int * refreshIP,XKeyEvent * key_eventSP)88 int KeyPress_ (MolComplexS *mol_complexSP, int *mol_complexesNP,
89 	       int *next_mol_complexIDP,
90 	       RuntimeS *runtimeSP, ConfigS *configSP, GUIS *guiSP,
91 	       NearestAtomS **nearest_atomSPP, size_t *pixelsNP,
92 	       unsigned int *refreshIP,
93 	       XKeyEvent *key_eventSP)
94 {
95 static char		stringA[STRINGSIZE];
96 static KeySym		key_symID;
97 static XComposeStatus	compose_statusS;
98 static double		rotation_angle;
99 static double		shift;
100 static int		carriage_pos, comm_length;
101 static int		new_char;
102 static int		command_code;
103 static int		n;
104 
105 /* Get the KeySym: */
106 XLookupString (key_eventSP, stringA, STRINGSIZE, &key_symID, &compose_statusS);
107 
108 /* Select the proper action for a given KeySym: */
109 switch (key_symID)
110 	{
111 
112 /*------modifiers:-----------------------------------------------------------*/
113 
114 	/* Shift key pressed: */
115 	case XK_Shift_L:
116 	case XK_Shift_R:
117 		guiSP->shift_pressedF = 1;
118 		break;
119 
120 	/* Control key pressed: */
121 	case XK_Control_L:
122 	case XK_Control_R:
123 		guiSP->control_pressedF = 1;
124 		break;
125 
126 	/* Alt or meta key pressed: */
127 	case XK_Alt_L:
128 	case XK_Alt_R:
129 	case XK_Meta_L:
130 	case XK_Meta_R:
131 		guiSP->alt_pressedF = 1;
132 		break;
133 
134 /*------rotations:-----------------------------------------------------------*/
135 
136 	/* Right-handed (positive) rotation about x: */
137 	case XK_KP_2:
138 	case XK_KP_Down:
139 		(*refreshIP)++;
140 		rotation_angle = RotationAngle_ (configSP, guiSP, 1.0);
141 		Rotate_ (mol_complexSP, *mol_complexesNP,
142 			 runtimeSP, configSP, rotation_angle, 1);
143 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
144 			      runtimeSP, configSP, guiSP,
145 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
146 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
147 				 configSP, guiSP);
148 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
149 		break;
150 
151 
152 	/* Left-handed (negative) rotation about x: */
153 	case XK_KP_8:
154 	case XK_KP_Up:
155 		(*refreshIP)++;
156 		rotation_angle = RotationAngle_ (configSP, guiSP, -1.0);
157 		Rotate_ (mol_complexSP, *mol_complexesNP,
158 			 runtimeSP, configSP, rotation_angle, 1);
159 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
160 			      runtimeSP, configSP, guiSP,
161 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
162 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
163 				 configSP, guiSP);
164 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
165 		break;
166 
167 	/* Right-handed (positive) rotation about y: */
168 	case XK_KP_4:
169 	case XK_KP_Left:
170 		(*refreshIP)++;
171 		rotation_angle = RotationAngle_ (configSP, guiSP, +1.0);
172 		Rotate_ (mol_complexSP, *mol_complexesNP,
173 			 runtimeSP, configSP, rotation_angle, 2);
174 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
175 			      runtimeSP, configSP, guiSP,
176 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
177 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
178 				 configSP, guiSP);
179 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
180 		break;
181 
182 	/* Left-handed (negative) rotation about y: */
183 	case XK_KP_6:
184 	case XK_KP_Right:
185 		(*refreshIP)++;
186 		rotation_angle = RotationAngle_ (configSP, guiSP, -1.0);
187 		Rotate_ (mol_complexSP, *mol_complexesNP,
188 			 runtimeSP, configSP, rotation_angle, 2);
189 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
190 			      runtimeSP, configSP, guiSP,
191 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
192 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
193 				 configSP, guiSP);
194 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
195 		break;
196 
197 	/* Right-handed (positive) rotation about z: */
198 	case XK_KP_9:
199 	case XK_KP_Prior:
200 		(*refreshIP)++;
201 		rotation_angle = RotationAngle_ (configSP, guiSP, +1.0);
202 		Rotate_ (mol_complexSP, *mol_complexesNP,
203 			 runtimeSP, configSP, rotation_angle, 3);
204 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
205 			      runtimeSP, configSP, guiSP,
206 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
207 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
208 				 configSP, guiSP);
209 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
210 		break;
211 
212 	/* Left-handed (negative) rotation about z: */
213 	case XK_KP_7:
214 	case XK_KP_Home:
215 		(*refreshIP)++;
216 		rotation_angle = RotationAngle_ (configSP, guiSP, -1.0);
217 		Rotate_ (mol_complexSP, *mol_complexesNP,
218 			 runtimeSP, configSP, rotation_angle, 3);
219 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
220 			      runtimeSP, configSP, guiSP,
221 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
222 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
223 				 configSP, guiSP);
224 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
225 		break;
226 
227 /*------translations:--------------------------------------------------------*/
228 
229 	/* Positive translation along x: */
230 	case XK_KP_Multiply:
231 	case XK_KP_F4:
232 		(*refreshIP)++;
233 		shift = TranslationShift_ (configSP, guiSP, +1.0);
234 		Translate_ (mol_complexSP, *mol_complexesNP,
235 			    runtimeSP, configSP, shift, 1);
236 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
237 			      runtimeSP, configSP, guiSP,
238 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
239 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
240 		break;
241 
242 	/* Negative translation along x: */
243 	case XK_KP_Divide:
244 	case XK_KP_F3:
245 		(*refreshIP)++;
246 		shift = TranslationShift_ (configSP, guiSP, -1.0);
247 		Translate_ (mol_complexSP, *mol_complexesNP,
248 			    runtimeSP, configSP, shift, 1);
249 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
250 			      runtimeSP, configSP, guiSP,
251 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
252 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
253 		break;
254 
255 	/* Positive translation along y: */
256 	case XK_KP_Add:
257 	case XK_KP_Separator:
258 		(*refreshIP)++;
259 		shift = TranslationShift_ (configSP, guiSP, +1.0);
260 		Translate_ (mol_complexSP, *mol_complexesNP,
261 			    runtimeSP, configSP, shift, 2);
262 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
263 			      runtimeSP, configSP, guiSP,
264 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
265 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
266 		break;
267 
268 	/* Negative translation along y: */
269 	case XK_KP_Subtract:
270 		(*refreshIP)++;
271 		shift = TranslationShift_ (configSP, guiSP, -1.0);
272 		Translate_ (mol_complexSP, *mol_complexesNP,
273 			    runtimeSP, configSP, shift, 2);
274 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
275 			      runtimeSP, configSP, guiSP,
276 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
277 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
278 		break;
279 
280 	/* Positive translation along z: */
281 	case XK_KP_5:
282 	case XK_KP_Begin:
283 		(*refreshIP)++;
284 		shift = TranslationShift_ (configSP, guiSP, +1.0);
285 		Translate_ (mol_complexSP, *mol_complexesNP,
286 			    runtimeSP, configSP, shift, 3);
287 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
288 			      runtimeSP, configSP, guiSP,
289 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
290 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
291 		break;
292 
293 	/* Negative translation along z: */
294 	case XK_KP_0:
295 	case XK_KP_Insert:
296 		(*refreshIP)++;
297 		shift = TranslationShift_ (configSP, guiSP, -1.0);
298 		Translate_ (mol_complexSP, *mol_complexesNP,
299 			    runtimeSP, configSP, shift, 3);
300 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
301 			      runtimeSP, configSP, guiSP,
302 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
303 		if (guiSP->dockingF) DockingRefresh_ (runtimeSP, guiSP);
304 		break;
305 
306 /*------slab:----------------------------------------------------------------*/
307 
308 	/* Push the back slab surface farther: */
309 	case XK_KP_1:
310 	case XK_KP_End:
311 		(*refreshIP)++;
312 		shift = SlabShift_ (configSP, guiSP, 1.0);
313 		MoveBackSlab_ (mol_complexSP, *mol_complexesNP,
314 			       configSP, shift);
315 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
316 			      runtimeSP, configSP, guiSP,
317 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
318 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
319 				 configSP, guiSP);
320 		break;
321 
322 	/* Pull the back slab surface closer: */
323 	case XK_KP_3:
324 	case XK_KP_Next:
325 		(*refreshIP)++;
326 		shift = SlabShift_ (configSP, guiSP, -1.0);
327 		MoveBackSlab_ (mol_complexSP, *mol_complexesNP,
328 			       configSP, shift);
329 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
330 			      runtimeSP, configSP, guiSP,
331 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
332 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
333 				 configSP, guiSP);
334 		break;
335 
336 	/* Push the front slab surface farther: */
337 	case XK_KP_Delete:
338 	case XK_KP_Decimal:
339 		(*refreshIP)++;
340 		shift = SlabShift_ (configSP, guiSP, 1.0);
341 		MoveFrontSlab_ (mol_complexSP, *mol_complexesNP,
342 				configSP, shift);
343 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
344 			      runtimeSP, configSP, guiSP,
345 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
346 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
347 				 configSP, guiSP);
348 		break;
349 
350 	/* Pull the front slab surface closer: */
351 	case XK_KP_Enter:
352 		(*refreshIP)++;
353 		shift = SlabShift_ (configSP, guiSP, -1.0);
354 		MoveFrontSlab_ (mol_complexSP, *mol_complexesNP,
355 				configSP, shift);
356 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
357 			      runtimeSP, configSP, guiSP,
358 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
359 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
360 				 configSP, guiSP);
361 		break;
362 
363 /*------fading:--------------------------------------------------------------*/
364 
365 	/* Push the back fading surface farther: */
366 	case XK_F1:
367 		(*refreshIP)++;
368 		shift = FadingShift_ (configSP, guiSP, 1.0);
369 		MoveBackFading_ (mol_complexSP, *mol_complexesNP,
370 				 configSP, shift);
371 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
372 			      runtimeSP, configSP, guiSP,
373 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
374 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
375 				 configSP, guiSP);
376 		break;
377 
378 	/* Pull the back fading surface closer: */
379 	case XK_F2:
380 		(*refreshIP)++;
381 		shift = FadingShift_ (configSP, guiSP, -1.0);
382 		MoveBackFading_ (mol_complexSP, *mol_complexesNP,
383 				 configSP, shift);
384 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
385 			      runtimeSP, configSP, guiSP,
386 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
387 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
388 				 configSP, guiSP);
389 		break;
390 
391 	/* Push the front fading surface farther: */
392 	case XK_F3:
393 		(*refreshIP)++;
394 		shift = FadingShift_ (configSP, guiSP, 1.0);
395 		MoveFrontFading_ (mol_complexSP, *mol_complexesNP,
396 				  configSP, shift);
397 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
398 			      runtimeSP, configSP, guiSP,
399 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
400 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
401 				 configSP, guiSP);
402 		break;
403 
404 	/* Pull the front fading surface closer: */
405 	case XK_F4:
406 		(*refreshIP)++;
407 		shift = FadingShift_ (configSP, guiSP, -1.0);
408 		MoveFrontFading_ (mol_complexSP, *mol_complexesNP,
409 				  configSP, shift);
410 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
411 			      runtimeSP, configSP, guiSP,
412 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
413 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
414 				 configSP, guiSP);
415 		break;
416 
417 /*------line editing:--------------------------------------------------------*/
418 
419 	/* Move the input window carriage (keyboard cursor) to the left: */
420 	case XK_Left:
421 		carriage_pos = runtimeSP->carriage_position;
422 		carriage_pos--;
423 		if (carriage_pos >= 0)
424 			{
425 			runtimeSP->carriage_position = carriage_pos;
426 			InputRefresh_ (guiSP, runtimeSP);
427 			}
428 		break;
429 
430 	/* Move the input window carriage (keyboard cursor) to the right: */
431 	case XK_Right:
432 		carriage_pos = runtimeSP->carriage_position;
433 		comm_length = runtimeSP->command_length;
434 		carriage_pos++;
435 		if (carriage_pos <= comm_length)
436 			{
437 			runtimeSP->carriage_position = carriage_pos;
438 			InputRefresh_ (guiSP, runtimeSP);
439 			}
440 		break;
441 
442 	/* Replace the current command with the previous one, if available: */
443 	case XK_Up:
444 		n = ReplaceCommand_ (runtimeSP, -1, guiSP);
445 		if (n < 0) break;
446 		InputRefresh_ (guiSP, runtimeSP);
447 		break;
448 
449 	/* Replace the current command with the next one (if available): */
450 	case XK_Down:
451 		n = ReplaceCommand_ (runtimeSP, +1, guiSP);
452 		if (n < 0) break;
453 		InputRefresh_ (guiSP, runtimeSP);
454 		break;
455 
456 	/* Move the input window carriage to the beginning of command line: */
457 	case XK_Home:
458 		runtimeSP->carriage_position = 0;
459 		InputRefresh_ (guiSP, runtimeSP);
460 		break;
461 
462 	/* Move the input window carrriage to the end of command line: */
463 	case XK_End:
464 		runtimeSP->carriage_position = runtimeSP->command_length;
465 		InputRefresh_ (guiSP, runtimeSP);
466 		break;
467 
468 	/* Remove one character on the left side: */
469 	case XK_BackSpace:
470 		EatLeftChar_ (runtimeSP);
471 		InputRefresh_ (guiSP, runtimeSP);
472 		break;
473 
474 	/* Remove one character on the right side: */
475 	case XK_Delete:
476 		EatRightChar_ (runtimeSP);
477 		InputRefresh_ (guiSP, runtimeSP);
478 		break;
479 
480 /*------command execution:---------------------------------------------------*/
481 
482 	/* Print command string to log file (if requested), */
483 	/* execute command,  truncate command string, reset */
484 	/* the string length and  refresh the input window. */
485 	/* If some kind  of error occurs,  the return  code */
486 	/* should  be  negative.  In  that case,  print the */
487 	/* error message to  log file (if it is requested). */
488 	case XK_Return:
489 		/** Print command to log file, if requested: **/
490 		if (configSP->log_fileF)
491 			{
492 			fprintf (configSP->log_fileP, "%s\n",
493 				 runtimeSP->curr_commandA);
494 			fflush (configSP->log_fileP);
495 			}
496 
497 		/** Parse command string and execute command: **/
498 		command_code = ExecuteCommand1_ (
499 					mol_complexSP, mol_complexesNP,
500 					next_mol_complexIDP,
501 					runtimeSP, configSP, guiSP,
502 					nearest_atomSPP, pixelsNP, refreshIP);
503 
504 		/** Print the latest message to log file, if requested: **/
505 		if ((command_code < 0) && (configSP->log_fileF))
506 			{
507 			fprintf (configSP->log_fileP, "#%s\n",
508 				 runtimeSP->messageA);
509 			fflush (configSP->log_fileP);
510 			}
511 
512 		/** Truncate the command string: **/
513 		TruncateCommand_ (runtimeSP);
514 
515 		/** Refresh (redraw) the input window: **/
516 		InputRefresh_ (guiSP, runtimeSP);
517 
518 		/** Update and check the command index **/
519 		/** and the  total number of commands: **/
520 		runtimeSP->next_commandI++;
521 		if (runtimeSP->next_commandI >= MAXCOMMSTRINGS - 1)
522 			{
523 			runtimeSP->next_commandI = 0;
524 			}
525 		if (runtimeSP->highest_commandI < MAXCOMMSTRINGS - 1)
526 			{
527 			runtimeSP->highest_commandI++;
528 			}
529 
530 		/** Update the old_commandI: **/
531 		runtimeSP->old_commandI = runtimeSP->next_commandI;
532 
533 		/** Return command code to the caller: **/
534 		return command_code;
535 		break;
536 
537 /*------escape key causes return to the main drawing mode:-------------------*/
538 
539 	/* Reset main window drawing mode and refresh the main window: */
540 	case XK_Escape:
541 		/* Reset drawing mode index: */
542 		guiSP->main_window_modeI = 0;
543 
544 		/* Reinitialize the NearestAtomS array: */
545 		InitNearest_ (*nearest_atomSPP, *pixelsNP);
546 		*refreshIP = 1;
547 
548 		/* Refresh the main window: */
549 		(*refreshIP)++;
550 		MainRefresh_ (mol_complexSP, *mol_complexesNP,
551 			      runtimeSP, configSP, guiSP,
552 			      *nearest_atomSPP, *pixelsNP, *refreshIP);
553 
554 		/* Refresh the control window: */
555 		ControlRefresh_ (mol_complexSP + runtimeSP->default_complexI,
556 				 configSP, guiSP);
557 		break;
558 
559 /*------character input:-----------------------------------------------------*/
560 
561 	/* All other keys should belong to the current command string: */
562 	default:
563 		/** Check the character: **/
564 		new_char = stringA[0];
565 		if (!isprint (new_char)) break;
566 
567 		/** Append the character to the command string: **/
568 		if (AddCharToCommand_ (runtimeSP, guiSP, new_char) < 0) break;
569 
570 		/** Refresh the input window: **/
571 		InputRefresh_ (guiSP, runtimeSP);
572 		;
573 
574 /*---------------------------------------------------------------------------*/
575 
576 	}
577 
578 /* Return zero if this point is reached: */
579 return 0;
580 }
581 
582 /*===========================================================================*/
583 
584 
585