Jitterbug no more.
[fvwm.git] / modules / FvwmIconMan / FvwmIconMan.c
blob80bd4fb1b2d5b4a16bd71bacddd80cae3af4ef74
1 /* -*-c-*- */
2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include "config.h"
19 #include <unistd.h>
20 #include <signal.h>
21 #include <errno.h>
22 #include "FvwmIconMan.h"
23 #include "readconfig.h"
24 #include "x.h"
25 #include "xmanager.h"
27 #include "libs/fvwmsignal.h"
28 #include "libs/Module.h"
29 #include "libs/FTips.h"
30 #include "libs/Parse.h"
33 char *MyName;
34 FlocaleWinString *FwinString;
35 int mods_unused = DEFAULT_MODS_UNUSED;
37 static RETSIGTYPE TerminateHandler(int);
39 char *copy_string(char **target, const char *src)
41 int len;
42 if (src == NULL)
44 len = 0;
45 if (*target)
47 Free(*target);
49 return *target = NULL;
52 len = strlen(src);
53 ConsoleDebug(CORE, "copy_string: 1: 0x%lx\n", (unsigned long)*target);
55 if (*target)
57 Free(*target);
60 ConsoleDebug(CORE, "copy_string: 2\n");
61 *target = (char *)safemalloc((len + 1) * sizeof(char));
62 strcpy(*target, src);
63 ConsoleDebug(CORE, "copy_string: 3\n");
64 return *target;
67 #ifdef TRACE_MEMUSE
69 long MemUsed = 0;
71 void Free(void *p)
73 struct malloc_header *head = (struct malloc_header *)p;
75 if (p != NULL)
77 head--;
78 if (head->magic != MALLOC_MAGIC)
80 fprintf(stderr, "Corrupted memory found in Free\n");
81 abort();
82 return;
84 if (head->len > MemUsed)
86 fprintf(stderr, "Free block too big\n");
87 return;
89 MemUsed -= head->len;
90 Free(head);
94 void PrintMemuse(void)
96 ConsoleDebug(CORE, "Memory used: %ld\n", MemUsed);
99 #else
101 void Free(void *p)
103 if (p != NULL)
105 free(p);
109 void PrintMemuse(void)
113 #endif
116 static RETSIGTYPE
117 TerminateHandler(int sig)
119 fvwmSetTerminate(sig);
120 SIGNAL_RETURN;
124 void
125 ShutMeDown(int flag)
127 ConsoleDebug(CORE, "Bye Bye\n");
128 exit(flag);
131 void
132 DeadPipe(int nothing)
134 (void)nothing;
135 ShutMeDown(0);
136 SIGNAL_RETURN;
139 static void
140 main_loop(void)
142 fd_set readset, saveset;
143 fd_set_size_t fd_width = x_fd;
144 unsigned long ms;
145 struct timeval tv;
148 * Calculate which is descriptor is numerically higher:
149 * this determines how wide the descriptor set needs to be ...
151 if (fd_width < fvwm_fd[1])
153 fd_width = fvwm_fd[1];
155 ++fd_width;
157 FD_ZERO(&saveset);
158 FD_SET(fvwm_fd[1], &saveset);
159 FD_SET(x_fd, &saveset);
161 tv.tv_sec = 60;
162 tv.tv_usec = 0;
164 while (!isTerminated)
166 /* Check the pipes for anything to read, and block if
167 * there is nothing there yet ...
169 readset = saveset;
171 if (fvwmSelect(fd_width, &readset, NULL, NULL, &tv) < 0)
173 ConsoleMessage(
174 "Internal error with select: errno=%s\n",
175 strerror(errno));
177 else
180 if (FD_ISSET(x_fd, &readset) || FPending(theDisplay))
182 xevent_loop();
184 if (FD_ISSET(fvwm_fd[1], &readset))
186 ReadFvwmPipe();
190 if ((ms = FTipsCheck(theDisplay)))
192 tv.tv_sec = ms / 1000;
193 tv.tv_usec = (ms % 1000) * 1000;
195 else
197 tv.tv_sec = 60;
198 tv.tv_usec = 0;
200 } /* while */
204 main(int argc, char **argv)
206 int i;
208 #ifdef HAVE_LIBEFENCE
209 extern int EF_PROTECT_BELOW, EF_PROTECT_FREE;
211 EF_PROTECT_BELOW = 1;
212 EF_PROTECT_FREE = 1;
213 #endif
215 FlocaleInit(LC_CTYPE, "", "", "FvwmIconMan");
217 OpenConsole(OUTPUT_FILE);
219 init_globals();
220 init_winlists();
222 MyName = GetFileNameFromPath(argv[0]);
224 if (argc >= 7)
226 if (strcasecmp(argv[6], "Transient")==0 ||
227 strcasecmp(argv[6], "-Transient") == 0)
229 globals.transient = 1;
231 /* Optionally accept an alias to use as the transient
232 * FvwmIconMan instance.
234 if (argv[7])
235 MyName = argv[7];
237 else
239 MyName = argv[6];
242 ModuleLen = strlen(MyName) + 1;
243 Module = safemalloc(ModuleLen+1);
244 *Module = '*';
245 strcpy(Module+1, MyName);
247 if (argc < 6)
249 fprintf(stderr,
250 "%s version %s should only be executed by fvwm!\n",
251 MyName, VERSION);
252 ShutMeDown(1);
254 fvwm_fd[0] = atoi(argv[1]);
255 fvwm_fd[1] = atoi(argv[2]);
256 init_display();
258 #ifdef HAVE_SIGACTION
260 struct sigaction sigact;
262 sigemptyset(&sigact.sa_mask);
263 sigaddset(&sigact.sa_mask, SIGPIPE);
264 sigaddset(&sigact.sa_mask, SIGINT);
265 sigaddset(&sigact.sa_mask, SIGHUP);
266 sigaddset(&sigact.sa_mask, SIGTERM);
267 sigaddset(&sigact.sa_mask, SIGQUIT);
268 # ifdef SA_RESTART
269 sigact.sa_flags = SA_RESTART;
270 # else
271 sigact.sa_flags = 0;
272 # endif
273 sigact.sa_handler = TerminateHandler;
275 sigaction(SIGPIPE, &sigact, NULL);
276 sigaction(SIGINT, &sigact, NULL);
277 sigaction(SIGHUP, &sigact, NULL);
278 sigaction(SIGTERM, &sigact, NULL);
279 sigaction(SIGQUIT, &sigact, NULL);
281 #else
282 /* We don't have sigaction(), so fall back to less robust methods. */
283 #ifdef USE_BSD_SIGNALS
284 fvwmSetSignalMask(
285 sigmask(SIGPIPE) |
286 sigmask(SIGINT) |
287 sigmask(SIGHUP) |
288 sigmask(SIGTERM) |
289 sigmask(SIGQUIT));
290 #endif
291 signal(SIGPIPE, TerminateHandler);
292 signal(SIGINT, TerminateHandler);
293 signal(SIGHUP, TerminateHandler);
294 signal(SIGTERM, TerminateHandler);
295 signal(SIGQUIT, TerminateHandler);
296 #ifdef HAVE_SIGINTERRUPT
297 siginterrupt(SIGPIPE, 0);
298 siginterrupt(SIGINT, 0);
299 siginterrupt(SIGHUP, 0);
300 siginterrupt(SIGTERM, 0);
301 siginterrupt(SIGQUIT, 0);
302 #endif
303 #endif
305 read_in_resources();
306 FlocaleAllocateWinString(&FwinString);
308 for (i = 0; i < globals.num_managers; i++)
310 X_init_manager(i);
313 assert(globals.managers);
315 SetMessageMask(
316 fvwm_fd, M_CONFIGURE_WINDOW | M_RES_CLASS | M_RES_NAME |
317 M_ADD_WINDOW | M_DESTROY_WINDOW | M_ICON_NAME |
318 M_DEICONIFY | M_ICONIFY | M_ICON_LOCATION | M_END_WINDOWLIST |
319 M_NEW_DESK | M_NEW_PAGE | M_FOCUS_CHANGE | M_WINDOW_NAME |
320 M_CONFIG_INFO | M_SENDCONFIG | M_VISIBLE_NAME |
321 M_MINI_ICON | M_STRING | M_WINDOWSHADE | M_DEWINDOWSHADE);
322 /* extended messages */
323 SetMessageMask(fvwm_fd, MX_VISIBLE_ICON_NAME | MX_PROPERTY_CHANGE);
325 SendText(fvwm_fd, "Send_WindowList", 0);
327 /* tell fvwm we're running */
328 SendFinishedStartupNotification(fvwm_fd);
330 /* Lock on send only for iconify and deiconify (for NoIconAction) */
331 SetSyncMask(fvwm_fd, M_DEICONIFY | M_ICONIFY);
332 SetNoGrabMask(fvwm_fd, M_DEICONIFY | M_ICONIFY);
334 main_loop();
336 return 0;