CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/functions_misc.c
Go to the documentation of this file.
1/*
2 * Misc function implementation
3 *
4 * These are things that either don't fit neatly into another category,
5 * or fit into a category too small to be worth making individual files
6 * for.
7 */
8
9#include "ctwm.h"
10
11#include <stdlib.h>
12
13#include "animate.h"
14#include "ctwm_shutdown.h"
15#include "functions.h"
16#include "functions_defs.h"
17#include "functions_internal.h"
18#include "icons.h"
19#include "otp.h"
20#include "screen.h"
21#ifdef SOUNDS
22#include "sound.h"
23#endif
24#include "util.h"
25#include "win_iconify.h"
26#ifdef WINBOX
27#include "windowbox.h"
28#endif
29#include "workspace_utils.h"
30
31#include "ext/repl_str.h"
32
33
34
35/*
36 * Animation-related
37 */
42
47
52
57
58
59
60/*
61 * Menu-related
62 */
64{
65 /*
66 * n.b.: The f.menu handler is all kinds of magic; it's actually
67 * completely unrelated to pulling up the menu.
68 *
69 * When a button/key binding invokes f.menu to open up a menu, that's
70 * actually handled in the KeyPress or ButtonPress handlers by
71 * calling do{_key,}_menu(). When we descend into a submenu, that's
72 * handled in KeyPress handler for keyboard navigation when we hit
73 * the Right arrow, or inside the
74 * event loop recapture in UpdateMenu() for mouse navigation when we
75 * move it to the right side of the menu entry.
76 *
77 * This handler is only used by "invoking" a menu item; releasing the
78 * mouse button on the left side without moving right to open out the
79 * submenu, or hitting the Enter key. All it does is immediately
80 * invoke the default entry, if there is one.
81 */
82 if(action && ! strncmp(action, "WGOTO : ", 8)) {
83 GotoWorkSpaceByName(/* XXXXX */ Scr->currentvs,
84 ((char *)action) + 8);
85 }
86 else {
87 MenuItem *item;
88
89 item = ActiveItem;
90 while(item && item->sub) {
91 if(!item->sub->defaultitem) {
92 break;
93 }
94 if(item->sub->defaultitem->func != F_MENU) {
95 break;
96 }
97 item = item->sub->defaultitem;
98 }
99 if(item && item->sub && item->sub->defaultitem) {
101 item->sub->defaultitem->action,
103 }
104 }
105}
106
107
109{
110 if(! ActiveMenu) {
111 return;
112 }
113 if(ActiveMenu->pinned) {
116 }
117 else {
119 MenuRoot *menu;
120
121 if(ActiveMenu->pmenu == NULL) {
122 menu = malloc(sizeof(MenuRoot));
123 *menu = *ActiveMenu;
124 menu->pinned = true;
125 menu->mapped = MRM_NEVER;
126 menu->width -= 10;
127 if(menu->pull) {
128 menu->width -= 16 + 10;
129 }
130 MakeMenu(menu);
131 ActiveMenu->pmenu = menu;
132 }
133 else {
134 menu = ActiveMenu->pmenu;
135 }
136 if(menu->mapped == MRM_MAPPED) {
137 return;
138 }
140 menu->x = attr.x;
141 menu->y = attr.y;
142 XMoveWindow(dpy, menu->w, menu->x, menu->y);
143 XMapRaised(dpy, menu->w);
144 menu->mapped = MRM_MAPPED;
145 }
146 PopDownMenu();
147}
148
149
150
151/*
152 * Alternate keymaps/contexts
153 */
155{
156 int alt, stat_;
157
158 if(! action) {
159 return;
160 }
161 stat_ = sscanf(action, "%d", &alt);
162 if(stat_ != 1) {
163 return;
164 }
165 if((alt < 1) || (alt > 5)) {
166 return;
167 }
168 AlternateKeymap = Alt1Mask << (alt - 1);
171 Scr->Root, Scr->AlterCursor, CurrentTime);
172 func_reset_cursor = false; // Leave special cursor alone
174 return;
175}
176
178{
179 AlternateContext = true;
182 Scr->Root, Scr->AlterCursor, CurrentTime);
183 func_reset_cursor = false; // Leave special cursor alone
185 return;
186}
187
188
189
190/*
191 * A few trivial ctwm-control-ish meta-functions
192 */
194{
195 DoShutdown();
196}
197
199{
200 DoRestart(eventp->xbutton.time);
201}
202
204{
205 XBell(dpy, 0);
206}
207
209{
210 DebugTrace(action);
211}
212
213
214
215#ifdef WINBOX
216/*
217 * Special windowbox-related
218 */
220{
221 if(!tmp_win->iswinbox) {
222 XBell(dpy, 0);
223 return;
224 }
226}
227#endif
228
229
230
231/*
232 * A few things that are sorta windows/icons related, but don't really
233 * fit with the window-targetted things in functions_win.
234 */
236{
237 ShowBackground(Scr->currentvs, -1);
238}
239
241{
242 for(TwmWindow *t = Scr->FirstWindow; t != NULL; t = t->next) {
243 if(t->icon && t->icon->w) {
245 }
246 }
247}
248
253
254
255
256/*
257 * Despite the name, this is more like 'gotoworkspace' than the other
258 * 'warpto*' funcs, as it's just about switching your view, not anything
259 * going to a window.
260 */
261static void
263{
265 int x, y, dumint;
266 unsigned int dummask;
268
269 while(!newscr) {
270 /* wrap around */
271 if(n < 0) {
272 n = NumScreens - 1;
273 }
274 else if(n >= NumScreens) {
275 n = 0;
276 }
277
279 if(!newscr) { /* make sure screen is managed */
280 if(inc) { /* walk around the list */
281 n += inc;
282 continue;
283 }
284 fprintf(stderr, "%s: unable to warp to unmanaged screen %d\n",
285 ProgramName, n);
286 XBell(dpy, 0);
287 return;
288 }
289 }
290
291 if(Scr->screen == n) {
292 return; /* already on that screen */
293 }
294
295 PreviousScreen = Scr->screen;
296 XQueryPointer(dpy, Scr->Root, &dumwin, &dumwin, &x, &y,
297 &dumint, &dumint, &dummask);
298
299 XWarpPointer(dpy, None, newscr->Root, 0, 0, 0, 0, x, y);
300 Scr = newscr;
301 return;
302}
303
305{
306 if(strcmp(action, WARPSCREEN_NEXT) == 0) {
307 WarpToScreen(Scr->screen + 1, 1);
308 }
309 else if(strcmp(action, WARPSCREEN_PREV) == 0) {
310 WarpToScreen(Scr->screen - 1, -1);
311 }
312 else if(strcmp(action, WARPSCREEN_BACK) == 0) {
314 }
315 else {
316 WarpToScreen(atoi(action), 0);
317 }
318}
319
320
321
322/*
323 * Sound-related
324 */
325#ifdef SOUNDS
327{
328 toggle_sound();
329}
330
332{
334}
335#endif
336
337
338
339/*
340 * And executing an external program
341 */
342static void Execute(const char *_s);
343
345{
346 PopDownMenu();
347 if(!Scr->NoGrabServer) {
349 XSync(dpy, 0);
350 }
352 XSync(dpy, 0);
353 Execute(action);
354}
355
356
357static void
358Execute(const char *_s)
359{
360 char *s;
361 char *_ds;
362 char *orig_display;
363 int restorevar = 0;
364 char *subs;
365
366 /* Seatbelt */
367 if(!_s) {
368 return;
369 }
370
371 /* Work on a local copy since we're mutating it */
372 s = strdup(_s);
373 if(!s) {
374 return;
375 }
376
377 /* Stash up current $DISPLAY value for resetting */
378 orig_display = getenv("DISPLAY");
379
380
381 /*
382 * Build a display string using the current screen number, so that
383 * X programs which get fired up from a menu come up on the screen
384 * that they were invoked from, unless specifically overridden on
385 * their command line.
386 *
387 * Which is to say, given that we're on display "foo.bar:1.2", we
388 * want to translate that into "foo.bar:1.{Scr->screen}".
389 *
390 * We strdup() because DisplayString() is a macro returning into the
391 * dpy structure, and we're going to mutate the value we get from it.
392 */
394 if(_ds) {
395 char *ds;
396 char *colon;
397
398 ds = strdup(_ds);
399 if(!ds) {
400 goto end_execute;
401 }
402
403 /* If it's not host:dpy, we don't have anything to do here */
404 colon = strrchr(ds, ':');
405 if(colon) {
406 char *dot, *new_display;
407
408 /* Find the . in display.screen and chop it off */
409 dot = strchr(colon, '.');
410 if(dot) {
411 *dot = '\0';
412 }
413
414 /* Build a new string with our correct screen info */
415 asprintf(&new_display, "%s.%d", ds, Scr->screen);
416 if(!new_display) {
417 free(ds);
418 goto end_execute;
419 }
420
421 /* And set */
422 setenv("DISPLAY", new_display, 1);
424 restorevar = 1;
425 }
426 free(ds);
427 }
428
429
430 /*
431 * We replace a couple placeholders in the string. $currentworkspace
432 * is documented in the manual; $redirect is not.
433 */
434 subs = strstr(s, "$currentworkspace");
435 if(subs) {
436 char *tmp;
437 char *wsname;
438
439 wsname = GetCurrentWorkSpaceName(Scr->currentvs);
440 if(!wsname) {
441 wsname = "";
442 }
443
444 tmp = replace_substr(s, "$currentworkspace", wsname);
445 if(!tmp) {
446 goto end_execute;
447 }
448 free(s);
449 s = tmp;
450 }
451
452#ifdef CAPTIVE
453 subs = strstr(s, "$redirect");
454 if(subs) {
455 char *tmp;
456 char *redir;
457
458 if(CLarg.is_captive) {
459 asprintf(&redir, "-xrm 'ctwm.redirect:%s'", Scr->captivename);
460 if(!redir) {
461 goto end_execute;
462 }
463 }
464 else {
465 redir = malloc(1);
466 *redir = '\0';
467 }
468
469 tmp = replace_substr(s, "$redirect", redir);
470 free(s);
471 s = tmp;
472
473 free(redir);
474 }
475#endif
476
477
478 /*
479 * Call it. Return value doesn't really matter, since whatever
480 * happened we're done. Maybe someday if we develop a "show user
481 * message" generalized func, we can tell the user if executing
482 * failed somehow.
483 */
484 system(s);
485
486
487 /*
488 * Restore $DISPLAY if we changed it. It's probably only necessary
489 * in edge cases (it might be used by ctwm restarting itself, for
490 * instance) and it's not quite clear whether the DisplayString()
491 * result would even be wrong for that, but what the heck, setenv()
492 * is cheap.
493 */
494 if(restorevar) {
495 if(orig_display) {
496 setenv("DISPLAY", orig_display, 1);
497 }
498 else {
499 unsetenv("DISPLAY");
500 }
501 }
502
503
504 /* Clean up */
506 free(s);
507 return;
508}
static int PlaceX
Definition add_window.c:82
void StartAnimation(void)
Definition animate.c:89
void StopAnimation(void)
Definition animate.c:117
void ModifyAnimationSpeed(int incr)
Definition animate.c:134
ctwm_cl_args CLarg
Definition clargs.c:27
int PreviousScreen
Definition ctwm_main.c:94
char * ProgramName
Definition ctwm_main.c:146
#define Alt1Mask
Definition ctwm.h:64
Display * dpy
Definition ctwm_main.c:84
int NumScreens
How many Screens are on our display.
Definition ctwm_main.c:89
#define Scr
ScreenInfo ** ScreenList
List of ScreenInfo structs for each Screen.
Definition ctwm_main.c:92
void DoShutdown(void)
Cleanup and exit ctwm.
void DoRestart(Time t)
exec() ourself to restart.
void ExecuteFunction(int func, void *action, Window w, TwmWindow *tmp_win, XEvent *eventp, int context, bool pulldown)
Definition functions.c:99
bool func_reset_cursor
Definition functions.c:65
#define DFHANDLER(func)
static void WarpToScreen(int n, int inc)
static void Execute(const char *_s)
int y
Definition menus.c:70
int x
Definition menus.c:69
MenuItem * ActiveItem
Definition menus.c:59
MenuRoot * ActiveMenu
Definition menus.c:58
void MakeMenu(MenuRoot *mr)
Definition menus.c:851
void PopDownMenu(void)
Definition menus.c:1442
bool AlternateContext
Definition menus.c:65
int AlternateKeymap
Definition menus.c:64
#define WARPSCREEN_NEXT
Definition menus.h:131
#define WARPSCREEN_BACK
Definition menus.h:133
#define WARPSCREEN_PREV
Definition menus.h:132
@ MRM_NEVER
Definition menus.h:42
@ MRM_UNMAPPED
Definition menus.h:43
@ MRM_MAPPED
Definition menus.h:44
void OtpRaise(TwmWindow *twm_win, WinType wintype)
Definition otp.c:763
@ IconWin
Definition otp.h:14
char * replace_substr(const char *str, const char *old, const char *new)
Definition repl_str.c:24
void toggle_sound(void)
Definition sound.c:278
void reread_sounds(void)
Definition sound.c:288
short func
Definition menus.h:59
char * action
Definition menus.h:54
struct MenuRoot * sub
Definition menus.h:51
short x
Definition menus.h:84
struct MenuRoot * pmenu
Definition menus.h:86
short width
Definition menus.h:79
struct MenuItem * defaultitem
Definition menus.h:70
short y
Definition menus.h:84
MRMapState mapped
Definition menus.h:77
Window w
Definition menus.h:74
bool pull
Definition menus.h:81
bool pinned
Definition menus.h:85
Info and control for each X Screen we control.
Definition screen.h:96
Info and control for every X Window we take over.
void RescueWindows(void)
Backend for f.rescuewindows.
Definition util.c:471
void DebugTrace(char *file)
Backend for f.trace.
Definition util.c:553
void fittocontent(TwmWindow *twmwin)
Definition windowbox.c:139
void GotoWorkSpaceByName(VirtualScreen *vs, const char *wname)
void ShowBackground(VirtualScreen *vs, int newstate)
char * GetCurrentWorkSpaceName(VirtualScreen *vs)