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