]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/utilsgtk.cpp
Fix memory leak when a spacer is added, and crash when a window is added before wxSiz...
[wxWidgets.git] / src / gtk1 / utilsgtk.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/utilsgtk.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #include "wx/utils.h"
14 #include "wx/string.h"
15
16 #include "wx/apptrait.h"
17 #include "wx/intl.h"
18 #include "wx/log.h"
19
20 #include "wx/process.h"
21
22 #include "wx/unix/execute.h"
23
24 #include <stdarg.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <sys/wait.h> // for WNOHANG
29 #include <unistd.h>
30
31 #include "glib.h"
32 #include "gdk/gdk.h"
33 #include "gtk/gtk.h"
34 #ifndef __WXGTK20__
35 #include "gtk/gtkfeatures.h"
36 #endif
37 #include "gdk/gdkx.h"
38
39 #ifdef HAVE_X11_XKBLIB_H
40 /* under HP-UX and Solaris 2.6, at least, XKBlib.h defines structures with
41 * field named "explicit" - which is, of course, an error for a C++
42 * compiler. To be on the safe side, just redefine it everywhere. */
43 #define explicit __wx_explicit
44
45 #include "X11/XKBlib.h"
46
47 #undef explicit
48 #endif // HAVE_X11_XKBLIB_H
49
50 //-----------------------------------------------------------------------------
51 // data
52 //-----------------------------------------------------------------------------
53
54 extern GtkWidget *wxGetRootWindow();
55
56 //----------------------------------------------------------------------------
57 // misc.
58 //----------------------------------------------------------------------------
59 #ifndef __EMX__
60 // on OS/2, we use the wxBell from wxBase library
61
62 void wxBell()
63 {
64 gdk_beep();
65 }
66 #endif
67
68 /* Don't synthesize KeyUp events holding down a key and producing
69 KeyDown events with autorepeat. */
70 #ifdef HAVE_X11_XKBLIB_H
71 bool wxSetDetectableAutoRepeat( bool flag )
72 {
73 Bool result;
74 XkbSetDetectableAutoRepeat( GDK_DISPLAY(), flag, &result );
75 return result; /* TRUE if keyboard hardware supports this mode */
76 }
77 #else
78 bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
79 {
80 return FALSE;
81 }
82 #endif
83
84 #ifdef __WXGTK20__
85 // Escapes string so that it is valid Pango markup XML string:
86 wxString wxEscapeStringForPangoMarkup(const wxString& str)
87 {
88 size_t len = str.length();
89 wxString out;
90 out.Alloc(len);
91 for (size_t i = 0; i < len; i++)
92 {
93 wxChar c = str[i];
94 switch (c)
95 {
96 case _T('&'):
97 out << _T("&amp;");
98 break;
99 case _T('<'):
100 out << _T("&lt;");
101 break;
102 case _T('>'):
103 out << _T("&gt;");
104 break;
105 case _T('\''):
106 out << _T("&apos;");
107 break;
108 case _T('"'):
109 out << _T("&quot;");
110 break;
111 default:
112 out << c;
113 break;
114 }
115 }
116 return out;
117 }
118 #endif
119
120
121 // ----------------------------------------------------------------------------
122 // display characterstics
123 // ----------------------------------------------------------------------------
124
125 void *wxGetDisplay()
126 {
127 return GDK_DISPLAY();
128 }
129
130 void wxDisplaySize( int *width, int *height )
131 {
132 if (width) *width = gdk_screen_width();
133 if (height) *height = gdk_screen_height();
134 }
135
136 void wxDisplaySizeMM( int *width, int *height )
137 {
138 if (width) *width = gdk_screen_width_mm();
139 if (height) *height = gdk_screen_height_mm();
140 }
141
142 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
143 {
144 // This is supposed to return desktop dimensions minus any window
145 // manager panels, menus, taskbars, etc. If there is a way to do that
146 // for this platform please fix this function, otherwise it defaults
147 // to the entire desktop.
148 if (x) *x = 0;
149 if (y) *y = 0;
150 wxDisplaySize(width, height);
151 }
152
153 void wxGetMousePosition( int* x, int* y )
154 {
155 gdk_window_get_pointer( (GdkWindow*) NULL, x, y, (GdkModifierType*) NULL );
156 }
157
158 bool wxColourDisplay()
159 {
160 return TRUE;
161 }
162
163 int wxDisplayDepth()
164 {
165 return gdk_window_get_visual( wxGetRootWindow()->window )->depth;
166 }
167
168 wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo()
169 {
170 static wxToolkitInfo info;
171 #ifdef __WXGTK20__
172 info.shortName = _T("gtk2");
173 #else
174 info.shortName = _T("gtk");
175 #endif
176 info.name = _T("wxGTK");
177 #ifdef __WXUNIVERSAL__
178 info.shortName << _T("univ");
179 info.name << _T("/wxUniversal");
180 #endif
181 info.versionMajor = gtk_major_version;
182 info.versionMinor = gtk_minor_version;
183 info.os = wxGTK;
184 return info;
185 }
186
187 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
188 {
189 return wxGenericFindWindowAtPoint(pt);
190 }
191
192
193 // ----------------------------------------------------------------------------
194 // subprocess routines
195 // ----------------------------------------------------------------------------
196
197 extern "C" {
198 static
199 void GTK_EndProcessDetector(gpointer data, gint source,
200 GdkInputCondition WXUNUSED(condition) )
201 {
202 wxEndProcessData *proc_data = (wxEndProcessData *)data;
203
204 // has the process really terminated? unfortunately GDK (or GLib) seem to
205 // generate G_IO_HUP notification even when it simply tries to read from a
206 // closed fd and hasn't terminated at all
207 int pid = (proc_data->pid > 0) ? proc_data->pid : -(proc_data->pid);
208 int status = 0;
209 int rc = waitpid(pid, &status, WNOHANG);
210
211 if ( rc == 0 )
212 {
213 // no, it didn't exit yet, continue waiting
214 return;
215 }
216
217 // set exit code to -1 if something bad happened
218 proc_data->exitcode = rc != -1 && WIFEXITED(status) ? WEXITSTATUS(status)
219 : -1;
220
221 // child exited, end waiting
222 close(source);
223
224 // don't call us again!
225 gdk_input_remove(proc_data->tag);
226
227 wxHandleProcessTermination(proc_data);
228 }
229 }
230
231 int wxAddProcessCallback(wxEndProcessData *proc_data, int fd)
232 {
233 int tag = gdk_input_add(fd,
234 GDK_INPUT_READ,
235 GTK_EndProcessDetector,
236 (gpointer)proc_data);
237
238 return tag;
239 }
240