1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$XConsortium: Protocols.c /main/15 1996/10/17 12:00:24 cde-osf $"
26 #endif
27 #endif
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 
33 #include <Xm/XmosP.h>           /* for bzero et al */
34 #include <Xm/ProtocolsP.h>
35 #include "BaseClassI.h"
36 #include "CallbackI.h"
37 #include "ExtObjectI.h"
38 #include "MessagesI.h"
39 #include "ProtocolsI.h"
40 #include "XmI.h"
41 
42 
43 #define MSG1	_XmMMsgProtocols_0000
44 #define MSG2	_XmMMsgProtocols_0001
45 #define MSG3	_XmMMsgProtocols_0002
46 
47 #define MAX_PROTOCOLS		32
48 #define PROTOCOL_BLOCK_SIZE	4
49 
50 /********    Static Function Declarations    ********/
51 
52 static void ClassInitialize( void ) ;
53 static void ClassPartInitialize(
54                         WidgetClass w) ;
55 static void Initialize(
56                         Widget req,
57                         Widget new_w,
58                         ArgList args,
59                         Cardinal *num_args) ;
60 static void Destroy(
61                         Widget w) ;
62 static void RemoveAllPMgrHandler(
63                         Widget w,
64                         XtPointer closure,
65                         XEvent *event,
66                         Boolean *continue_to_dispatch) ;
67 static void RemoveAllPMgr(
68                         Widget w,
69                         XtPointer closure,
70                         XtPointer call_data) ;
71 static XmAllProtocolsMgr GetAllProtocolsMgr(
72                         Widget shell) ;
73 static void UpdateProtocolMgrProperty(
74                         Widget shell,
75                         XmProtocolMgr p_mgr) ;
76 static void InstallProtocols(
77                         Widget w,
78                         XmAllProtocolsMgr ap_mgr) ;
79 static void RealizeHandler(
80                         Widget w,
81                         XtPointer closure,
82                         XEvent *event,
83                         Boolean *cont) ;
84 static void ProtocolHandler(
85                         Widget w,
86                         XtPointer closure,
87                         XEvent *event,
88                         Boolean *cont) ;
89 static XmProtocol GetProtocol(
90                         XmProtocolMgr p_mgr,
91                         Atom p_atom) ;
92 static XmProtocolMgr AddProtocolMgr(
93                         XmAllProtocolsMgr ap_mgr,
94                         Atom property) ;
95 static XmProtocolMgr GetProtocolMgr(
96                         XmAllProtocolsMgr ap_mgr,
97                         Atom property) ;
98 static void RemoveProtocolMgr(
99                         XmAllProtocolsMgr ap_mgr,
100                         XmProtocolMgr p_mgr) ;
101 static void AddProtocols(
102                         Widget shell,
103                         XmProtocolMgr p_mgr,
104                         Atom *protocols,
105                         Cardinal num_protocols) ;
106 static void RemoveProtocols(
107                         Widget shell,
108                         XmProtocolMgr p_mgr,
109                         Atom *protocols,
110                         Cardinal num_protocols) ;
111 
112 /********    End Static Function Declarations    ********/
113 
114 
115 /***************************************************************************
116  *
117  * ProtocolObject Resources
118  *
119  ***************************************************************************/
120 
121 static XContext	allProtocolsMgrContext = (XContext) NULL;
122 
123 
124 #define Offset(field) XtOffsetOf( struct _XmProtocolRec, protocol.field)
125 
126 static XtResource protocolResources[] =
127 {
128     {
129 	XmNextensionType,
130 	XmCExtensionType, XmRExtensionType, sizeof (unsigned char),
131 	XtOffsetOf( struct _XmExtRec, ext.extensionType),
132 	XmRImmediate, (XtPointer)XmPROTOCOL_EXTENSION,
133     },
134     {
135 	XmNprotocolCallback,
136 	XmCProtocolCallback, XmRCallback, sizeof (XtCallbackList),
137 	Offset (callbacks),
138 	XmRImmediate, (XtPointer)NULL,
139     },
140 };
141 #undef Offset
142 
143 
144 externaldef(xmprotocolclassrec)
145 XmProtocolClassRec xmProtocolClassRec = {
146     {
147 	(WidgetClass) &xmExtClassRec,/* superclass 		*/
148 	"protocol",			/* class_name 		*/
149 	sizeof(XmProtocolRec),	 	/* size 		*/
150 	ClassInitialize, 		/* Class Initializer 	*/
151 	ClassPartInitialize, 		/* class_part_init 	*/
152 	FALSE, 				/* Class init'ed ? 	*/
153 	Initialize, 			/* initialize         	*/
154 	NULL, 				/* initialize_notify    */
155 	NULL,	 			/* realize            	*/
156 	NULL,	 			/* actions            	*/
157 	0,				/* num_actions        	*/
158 	protocolResources,		/* resources          	*/
159 	XtNumber(protocolResources),	/* resource_count     	*/
160 	NULLQUARK, 			/* xrm_class          	*/
161 	FALSE, 				/* compress_motion    	*/
162 	FALSE, 				/* compress_exposure  	*/
163 	FALSE, 				/* compress_enterleave	*/
164 	FALSE, 				/* visible_interest   	*/
165 	Destroy,			/* destroy            	*/
166 	NULL,		 		/* resize             	*/
167 	NULL, 				/* expose             	*/
168 	NULL,		 		/* set_values         	*/
169 	NULL, 				/* set_values_hook      */
170 	NULL,			 	/* set_values_almost    */
171 	NULL,				/* get_values_hook      */
172 	NULL, 				/* accept_focus       	*/
173 	XtVersion, 			/* intrinsics version 	*/
174 	NULL, 				/* callback offsets   	*/
175 	NULL,				/* tm_table           	*/
176 	NULL, 				/* query_geometry       */
177 	NULL, 				/* display_accelerator  */
178 	NULL, 				/* extension            */
179     },
180     {
181 	NULL,				/* synthetic resources	*/
182 	0,				/* num syn resources	*/
183     },
184     {
185 	NULL,				/* extension		*/
186     },
187 };
188 
189 externaldef(xmprotocolobjectclass) WidgetClass
190   xmProtocolObjectClass = (WidgetClass) (&xmProtocolClassRec);
191 
192 /************************************************************************
193  *
194  *  ClassInitialize
195  *    Initialize the vendorShell class structure.  This is called only
196  *    the first time a vendorShell widget is created.  It registers the
197  *    resource type converters unique to this class.
198  *
199  ************************************************************************/
200 static void
ClassInitialize(void)201 ClassInitialize( void )
202 {
203 
204 }
205 
206 /************************************************************************
207  *
208  *  ClassPartInitialize
209  *    Set up the inheritance mechanism for the routines exported by
210  *    vendorShells class part.
211  *
212  ************************************************************************/
213 static void
ClassPartInitialize(WidgetClass w)214 ClassPartInitialize(
215         WidgetClass w )
216 {
217     XmProtocolObjectClass wc = (XmProtocolObjectClass) w;
218 
219     if (wc == (XmProtocolObjectClass)xmProtocolObjectClass)
220       return;
221 }
222 
223 /*ARGSUSED*/
224 static void
Initialize(Widget req,Widget new_w,ArgList args,Cardinal * num_args)225 Initialize(
226         Widget req,		/* unused */
227         Widget new_w,
228         ArgList args,		/* unused */
229         Cardinal *num_args )	/* unused */
230 {
231     XmProtocol				ne = (XmProtocol) new_w;
232     XmWidgetExtData			extData;
233 
234     /*
235      * we should free this in ExtObject's destroy proc, but since all
236      * gadgets would need to change to not free it in thier code we'll
237      * do it here. |||
238      */
239     extData = _XmGetWidgetExtData(ne->ext.logicalParent,
240 				  ne->ext.extensionType);
241 if(extData == NULL)
242 {
243 #ifdef DEBUG
244         XmeWarning(NULL, "_XmGetWidgetExtData() returned NULL pointer.");
245 #endif
246         return;
247 }
248 
249     _XmProcessLock();
250     _XmExtObjFree((XtPointer) extData->reqWidget);
251     _XmProcessUnlock();
252     extData->reqWidget = NULL;
253 }
254 
255 /************************************************************************
256  *
257  *  Destroy
258  *
259  ************************************************************************/
260 /*ARGSUSED*/
261 static void
Destroy(Widget w)262 Destroy(
263         Widget w )		/* unused */
264 {
265   /*EMPTY*/
266 }
267 
268 /*ARGSUSED*/
269 static void
RemoveAllPMgrHandler(Widget w,XtPointer closure,XEvent * event,Boolean * continue_to_dispatch)270 RemoveAllPMgrHandler(
271         Widget w,
272         XtPointer closure,
273         XEvent *event,		/* unused */
274         Boolean *continue_to_dispatch)
275 {
276     XmAllProtocolsMgr ap_mgr = (XmAllProtocolsMgr) closure ;
277     Cardinal	i;
278 
279     for (i = 0; i < ap_mgr->num_protocol_mgrs; i++)
280       {
281 	  RemoveProtocolMgr(ap_mgr, ap_mgr->protocol_mgrs[i]);
282       }
283     /* free the context manager entry ||| */
284     XDeleteContext(XtDisplay(w),
285 		   (Window)w,
286 		   allProtocolsMgrContext);
287     XtFree((char *)ap_mgr->protocol_mgrs);
288     XtFree((char *)ap_mgr);
289 
290     *continue_to_dispatch = False;
291     return ;
292     }
293 
294 /************************************<+>*************************************
295  *
296  *   RemoveAllPMgr
297  *
298  *************************************<+>************************************/
299 /*ARGSUSED*/
300 static void
RemoveAllPMgr(Widget w,XtPointer closure,XtPointer call_data)301 RemoveAllPMgr(
302         Widget w,
303         XtPointer closure,
304         XtPointer call_data )	/* unused */
305 {
306 	XEvent ev ;
307         Boolean save_sensitive = w->core.sensitive ;
308         Boolean save_ancestor_sensitive = w->core.ancestor_sensitive ;
309 
310     XtInsertEventHandler( w, KeyPressMask, TRUE, RemoveAllPMgrHandler,
311                                                          closure, XtListHead) ;
312     bzero((void *) &ev, sizeof(XEvent));
313     ev.xkey.type = KeyPress ;
314     ev.xkey.display = XtDisplay( w) ;
315     ev.xkey.time = XtLastTimestampProcessed( XtDisplay( w)) ;
316     ev.xkey.send_event = True ;
317     ev.xkey.serial = LastKnownRequestProcessed( XtDisplay( w)) ;
318     ev.xkey.window = XtWindow( w) ;
319     ev.xkey.keycode = 0;
320     ev.xkey.state = 0;
321 
322     /* make sure we get it even if we're unrealized, or if widget
323      * is insensitive.
324      */
325     XtAddGrab( w, True, True) ;
326     w->core.sensitive = TRUE ;
327     w->core.ancestor_sensitive = TRUE ;
328     XtDispatchEvent(&ev) ;
329     w->core.sensitive = save_sensitive ;
330     w->core.ancestor_sensitive = save_ancestor_sensitive ;
331     XtRemoveGrab( w) ;
332 
333     XtRemoveEventHandler(w, (EventMask)NULL, TRUE, RemoveAllPMgrHandler,
334 			 closure) ;
335     }
336 
337 /************************************<+>*************************************
338  *
339  *   GetAllProtocolsMgr
340  *
341  *************************************<+>************************************/
342 static XmAllProtocolsMgr
GetAllProtocolsMgr(Widget shell)343 GetAllProtocolsMgr(
344         Widget shell )
345 {
346     XmAllProtocolsMgr	ap_mgr;
347     Display		*display;
348 
349     if (!XmIsVendorShell(shell))
350       {
351 	  XmeWarning(NULL, MSG1);
352 	  return ((XmAllProtocolsMgr)0);
353       }
354     else
355       {
356 	  display = XtDisplay(shell);
357 
358 	  _XmProcessLock();
359 	  if (allProtocolsMgrContext == (XContext) NULL)
360 	    allProtocolsMgrContext = XUniqueContext();
361 	  _XmProcessUnlock();
362 
363 	  if (XFindContext(display,
364 			   (Window) shell,
365 			   allProtocolsMgrContext,
366 			   (char **)&ap_mgr))
367 	    {
368 		ap_mgr = XtNew(XmAllProtocolsMgrRec);
369 
370 		ap_mgr->shell = shell;
371 		ap_mgr->num_protocol_mgrs =
372 		  ap_mgr->max_protocol_mgrs = 0;
373 		ap_mgr->protocol_mgrs = NULL;
374 		(void) XSaveContext(display,
375 				    (Window) shell,
376 				    allProtocolsMgrContext,
377 				    (XPointer) ap_mgr);
378 
379 		/* !!! should this be in some init code for vendor shell ? */
380 		/* if shell isn't realized, add an event handler for everybody */
381 
382 		if (!XtIsRealized(shell))
383 		  {
384 		      XtAddEventHandler((Widget) shell, StructureNotifyMask,
385                                     FALSE, RealizeHandler, (XtPointer) ap_mgr);
386 		  }
387 		XtAddCallback((Widget) shell, XmNdestroyCallback,
388                                              RemoveAllPMgr, (XtPointer)ap_mgr);
389 
390 	    }
391 	  return ap_mgr;
392       }
393 }
394 /************************************<+>*************************************
395  *
396  *   SetProtocolProperty
397  *
398  *************************************<+>************************************/
399 #define SetProtocolProperty(shell, property, prop_type, atoms, num_atoms) \
400   XChangeProperty((shell)->core.screen->display, XtWindow(shell), \
401 		  property, prop_type, 32, PropModeReplace, \
402 		  atoms, num_atoms)
403 
404 
405 /************************************<+>*************************************
406  *
407  *   UpdateProtocolMgrProperty
408  *
409  *************************************<+>************************************/
410 static void
UpdateProtocolMgrProperty(Widget shell,XmProtocolMgr p_mgr)411 UpdateProtocolMgrProperty(
412         Widget shell,
413         XmProtocolMgr p_mgr )
414 {
415     Cardinal	i, num_active = 0;
416     Atom	active_protocols[MAX_PROTOCOLS];
417     XmProtocolList	protocols = p_mgr->protocols;
418 
419     for (i = 0; i < p_mgr->num_protocols; i++) {
420 	if (protocols[i]->protocol.active)
421 	  active_protocols[num_active++] = protocols[i]->protocol.atom;
422     }
423     SetProtocolProperty(shell, p_mgr->property, XA_ATOM,
424 		(unsigned char *)active_protocols, num_active);
425 }
426 
427 
428 /************************************<+>*************************************
429  *
430  *   InstallProtocols
431  *
432  *************************************<+>************************************/
433 static void
InstallProtocols(Widget w,XmAllProtocolsMgr ap_mgr)434 InstallProtocols(
435         Widget w,
436         XmAllProtocolsMgr ap_mgr )
437 {
438     Cardinal		i;
439 
440     XtAddRawEventHandler(w, (EventMask)0, TRUE,
441 			 ProtocolHandler, (XtPointer) ap_mgr);
442     XtRemoveEventHandler(w,StructureNotifyMask , FALSE,
443 			 RealizeHandler, ap_mgr);
444 
445     for (i=0; i < ap_mgr->num_protocol_mgrs; i++)
446       UpdateProtocolMgrProperty(w, ap_mgr->protocol_mgrs[i]);
447 
448 }
449 
450 /************************************<+>*************************************
451  *
452  *   RealizeHandler
453  *
454  *************************************<+>************************************/
455 /*ARGSUSED*/
456 static void
RealizeHandler(Widget w,XtPointer closure,XEvent * event,Boolean * cont)457 RealizeHandler(
458         Widget w,
459         XtPointer closure,
460         XEvent *event,
461         Boolean *cont )		/* unused */
462 {
463     XmAllProtocolsMgr	ap_mgr = (XmAllProtocolsMgr)closure;
464 
465     switch (event->type)
466       {
467 	case MapNotify:
468 	  InstallProtocols(w, ap_mgr);
469 	default:
470 	  break;
471       }
472 }
473 
474 /************************************<+>*************************************
475  *
476  *   ProtocolHandler
477  *
478  *************************************<+>************************************/
479 /*ARGSUSED*/
480 static void
ProtocolHandler(Widget w,XtPointer closure,XEvent * event,Boolean * cont)481 ProtocolHandler(
482         Widget w,
483         XtPointer closure,
484         XEvent *event,
485         Boolean *cont )		/* unused */
486 {
487   XmAllProtocolsMgr	ap_mgr = (XmAllProtocolsMgr)closure;
488   XmProtocolMgr	p_mgr;
489   XmProtocol		protocol;
490   XmAnyCallbackStruct	call_data_rec;
491   XtCallbackProc	func;
492 
493   call_data_rec.reason = XmCR_PROTOCOLS;
494   call_data_rec.event = event;
495 
496   switch (event->type) {
497   case ClientMessage: {
498       XClientMessageEvent	*p_event = (XClientMessageEvent *) event;
499       Atom			p_atom = (Atom) p_event->data.l[0];
500 
501       if (((p_mgr = GetProtocolMgr(ap_mgr, (Atom)p_event->message_type))
502 	   == (XmProtocolMgr)0) ||
503 	  ((protocol = GetProtocol(p_mgr, p_atom)) == (XmProtocol)0))
504 	return;
505       else {
506 	if ((func = protocol->protocol.pre_hook.callback) != (XtCallbackProc)0)
507 	  (*func) (w, protocol->protocol.pre_hook.closure, (XtPointer) &call_data_rec);
508 
509 	if (protocol->protocol.callbacks)
510 	  _XmCallCallbackList(w,
511 			      protocol->protocol.callbacks,
512 			      (XtPointer) &call_data_rec);
513 
514 	if ((func = protocol->protocol.post_hook.callback) != (XtCallbackProc)0)
515 	  (*func) (w, protocol->protocol.post_hook.closure, (XtPointer) &call_data_rec);
516       }
517       break;
518     }
519     default: {
520       break;
521     }
522   }
523 }
524 
525 
526 
527 /************************************<+>*************************************
528  *
529  *   GetProtocol
530  *
531  *************************************<+>************************************/
532 static XmProtocol
GetProtocol(XmProtocolMgr p_mgr,Atom p_atom)533 GetProtocol(
534         XmProtocolMgr p_mgr,
535         Atom p_atom )
536 {
537     Cardinal	i;
538     XmProtocol	protocol;
539 
540     i = 0;
541     while ((i < p_mgr->num_protocols) &&
542 	   (p_mgr->protocols[i]->protocol.atom != p_atom))
543       i++;
544 
545     if (i < p_mgr->num_protocols)
546       {
547 	  protocol = p_mgr->protocols[i];
548       }
549     else
550       {
551 	  protocol = (XmProtocol)0;
552       }
553     return(protocol);
554 }
555 
556 
557 /************************************<+>*************************************
558  *
559  *   AddProtocolMgr
560  *
561  *************************************<+>************************************/
562 static XmProtocolMgr
AddProtocolMgr(XmAllProtocolsMgr ap_mgr,Atom property)563 AddProtocolMgr(
564         XmAllProtocolsMgr ap_mgr,
565         Atom property )
566 {
567     XmProtocolMgr	p_mgr;
568     Cardinal		i;
569 
570     i = 0;
571     while ((i < ap_mgr->num_protocol_mgrs) &&
572 	   (ap_mgr->protocol_mgrs[i]->property != property))
573       i++;
574 
575     if (i < ap_mgr->num_protocol_mgrs)
576       {
577 	  XmeWarning(NULL, MSG2);
578       }
579 
580     if (ap_mgr->num_protocol_mgrs + 2 >= ap_mgr->max_protocol_mgrs)
581       {
582 	  ap_mgr->max_protocol_mgrs += 2;
583 	  ap_mgr->protocol_mgrs = (XmProtocolMgrList)
584 	    XtRealloc((char *) ap_mgr->protocol_mgrs ,
585 		      ((unsigned) (ap_mgr->max_protocol_mgrs)
586 		       * sizeof(XmProtocolMgr)));
587       }
588     ap_mgr->protocol_mgrs[ap_mgr->num_protocol_mgrs++]
589       = p_mgr = XtNew(XmProtocolMgrRec);
590 
591     p_mgr->property = property;
592     p_mgr->num_protocols =
593       p_mgr->max_protocols = 0;
594 
595     p_mgr->protocols = NULL;
596 
597     return(p_mgr);
598 }
599 /************************************<+>*************************************
600  *
601  *   GetProtcolMgr
602  *
603  *************************************<+>************************************/
604 static XmProtocolMgr
GetProtocolMgr(XmAllProtocolsMgr ap_mgr,Atom property)605 GetProtocolMgr(
606         XmAllProtocolsMgr ap_mgr,
607         Atom property )
608 {
609     XmProtocolMgr	p_mgr = (XmProtocolMgr)0;
610     Cardinal		i;
611 
612     if (!ap_mgr) return p_mgr;
613 
614     i = 0;
615     while ((i < ap_mgr->num_protocol_mgrs) &&
616 	   (ap_mgr->protocol_mgrs[i]->property != property))
617       i++;
618 
619     if (i < ap_mgr->num_protocol_mgrs)
620       {
621 	  p_mgr = ap_mgr->protocol_mgrs[i];
622       }
623     else
624       p_mgr = (XmProtocolMgr)0;
625 
626     return p_mgr;
627 }
628 
629 
630 /************************************<+>*************************************
631  *
632  *   RemoveProtocolMgr
633  *
634  *************************************<+>************************************/
635 static void
RemoveProtocolMgr(XmAllProtocolsMgr ap_mgr,XmProtocolMgr p_mgr)636 RemoveProtocolMgr(
637         XmAllProtocolsMgr ap_mgr,
638         XmProtocolMgr p_mgr )
639 {
640     Widget	shell = ap_mgr->shell;
641     Cardinal 	i;
642 
643     for (i = 0; i < p_mgr->num_protocols; i++)
644       {
645           _XmRemoveAllCallbacks(
646 		(InternalCallbackList *)&(p_mgr->protocols[i]->protocol.callbacks) );
647           XtFree((char *) p_mgr->protocols[i]);
648       }
649     if (XtIsRealized(shell))
650 	XDeleteProperty(XtDisplay(shell),
651 			XtWindow(shell),
652 			p_mgr->property);
653 
654     for (i = 0;  i < ap_mgr->num_protocol_mgrs;  i++)
655       if (ap_mgr->protocol_mgrs[i] == p_mgr)
656 	break;
657 
658     XtFree((char *) p_mgr->protocols);
659     XtFree((char *) p_mgr);
660 
661     /* ripple mgrs down */
662     for ( ; i < ap_mgr->num_protocol_mgrs-1; i++)
663       ap_mgr->protocol_mgrs[i] = ap_mgr->protocol_mgrs[i+1];
664 }
665 /************************************<+>*************************************
666  *
667  *  AddProtocols
668  *
669  *************************************<+>************************************/
670 static void
AddProtocols(Widget shell,XmProtocolMgr p_mgr,Atom * protocols,Cardinal num_protocols)671 AddProtocols(
672         Widget shell,
673         XmProtocolMgr p_mgr,
674         Atom *protocols,
675         Cardinal num_protocols )
676 {
677     Cardinal		new_num_protocols, i, j;
678     XtPointer           newSec;
679     WidgetClass         wc;
680     Cardinal            size;
681 
682     wc = XtClass(shell);
683     size = wc->core_class.widget_size;
684 
685     new_num_protocols = p_mgr->num_protocols + num_protocols;
686 
687     if (new_num_protocols >= p_mgr->max_protocols)
688       {
689 	  /* Allocate more space */
690 	  Cardinal	add_size;
691 
692 	  if (num_protocols >= PROTOCOL_BLOCK_SIZE)
693 	    add_size = num_protocols + PROTOCOL_BLOCK_SIZE;
694 	  else
695 	    add_size = PROTOCOL_BLOCK_SIZE;
696 
697 	  p_mgr->max_protocols +=  add_size;
698 	  p_mgr->protocols = (XmProtocolList)
699 	    XtRealloc((char *) p_mgr->protocols ,
700 		      (unsigned) (p_mgr->max_protocols) * sizeof(XmProtocol));
701       }
702 
703     for (i = p_mgr->num_protocols, j = 0;
704 	 i < new_num_protocols;
705 	 i++,j++)
706       {
707 
708           newSec = XtMalloc(size);
709 
710           ((XmProtocol) newSec)->protocol.atom = protocols[j];
711 	  ((XmProtocol)newSec)->protocol.active = TRUE; /*default */
712 	  ((XmProtocol)newSec)->protocol.callbacks = (XtCallbackList)0;
713 	  ((XmProtocol)newSec)->protocol.pre_hook.callback =
714           ((XmProtocol)newSec)->protocol.post_hook.callback = (XtCallbackProc)0;
715 	  ((XmProtocol)newSec)->protocol.pre_hook.closure =
716 	  ((XmProtocol)newSec)->protocol.post_hook.closure = (XtPointer)0;
717 
718           p_mgr->protocols[i] = (XmProtocol)newSec;
719       }
720     p_mgr->num_protocols = new_num_protocols;
721 
722 }
723 
724 /************************************<+>*************************************
725  *
726  *   RemoveProtocols
727  *
728  *************************************<+>************************************/
729 /*ARGSUSED*/
730 static void
RemoveProtocols(Widget shell,XmProtocolMgr p_mgr,Atom * protocols,Cardinal num_protocols)731 RemoveProtocols(
732         Widget shell,		/* unused */
733         XmProtocolMgr p_mgr,
734         Atom *protocols,
735         Cardinal num_protocols )
736 {
737     Boolean	match_list[MAX_PROTOCOLS];
738     Cardinal		i, j;
739 
740     if (!p_mgr || !p_mgr->num_protocols || !num_protocols) return;
741 
742     if (p_mgr->num_protocols > MAX_PROTOCOLS)
743       XmeWarning(NULL, MSG3);
744 
745     for (i = 0; i <= p_mgr->num_protocols; i++)
746       match_list[i] = FALSE;
747 
748     /* setup the match list */
749     for (i = 0; i < num_protocols; i++)
750       {
751 	  j = 0;
752 	  while ((j < p_mgr->num_protocols) &&
753 		 (p_mgr->protocols[j]->protocol.atom != protocols[i]))
754 	    j++;
755 	  if (j < p_mgr->num_protocols)
756 	    match_list[j] = TRUE;
757       }
758 
759     /*
760      * keep only the protocols that arent in the match list.
761      */
762     for (j = 0, i = 0; i < p_mgr->num_protocols; i++)
763       {
764 	  if ( ! match_list[i] ) {
765 	      p_mgr->protocols[j] = p_mgr->protocols[i];
766 	      j++;
767 	  }
768 	  else
769           {
770             _XmRemoveAllCallbacks((InternalCallbackList *) &(p_mgr->protocols[i]->protocol.callbacks));
771             XtFree((char *) p_mgr->protocols[i]);
772           }
773       }
774 
775     p_mgr->num_protocols = j;
776 
777 }
778 
779 
780 
781 
782 /*
783  *
784  * PUBLIC INTERFACES
785  *
786  */
787 
788 
789 /************************************<+>*************************************
790  *
791  *   _XmInstallProtocols
792  *
793  *************************************<+>************************************/
794 void
_XmInstallProtocols(Widget w)795 _XmInstallProtocols(
796         Widget w )
797 {
798     XmAllProtocolsMgr	ap_mgr;
799 
800     if ((ap_mgr = GetAllProtocolsMgr(w)) != NULL)
801       InstallProtocols(w, ap_mgr);
802 }
803 
804 
805 
806 /************************************<+>*************************************
807  *
808  *   XmAddProtocols
809  *
810  *************************************<+>************************************/
811 void
XmAddProtocols(Widget shell,Atom property,Atom * protocols,Cardinal num_protocols)812 XmAddProtocols(
813         Widget shell,
814         Atom property,
815         Atom *protocols,
816         Cardinal num_protocols )
817 {
818     XmAllProtocolsMgr	ap_mgr;
819     XmProtocolMgr	p_mgr ;
820     _XmWidgetToAppContext(shell);
821 
822     _XmAppLock(app);
823 
824     if (shell->core.being_destroyed) {
825 	_XmAppUnlock(app);
826         return;
827     }
828     if (((ap_mgr = GetAllProtocolsMgr(shell)) == 0) ||	!num_protocols)
829     {
830       _XmAppUnlock(app);
831       return;
832     }
833     if ((p_mgr = GetProtocolMgr(ap_mgr, property)) == 0)
834       p_mgr = AddProtocolMgr(ap_mgr, property);
835 
836     /* get rid of duplicates and then append to end */
837     RemoveProtocols(shell, p_mgr, protocols, num_protocols);
838     AddProtocols(shell, p_mgr, protocols, num_protocols);
839 
840     if (XtIsRealized(shell))
841       UpdateProtocolMgrProperty(shell, p_mgr);
842     _XmAppUnlock(app);
843 }
844 
845 
846 
847 /************************************<+>*************************************
848  *
849  *   XmRemoveProtocols
850  *
851  *************************************<+>************************************/
852 void
XmRemoveProtocols(Widget shell,Atom property,Atom * protocols,Cardinal num_protocols)853 XmRemoveProtocols(
854         Widget shell,
855         Atom property,
856         Atom *protocols,
857         Cardinal num_protocols )
858 {
859     XmAllProtocolsMgr	ap_mgr;
860     XmProtocolMgr	p_mgr ;
861     _XmWidgetToAppContext(shell);
862 
863     _XmAppLock(app);
864 
865     if (shell->core.being_destroyed) {
866 	_XmAppUnlock(app);
867         return;
868     }
869     if (((ap_mgr = GetAllProtocolsMgr(shell)) == 0) 		||
870 	((p_mgr = GetProtocolMgr(ap_mgr, property)) == 0) 	||
871 	!num_protocols) {
872       _XmAppUnlock(app);
873       return;
874     }
875 
876 
877     RemoveProtocols(shell, p_mgr, protocols, num_protocols);
878 
879     if (XtIsRealized(shell))
880       UpdateProtocolMgrProperty(shell, p_mgr);
881     _XmAppUnlock(app);
882 }
883 
884 /************************************<+>*************************************
885  *
886  *   XmAddProtocolCallback
887  *
888  *************************************<+>************************************/
889 void
XmAddProtocolCallback(Widget shell,Atom property,Atom proto_atom,XtCallbackProc callback,XtPointer closure)890 XmAddProtocolCallback(
891         Widget shell,
892         Atom property,
893         Atom proto_atom,
894         XtCallbackProc callback,
895         XtPointer closure )
896 {
897     XmAllProtocolsMgr	ap_mgr;
898     XmProtocolMgr	p_mgr ;
899     XmProtocol		protocol;
900     _XmWidgetToAppContext(shell);
901 
902     _XmAppLock(app);
903 
904     if (shell->core.being_destroyed) {
905 	 _XmAppUnlock(app);
906          return;
907     }
908     if ((ap_mgr = GetAllProtocolsMgr(shell)) == (XmAllProtocolsMgr)0) {
909       _XmAppUnlock(app);
910       return;
911     }
912     if ((p_mgr = GetProtocolMgr(ap_mgr, property)) == (XmProtocolMgr)0)
913       p_mgr = AddProtocolMgr(ap_mgr, property);
914     if ((protocol = GetProtocol(p_mgr, proto_atom)) == (XmProtocol)0)
915       {
916 	  XmAddProtocols(shell, property, &proto_atom, 1);
917 	  protocol = GetProtocol(p_mgr, proto_atom);
918       }
919 
920     _XmAddCallback((InternalCallbackList *) &(protocol->protocol.callbacks),
921                     callback,
922                     closure) ;
923     _XmAppUnlock(app);
924 }
925 
926 /************************************<+>*************************************
927  *
928  *   XmRemoveProtocolCallback
929  *
930  *************************************<+>************************************/
931 void
XmRemoveProtocolCallback(Widget shell,Atom property,Atom proto_atom,XtCallbackProc callback,XtPointer closure)932 XmRemoveProtocolCallback(
933         Widget shell,
934         Atom property,
935         Atom proto_atom,
936         XtCallbackProc callback,
937         XtPointer closure )
938 {
939     XmAllProtocolsMgr	ap_mgr;
940     XmProtocolMgr	p_mgr ;
941     XmProtocol		protocol;
942     _XmWidgetToAppContext(shell);
943 
944     _XmAppLock(app);
945 
946     if (shell->core.being_destroyed) {
947 	_XmAppUnlock(app);
948         return;
949     }
950     if (((ap_mgr = GetAllProtocolsMgr(shell)) == 0) 		||
951 	((p_mgr = GetProtocolMgr(ap_mgr, property)) == 0) 	||
952 	((protocol = GetProtocol(p_mgr, proto_atom)) == 0)) {
953       _XmAppUnlock(app);
954       return;
955     }
956 
957     _XmRemoveCallback((InternalCallbackList *) &(protocol->protocol.callbacks),
958                     callback,
959                     closure) ;
960     _XmAppUnlock(app);
961 }
962 
963 /************************************<+>*************************************
964  *
965  *   XmActivateProtocol
966  *
967  *************************************<+>************************************/
968 void
XmActivateProtocol(Widget shell,Atom property,Atom proto_atom)969 XmActivateProtocol(
970         Widget shell,
971         Atom property,
972         Atom proto_atom )
973 {
974     XmAllProtocolsMgr	ap_mgr;
975     XmProtocolMgr	p_mgr ;
976     XmProtocol		protocol;
977     _XmWidgetToAppContext(shell);
978 
979     _XmAppLock(app);
980 
981     if (shell->core.being_destroyed) {
982 	 _XmAppUnlock(app);
983          return;
984     }
985     if (((ap_mgr = GetAllProtocolsMgr(shell)) == 0) 		||
986 	((p_mgr = GetProtocolMgr(ap_mgr, property)) == 0) 	||
987 	((protocol = GetProtocol(p_mgr, proto_atom)) == 0) 	||
988 	protocol->protocol.active) {
989       _XmAppUnlock(app);
990       return;
991     }
992     else
993       {
994 	  protocol->protocol.active = TRUE;
995 	  if (XtIsRealized(shell))
996 	    UpdateProtocolMgrProperty(shell, p_mgr);
997       }
998     _XmAppUnlock(app);
999 }
1000 
1001 /************************************<+>*************************************
1002  *
1003  *   XmDeactivateProtocol
1004  *
1005  *************************************<+>************************************/
1006 void
XmDeactivateProtocol(Widget shell,Atom property,Atom proto_atom)1007 XmDeactivateProtocol(
1008         Widget shell,
1009         Atom property,
1010         Atom proto_atom )
1011 {
1012     XmAllProtocolsMgr	ap_mgr;
1013     XmProtocolMgr	p_mgr ;
1014     XmProtocol		protocol;
1015     _XmWidgetToAppContext(shell);
1016 
1017     _XmAppLock(app);
1018 
1019     if (shell->core.being_destroyed) {
1020 	_XmAppUnlock(app);
1021         return;
1022     }
1023     if (((ap_mgr = GetAllProtocolsMgr(shell)) == 0) 		||
1024 	((p_mgr = GetProtocolMgr(ap_mgr, property)) == 0) 	||
1025 	((protocol = GetProtocol(p_mgr, proto_atom)) == 0) 	||
1026 	!protocol->protocol.active) {
1027       _XmAppUnlock(app);
1028       return;
1029     }
1030     else
1031       {
1032 	  protocol->protocol.active = FALSE;
1033 	  if (XtIsRealized(shell))
1034 	    UpdateProtocolMgrProperty(shell, p_mgr);
1035       }
1036     _XmAppUnlock(app);
1037 }
1038 
1039 /************************************<+>*************************************
1040  *
1041  *   XmSetProtocolHooks
1042  *
1043  *************************************<+>************************************/
1044 void
XmSetProtocolHooks(Widget shell,Atom property,Atom proto_atom,XtCallbackProc pre_hook,XtPointer pre_closure,XtCallbackProc post_hook,XtPointer post_closure)1045 XmSetProtocolHooks(
1046         Widget shell,
1047         Atom property,
1048         Atom proto_atom,
1049         XtCallbackProc pre_hook,
1050         XtPointer pre_closure,
1051         XtCallbackProc post_hook,
1052         XtPointer post_closure )
1053 {
1054     XmAllProtocolsMgr	ap_mgr;
1055     XmProtocolMgr	p_mgr ;
1056     XmProtocol		protocol;
1057     _XmWidgetToAppContext(shell);
1058 
1059     _XmAppLock(app);
1060     if (shell->core.being_destroyed) {
1061 	_XmAppUnlock(app);
1062         return;
1063     }
1064     if (((ap_mgr = GetAllProtocolsMgr(shell)) == 0) 		||
1065 	((p_mgr = GetProtocolMgr(ap_mgr, property)) == 0) 	||
1066 	((protocol = GetProtocol(p_mgr, proto_atom)) == 0)) {
1067       _XmAppUnlock(app);
1068       return;
1069     }
1070 
1071     protocol->protocol.pre_hook.callback = pre_hook;
1072     protocol->protocol.pre_hook.closure = pre_closure;
1073     protocol->protocol.post_hook.callback = post_hook;
1074     protocol->protocol.post_hook.closure = post_closure;
1075     _XmAppUnlock(app);
1076 }
1077