1 /*****************************************************************************
2   FILE           : $Source: /projects/higgs1/SNNS/CVS/SNNS/xgui/sources/ui_event.c,v $
3   SHORTNAME      : event.c
4   SNNS VERSION   : 4.2
5 
6   PURPOSE        : event handler for all graphic windows. This handler only
7                    reacts on mouse and window events. A separate handler of
8                    map events is defined as well.
9   NOTES          :
10 
11   AUTHOR         : Tilman Sommer
12   DATE           : 15.5.1990
13 
14   CHANGED BY     : Michael Vogt, Guenter Mamier
15   RCS VERSION    : $Revision: 2.9 $
16   LAST CHANGE    : $Date: 1998/03/03 14:10:23 $
17 
18     Copyright (c) 1990-1995  SNNS Group, IPVR, Univ. Stuttgart, FRG
19     Copyright (c) 1996-1998  SNNS Group, WSI, Univ. Tuebingen, FRG
20 
21 ******************************************************************************/
22 #include <config.h>
23 
24 
25 #include <X11/X.h>
26 
27 #include "ui.h"
28 
29 #include "glob_typ.h"	/*  Kernel constant and type definitions  */
30 #include "kr_ui.h"	/*  Kernel interface functions	*/
31 
32 #include "ui_xGraphic.h"
33 #include "ui_status.h"
34 #include "ui_infoP.h"
35 #include "ui_netUpdate.h"
36 #include "ui_selection.h"
37 #include "ui_utilP.h"
38 #include "ui_display.h"
39 #include "ui_action.h"    /* move, copy */
40 #include "ui_key.h"       /* ui_key_popMenu() */
41 #include "ui_confirmer.h"
42 #include "ui_mainP.h"
43 #include "ui_colEdit.h"
44 #include "ui_color.h"
45 #include "ui_info.h"
46 
47 #include "ui_event.ph"
48 
49 
50 /*****************************************************************************
51   FUNCTION : ui_can_MapEventProc
52 
53   PURPOSE  : notifies all map/unmap events
54   RETURNS  : void
55   NOTES    : sets the component flags (bit 0) in the display structure
56              indicating, whether drawing in this display is neccessary
57 
58   UPDATE   : 20.9.1990
59 ******************************************************************************/
60 
ui_can_MapEventProc(Widget w,struct Ui_DisplayType * displayPtr,XEvent * event)61 void ui_can_MapEventProc (Widget w,  struct Ui_DisplayType *displayPtr,
62 	XEvent    *event)
63 
64 {
65 
66     switch (event->type) {
67       case MapNotify:
68 	ui_utilSetFlag(displayPtr->flags, 1);
69 	break;
70       case UnmapNotify:
71 	ui_utilResetFlag(displayPtr->flags, 1);
72 	break;
73     }
74 }
75 
76 
77 /*****************************************************************************
78   FUNCTION : ui_mw_eventProc
79 
80   PURPOSE  : handles all events caused by working in the canvas subwindow
81   RETURNS  : void    lot of sideeffects
82   NOTES    : This is the main event handler for all pointer (mouse) events
83              occurring in the canvas pixwin subwindow.
84 	     Each accepted event forces an action and also a feedback to the
85 	     user. This feedback can be:
86 	     - the cursor changes
87 	     - a message will occur, what's going on
88 	     - the position messages (status) below the canvas will be updated
89 	     - a side effect will occur (i.e. update of the unit-panel)
90 	     The mouse cursor must be in the window !!
91 	     * Click down, dragg and release left mouse button will select all
92 	     units in a rectangle area.
93 
94   UPDATE   :
95 *****************************************************************************/
96 
ui_mw_eventProc(Widget w,struct Ui_DisplayType * displayPtr,XEvent * event)97 void ui_mw_eventProc (Widget w, struct Ui_DisplayType *displayPtr,
98 	XEvent    *event)
99 
100 {
101     int        unitNo;
102     FlintType  weight;        /* holds temporary the  weight of a link */
103 
104 /* ------------------------------------------------------------------------ */
105 /* ------------------------------------------------------------------------ */
106     switch (event->type) {
107 /* ------------------------------------------------------------------------ */
108 /* ------------------------------------------------------------------------ */
109       case ButtonPress:
110 	if (displayPtr->frozen) return; /* don't accept this event here */
111 	ui_pixPosMouse.x = (int) event->xbutton.x;
112 	ui_pixPosMouse.y = (int) event->xbutton.y;
113 	ui_gridPosMouse  = ui_utilPixToGrid(displayPtr, ui_pixPosMouse);
114 	ui_unselectFlg   = event->xbutton.state BIT_AND ShiftMask;
115 /* ------------------------------------------------------------------------ */
116 	switch (event->xbutton.button) {
117 /* ------------------------------------------------------------------------ */
118 	  case 1:
119 	    /* LEFT MOUSE BUTTON PRESSED */
120 	    if (event->xbutton.state BIT_AND ControlMask) {
121 		ui_key_popMenu(displayPtr);
122 		/* ui_confirmOk("Menu"); */
123 		break;
124 	    }
125 	    if (NOT ui_outlineActive) {
126 		ui_leftButton   = TRUE;
127 		/* feedback to user: change cursor */
128 		/* store this position for later use */
129 		/* draw a initial box and set the flag */
130 		ui_selGridPos1   = ui_gridPosMouse;
131 		ui_selPixPos1    = ui_pixPosMouse;
132 		ui_selPixPosBox  = ui_pixPosMouse;
133 
134 		XSetFunction(ui_display, ui_gc, GXinvert);
135 		XSetBackground(ui_display, ui_gc, ui_backgroundColor); /* back */
136 		XSetForeground(ui_display, ui_gc, ui_textColor); /* text */
137 		if (ui_col_colorDisplay)
138 		    XSetPlaneMask(ui_display, ui_gc,
139 				  ui_textColor BIT_XOR ui_backgroundColor);
140 		ui_xDrawBox(ui_display, displayPtr->drawable,
141 			    ui_gc, ui_selPixPos1, ui_selPixPosBox);
142 		if (ui_col_colorDisplay)
143 		    XSetPlaneMask(ui_display, ui_gc, AllPlanes);
144 		ui_pixBoxDrawnFlg = TRUE; /* a box is drawn */
145 	    }
146 	    break;
147 /* ------------------------------------------------------------------------ */
148 	  case 2:
149 	    /* MIDDLE MOUSE BUTTON PRESSED */
150 	    if (not ui_outlineActive) {
151 		ui_middleButton      = TRUE;
152 		ui_link_sourceUnitNo =
153 		    krui_getUnitNoNearPosition(&ui_gridPosMouse,
154 					       displayPtr->subNetNo,
155 					       9,
156 					       displayPtr->gridSize);
157 	    }
158 	    break;
159 /* ------------------------------------------------------------------------ */
160 	  case 3:
161 	    /* RIGHT MOUSE BUTTON PRESSED */
162 	    break;
163 	}
164 	break;
165 /* ------------------------------------------------------------------------ */
166 /* ------------------------------------------------------------------------ */
167       case ButtonRelease:
168 	if (displayPtr->frozen) return; /* don't accept this event here */
169 	ui_pixPosMouse.x = (int) event->xbutton.x;
170 	ui_pixPosMouse.y = (int) event->xbutton.y;
171 	ui_gridPosMouse  = ui_utilPixToGrid(displayPtr, ui_pixPosMouse);
172 	ui_unselectFlg   = event->xbutton.state BIT_AND ShiftMask;
173 /* ------------------------------------------------------------------------ */
174 	switch (event->xbutton.button) {
175 /* ------------------------------------------------------------------------ */
176 	  case 1:
177 	    /* LEFT MOUSE BUTTON RELEASED */
178 	    if (ui_outlineActive) {
179 		struct PosType offset;
180 		/* erase outline */
181 		offset.x = ui_gridPosMouse.x - ui_targetUnit.gridPos.x;
182 		offset.y = ui_gridPosMouse.y - ui_targetUnit.gridPos.y;
183 		ui_sel_drawBoxes(displayPtr, UI_GLOBAL, offset);
184 		ui_outlineActive = FALSE;
185 		ui_key_eventPos  = ui_gridPosMouse;
186 		if (ui_key_action == UI_ACTION_MOVE) {
187 		    ui_printMessage("Units Move ...");
188 		    ui_action_unitsMove();
189 		} else {
190 		    ui_printMessage("Units Copy ...");
191 		    ui_action_unitsCopy();
192 		}
193 		ui_printMessage(">");
194 		ui_key_currentState = ui_key_returnUnitState;
195 	    } else {
196 		ui_leftButton   = FALSE;
197 
198 		/* erase box, store position and normalize */
199 		/* normalize: gridPos1 will be the upper left corner */
200 
201 		if (ui_pixBoxDrawnFlg) {
202 		    XSetFunction(ui_display, ui_gc, GXinvert);
203 		    XSetBackground(ui_display, ui_gc, ui_backgroundColor); /* back */
204 		    XSetForeground(ui_display, ui_gc, ui_textColor);
205 		    if (ui_col_colorDisplay)
206 			XSetPlaneMask(ui_display, ui_gc,
207 				      ui_textColor BIT_XOR ui_backgroundColor);
208 		    ui_xDrawBox(ui_display, displayPtr->drawable, ui_gc,
209 				ui_selPixPos1, ui_selPixPosBox);
210 		    if (ui_col_colorDisplay)
211 			XSetPlaneMask(ui_display, ui_gc, AllPlanes);
212 		    ui_pixBoxDrawnFlg = FALSE;
213 		}
214 
215 		ui_selGridPos2 = ui_gridPosMouse;
216 
217 		ui_utilNormalizeRect(&ui_selGridPos1, &ui_selGridPos2);
218 
219 		/* depending of the shift state: select or unselect */
220 
221 		if (ui_unselectFlg)  /* unselect */
222 
223 		    if ((NOT (krui_getUnitNoNearPosition(&ui_selGridPos1,
224 							 displayPtr->subNetNo,
225 							 9,
226 							 displayPtr->gridSize) > 0)) AND
227 			(ui_utilAreEqualPositions(ui_selGridPos1, ui_selGridPos2))) {
228 			/* user clicked a empty position -> select all */
229 			/* ui_sel_selectAll(...) not implemented */
230 			ui_stat_displayStatus(ui_gridPosMouse);
231 		    } else
232 			if (ui_utilAreEqualPositions(ui_selGridPos1,
233 						     ui_selGridPos2)) {
234 			    int unitNo;
235 			    if ((unitNo =
236 				krui_getUnitNoNearPosition(&ui_selGridPos1,
237 							   displayPtr->subNetNo,
238 							   9,
239 							   displayPtr->gridSize)) > 0) {
240 				krui_getUnitPosition(unitNo, &ui_selGridPos1);
241 				ui_sel_unselectOne(displayPtr, UI_GLOBAL,
242 						   unitNo, ui_selGridPos1);
243 			    }
244 			} else
245 			    ui_sel_unselectRect(displayPtr, UI_GLOBAL,
246 						ui_selGridPos1, ui_selGridPos2);
247 		else  /* select */
248 		    if (ui_utilAreEqualPositions(ui_selGridPos1,
249 						 ui_selGridPos2)) {
250 			int unitNo;
251 			if ((unitNo =
252 			     krui_getUnitNoNearPosition(&ui_selGridPos1,
253 							displayPtr->subNetNo,
254 							9,
255 							displayPtr->gridSize)) > 0) {
256 			    krui_getUnitPosition(unitNo, &ui_selGridPos1);
257 			    ui_sel_selectOne(displayPtr, UI_GLOBAL,
258 					     unitNo, ui_selGridPos1);
259 			}
260 		    } else
261 			ui_sel_selectRect(displayPtr, UI_GLOBAL,
262 					  ui_selGridPos1, ui_selGridPos2);
263 
264 		ui_leftButton = FALSE;  /* signal: end of operation */
265 	    }
266 	    break;
267 /* ------------------------------------------------------------------------ */
268 	  case 2:
269 	    /* MIDDLE MOUSE BUTTON RELEASED */
270 	    if ((NOT ui_outlineActive) AND ui_middleButton) {
271 		int targetUnitNo;
272 
273 		if ((targetUnitNo =
274 		     krui_getUnitNoNearPosition(&ui_gridPosMouse,
275 						displayPtr->subNetNo,
276 						9,
277 						displayPtr->gridSize)) > 0) {
278 		    /* a target unit exist */
279 		    if (ui_link_sourceUnitNo == 0)
280 			/* if pressed on an empty position then use
281 			   old SOURCE instead ! */
282 			ui_link_sourceUnitNo = ui_sourceUnit.no;
283 
284 		    /* show data in the unit info panel */
285 		    ui_info_showSelectedUnit(targetUnitNo);
286 
287 		    krui_setCurrentUnit(targetUnitNo);
288 		    if (krui_isConnected(ui_link_sourceUnitNo)) {
289 			/* if the source unit exists and already connected
290 			   then show all data of the Link */
291 			weight = krui_getLinkWeight();
292 			if( ui_infoIsCreated )
293 			    ui_info_showPredOfTargetUnit(ui_link_sourceUnitNo,
294 							 weight);
295 		    }
296 		} else { /* released on empty position */
297 		    if (ui_link_sourceUnitNo != 0) {
298 			/* pressed on a unit position */
299 			/* try to display the connection source -> TARGET */
300 			krui_setCurrentUnit(ui_targetUnit.no);
301 			if (krui_areConnectedWeight(ui_link_sourceUnitNo,
302 						    ui_targetUnit.no,&weight)
303 			    AND ui_infoIsCreated) {
304 			    /* if the source unit exists and already connected
305 			       then show all data of the Link */
306 			    ui_info_showPredOfTargetUnit(ui_link_sourceUnitNo,
307 							 weight);
308 			}
309 		    }
310 		}
311 	    }
312 	    ui_middleButton = FALSE;
313 	    break;
314 /* ------------------------------------------------------------------------ */
315 	  case 3:
316 	    /* RIGHT MOUSE BUTTON RELEASED */
317 	    if (NOT ui_outlineActive) {
318 		struct PosType  gridPos;
319 		if ((unitNo =
320 		    krui_getUnitNoNearPosition(&ui_gridPosMouse,
321 					       displayPtr->subNetNo,
322 					       9,
323 					       displayPtr->gridSize)) > 0) {
324 		    krui_getUnitPosition(unitNo, &gridPos);
325 		    ui_sel_unselectOne(displayPtr, UI_GLOBAL, unitNo, gridPos);
326 		    /* unselectOne gives not a message by itsself ! */
327 		    ui_sel_msgNumber();
328 		} else { /* user clicked on an empty position */
329 		    ui_sel_unselectAll(displayPtr, UI_GLOBAL);
330 		    ui_stat_displayStatus(ui_gridPosMouse);
331 		}
332 	    }
333 	    break;
334 /* ------------------------------------------------------------------------ */
335 	}
336 	break;
337 /* ------------------------------------------------------------------------ */
338 /* ------------------------------------------------------------------------ */
339       case MotionNotify:
340 	if (displayPtr->frozen) return; /* don't accept this event here */
341 
342 	ui_pixPosMouse.x = (int) event->xbutton.x;
343 	ui_pixPosMouse.y = (int) event->xbutton.y;
344 	ui_gridPosMouse  = ui_utilPixToGrid(displayPtr, ui_pixPosMouse);
345 
346 	if (ui_utilAreDifferentPositions(ui_gridPosOld, ui_gridPosMouse)) {
347 	    ui_stat_displayStatus(ui_gridPosMouse);
348 
349 	    if (ui_outlineActive) {
350 		struct PosType offset;
351 		offset.x = ui_gridPosOld.x - ui_targetUnit.gridPos.x;
352 		offset.y = ui_gridPosOld.y - ui_targetUnit.gridPos.y;
353 		ui_sel_drawBoxes(displayPtr, UI_GLOBAL, offset);
354 		offset.x = ui_gridPosMouse.x - ui_targetUnit.gridPos.x;
355 		offset.y = ui_gridPosMouse.y - ui_targetUnit.gridPos.y;
356 		ui_sel_drawBoxes(displayPtr, UI_GLOBAL, offset);
357 	    }
358 	}
359 
360 	if ((NOT ui_outlineActive) AND (event->xmotion.state AND
361 					(Button1Mask | Button2Mask |
362 					 Button3Mask))) {
363 	    /* at least one of the three mouse buttons is depressed !
364 	       ==> MOUSE DRAGG */
365 
366 	    /* only with left button down */
367 	    if (ui_leftButton) {
368 		/* draw rubber square on screen while dragging the mouse */
369 		/* Because two boxes are drawn, don't change the flag
370 		   ui_pixBoxDrawnFlg ! */
371 		XSetFunction(ui_display, ui_gc, GXinvert);
372 		XSetBackground(ui_display, ui_gc, ui_backgroundColor); /* back */
373 		XSetForeground(ui_display, ui_gc, ui_textColor);
374 		if (ui_col_colorDisplay)
375 		    XSetPlaneMask(ui_display, ui_gc,
376 				  ui_textColor BIT_XOR ui_backgroundColor);
377 		ui_xDrawBox(ui_display, displayPtr->drawable,
378 			    ui_gc, ui_selPixPos1, ui_selPixPosBox);
379 		ui_selPixPosBox = ui_pixPosMouse;
380 		ui_xDrawBox(ui_display, displayPtr->drawable,
381 			    ui_gc, ui_selPixPos1, ui_selPixPosBox);
382 		if (ui_col_colorDisplay)
383 		    XSetPlaneMask(ui_display, ui_gc, AllPlanes);
384 		ui_pixBoxDrawnFlg = TRUE; /* a box is drawn */
385 	    }
386 	}
387 	break;
388 /* ------------------------------------------------------------------------ */
389 /* ------------------------------------------------------------------------ */
390       case EnterNotify:
391 	/* mouse cursor moved into canvas subwindow */
392 	if (displayPtr->frozen) return; /* don't accept this event here */
393 	ui_pixPosMouse.x = (int) event->xbutton.x;
394 	ui_pixPosMouse.y = (int) event->xbutton.y;
395 	ui_gridPosMouse  = ui_utilPixToGrid(displayPtr, ui_pixPosMouse);
396 	ui_stat_displayStatus(ui_gridPosMouse);
397 	ui_currentDisplay = displayPtr;
398 	if (ui_outlineActive) {
399 	    struct PosType offset;
400 	    offset.x = ui_gridPosMouse.x - ui_targetUnit.gridPos.x;
401 	    offset.y = ui_gridPosMouse.y - ui_targetUnit.gridPos.y;
402 	    ui_sel_drawBoxes(displayPtr, UI_GLOBAL, offset);
403 #ifdef DEBUG
404 	    XFlush(ui_display);
405 #endif
406 	}
407 	break;
408 /* ------------------------------------------------------------------------ */
409 /* ------------------------------------------------------------------------ */
410       case LeaveNotify:
411 	/* mouse cursor moved out of canvas subwindow */
412 	if (displayPtr->frozen) return; /* don't accept this event here */
413 	if (ui_outlineActive) {
414 	    struct PosType offset;
415 	    offset.x = ui_gridPosOld.x - ui_targetUnit.gridPos.x;
416 	    offset.y = ui_gridPosOld.y - ui_targetUnit.gridPos.y;
417 	    ui_sel_drawBoxes(displayPtr, UI_GLOBAL, offset);
418 #ifdef DEBUG
419 	    XFlush(ui_display);
420 #endif
421 	}
422 	break;
423 /* ------------------------------------------------------------------------ */
424 /* ------------------------------------------------------------------------ */
425     }
426 /* ------------------------------------------------------------------------ */
427 /* ------------------------------------------------------------------------ */
428 
429     ui_pixPosOld  = ui_pixPosMouse; /* store pos for the next call */
430     ui_gridPosOld = ui_gridPosMouse;
431 }
432 
433 
434 
435 
436 
437 /* end of file */
438 /* lines: 479 */
439