1 /*
2  * $Id: plug.c,v 1.9 2005/01/01 15:27:54 baum Exp $
3  *
4  * This file implements the plug widget
5  *
6  * Copyright (c) 2001 - 2005 Peter G. Baum  http://www.dr-baum.net
7  *
8  * See the file "license.terms" for information on usage and redistribution
9  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10  *
11  */
12 
13 /*
14    History:
15    2013-07:	added commands, options, commands
16    2003-06: added onDestroy
17    2002-02: switched from GnoclWidgetOptions to GnoclOption
18    2001-11: Begin of developement
19  */
20 
21 /**
22 \page page_plug  gnocl::plug
23 \htmlinclude plug.html
24 **/
25 
26 #include "gnocl.h"
27 #ifdef WIN32  /* native MS */
28 #include <gdk/gdkwin32.h>
29 #else
30 #include <gdk/gdkx.h>
31 #endif
32 
33 static GnoclOption plugOptions[] =
34 {
35 	{ "-socketID", GNOCL_OBJ, NULL },                    /* 0 */
36 	{ "-defaultWidth", GNOCL_INT, "default-width" },     /* these must be */
37 	{ "-defaultHeight", GNOCL_INT, "default-height" },   /* before -visible! */
38 	{ "-visible", GNOCL_BOOL, "visible" },               /* 3 */
39 	{ "-allowShrink", GNOCL_BOOL, "allow-shrink" },
40 	{ "-allowGrow", GNOCL_BOOL, "allow-grow" },
41 	{ "-child", GNOCL_OBJ, "", gnoclOptChild },
42 	{ "-resizable", GNOCL_BOOL, "resizable" },
43 	{ "-onDestroy", GNOCL_OBJ, "destroy", gnoclOptCommand },
44 	{ NULL },
45 };
46 /*****/
47 
48 /****v* plug/constants
49  * AUTHOR
50  *	PGB
51  * SOURCE
52  */
53 static const int socketIDIdx = 0;
54 static const int visibleIdx  = 3;
55 
56 /**
57 \brief
58 **/
configure(Tcl_Interp * interp,GtkPlug * plug,GnoclOption options[])59 static int configure ( Tcl_Interp *interp, GtkPlug *plug,
60 					   GnoclOption options[] )
61 {
62 
63 	return TCL_OK;
64 }
65 
66 static const char *cmds[] = { "delete", "configure", "getID", NULL };
67 
68 /**
69 \brief
70 **/
plugFunc(ClientData data,Tcl_Interp * interp,int objc,Tcl_Obj * const objv[])71 static int plugFunc ( ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[] )
72 {
73 
74 	enum cmdIdx { DeleteIdx, ConfigureIdx, GetIDIdx, OptionsIdx, CommandsIdx };
75 
76 	int idx;
77 	GtkPlug *plug = GTK_PLUG ( data );
78 
79 	if ( objc < 2 )
80 	{
81 		Tcl_WrongNumArgs ( interp, 1, objv, "command" );
82 		return TCL_ERROR;
83 	}
84 
85 	if ( Tcl_GetIndexFromObj ( interp, objv[1], cmds, "command", TCL_EXACT, &idx ) != TCL_OK )
86 	{
87 		return TCL_ERROR;
88 	}
89 
90 	switch ( idx )
91 	{
92 
93 		case DeleteIdx:
94 			{
95 				return gnoclDelete ( interp, GTK_WIDGET ( plug ), objc, objv );
96 			}
97 		case ConfigureIdx:
98 			{
99 				int ret = TCL_ERROR;
100 
101 				if ( plugOptions[socketIDIdx].status == GNOCL_STATUS_CHANGED )
102 				{
103 					Tcl_SetResult ( interp, "Option -socketID cannot be changed after creation", TCL_STATIC );
104 					return TCL_ERROR;
105 				}
106 
107 				if ( gnoclParseAndSetOptions ( interp, objc - 1, objv + 1, plugOptions, G_OBJECT ( plug ) ) == TCL_OK )
108 				{
109 					ret = configure ( interp, plug, plugOptions );
110 				}
111 
112 				gnoclClearOptions ( plugOptions );
113 
114 				return ret;
115 			}
116 
117 			break;
118 		case GetIDIdx:
119 			{
120 				long xid;
121 				Tcl_Obj *val;
122 
123 				if ( objc != 2 )
124 				{
125 					Tcl_WrongNumArgs ( interp, 2, objv, NULL );
126 					return TCL_ERROR;
127 				}
128 
129 				xid = gtk_plug_get_id ( plug );
130 
131 				val = Tcl_NewLongObj ( xid );
132 				Tcl_SetObjResult ( interp, val );
133 			}
134 
135 			break;
136 	}
137 
138 	return TCL_OK;
139 }
140 
141 /**
142 \brief
143 **/
gnoclPlugCmd(ClientData data,Tcl_Interp * interp,int objc,Tcl_Obj * const objv[])144 int gnoclPlugCmd ( ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[] )
145 {
146 
147 	if ( gnoclGetCmdsAndOpts ( interp, cmds, plugOptions, objv, objc ) == TCL_OK )
148 	{
149 		return TCL_OK;
150 	}
151 
152 
153 	int     ret;
154 	GtkPlug *plug;
155 	long    socketId = 0;
156 
157 	if ( gnoclParseOptions ( interp, objc, objv, plugOptions ) != TCL_OK )
158 	{
159 		gnoclClearOptions ( plugOptions );
160 		return TCL_ERROR;
161 	}
162 
163 	if ( plugOptions[socketIDIdx].status == GNOCL_STATUS_CHANGED )
164 	{
165 		if ( Tcl_GetLongFromObj ( interp, plugOptions[socketIDIdx].val.obj, &socketId ) != TCL_OK )
166 			return TCL_ERROR;
167 	}
168 
169 	plug = GTK_PLUG ( gtk_plug_new ( socketId ) );
170 
171 	if ( plugOptions[visibleIdx].status == 0 )
172 		gtk_widget_show ( GTK_WIDGET ( plug ) );
173 
174 	ret = gnoclSetOptions ( interp, plugOptions, G_OBJECT ( plug ), -1 );
175 
176 	if ( ret == TCL_OK )
177 	{
178 		ret = configure ( interp, plug, plugOptions );
179 	}
180 
181 	gnoclClearOptions ( plugOptions );
182 
183 	if ( ret != TCL_OK )
184 	{
185 		gtk_widget_destroy ( GTK_WIDGET ( plug ) );
186 		return TCL_ERROR;
187 	}
188 
189 	return gnoclRegisterWidget ( interp, GTK_WIDGET ( plug ), plugFunc );
190 }
191 
192 
193