void SetDeskPageBackground(const Command *c) { Display *dpy2 = NULL; Window root2 = None; int screen2; Pixmap pix = None; current_colorset = -1; /* FvwmBacker bg preperation */ switch (c->type) { case 1: /* solid colors */ case 2: /* colorset */ dpy2 = XOpenDisplay(displayName); if (!dpy2) { fvwm_msg(ERR, "FvwmBacker", "Fail to create a forking dpy, Exit!"); exit(2); } screen2 = DefaultScreen(dpy2); root2 = RootWindow(dpy2, screen2); if (RetainPixmap) { XSetCloseDownMode(dpy2, RetainPermanent); } XGrabServer(dpy2); DeleteRootAtoms(dpy2, root2); switch (c->type) { case 2: current_colorset = c->colorset; /* Process a colorset */ if (CSET_IS_TRANSPARENT(c->colorset)) { fvwm_msg(ERR,"FvwmBacker", "You cannot " "use a transparent colorset as " "background!"); XUngrabServer(dpy2); XCloseDisplay(dpy2); return; } else if (Pdepth != DefaultDepth(dpy2, screen2)) { fvwm_msg(ERR,"FvwmBacker", "You cannot " "use a colorset background if\n" "the fvwm depth is not equal " "to the root depth!"); XUngrabServer(dpy2); XCloseDisplay(dpy2); return; } else if (RetainPixmap) { pix = CreateBackgroundPixmap( dpy2, root2, MyDisplayWidth, MyDisplayHeight, &Colorset[c->colorset], DefaultDepth(dpy2, screen2), DefaultGC(dpy2, screen2), False); if (pix != None) { XSetWindowBackgroundPixmap( dpy2, root2, pix); XClearWindow(dpy2, root2); } } else { SetWindowBackground( dpy2, root2, MyDisplayWidth, MyDisplayHeight, &Colorset[c->colorset], DefaultDepth(dpy2, screen2), DefaultGC(dpy2, screen2), True); } break; case 1: /* Process a solid color request */ if (RetainPixmap) { GC gc; XGCValues xgcv; xgcv.foreground = c->solidColor; gc = fvwmlib_XCreateGC( dpy2, root2, GCForeground, &xgcv); pix = XCreatePixmap( dpy2, root2, 1, 1, DefaultDepth(dpy2, screen2)); XFillRectangle( dpy2, pix, gc, 0, 0, 1, 1); XFreeGC(dpy2, gc); } XSetWindowBackground(dpy2, root2, c->solidColor); XClearWindow(dpy2, root2); break; } SetRootAtoms(dpy2, root2, pix); XUngrabServer(dpy2); XCloseDisplay(dpy2); /* this XSync, Ungrab, ...etc */ break; case -1: case 0: default: if(c->cmdStr != NULL) { SendFvwmPipe(fvwm_fd, c->cmdStr, (unsigned long)0); } break; } }
/* read an X event */ void ReadXServer (void) { static XEvent event; int old_cursor = 0, keypress; Item *item, *old_item; KeySym ks; char *sp, *dp; static unsigned char buf[10]; /* unsigned for international */ static int n; while (FEventsQueued(dpy, QueuedAfterReading)) { FNextEvent(dpy, &event); if (event.xany.window == CF.frame) { switch (event.type) { case ClientMessage: { if(event.xclient.format == 32 && event.xclient.data.l[0] == wm_del_win) { exit(0); } } break; case ConfigureNotify: /* has window be reconfigured */ { XEvent tmpe; while (FCheckTypedWindowEvent( dpy, CF.frame, ConfigureNotify, &tmpe)) { if (!tmpe.xconfigure.send_event) continue; event.xconfigure.x = tmpe.xconfigure.x; event.xconfigure.y = tmpe.xconfigure.y; event.xconfigure.send_event = True; } if (CF.max_width != event.xconfigure.width || CF.total_height != event.xconfigure.height) { /* adjust yourself... do noting */ ResizeFrame(); CF.max_width = event.xconfigure.width; CF.total_height = event.xconfigure.height; UpdateRootTransapency(False, True); if (!CSET_IS_TRANSPARENT(colorset)) { RedrawFrame(NULL); } } else if (event.xconfigure.send_event) { UpdateRootTransapency(False, True); } } break; #if 0 case SelectionClear: selection_clear (); break; case SelectionNotify: selection_paste (); break; case SelectionRequest: selection_send (); break; #endif case Expose: { int ex = event.xexpose.x; int ey = event.xexpose.y; int ex2 = event.xexpose.x + event.xexpose.width; int ey2 = event.xexpose.y + event.xexpose.height; while (FCheckTypedWindowEvent(dpy, CF.frame, Expose, &event)) { ex = min(ex, event.xexpose.x); ey = min(ey, event.xexpose.y); ex2 = max(ex2, event.xexpose.x + event.xexpose.width); ey2 = max(ey2 , event.xexpose.y + event.xexpose.height); } event.xexpose.x = ex; event.xexpose.y = ey; event.xexpose.width = ex2 - ex; event.xexpose.height = ey2 - ey; RedrawFrame(&event); if (CF.grab_server && !CF.server_grabbed) { if (GrabSuccess == XGrabPointer(dpy, CF.frame, True, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime)) CF.server_grabbed = 1; } } break; case VisibilityNotify: if (CF.server_grabbed && event.xvisibility.state != VisibilityUnobscured) { /* raise our window to the top */ XRaiseWindow(dpy, CF.frame); XSync(dpy, 0); } break; case KeyPress: /* we do text input here */ n = XLookupString(&event.xkey, (char *)buf, sizeof(buf), &ks, NULL); keypress = buf[0]; myfprintf((stderr, "Keypress [%s]\n", buf)); if (n == 0) { /* not a regular key, translate it into one */ switch (ks) { case XK_Home: case XK_Begin: buf[0] = '\001'; /* ^A */ break; case XK_End: buf[0] = '\005'; /* ^E */ break; case XK_Left: buf[0] = '\002'; /* ^B */ break; case XK_Right: buf[0] = '\006'; /* ^F */ break; case XK_Up: buf[0] = '\020'; /* ^P */ break; case XK_Down: buf[0] = '\016'; /* ^N */ break; default: if (ks >= XK_F1 && ks <= XK_F35) { buf[0] = '\0'; keypress = 257 + ks - XK_F1; } else goto no_redraw; /* no action for this event */ } } switch (ks) { /* regular key, may need adjustment */ case XK_Tab: #ifdef XK_XKB_KEYS case XK_ISO_Left_Tab: #endif if (event.xkey.state & ShiftMask) { /* shifted key */ buf[0] = '\020'; /* chg shift tab to ^P */ } break; case '>': if (event.xkey.state & Mod1Mask) { /* Meta, shift > */ process_history(1); goto redraw_newcursor; } break; case '<': if (event.xkey.state & Mod1Mask) { /* Meta, shift < */ process_history(-1); goto redraw_newcursor; } break; } if (!CF.cur_input) { /* no text input fields */ for (item = root_item_ptr; item != 0; item = item->header.next) {/* all items */ if (item->type == I_BUTTON && item->button.keypress == keypress) { RedrawItem(item, 1, NULL); usleep(MICRO_S_FOR_10MS); RedrawItem(item, 0, NULL); DoCommand(item); goto no_redraw; } } break; } else if (CF.cur_input == CF.cur_input->input.next_input) { /* 1 ip field */ switch (buf[0]) { case '\020': /* ^P previous field */ process_history(-1); goto redraw_newcursor; break; case '\016': /* ^N next field */ process_history(1); goto redraw_newcursor; break; } /* end switch */ } /* end one input field */ switch (buf[0]) { case '\001': /* ^A */ old_cursor = CF.abs_cursor; CF.rel_cursor = 0; CF.abs_cursor = 0; CF.cur_input->input.left = 0; goto redraw_newcursor; break; case '\005': /* ^E */ old_cursor = CF.abs_cursor; CF.rel_cursor = CF.cur_input->input.n; if ((CF.cur_input->input.left = CF.rel_cursor - CF.cur_input->input.size) < 0) CF.cur_input->input.left = 0; CF.abs_cursor = CF.rel_cursor - CF.cur_input->input.left; goto redraw_newcursor; break; case '\002': /* ^B */ old_cursor = CF.abs_cursor; if (CF.rel_cursor > 0) { CF.rel_cursor--; CF.abs_cursor--; if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) { CF.abs_cursor++; CF.cur_input->input.left--; } } goto redraw_newcursor; break; case '\006': /* ^F */ old_cursor = CF.abs_cursor; if (CF.rel_cursor < CF.cur_input->input.n) { CF.rel_cursor++; CF.abs_cursor++; if (CF.abs_cursor >= CF.cur_input->input.size && CF.rel_cursor < CF.cur_input->input.n) { CF.abs_cursor--; CF.cur_input->input.left++; } } goto redraw_newcursor; break; case '\010': /* ^H */ old_cursor = CF.abs_cursor; if (CF.rel_cursor > 0) { sp = CF.cur_input->input.value + CF.rel_cursor; dp = sp - 1; for (; *dp = *sp, *sp != '\0'; dp++, sp++); CF.cur_input->input.n--; CF.rel_cursor--; if (CF.rel_cursor < CF.abs_cursor) { CF.abs_cursor--; if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) { CF.abs_cursor++; CF.cur_input->input.left--; } } else CF.cur_input->input.left--; } goto redraw_newcursor; break; case '\177': /* DEL */ case '\004': /* ^D */ if (CF.rel_cursor < CF.cur_input->input.n) { sp = CF.cur_input->input.value + CF.rel_cursor + 1; dp = sp - 1; for (; *dp = *sp, *sp != '\0'; dp++, sp++); CF.cur_input->input.n--; goto redraw_newcursor; } break; case '\013': /* ^K */ CF.cur_input->input.value[CF.rel_cursor] = '\0'; CF.cur_input->input.n = CF.rel_cursor; goto redraw_newcursor; case '\025': /* ^U */ CF.cur_input->input.value[0] = '\0'; CF.cur_input->input.n = CF.cur_input->input.left = 0; CF.rel_cursor = CF.abs_cursor = 0; goto redraw_newcursor; case '\020': /* ^P previous field */ old_item = CF.cur_input; CF.cur_input = old_item->input.prev_input; /* new current input fld */ RedrawItem(old_item, 1, NULL); CF.rel_cursor = CF.abs_cursor = 0; /* home cursor in new input field */ goto redraw; break; case '\t': case '\n': case '\015': case '\016': /* LINEFEED, TAB, RETURN, ^N, jump to the next field */ switch (process_tabtypes(&buf[0])) { case 0: goto no_redraw;break; case 1: goto redraw;break; } break; default: old_cursor = CF.abs_cursor; if((buf[0] >= ' ' && buf[0] < '\177') || (buf[0] >= 160)) { /* regular or intl char */ process_regular_char_input(&buf[0]); /* insert into input field */ goto redraw_newcursor; } /* unrecognized key press, check for buttons */ for (item = root_item_ptr; item != 0; item = item->header.next) { /* all items */ myfprintf((stderr, "Button: keypress==%d\n", item->button.keypress)); if (item->type == I_BUTTON && item->button.keypress == keypress) { RedrawItem(item, 1, NULL); usleep(MICRO_S_FOR_10MS); /* .1 seconds */ RedrawItem(item, 0, NULL); DoCommand(item); goto no_redraw; } } break; } redraw_newcursor: { XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC, CF.cur_input->header.dt_ptr->dt_colors[c_item_bg]); /* Since DrawString is being used, I changed this to clear the entire input field. dje 10/24/99. */ XClearArea(dpy, CF.cur_input->header.win, BOX_SPC + TEXT_SPC - 1, BOX_SPC, CF.cur_input->header.size_x - (2 * BOX_SPC) - 2 - TEXT_SPC, (CF.cur_input->header.size_y - 1) - 2 * BOX_SPC + 1, False); } redraw: { int len, x, dy; len = CF.cur_input->input.n - CF.cur_input->input.left; XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC, CF.cur_input->header.dt_ptr->dt_colors[c_item_fg]); if (len > CF.cur_input->input.size) len = CF.cur_input->input.size; CF.cur_input->header.dt_ptr->dt_Fstr->win = CF.cur_input->header.win; CF.cur_input->header.dt_ptr->dt_Fstr->gc = CF.cur_input->header.dt_ptr->dt_item_GC; CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = False; if (itemcolorset >= 0) { CF.cur_input->header.dt_ptr->dt_Fstr->colorset = &Colorset[itemcolorset]; CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = True; } CF.cur_input->header.dt_ptr->dt_Fstr->str = CF.cur_input->input.value; CF.cur_input->header.dt_ptr->dt_Fstr->x = BOX_SPC + TEXT_SPC; CF.cur_input->header.dt_ptr->dt_Fstr->y = BOX_SPC + TEXT_SPC + CF.cur_input->header.dt_ptr->dt_Ffont->ascent; CF.cur_input->header.dt_ptr->dt_Fstr->len = len; FlocaleDrawString(dpy, CF.cur_input->header.dt_ptr->dt_Ffont, CF.cur_input->header.dt_ptr->dt_Fstr, FWS_HAVE_LENGTH); x = BOX_SPC + TEXT_SPC + FlocaleTextWidth(CF.cur_input->header.dt_ptr->dt_Ffont, CF.cur_input->input.value,CF.abs_cursor) - 1; dy = CF.cur_input->header.size_y - 1; XDrawLine(dpy, CF.cur_input->header.win, CF.cur_input->header.dt_ptr->dt_item_GC, x, BOX_SPC, x, dy - BOX_SPC); myfprintf((stderr,"Line %d/%d - %d/%d (char)\n", x, BOX_SPC, x, dy - BOX_SPC)); } no_redraw: break; /* end of case KeyPress */ } /* end of switch (event.type) */ continue; } /* end of if (event.xany.window == CF.frame) */ for (item = root_item_ptr; item != 0; item = item->header.next) { /* all items */ if (event.xany.window == item->header.win) { switch (event.type) { case Expose: { int ex = event.xexpose.x; int ey = event.xexpose.y; int ex2 = event.xexpose.x + event.xexpose.width; int ey2 = event.xexpose.y + event.xexpose.height; while (FCheckTypedWindowEvent( dpy, item->header.win, Expose, &event)) { ex = min(ex, event.xexpose.x); ey = min(ey, event.xexpose.y); ex2 = max(ex2, event.xexpose.x + event.xexpose.width); ey2 = max(ey2 , event.xexpose.y + event.xexpose.height); } event.xexpose.x = ex; event.xexpose.y = ey; event.xexpose.width = ex2 - ex; event.xexpose.height = ey2 - ey; RedrawItem(item, 0, &event); } break; case ButtonPress: if (item->type == I_INPUT) { old_item = CF.cur_input; CF.cur_input = item; RedrawItem(old_item, 1, NULL); { Bool done = False; CF.abs_cursor = 0; while(CF.abs_cursor <= item->input.size && !done) { if (FlocaleTextWidth(item->header.dt_ptr->dt_Ffont, item->input.value, CF.abs_cursor) >= event.xbutton.x - BOX_SPC - TEXT_SPC) { done = True; CF.abs_cursor--; } else { CF.abs_cursor++; } } } if (CF.abs_cursor < 0) CF.abs_cursor = 0; if (CF.abs_cursor > item->input.size) CF.abs_cursor = item->input.size; CF.rel_cursor = CF.abs_cursor + item->input.left; if (CF.rel_cursor < 0) CF.rel_cursor = 0; if (CF.rel_cursor > item->input.n) CF.rel_cursor = item->input.n; if (CF.rel_cursor > 0 && CF.rel_cursor == item->input.left) item->input.left--; if (CF.rel_cursor < item->input.n && CF.rel_cursor == item->input.left + item->input.size) item->input.left++; CF.abs_cursor = CF.rel_cursor - item->input.left; if (event.xbutton.button == Button2) { /* if paste request */ process_paste_request (&event, item); } RedrawItem(item, 0, NULL); } if (item->type == I_CHOICE) ToggleChoice(item); if (item->type == I_BUTTON) { RedrawItem(item, 1, NULL); /* push button in */ if (CF.activate_on_press) { usleep(MICRO_S_FOR_10MS); /* make sure its visible */ RedrawItem(item, 0, NULL); /* pop button out */ DoCommand(item); /* execute the button command */ } else { XGrabPointer(dpy, item->header.win, False, /* owner of events */ ButtonReleaseMask, /* events to report */ GrabModeAsync, /* keyboard mode */ GrabModeAsync, /* pointer mode */ None, /* confine to */ /* I sort of like this, the hand points in the other direction and the color is reversed. I don't know what other GUIs do, Java doesn't do anything, neither does anything else I can find...dje */ CF.pointer[button_in_pointer], /* cursor */ CurrentTime); } /* end activate on press */ } break; case ButtonRelease: if (!CF.activate_on_press) { RedrawItem(item, 0, NULL); if (CF.grab_server && CF.server_grabbed) { /* You have to regrab the pointer, or focus can go to another window. grab... */ XGrabPointer(dpy, CF.frame, True, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); XFlush(dpy); } else { XUngrabPointer(dpy, CurrentTime); XFlush(dpy); } if (event.xbutton.x >= 0 && event.xbutton.x < item->header.size_x && event.xbutton.y >= 0 && event.xbutton.y < item->header.size_y) { DoCommand(item); } } break; } } } /* end of for (i = 0) */ } /* while loop */ }
void move_icon_to_position( FvwmWindow *fw) { Bool draw_picture_w = False; Bool draw_title_w = False; if (fw->icon_g.picture_w_g.width > 0) { int cs; if (Scr.Hilite == fw) { cs = fw->cs_hi; } else { cs = fw->cs; } XMoveWindow( dpy, FW_W_ICON_PIXMAP(fw), fw->icon_g.picture_w_g.x, fw->icon_g.picture_w_g.y); if (fw->icon_alphaPixmap || (cs >= 0 && Colorset[cs].icon_alpha_percent < 100) || CSET_IS_TRANSPARENT(fw->icon_background_cs) || (!IS_ICON_SHAPED(fw) && fw->icon_background_padding > 0)) { draw_picture_w = True; } } if (!HAS_NO_ICON_TITLE(fw)) { int cs; rectangle dummy; if (Scr.Hilite == fw) { cs = fw->icon_title_cs_hi; } else { cs = fw->icon_title_cs; } XMoveWindow( dpy, FW_W_ICON_TITLE(fw), fw->icon_g.title_w_g.x, fw->icon_g.title_w_g.y); if (CSET_IS_TRANSPARENT(cs) && !get_visible_icon_picture_geometry(fw, &dummy) && get_visible_icon_title_geometry(fw, &dummy)) { draw_title_w = True; } } if (draw_title_w || draw_picture_w) { DrawIconWindow( fw, draw_title_w, draw_picture_w, False, draw_picture_w, NULL); } return; }