1 /*
  2  * Copyright �� 2010 Sam Spilsbury
  3  *
  4  * Permission to use, copy, modify, distribute, and sell this software
  5  * and its documentation for any purpose is hereby granted without
  6  * fee, provided that the above copyright notice appear in all copies
  7  * and that both that copyright notice and this permission notice
  8  * appear in supporting documentation, and that the name of
  9  * Dennis Kasprzyk not be used in advertising or publicity pertaining to
 10  * distribution of the software without specific, written prior permission.
 11  * Dennis Kasprzyk makes no representations about the suitability of this
 12  * software for any purpose. It is provided "as is" without express or
 13  * implied warranty.
 14  *
 15  * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 17  * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 19  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 20  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 21  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 22  *
 23  * Authors: Sam Spilsbury <smspillaz@gmail.com>
 24  */
 25 
 26 #include <core/propertywriter.h>
 27 #include <core/screen.h>
 28 
 29 PropertyWriter::PropertyWriter ()
 30 {
CID 12591 - UNINIT_CTOR
Non-static class member "mAtom" is not initialized in this constructor nor in any functions that it calls.
 31 }
 32 
 33 PropertyWriter::PropertyWriter (CompString propName,
 34 				CompOption::Vector &readTemplate)
 35 {
 36     mPropertyValues = readTemplate;
 37     mAtom = XInternAtom (screen->dpy (), propName.c_str (), 0);
 38 }
 39 
 40 void
 41 PropertyWriter::setReadTemplate (const CompOption::Vector &readTemplate)
 42 {
 43     mPropertyValues = readTemplate;
 44 }
 45 
 46 const CompOption::Vector &
 47 PropertyWriter::getReadTemplate ()
 48 {
 49     return mPropertyValues;
 50 }
 51 
 52 bool
 53 PropertyWriter::updateProperty (Window		  	 id,
 54 				CompOption::Vector &propertyData,
 55 				int			 type)
 56 {
 57     int count = 0;
 58 
 59 
 60     if (type != XA_STRING)
 61     {
 62         long int data[propertyData.size ()];
 63 
 64         foreach (CompOption &o, propertyData)
 65         {
 66 	    switch (o.type ())
 67 	    {
 68 	        case CompOption::TypeBool:
 69 		    data[count] = o.value ().b ();
 70 		    break;
 71 	        case CompOption::TypeInt:
 72 		    data[count] = o.value ().i ();
 73 		    break;
 74 	        default:
 75 		    data[count] = 0;
 76 		    break;
 77 	    }
 78 
 79 	    count++;
 80         }
 81 
 82         XChangeProperty (screen->dpy (), id,
 83 		         mAtom, type, 32,
 84 		         PropModeReplace,  (unsigned char *)data,
 85 		         propertyData.size ());
 86     }
 87     else
 88     {
 89         char * data[propertyData.size ()];
 90         XTextProperty prop;
 91         bool   ok = true;
 92 
 93         foreach (CompOption &o, propertyData)
 94         {
 95 	    switch (o.type ())
 96 	    {
 97 	        case CompOption::TypeString:
 98 		    data[count] = (char *) o.value ().s ().c_str ();
 99 		    break;
100 	        default:
101 		    data[count] = NULL;
102 		    break;
103 	    }
104 
105 	    count++;
106         }
107 
108         for (int i = 0; i < count; i++)
109         {
110 	    if (data[i] == NULL)
111 	    {
112 	        ok = false;
113 	    }
114         }
115 
116         if (ok)
117         {
118 	    if (XStringListToTextProperty (data, count, &prop))
119 	    {
120 	        XSetTextProperty (screen->dpy (), id, &prop, mAtom);
121 		XFree (prop.value);
122 	    }
123         }
124     }
125 
126     return true;
127 }
128 
129 void
130 PropertyWriter::deleteProperty (Window id)
131 {
132     XDeleteProperty (screen->dpy (), id, mAtom);
133 }
134 
135 const CompOption::Vector &
136 PropertyWriter::readProperty (Window id)
137 {
138     Atom 	  type;
139     int  	  retval, fmt;
140     unsigned long nitems, exbyte;
141     long int	  *data;
142 
143     if (mPropertyValues.empty ())
144 	return mPropertyValues;
145 
146     retval = XGetWindowProperty (screen->dpy (), id, mAtom, 0,
147     				 mPropertyValues.size (), False, XA_CARDINAL,
148     				 &type, &fmt, &nitems, &exbyte,
149     				 (unsigned char **)&data);
150 
151     if (retval == Success && !mPropertyValues.empty ())
152     {
153 	int  count = 0;
154 
155 	if (type == XA_CARDINAL && fmt == 32 &&
156 	    nitems == mPropertyValues.size ())
157 	{
158 	    foreach (CompOption &o, mPropertyValues)
159 	    {
160 		CompOption::Value tmpVal;
161 		switch (mPropertyValues.at (count).type ())
162 		{
163 		    case CompOption::TypeBool:
164 			tmpVal = CompOption::Value ((bool) data[count]);
165 			o.set (tmpVal);
166 			break;
167 		    case CompOption::TypeInt:
168 			tmpVal = CompOption::Value ((int) data[count]);
169 			o.set (tmpVal);
170 			break;
171 		    default:
172 			tmpVal = CompOption::Value (CompOption::Value (0));
173 			o.set (tmpVal);
174 			break;
175 		}
176 
177 		count++;
178 	    }
179 
180 	    XFree (data);
181 
182 	    return mPropertyValues;
183 	}
184 	else if (type == XA_STRING && fmt == 8)
185 	{
186 	    XTextProperty tProp;
187 	    retval = XGetTextProperty (screen->dpy (), id, &tProp, mAtom);
188 
189 	    if (tProp.value)
190 	    {
191 	        int  retCount = 0;
192 	        char **tData = NULL;
193 
194 	        XTextPropertyToStringList (&tProp, &tData, &retCount);
195 
196 	        if (retCount == (int) mPropertyValues.size ())
197 	        {
198 		    foreach (CompOption &o, mPropertyValues)
199 		    {
200 		        CompOption::Value tmpVal;
201 		        tmpVal = CompOption::Value (CompString ((char *) tData[count]));
202 
203 		        o.set (tmpVal);
204 
205 		        count++;
206 		    }
207 
208 		    XFreeStringList (tData);
209 		    XFree (data);
210 		    XFree (tProp.value);
211 
212 		    return mPropertyValues;
213 	        }
214 	        else
215 	        {
216 		    XFreeStringList (tData);
217 		    XFree (data);
218 		    XFree (tProp.value);
219 
220 		    return nilValues;
221 	        }
222 	    }
223 	    else
224 	    {
225 		XFree (data);
226 		XFree (tProp.value);
227 
228 	        return nilValues;
229 	    }
230 	}
231 	else if (fmt != 0)
232 	{
233 	    XFree (data);
234 	}
235     }
236     else
237     {
238 	return mPropertyValues;
239     }
240 
241     return mPropertyValues;
242 }