static void __draw(Display *dpy) { if (!current_config->Ffont) { return; } fwin_string.str = label; fwin_string.win = win; fwin_string.gc = gc; if (current_config->colorset > -1) { fwin_string.colorset = &Colorset[current_config->colorset]; fwin_string.flags.has_colorset = True; } else { fwin_string.flags.has_colorset = False; } fwin_string.x = 2; fwin_string.y = current_config->Ffont->ascent; FlocaleDrawString(dpy, current_config->Ffont, &fwin_string, 0); return; }
/* 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 DrawGoodies(XEvent *evp) { XRectangle rect; struct tm *tms; static char str[40]; static time_t timer; static int last_mail_check = -1; int x = win_width - stwin_width; int y = 0; int w = stwin_width; int h = RowHeight; Region t_region; if (goodies_width == 0) { return; } if (evp) { if (!frect_get_intersection( x, y, w, h, evp->xexpose.x, evp->xexpose.y, evp->xexpose.width, evp->xexpose.height, &rect)) { return; } } else { rect.x = x; rect.y = y; rect.width = w; rect.height = h; } time(&timer); tms = localtime(&timer); if (clockfmt) { strftime(str, 24, clockfmt, tms); if (str[0] == '0') str[0]=' '; } else { strftime(str, 15, "%R", tms); } Draw3dBox(win, x, y, w, h, &rect); t_region = XCreateRegion(); XUnionRectWithRegion (&rect, t_region, t_region); FwinString->win = win; FwinString->gc = statusgc; FwinString->str = str; FwinString->x = x + 4; FwinString->y = ((RowHeight - goodies_fontheight) >> 1) + FStatusFont->ascent; FwinString->flags.has_clip_region = True; FwinString->clip_region = t_region; if (colorset >= 0) { FwinString->colorset = &Colorset[colorset]; FwinString->flags.has_colorset = True; } else { FwinString->flags.has_colorset = False; } FlocaleDrawString(dpy, FStatusFont, FwinString, 0); FwinString->flags.has_clip_region = False; XDestroyRegion(t_region); if (!do_check_mail) { return; } if (timer - last_mail_check >= mailcheck_interval) { cool_get_inboxstatus(); last_mail_check = timer; if (newmail) XBell(dpy, BellVolume); } if (!mailcleared && (unreadmail || newmail)) { XCopyArea(dpy, wmailpix, win, statusgc, 0, 0, minimail_width, minimail_height, win_width - stwin_width + clock_width + 3, ((RowHeight - minimail_height) >> 1)); }
/* * * Procedure: * menuitem_paint - draws a single entry in a popped up menu * * mr - the menu instance that holds the menu item * mi - the menu item to redraw * fw - the FvwmWindow structure to check against allowed functions * */ void menuitem_paint( struct MenuItem *mi, struct MenuPaintItemParameters *mpip) { struct MenuStyle *ms = mpip->ms; struct MenuDimensions *dim = mpip->dim; static FlocaleWinString *fws = NULL; int y_offset; int text_y; int y_height; int x; int y; int lit_x_start; int lit_x_end; gc_quad_t gcs; gc_quad_t off_gcs; int cs = -1; int off_cs; FvwmRenderAttributes fra; /*Pixel fg, fgsh;*/ int relief_thickness = ST_RELIEF_THICKNESS(ms); Bool is_item_selected; Bool item_cleared = False; Bool xft_clear = False; Bool empty_inter = False; XRectangle b; Region region = None; int i; int sx1; int sx2; FlocaleFont* font; if (!mi) { return; } is_item_selected = (mi == mpip->selected_item); if (MI_IS_TITLE(mi)) { font = ST_PTITLEFONT(ms); } else { font = ST_PSTDFONT(ms); } y_offset = MI_Y_OFFSET(mi); y_height = MI_HEIGHT(mi); if (MI_IS_SELECTABLE(mi)) { text_y = y_offset + MDIM_ITEM_TEXT_Y_OFFSET(*dim); } else { text_y = y_offset + font->ascent + ST_TITLE_GAP_ABOVE(ms); } /* center text vertically if the pixmap is taller */ if (MI_PICTURE(mi)) { text_y += MI_PICTURE(mi)->height; } for (i = 0; i < mpip->used_mini_icons; i++) { y = 0; if (MI_MINI_ICON(mi)[i]) { if (MI_MINI_ICON(mi)[i]->height > y) { y = MI_MINI_ICON(mi)[i]->height; } } y -= font->height; if (y > 1) { text_y += y / 2; } } off_cs = ST_HAS_MENU_CSET(ms) ? ST_CSET_MENU(ms) : -1; /* Note: it's ok to pass a NULL label to is_function_allowed. */ if ( !IS_EWMH_DESKTOP_FW(mpip->fw) && !is_function_allowed( MI_FUNC_TYPE(mi), MI_LABEL(mi)[0], mpip->fw, RQORIG_PROGRAM_US, False)) { gcs = ST_MENU_STIPPLE_GCS(ms); off_gcs = gcs; off_cs = ST_HAS_GREYED_CSET(ms) ? ST_CSET_GREYED(ms) : -1; } else if (is_item_selected) { gcs = ST_MENU_ACTIVE_GCS(ms); off_gcs = ST_MENU_INACTIVE_GCS(ms); } else if (MI_IS_TITLE(mi)) { gcs = ST_MENU_TITLE_GCS(ms); off_gcs = ST_MENU_INACTIVE_GCS(ms); } else { gcs = ST_MENU_INACTIVE_GCS(ms); off_gcs = ST_MENU_INACTIVE_GCS(ms); } if (is_item_selected) { cs = (ST_HAS_ACTIVE_CSET(ms)) ? ST_CSET_ACTIVE(ms) : -1; } else if (MI_IS_TITLE(mi)) { cs = (ST_HAS_TITLE_CSET(ms)) ? ST_CSET_TITLE(ms) : off_cs; } else { cs = off_cs; } /* * Hilight the item. */ if (FftSupport && ST_PSTDFONT(ms)->fftf.fftfont != NULL) { xft_clear = True; } /* Hilight or clear the background. */ lit_x_start = -1; lit_x_end = -1; if (is_item_selected && (ST_DO_HILIGHT_BACK(ms) || ST_DO_HILIGHT_FORE(ms))) { /* Hilight the background. */ if (MDIM_HILIGHT_WIDTH(*dim) - 2 * relief_thickness > 0) { lit_x_start = MDIM_HILIGHT_X_OFFSET(*dim) + relief_thickness; lit_x_end = lit_x_start + MDIM_HILIGHT_WIDTH(*dim) - 2 * relief_thickness; if (ST_DO_HILIGHT_BACK(ms)) { draw_highlight_background( mpip, lit_x_start, y_offset + relief_thickness, lit_x_end - lit_x_start, y_height - relief_thickness, (cs >= 0 ? &Colorset[cs] : NULL), gcs.back_gc); item_cleared = True; } } } else if ((MI_WAS_DESELECTED(mi) && (relief_thickness > 0 || ST_DO_HILIGHT_BACK(ms) || ST_DO_HILIGHT_FORE(ms)) && (ST_FACE(ms).type != GradientMenu || ST_HAS_MENU_CSET(ms)))) { int x1; int x2; /* we clear if xft_clear and !ST_HAS_MENU_CSET(ms) as the * non colorset code is too complicate ... olicha */ int d = 0; if (MI_PREV_ITEM(mi) && mpip->selected_item == MI_PREV_ITEM(mi)) { /* Don't paint over the hilight relief. */ d = relief_thickness; } /* Undo the hilighting. */ x1 = min( MDIM_HILIGHT_X_OFFSET(*dim), MDIM_ITEM_X_OFFSET(*dim)); x2 = max( MDIM_HILIGHT_X_OFFSET(*dim) + MDIM_HILIGHT_WIDTH(*dim), MDIM_ITEM_X_OFFSET(*dim) + MDIM_ITEM_WIDTH(*dim)); clear_menu_item_background( mpip, x1, y_offset + d, x2 - x1, y_height + relief_thickness - d); item_cleared = True; } else if (MI_IS_TITLE(mi)) { lit_x_start = MDIM_ITEM_X_OFFSET(*dim); lit_x_end = lit_x_start + MDIM_ITEM_WIDTH(*dim); /* Hilight the background. */ if ( MDIM_HILIGHT_WIDTH(*dim) > 0 && ST_DO_HILIGHT_TITLE_BACK(ms)) { draw_highlight_background( mpip, lit_x_start, y_offset + relief_thickness, lit_x_end - lit_x_start, y_height - relief_thickness, (cs >= 0 ? &Colorset[cs] : NULL), gcs.back_gc); item_cleared = True; } } MI_WAS_DESELECTED(mi) = False; memset(&fra, 0, sizeof(fra)); fra.mask = 0; /* Hilight 3D */ if (is_item_selected && relief_thickness > 0) { GC rgc; GC sgc; rgc = gcs.hilight_gc; sgc = gcs.shadow_gc; if (ST_IS_ITEM_RELIEF_REVERSED(ms)) { GC tgc = rgc; /* swap gcs for reversed relief */ rgc = sgc; sgc = tgc; } if (MDIM_HILIGHT_WIDTH(*dim) - 2 * relief_thickness > 0) { /* The relief reaches down into the next item, hence * the value for the second y coordinate: * MI_HEIGHT(mi) + 1 */ RelieveRectangle( dpy, mpip->w, MDIM_HILIGHT_X_OFFSET(*dim), y_offset, MDIM_HILIGHT_WIDTH(*dim) - 1, MI_HEIGHT(mi) - 1 + relief_thickness, rgc, sgc, relief_thickness); } } /* * Draw the item itself. */ /* Calculate the separator offsets. */ if (ST_HAS_LONG_SEPARATORS(ms)) { sx1 = MDIM_ITEM_X_OFFSET(*dim) + relief_thickness; sx2 = MDIM_ITEM_X_OFFSET(*dim) + MDIM_ITEM_WIDTH(*dim) - 1 - relief_thickness; } else { sx1 = MDIM_ITEM_X_OFFSET(*dim) + relief_thickness + MENU_SEPARATOR_SHORT_X_OFFSET; sx2 = MDIM_ITEM_X_OFFSET(*dim) + MDIM_ITEM_WIDTH(*dim) - 1 - relief_thickness - MENU_SEPARATOR_SHORT_X_OFFSET; } if (MI_IS_SEPARATOR(mi)) { if (sx1 < sx2) { /* It's a separator. */ draw_separator( mpip->w, gcs.shadow_gc, gcs.hilight_gc, sx1, y_offset + y_height - MENU_SEPARATOR_HEIGHT, sx2); /* Nothing else to do. */ } return; } else if (MI_IS_TEAR_OFF_BAR(mi)) { int tx1; int tx2; tx1 = MDIM_ITEM_X_OFFSET(*dim) + relief_thickness + MENU_TEAR_OFF_BAR_X_OFFSET; tx2 = MDIM_ITEM_X_OFFSET(*dim) + MDIM_ITEM_WIDTH(*dim) - 1 - relief_thickness - MENU_TEAR_OFF_BAR_X_OFFSET; if (tx1 < tx2) { /* It's a tear off bar. */ draw_tear_off_bar( mpip->w, gcs.shadow_gc, gcs.hilight_gc, tx1, y_offset + relief_thickness + MENU_TEAR_OFF_BAR_Y_OFFSET, tx2); } /* Nothing else to do. */ return; } else if (MI_IS_TITLE(mi)) { /* Separate the title. */ if (ST_TITLE_UNDERLINES(ms) > 0 && !mpip->flags.is_first_item) { int add = (MI_IS_SELECTABLE(MI_PREV_ITEM(mi))) ? relief_thickness : 0; text_y += MENU_SEPARATOR_HEIGHT + add; y = y_offset + add; if (sx1 < sx2) { draw_separator( mpip->w, gcs.shadow_gc, gcs.hilight_gc, sx1, y, sx2); } } /* Underline the title. */ switch (ST_TITLE_UNDERLINES(ms)) { case 0: break; case 1: if (MI_NEXT_ITEM(mi) != NULL) { y = y_offset + y_height - MENU_SEPARATOR_HEIGHT; draw_separator( mpip->w, gcs.shadow_gc, gcs.hilight_gc, sx1, y, sx2); } break; default: for (i = ST_TITLE_UNDERLINES(ms); i-- > 0; ) { y = y_offset + y_height - 1 - i * MENU_UNDERLINE_HEIGHT; XDrawLine( dpy, mpip->w, gcs.shadow_gc, sx1, y, sx2, y); } break; } } /* * Draw the labels. */ if (fws == NULL) { FlocaleAllocateWinString(&fws); } fws->win = mpip->w; fws->y = text_y; fws->flags.has_colorset = 0; b.y = text_y - font->ascent; b.height = font->height + 1; /* ? */ if (!item_cleared && mpip->ev) { int u,v; if (!frect_get_seg_intersection( mpip->ev->xexpose.y, mpip->ev->xexpose.height, b.y, b.height, &u, &v)) { /* empty intersection */ empty_inter = True; } b.y = u; b.height = v; } for (i = MAX_MENU_ITEM_LABELS; i-- > 0; ) { if (!empty_inter && MI_LABEL(mi)[i] && *(MI_LABEL(mi)[i])) { Bool draw_string = True; int text_width; int tmp_cs; if (MI_LABEL_OFFSET(mi)[i] >= lit_x_start && MI_LABEL_OFFSET(mi)[i] < lit_x_end) { /* label is in hilighted area */ fws->gc = gcs.fore_gc; tmp_cs = cs; } else { /* label is in unhilighted area */ fws->gc = off_gcs.fore_gc; tmp_cs = off_cs; } if (tmp_cs >= 0) { fws->colorset = &Colorset[tmp_cs]; fws->flags.has_colorset = 1; } fws->str = MI_LABEL(mi)[i]; b.x = fws->x = MI_LABEL_OFFSET(mi)[i]; b.width = text_width = FlocaleTextWidth( font, fws->str, strlen(fws->str)); if (!item_cleared && mpip->ev) { int s_x,s_w; if (frect_get_seg_intersection( mpip->ev->xexpose.x, mpip->ev->xexpose.width, fws->x, text_width, &s_x, &s_w)) { b.x = s_x; b.width = s_w; region = XCreateRegion(); XUnionRectWithRegion( &b, region, region); fws->flags.has_clip_region = True; fws->clip_region = region; draw_string = True; XSetRegion(dpy, fws->gc, region); } else { /* empty intersection */ draw_string = False; } } if (draw_string) { if (!item_cleared && xft_clear) { clear_menu_item_background( mpip, b.x, b.y, b.width, b.height); } FlocaleDrawString(dpy, font, fws, 0); /* hot key */ if (MI_HAS_HOTKEY(mi) && !MI_IS_TITLE(mi) && (!MI_IS_HOTKEY_AUTOMATIC(mi) || ST_USE_AUTOMATIC_HOTKEYS(ms)) && MI_HOTKEY_COLUMN(mi) == i) { FlocaleDrawUnderline( dpy, ST_PSTDFONT(ms), fws, MI_HOTKEY_COFFSET(mi)); } } } if (region) { XDestroyRegion(region); region = None; fws->flags.has_clip_region = False; fws->clip_region = None; XSetClipMask(dpy, fws->gc, None); } } /* * Draw the submenu triangle. */ if (MI_IS_POPUP(mi)) { GC tmp_gc; if (MDIM_TRIANGLE_X_OFFSET(*dim) >= lit_x_start && MDIM_TRIANGLE_X_OFFSET(*dim) < lit_x_end && is_item_selected) { /* triangle is in hilighted area */ if (ST_TRIANGLES_USE_FORE(ms)) { tmp_gc = gcs.fore_gc; } else { tmp_gc = gcs.hilight_gc; } } else { /* triangle is in unhilighted area */ if (ST_TRIANGLES_USE_FORE(ms)) { tmp_gc = off_gcs.fore_gc; } else { tmp_gc = off_gcs.hilight_gc; } } y = y_offset + (y_height - MENU_TRIANGLE_HEIGHT + relief_thickness) / 2; if (ST_TRIANGLES_USE_FORE(ms)) { DrawTrianglePattern( dpy, mpip->w, tmp_gc, tmp_gc, tmp_gc, MDIM_TRIANGLE_X_OFFSET(*dim), y, MENU_TRIANGLE_WIDTH, MENU_TRIANGLE_HEIGHT, 0, (mpip->flags.is_left_triangle) ? 'l' : 'r', ST_HAS_TRIANGLE_RELIEF(ms), !ST_HAS_TRIANGLE_RELIEF(ms), is_item_selected); } else { DrawTrianglePattern( dpy, mpip->w, gcs.hilight_gc, gcs.shadow_gc, tmp_gc, MDIM_TRIANGLE_X_OFFSET(*dim), y, MENU_TRIANGLE_WIDTH, MENU_TRIANGLE_HEIGHT, 0, (mpip->flags.is_left_triangle) ? 'l' : 'r', ST_HAS_TRIANGLE_RELIEF(ms), !ST_HAS_TRIANGLE_RELIEF(ms), is_item_selected); } } /* * Draw the item picture. */ if (MI_PICTURE(mi)) { GC tmp_gc; int tmp_cs; Bool draw_picture = True; x = menudim_middle_x_offset(mpip->dim) - MI_PICTURE(mi)->width / 2; y = y_offset + ((MI_IS_SELECTABLE(mi)) ? relief_thickness : 0); if (x >= lit_x_start && x < lit_x_end) { tmp_gc = gcs.fore_gc; tmp_cs = cs; } else { tmp_gc = off_gcs.fore_gc; tmp_cs = off_cs; } fra.mask = FRAM_DEST_IS_A_WINDOW; if (tmp_cs >= 0) { fra.mask |= FRAM_HAVE_ICON_CSET; fra.colorset = &Colorset[tmp_cs]; } b.x = x; b.y = y; b.width = MI_PICTURE(mi)->width; b.height = MI_PICTURE(mi)->height; if (!item_cleared && mpip->ev) { if (!frect_get_intersection( mpip->ev->xexpose.x, mpip->ev->xexpose.y, mpip->ev->xexpose.width, mpip->ev->xexpose.height, b.x, b.y, b.width, b.height, &b)) { draw_picture = False; } } if (draw_picture) { if ( !item_cleared && (MI_PICTURE(mi)->alpha != None || (tmp_cs >=0 && Colorset[tmp_cs].icon_alpha_percent < 100))) { clear_menu_item_background( mpip, b.x, b.y, b.width, b.height); } PGraphicsRenderPicture( dpy, mpip->w, MI_PICTURE(mi), &fra, mpip->w, tmp_gc, Scr.MonoGC, Scr.AlphaGC, b.x - x, b.y - y, b.width, b.height, b.x, b.y, b.width, b.height, False); } } /* * Draw the mini icons. */ for (i = 0; i < mpip->used_mini_icons; i++) { int k; Bool draw_picture = True; /* We need to reverse the mini icon order for left submenu * style. */ k = (ST_USE_LEFT_SUBMENUS(ms)) ? mpip->used_mini_icons - 1 - i : i; if (MI_MINI_ICON(mi)[i]) { GC tmp_gc; int tmp_cs; if (MI_PICTURE(mi)) { y = y_offset + MI_HEIGHT(mi) - MI_MINI_ICON(mi)[i]->height; } else { y = y_offset + (MI_HEIGHT(mi) + ((MI_IS_SELECTABLE(mi)) ? relief_thickness : 0) - MI_MINI_ICON(mi)[i]->height) / 2; } if (MDIM_ICON_X_OFFSET(*dim)[k] >= lit_x_start && MDIM_ICON_X_OFFSET(*dim)[k] < lit_x_end) { /* icon is in hilighted area */ tmp_gc = gcs.fore_gc; tmp_cs = cs; } else { /* icon is in unhilighted area */ tmp_gc = off_gcs.fore_gc; tmp_cs = off_cs; } fra.mask = FRAM_DEST_IS_A_WINDOW; if (tmp_cs >= 0) { fra.mask |= FRAM_HAVE_ICON_CSET; fra.colorset = &Colorset[tmp_cs]; } b.x = MDIM_ICON_X_OFFSET(*dim)[k]; b.y = y; b.width = MI_MINI_ICON(mi)[i]->width; b.height = MI_MINI_ICON(mi)[i]->height; if (!item_cleared && mpip->ev) { if (!frect_get_intersection( mpip->ev->xexpose.x, mpip->ev->xexpose.y, mpip->ev->xexpose.width, mpip->ev->xexpose.height, b.x, b.y, b.width, b.height, &b)) { draw_picture = False; } } if (draw_picture) { if (!item_cleared && (MI_MINI_ICON(mi)[i]->alpha != None || (tmp_cs >=0 && Colorset[tmp_cs].icon_alpha_percent < 100))) { clear_menu_item_background( mpip, b.x, b.y, b.width, b.height); } PGraphicsRenderPicture( dpy, mpip->w, MI_MINI_ICON(mi)[i], &fra, mpip->w, tmp_gc, Scr.MonoGC, Scr.AlphaGC, b.x - MDIM_ICON_X_OFFSET(*dim)[k], b.y - y, b.width, b.height, b.x, b.y, b.width, b.height, False); } } } return; }
void DrawTextField(struct XObj *xobj, XEvent *evp) { int x1,y1; int x2,l; int nl=0; int right=0; int offset,offset2,offset3; int end_value; fprintf(stderr,"DrawTextField: value %d value2 %d value3 %d\n", xobj->value, xobj->value2, xobj->value3); y1 = xobj->Ffont->ascent; l=strlen(xobj->title); /* calculate byte offsets corresponding to value,value2,value3 */ offset = getByteOffsetBoundsCheck(xobj->Ffont,xobj->title,xobj->value); offset2 = getByteOffsetBoundsCheck(xobj->Ffont,xobj->title, xobj->value2); offset3 = getByteOffsetBoundsCheck(xobj->Ffont,xobj->title, xobj->value3); /* value corresponding to behind last character */ end_value = FlocaleStringCharLength(xobj->Ffont, xobj->title ); if(offset == l) xobj->value = end_value; if(offset2 == l) xobj->value2 = end_value; if(offset3 == l) xobj->value3 = end_value; fprintf(stderr, "DrawTextField: offset: %d offset2 %d, offset3: %d\n", offset, offset2, offset3); /*if (offset > l) xobj->value = FlocaleStringByteToCharOffset(xobj->Ffont, xobj->title, l-1) + 1; if (offset2 > l) xobj->value2 = FlocaleStringByteToCharOffset(xobj->Ffont, xobj->title, l-1) + 1; */ DrawReliefRect(0,0,xobj->width,xobj->height,xobj,shad,hili); XClearArea(dpy,xobj->win,2,2,xobj->width-4,xobj->height-4,False); XSetForeground(dpy,xobj->gc,xobj->TabColor[fore]); /* calcul du premier caractere visible */ /* computation of the first visible character */ while (l-nl >= 1 && FlocaleTextWidth(xobj->Ffont,xobj->title + nl, offset - nl) > (xobj->width-10)) { nl += FlocaleStringNumberOfBytes(xobj->Ffont,xobj->title + nl); fprintf(stderr,"nl: %d\n", nl); } /* now nl is the byte offset of the first the first visible character */ if (nl > offset3) /* the first visible character needs to be updated */ { xobj->value3 = getCharOffsetBoundsCheck(xobj->Ffont, xobj->title, nl); /*FlocaleStringByteToCharOffset(xobj->Ffont, xobj->title, nl);*/ offset3 = nl; } else if (xobj->value3 > xobj->value) { xobj->value3--; offset3 = FlocaleStringCharToByteOffset(xobj->Ffont, xobj->title, xobj->value3); } fprintf(stderr, "Got visible offset; %d char %d\n", offset3, xobj->value3); /* calcul de la longueur du titre visible */ /* computation of the length of the visible title */ /* increase string until it won't fit anymore into into the textbox */ right = offset3; while(right < l && FlocaleTextWidth(xobj->Ffont, xobj->title + offset3, right - offset3) <= xobj->width - 10) { right += FlocaleStringNumberOfBytes(xobj->Ffont, xobj->title + right); } /* the string didn't fit? */ if(FlocaleTextWidth(xobj->Ffont, xobj->title + offset3, right - offset3) > xobj->width - 10) { right -= FlocaleStringNumberOfBytes( xobj->Ffont, xobj->title + FlocaleStringCharToByteOffset( xobj->Ffont, xobj->title, FlocaleStringByteToCharOffset( xobj->Ffont, xobj->title, right) - 1)); } /* unless we had an empty string, we would have already been at the beginning */ if(right < offset3) right = offset3; /*while ( l - offset3 - right >= 1 && FlocaleTextWidth(xobj->Ffont,xobj->title + offset3, l - offset3 - right) > (xobj->width-10)) { right += FlocaleStringNumberOfBytes(xobj->Ffont, xobj->title + right); fprintf(stderr, "sl: %d\n", l - offset3 - right); } */ fprintf(stderr,"computed length of visible string\n"); FwinString->win = xobj->win; FwinString->gc = xobj->gc; FwinString->x = 5; FwinString->y = y1+5; FwinString->str = xobj->title + offset3; FwinString->len = right - offset3; /*strlen(xobj->title) - offset3 - right;*/ FlocaleDrawString(dpy, xobj->Ffont, FwinString, FWS_HAVE_LENGTH); #if 0 XmbDrawString(dpy,xobj->win,xobj->xfontset,xobj->gc,5,y1+5, xobj->title + xobj->value3, strlen(xobj->title) - xobj->value3-right); #endif /* Dessin de la zone selectionnee */ /* selected zone drawing */ XSetFunction(dpy,xobj->gc,GXinvert); if (xobj->value2>xobj->value) /* Curseur avant la souris */ { x1=FlocaleTextWidth(xobj->Ffont,&xobj->title[offset3], offset - offset3); x2=FlocaleTextWidth(xobj->Ffont,&xobj->title[offset], offset2 - offset); } else /* Curseur apres la souris / cursor after the mouse */ { x1=FlocaleTextWidth(xobj->Ffont,&xobj->title[offset3], offset2 - offset3); x2=FlocaleTextWidth(xobj->Ffont,&xobj->title[offset2], offset - offset2); } XFillRectangle( dpy,xobj->win,xobj->gc,x1+5,7,x2,y1+xobj->Ffont->descent-2); XSetFunction(dpy,xobj->gc,GXcopy); /* Dessin du point d'insertion */ /* insertion point drawing */ DrawPointTxt(xobj,xobj->TabColor[fore]); }