/****************************************************************************** ReadFvwmPipe - Read a single message from the pipe from Fvwm Originally Loop() from FvwmIdent: Copyright 1994, Robert Nation and Nobutaka Suzuki. ******************************************************************************/ void ReadFvwmPipe(void) { unsigned long header[HEADER_SIZE],*body; if(ReadFvwmPacket(Fvwm_fd[1],header,&body) > 0) { ProcessMessage(header[1],body); free(body); } }
/*********************************************************************** * * Procedure: * Loop - wait for data to process * ***********************************************************************/ void Loop(int *fd) { while(1) { FvwmPacket* packet = ReadFvwmPacket(fd[1]); if ( packet == NULL ) exit(0); else process_message( packet->type, packet->body ); } }
/****************************************************************************** ReadFvwmPipe - Read a single message from the pipe from Fvwm Originally Loop() from FvwmIdent: Copyright 1994, Robert Nation and Nobutaka Suzuki. ******************************************************************************/ void ReadFvwmPipe() { int count,total,count2=0,body_length; unsigned long header[HEADER_SIZE],*body; char *cbody; if(ReadFvwmPacket(Fvwm_fd[1],header,&body) > 0) { ProcessMessage(header[1],body); free(body); } }
/* ReadFvwmPipe - Read a single message from the pipe from fvwm */ void ReadFvwmPipe(void) { FvwmPacket* packet = ReadFvwmPacket(fvwm_fd[1]); if ( packet == NULL ) { exit(0); } else { ProcessMessage( packet->type, packet->body ); } }
/****************************************************************************** ReadFvwmPipe - Read a single message from the pipe from Fvwm Originally Loop() from FvwmIdent: Copyright 1994, Robert Nation and Nobutaka Suzuki. ******************************************************************************/ void ReadFvwmPipe() { int count; unsigned long header[HEADER_SIZE],*body; body = NULL; if((count = ReadFvwmPacket(Fvwm_fd[1],header,&body)) > 0) { ProcessMessage(header[1],body); free(body); } }
/*************************************************************************** * * Waits for next X event, or for an auto-raise timeout. * ****************************************************************************/ int My_XNextEvent(Display *dpy, XEvent *event) { fd_set in_fdset; unsigned long header[3]; int body_length; int count,count2 = 0; static int miss_counter = 0; unsigned long *body; int total; char *cbody; if(XPending(dpy)) { XNextEvent(dpy,event); return 1; } FD_ZERO(&in_fdset); FD_SET(x_fd,&in_fdset); FD_SET(fd[1],&in_fdset); #ifdef __hpux select(fd_width,(int *)&in_fdset, 0, 0, NULL); #else select(fd_width,&in_fdset, 0, 0, NULL); #endif if(FD_ISSET(x_fd, &in_fdset)) { if(XPending(dpy)) { XNextEvent(dpy,event); miss_counter = 0; return 1; } else miss_counter++; if(miss_counter > 100) DeadPipe(0); } if(FD_ISSET(fd[1], &in_fdset)) { if(count = ReadFvwmPacket(fd[1],header,&body) > 0) { process_message(header[1],body); free(body); } } return 0; }
/************************************************************************** * * Read the entire window list from fvwm * *************************************************************************/ void Loop(int *fd) { unsigned long header[4], *body; char *cbody; int body_length,count,count2=0,total; while(1) { if(count = ReadFvwmPacket(fd[1],header,&body) > 0) { process_message(header[1],body); free(body); } } }
/*********************************************************************** * * Procedure: * Loop - wait for data to process * ***********************************************************************/ void Loop(int *fd) { unsigned long header[3], *body; char *cbody; int body_length,count,count2=0,total; while(1) { /* read a packet */ if(count = ReadFvwmPacket(fd[1],header, &body) > 0) { /* dispense with the new packet */ process_message(header[1],body); free(body); } } }
void wait_configure(window_item *wi) { int found = 0; unsigned long header[HEADER_SIZE], *body; int count; fd_set infds; FD_ZERO(&infds); FD_SET(fd[1], &infds); select(fd_width,&infds, 0, 0, NULL); while (!found) if ((count = ReadFvwmPacket(fd[1],header,&body)) > 0) { if ((header[1] == M_CONFIGURE_WINDOW) && (Window)body[1] == wi->frame) found = 1; free(body); } }
/* main event loop */ void MainLoop () { fd_set in_fdset; unsigned long header[HEADER_SIZE]; unsigned long *body; int count,i; struct timeval tv; int res; while (1) { FD_ZERO(&in_fdset); FD_SET(x_fd,&in_fdset); FD_SET(fd[1],&in_fdset); XFlush(x11base->display); tv.tv_sec = 1; tv.tv_usec = 0; if (x11base->periodictasks!=NULL) res=select(32, &in_fdset, NULL, NULL, &tv); else res=select(32, &in_fdset, NULL, NULL, NULL); if (res > 0) { if (FD_ISSET(x_fd, &in_fdset)) ReadXServer(); if(FD_ISSET(fd[1], &in_fdset)) { if((count = ReadFvwmPacket(fd[1], header, &body)) > 0) { for (i=0;i<nbobj;i++) tabxobj[i]->ProcessMsg(tabxobj[i],header[1],body); free(body); } } } if (x11base->periodictasks!=NULL) /* Execution des taches periodics */ ExecBloc(x11base->periodictasks); } }
int get_window(void) { FvwmPacket* packet; struct ConfigWinPacket *cfgpacket; int last = 0; fd_set infds; FD_ZERO(&infds); FD_SET(fd[1], &infds); select(fd_width, SELECT_FD_SET_CAST &infds, 0, 0, NULL); if ( (packet = ReadFvwmPacket(fd[1])) == NULL ) DeadPipe(0); else { cfgpacket = (struct ConfigWinPacket*) packet->body; switch (packet->type) { case M_CONFIGURE_WINDOW: if (is_suitable_window(packet->body)) { window_item *wi = (window_item*)safemalloc(sizeof( window_item )); wi->frame = cfgpacket->frame; wi->th = cfgpacket->title_height; wi->bw = cfgpacket->border_width; wi->width = cfgpacket->frame_width; wi->height = cfgpacket->frame_height; if (!wins_tail) wins_tail = wi; insert_window_list(&wins, wi); ++wins_count; } last = 1; break; case M_END_WINDOWLIST: break; default: fprintf(console, "%s: internal inconsistency: unknown message 0x%08x\n", module->name, (int)packet->type); break; } } return last; }
void wait_configure(window_item *wi) { int found = 0; /** Uh, what's the point of the select() here?? **/ fd_set infds; FD_ZERO(&infds); FD_SET(fd[1], &infds); select(fd_width, SELECT_FD_SET_CAST &infds, 0, 0, NULL); while (!found) { FvwmPacket* packet = ReadFvwmPacket(fd[1]); if ( packet == NULL ) DeadPipe(0); if ( packet->type == M_CONFIGURE_WINDOW && (Window)(packet->body[1]) == wi->frame ) found = 1; } }
/*************************************************************************** * * Waits for next X event, or for an auto-raise timeout. * ****************************************************************************/ int My_XNextEvent(Display *dpy, XEvent *event) { fd_set in_fdset; static int miss_counter = 0; if(XPending(dpy)) { XNextEvent(dpy,event); return 1; } FD_ZERO(&in_fdset); FD_SET(x_fd,&in_fdset); FD_SET(fd[1],&in_fdset); if (fvwmSelect(fd_width, &in_fdset, 0, 0, NULL) > 0) { if(FD_ISSET(x_fd, &in_fdset)) { if(XPending(dpy)) { XNextEvent(dpy,event); miss_counter = 0; return 1; } miss_counter++; #ifdef WORRY_ABOUT_MISSED_XEVENTS if(miss_counter > 100) DeadPipe(0); #endif } if(FD_ISSET(fd[1], &in_fdset)) { FvwmPacket* packet = ReadFvwmPacket(fd[1]); if ( packet == NULL ) exit(0); process_message( packet ); } } return 0; }
int get_window(void) { unsigned long header[HEADER_SIZE], *body; int count, last = 0; fd_set infds; FD_ZERO(&infds); FD_SET(fd[1], &infds); select(fd_width,&infds, 0, 0, NULL); if ((count = ReadFvwmPacket(fd[1],header,&body)) > 0) { switch (header[1]) { case M_CONFIGURE_WINDOW: if (is_suitable_window(body)) { window_item *wi = (window_item*)safemalloc(sizeof( window_item )); wi->frame = (Window)body[1]; wi->th = (int)body[9]; wi->bw = (int)body[10]; wi->width = body[5]; wi->height = body[6]; if (!wins_tail) wins_tail = wi; insert_window_list(&wins, wi); ++wins_count; } last = 1; break; case M_END_WINDOWLIST: break; default: fprintf(console, "%s: internal inconsistency: unknown message\n", argv0); break; } free(body); } return last; }
/* * * Procedure: * main - start of module * */ int main(int argc, char **argv) { /* The struct holding the module info */ static ModuleArgs* module; char *enter_fn="Silent Raise"; /* default */ char *leave_fn=NULL; char *buf; int len; unsigned long m_mask; unsigned long mx_mask; unsigned long last_win = 0; /* last window handled */ unsigned long focus_win = 0; /* current focus */ unsigned long raised_win = 0; fd_set_size_t fd_width; int fd[2]; int timeout; int sec = 0; int usec = 0; int n; struct timeval value; struct timeval *delay; fd_set in_fdset; Bool do_pass_id = False; Bool use_enter_mode = False; Bool use_leave_mode = False; #ifdef DEBUG int count = 0; #endif #ifdef DEBUGTOFILE freopen(".FvwmAutoDebug","w",stderr); #endif module = ParseModuleArgs(argc,argv,0); /* no alias in this module */ if (module==NULL) { fprintf(stderr,"FvwmAuto Version "VERSION" should only be executed by fvwm!\n"); exit(1); } if (module->user_argc < 1 || module->user_argc > 5) { fprintf(stderr,"FvwmAuto can use one to five arguments.\n"); exit(1); } /* Dead pipes mean fvwm died */ #ifdef HAVE_SIGACTION { struct sigaction sigact; sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask, SIGPIPE); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGHUP); sigaddset(&sigact.sa_mask, SIGQUIT); sigaddset(&sigact.sa_mask, SIGTERM); #ifdef SA_RESTART sigact.sa_flags = SA_RESTART; # else sigact.sa_flags = 0; #endif sigact.sa_handler = TerminateHandler; sigaction(SIGPIPE, &sigact, NULL); sigaction(SIGINT, &sigact, NULL); sigaction(SIGHUP, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); } #else /* We don't have sigaction(), so fall back to less robust methods. */ #ifdef USE_BSD_SIGNALS fvwmSetSignalMask( sigmask(SIGPIPE) | sigmask(SIGINT) | sigmask(SIGHUP) | sigmask(SIGQUIT) | sigmask(SIGTERM) ); #endif signal(SIGPIPE, TerminateHandler); signal(SIGINT, TerminateHandler); signal(SIGHUP, TerminateHandler); signal(SIGQUIT, TerminateHandler); signal(SIGTERM, TerminateHandler); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGPIPE, 0); siginterrupt(SIGINT, 0); siginterrupt(SIGHUP, 0); siginterrupt(SIGQUIT, 0); siginterrupt(SIGTERM, 0); #endif #endif fd[0] = module->to_fvwm; fd[1] = module->from_fvwm; if ((timeout = atoi(module->user_argv[0]) )) { sec = timeout / 1000; usec = (timeout % 1000) * 1000; } else { sec = 0; usec = 1000; } delay = &value; n = 1; if (n < module->user_argc && module->user_argv[n]) { char *token; /* -passid option */ if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-passid")) { do_pass_id = True; n++; } if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-menterleave")) { /* enterleave mode */ use_leave_mode = True; use_enter_mode = True; n++; } else if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-menter")) { /* enter mode */ use_leave_mode = False; use_enter_mode = True; n++; } else if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-mfocus")) { /* focus mode */ use_leave_mode = False; use_enter_mode = False; n++; } /*** enter command ***/ if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "Nop")) { /* nop */ enter_fn = NULL; n++; } else if (n < module->user_argc) { /* override default */ enter_fn = module->user_argv[n]; n++; } /* This is a hack to prevent user interaction with old configs. */ if (enter_fn) { token = PeekToken(enter_fn, NULL); if (!StrEquals(token, "Silent")) { enter_fn = safestrdup( CatString2("Silent ", enter_fn)); } } /*** leave command ***/ if (n < module->user_argc && module->user_argv[n] && *module->user_argv[n] && StrEquals(module->user_argv[n], "Nop")) { /* nop */ leave_fn = NULL; n++; } else if (n < module->user_argc) { /* leave function specified */ leave_fn=module->user_argv[n]; n++; } if (leave_fn) { token = PeekToken(leave_fn, NULL); if (!StrEquals(token, "Silent")) { leave_fn = safestrdup( CatString2("Silent ", leave_fn)); } } } /* Exit if nothing to do. */ if (!enter_fn && !leave_fn) { return -1; } if (use_enter_mode) { m_mask = 0; mx_mask = MX_ENTER_WINDOW | MX_LEAVE_WINDOW | M_EXTENDED_MSG; } else { mx_mask = M_EXTENDED_MSG; m_mask = M_FOCUS_CHANGE; } /* Disable special raise/lower support on general actions. * * This works as expected in most of cases. */ if (matchWildcards("*Raise*", CatString2(enter_fn, leave_fn)) || matchWildcards("*Lower*", CatString2(enter_fn, leave_fn))) { m_mask |= M_RAISE_WINDOW | M_LOWER_WINDOW; } /* migo (04/May/2000): It is simply incorrect to listen to raise/lower * packets and change the state if the action itself has no raise/lower. * Detecting whether to listen or not by the action name is good enough. m_mask = M_FOCUS_CHANGE | M_RAISE_WINDOW | M_LOWER_WINDOW; */ SetMessageMask(fd, m_mask); SetMessageMask(fd, mx_mask); /* tell fvwm we're running */ SendFinishedStartupNotification(fd); /* tell fvwm that we want to be lock on send */ SetSyncMask(fd, m_mask); SetSyncMask(fd, mx_mask); fd_width = fd[1] + 1; FD_ZERO(&in_fdset); /* create the command buffer */ len = 0; if (enter_fn != 0) { len = strlen(enter_fn); } if (leave_fn != NULL) { len = max(len, strlen(leave_fn)); } if (do_pass_id) { len += 32; } buf = safemalloc(len); while (!isTerminated) { char raise_window_now; static char have_new_window = 0; FD_SET(fd[1], &in_fdset); myfprintf( (stderr, "\nstart %d (hnw = %d, usec = %d)\n", count++, have_new_window, usec)); /* fill in struct - modified by select() */ delay->tv_sec = sec; delay->tv_usec = usec; #ifdef DEBUG { char tmp[32]; sprintf(tmp, "%d usecs", (delay) ? (int)delay->tv_usec : -1); myfprintf((stderr, "select: delay = %s\n", (have_new_window) ? tmp : "infinite" )); } #endif if (fvwmSelect(fd_width, &in_fdset, NULL, NULL, (have_new_window) ? delay : NULL) == -1) { myfprintf( (stderr, "select: error! (%s)\n", strerror(errno))); break; } raise_window_now = 0; if (FD_ISSET(fd[1], &in_fdset)) { FvwmPacket *packet = ReadFvwmPacket(fd[1]); if (packet == NULL) { myfprintf( (stderr, "Leaving because of null packet\n")); break; } myfprintf( (stderr, "pw = 0x%x, fw=0x%x, rw = 0x%x, lw=0x%x\n", (int)packet->body[0], (int)focus_win, (int)raised_win, (int)last_win)); switch (packet->type) { case MX_ENTER_WINDOW: focus_win = packet->body[0]; if (focus_win != raised_win) { myfprintf((stderr, "entered new window\n")); have_new_window = 1; raise_window_now = 0; } else if (focus_win == last_win) { have_new_window = 0; } else { myfprintf((stderr, "entered other window\n")); } break; case MX_LEAVE_WINDOW: if (use_leave_mode) { if (focus_win == raised_win) { focus_win = 0; } myfprintf((stderr, "left raised window\n")); have_new_window = 1; raise_window_now = 0; } break; case M_FOCUS_CHANGE: /* it's a focus package */ focus_win = packet->body[0]; if (focus_win != raised_win) { myfprintf((stderr, "focus on new window\n")); have_new_window = 1; raise_window_now = 0; } else { myfprintf((stderr, "focus on old window\n")); } break; case M_RAISE_WINDOW: myfprintf( (stderr, "raise packet 0x%x\n", (int)packet->body[0])); raised_win = packet->body[0]; if (have_new_window && focus_win == raised_win) { myfprintf( (stderr, "its the old window:" " don't raise\n")); have_new_window = 0; } break; case M_LOWER_WINDOW: myfprintf( (stderr, "lower packet 0x%x\n", (int)packet->body[0])); if (have_new_window && focus_win == packet->body[0]) { myfprintf( (stderr, "window was explicitly" " lowered, don't raise it" " again\n")); have_new_window = 0; } break; } /* switch */ SendUnlockNotification(fd); } else { if (have_new_window) { myfprintf((stderr, "must raise now\n")); raise_window_now = 1; } } if (raise_window_now) { myfprintf((stderr, "raising 0x%x\n", (int)focus_win)); if (leave_fn && ((last_win && !use_leave_mode) || (raised_win && use_enter_mode))) { /* if focus_win isn't the root */ if (do_pass_id) { sprintf(buf, "%s 0x%x\n", leave_fn, (int)last_win); } else { sprintf(buf, "%s\n", leave_fn); } SendInfo(fd, buf, last_win); if (use_enter_mode) { raised_win = 0; } } if (focus_win && enter_fn) { /* if focus_win isn't the root */ if (do_pass_id) { sprintf(buf, "%s 0x%x\n", enter_fn, (int)focus_win); } else { sprintf(buf, "%s\n", enter_fn); } SendInfo(fd, buf, focus_win); raised_win = focus_win; } else if (focus_win && enter_fn == NULL) { raised_win = focus_win; } /* force fvwm to synchronise on slow X connections to * avoid a race condition. Still possible, but much * less likely. */ SendInfo(fd, "XSync", focus_win); /* switch to wait mode again */ last_win = focus_win; have_new_window = 0; } } /* while */ return 0; }