/* text cursor drawing */ void DrawPointTxt(struct XObj *xobj,unsigned int pixel) { #define dec 2 int x,y; int offset_abs,offset_rel; XSegment segm[2]; /* calculate byte offsets */ offset_abs = FlocaleStringCharToByteOffset(xobj->Ffont,xobj->title, xobj->value); offset_rel = FlocaleStringCharToByteOffset(xobj->Ffont,xobj->title, xobj->value3); x = FlocaleTextWidth(xobj->Ffont, xobj->title + offset_rel, offset_abs - offset_rel)+5; y = xobj->Ffont->ascent + 5; segm[0].x1=x; segm[0].y1=y; segm[0].x2=x-dec; segm[0].y2=y+dec; segm[1].x1=x; segm[1].y1=y; segm[1].x2=x+dec; segm[1].y2=y+dec; XSetForeground(dpy,xobj->gc,pixel); XDrawSegments(dpy,xobj->win,xobj->gc,segm,2); }
/* * Fonction pour VScrollBar */ void DrawThumbV(struct XObj *xobj, XEvent *evp) { int x,y,w,h; XSegment segm; char str[20]; x = xobj->width/2 - 10; y = 2 + (xobj->height - 36)*(xobj->value - xobj->value3) / (xobj->value2 - xobj->value3); w = 20; h = 32; DrawReliefRect(x, y, w, h, xobj, hili, shad); segm.x1 = x + 3; segm.y1 = y + 15; segm.x2 = x + w - 3; segm.y2 = y + 15; XSetForeground(dpy, xobj->gc, xobj->TabColor[shad]); XDrawSegments(dpy, xobj->win, xobj->gc, &segm, 1); segm.x1 = x + 3; segm.y1 = y + 16; segm.x2 = x + w - 3; segm.y2 = y + 16; XSetForeground(dpy, xobj->gc, xobj->TabColor[hili]); XDrawSegments(dpy, xobj->win, xobj->gc, &segm, 1); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); sprintf(str, "%d", xobj->value); x = x-FlocaleTextWidth(xobj->Ffont, str, strlen(str))-6; y = y + 13 + xobj->Ffont->ascent/2; MyDrawString(dpy, xobj, xobj->win, x, y, str, fore, hili, back, !xobj->flags[1], NULL, evp); }
void InitGoodies(void) { struct passwd *pwent; char tmp[1024]; if (mailpath == NULL) { strcpy(tmp, DEFAULT_MAIL_PATH); pwent = getpwuid(getuid()); strcat(tmp, (char *) (pwent->pw_name)); UpdateString(&mailpath, tmp); } CreateOrUpdateGoodyGC(); if (clockfmt) { if (!do_display_clock) { clock_width = 0; } else { struct tm *tms; static time_t timer; static char str[24]; time(&timer); tms = localtime(&timer); strftime(str, 24, clockfmt, tms); clock_width = FlocaleTextWidth( FStatusFont, str, strlen(str)) + 4; } } else { clock_width = FlocaleTextWidth(FStatusFont, "XX:XX", 5) + 4; } goodies_width += clock_width; stwin_width = goodies_width; }
void DrawPopupMenu(struct XObj *xobj, XEvent *evp) { XSegment segm[4]; char* str; int x,y; int asc = xobj->Ffont->ascent; DrawReliefRect(0, 0, xobj->width, xobj->height, xobj, hili, shad); /* Dessin de la fleche / arrow drawing */ segm[0].x1 = 7; segm[0].y1 = asc; segm[0].x2 = 19; segm[0].y2 = asc; segm[1].x1 = 8; segm[1].y1 = asc; segm[1].x2 = 13; segm[1].y2 = 5 + asc; segm[2].x1 = 6; segm[2].y1 = asc - 1; segm[2].x2 = 19; segm[2].y2 = 0 + asc -1; segm[3].x1 = 7; segm[3].y1 = asc; segm[3].x2 = 12; segm[3].y2 = 5 +asc; XSetForeground(dpy, xobj->gc, xobj->TabColor[shad]); XDrawSegments(dpy, xobj->win, xobj->gc, segm, 4); segm[0].x1 = 17; segm[0].y1 = asc + 1; segm[0].x2 = 13; segm[0].y2 = 5 + asc; segm[1].x1 = 19; segm[1].y1 = asc; segm[1].x2 = 14; segm[1].y2 = 5 + asc; XSetForeground(dpy, xobj->gc, xobj->TabColor[hili]); XDrawSegments(dpy, xobj->win, xobj->gc, segm, 2); /* Dessin du titre du popup menu */ str = (char*)GetMenuTitle(xobj->title, xobj->value); y = asc + 5; x = GetXTextPosition(xobj,xobj->width, FlocaleTextWidth(xobj->Ffont,str,strlen(str)), 25,8,8); MyDrawString(dpy, xobj, xobj->win, x, y, str, fore, hili, back, !xobj->flags[1], NULL, evp); free(str); }
void InitPopupMenu(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i; char *str; /* Enregistrement des couleurs et de la police / set the colors and the font */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask = 0; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; Attr.cursor = XCreateFontCursor(dpy, XC_hand2); mask |= CWCursor; /* Curseur pour la fenetre / window cursor */ xobj->win = XCreateWindow(dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy, xobj->win, 0, NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); if ((xobj->Ffont = FlocaleLoadFont(dpy, xobj->font, ScriptName)) == NULL) { fprintf(stderr, "%s: Couldn't load font. Exiting!\n", ScriptName); exit(1); } if (xobj->Ffont->font != NULL) XSetFont(dpy, xobj->gc, xobj->Ffont->font->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); xobj->value3 = CountOption(xobj->title); if (xobj->value > xobj->value3) xobj->value = xobj->value3; if (xobj->value < 1) xobj->value = 1; /* Redimensionnement du widget / Widget resizing */ xobj->height = xobj->Ffont->height +12; xobj->width = 30; for (i = 1; i <= xobj->value3; i++) { str = (char*)GetMenuTitle(xobj->title, i); if (xobj->width < FlocaleTextWidth(xobj->Ffont, str, strlen(str))+34) xobj->width = FlocaleTextWidth(xobj->Ffont, str, strlen(str))+34; free(str); } XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); }
/* * * 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; }
/* Calculate the size of the various parts of the item. The sizes are returned * through mipst. */ void menuitem_get_size( struct MenuItem *mi, struct MenuItemPartSizesT *mipst, FlocaleFont *font, Bool do_reverse_icon_order) { int i; int j; int w; memset(mipst, 0, sizeof(MenuItemPartSizesT)); if (MI_IS_POPUP(mi)) { mipst->triangle_width = MENU_TRIANGLE_WIDTH; } else if (MI_IS_TITLE(mi) && !MI_HAS_PICTURE(mi)) { Bool is_formatted = False; /* titles stretch over the whole menu width, so count the * maximum separately if the title is unformatted. */ for (j = 1; j < MAX_MENU_ITEM_LABELS; j++) { if (MI_LABEL(mi)[j] != NULL) { is_formatted = True; break; } else { MI_LABEL_OFFSET(mi)[j] = 0; } } if (!is_formatted && MI_LABEL(mi)[0] != NULL) { MI_LABEL_STRLEN(mi)[0] = strlen(MI_LABEL(mi)[0]); w = FlocaleTextWidth( font, MI_LABEL(mi)[0], MI_LABEL_STRLEN(mi)[0]); MI_LABEL_OFFSET(mi)[0] = w; MI_IS_TITLE_CENTERED(mi) = True; if (mipst->title_width < w) { mipst->title_width = w; } return; } } /* regular item or formatted title */ for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { if (MI_LABEL(mi)[i]) { MI_LABEL_STRLEN(mi)[i] = strlen(MI_LABEL(mi)[i]); w = FlocaleTextWidth( font, MI_LABEL(mi)[i], MI_LABEL_STRLEN(mi)[i]); MI_LABEL_OFFSET(mi)[i] = w; if (mipst->label_width[i] < w) { mipst->label_width[i] = w; } } } if (MI_PICTURE(mi) && mipst->picture_width < MI_PICTURE(mi)->width) { mipst->picture_width = MI_PICTURE(mi)->width; } for (i = 0; i < MAX_MENU_ITEM_MINI_ICONS; i++) { if (MI_MINI_ICON(mi)[i]) { int k; /* Reverse mini icon order for left submenu style. */ k = (do_reverse_icon_order == True) ? MAX_MENU_ITEM_MINI_ICONS - 1 - i : i; mipst->icon_width[k] = MI_MINI_ICON(mi)[i]->width; } } return; }
void EvtKeyTextField(struct XObj *xobj,XKeyEvent *EvtKey) { int i,x2; char car[11]; char* carks2; char* carks = NULL; KeySym ks; int Size; int NewPos; int new_value; /* Recherche du charactere */ i=XLookupString(EvtKey,car,10,&ks,NULL); /* calculate byte offset from current position */ NewPos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title, xobj->value); car[i]='\0'; carks2=XKeysymToString(ks); if (carks2!=NULL) { carks=(char*)calloc(sizeof(char),30); sprintf(carks,"%s",carks2); if (strcmp(carks,"Right")==0) { /* if we are at the end, don't go further */ if (NewPos >= strlen(xobj->title)) NewPos = strlen(xobj->title); /* otherwise step forward as many bytes as the next charcter at the insertion point is wide */ else NewPos += FlocaleStringNumberOfBytes( xobj->Ffont, xobj->title + NewPos); } else if (strcmp(carks,"Left")==0) { /* if we are at the beginning, don't go further */ if (NewPos <= 0) NewPos=0; /* otherwise step back as many bytes as the chacter behind the insertion point */ else NewPos = FlocaleStringCharToByteOffset( xobj->Ffont, xobj->title, xobj->value - 1); } else if (strcmp(carks,"Return")==0) { ; } else if ((strcmp(carks,"Delete")==0)|| (strcmp(carks,"BackSpace")==0)) { if (NewPos>0) { /* need to delete the "right" amount of bytes from the string, we might be using multi-byte strings */ int PrevPos; Size=strlen(xobj->title); PrevPos = FlocaleStringCharToByteOffset( xobj->Ffont, xobj->title, xobj->value - 1); memmove( &xobj->title[PrevPos], &xobj->title[NewPos], Size-NewPos+1); xobj->title=(char*)realloc( xobj->title, (Size - (NewPos - PrevPos) + 1) * sizeof(char)); NewPos = PrevPos; SendMsg(xobj,SingleClic); } } else if (i!=0) /* Cas d'un caractere normal */ { /* Insertion du caractere dans le titre */ /* a normal character: insertion in the title */ /* here "i" is the number of bytes returned need not be 1 incase of MB locale */ Size=strlen(xobj->title); fprintf(stderr, "Current size: %d\n", Size); /* make room for more the new text */ /* shouldn't saferealloc be used here? */ xobj->title=(char*)realloc( xobj->title,(Size+i+1)*sizeof(char)); /* new text will be inserted at NewPos */ /* move string currently in wiget's buffer to make room for new text */ memmove(&xobj->title[NewPos+i],&xobj->title[NewPos], Size - NewPos + 1); /* and insert new text */ memcpy(&xobj->title[NewPos],car,i); NewPos += i; SendMsg(xobj,SingleClic); } } new_value = getCharOffsetBoundsCheck(xobj->Ffont, xobj->title, NewPos); if ((xobj->value != new_value) || (xobj->value2 != new_value)) { XSetForeground(dpy,xobj->gc,xobj->TabColor[back]); x2=FlocaleTextWidth( xobj->Ffont,xobj->title,strlen(xobj->title)); XFillRectangle(dpy,xobj->win,xobj->gc,x2+4,4,xobj->width-x2-8, xobj->height-8); /* convert back to char offsets */ xobj->value = new_value; /*FlocaleStringByteToCharOffset(xobj->Ffont, xobj->title, NewPos);*/ xobj->value2 = new_value; /*FlocaleStringByteToCharOffset(xobj->Ffont, xobj->title, NewPos);*/ DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj,NULL); } free(carks); }
void InitVScrollBar(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i,j; char str[20]; /* Enregistrement des couleurs et de la police */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask = 0; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; Attr.cursor = XCreateFontCursor(dpy,XC_hand2); mask |= CWCursor; /* Curseur pour la fenetre */ xobj->win = XCreateWindow( dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy, xobj->win, 0, NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); if ((xobj->Ffont = FlocaleLoadFont(dpy, xobj->font, ScriptName)) == NULL) { fprintf( stderr, "%s: Couldn't load font. Exiting!\n", ScriptName); exit(1); } if (xobj->Ffont->font != NULL) XSetFont(dpy, xobj->gc, xobj->Ffont->font->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); if ((xobj->value3 - xobj->value2) <= 0) xobj->value3 = xobj->value2 + 10; if (!((xobj->value >= xobj->value2) && (xobj->value <= xobj->value3))) xobj->value = xobj->value2; i = (xobj->Ffont->height)*2+30; if (xobj->height < i) xobj->height = i; sprintf(str, "%d", xobj->value2); i = FlocaleTextWidth(xobj->Ffont, str, strlen(str)); sprintf(str, "%d", xobj->value3); j = FlocaleTextWidth(xobj->Ffont, str, strlen(str)); if (i<j) i = j*2+30; else i = i*2+30; xobj->width = i; XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); }
void InitTextField(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i; int num_chars; /* Enregistrement des couleurs et de la police */ /* colors and fonts */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask=0; Attr.cursor=XCreateFontCursor(dpy,XC_xterm); mask|=CWCursor; /* Curseur pour la fenetre / window cursor */ Attr.background_pixel=xobj->TabColor[back]; mask|=CWBackPixel; xobj->win=XCreateWindow(dpy,*xobj->ParentWin, xobj->x,xobj->y,xobj->width,xobj->height,0, CopyFromParent,InputOutput,CopyFromParent, mask,&Attr); xobj->gc=fvwmlib_XCreateGC(dpy,xobj->win,0,NULL); XSetForeground(dpy,xobj->gc,xobj->TabColor[fore]); if ((xobj->Ffont = FlocaleLoadFont( dpy, xobj->font, ScriptName)) == NULL) { fprintf( stderr, "%s: Couldn't load font. Exiting!\n", ScriptName); exit(1); } if (xobj->Ffont->font != NULL) XSetFont(dpy, xobj->gc, xobj->Ffont->font->fid); XSetLineAttributes(dpy,xobj->gc,1,LineSolid,CapRound,JoinMiter); /* value2 représente la fin de la zone selectionnee */ /* value2 gives the end of the selected zone */ /* calculate number of characters in title */ num_chars = FlocaleStringCharLength(xobj->Ffont, xobj->title); if (xobj->value > num_chars) xobj->value = num_chars; xobj->value2=xobj->value; /* left position of the visible title */ xobj->value3=0; /* Redimensionnement du widget */ /* widget resizing */ xobj->height= xobj->Ffont->height + 10; i = FlocaleTextWidth(xobj->Ffont,xobj->title,strlen(xobj->title))+40; if (xobj->width<i) xobj->width=i; XResizeWindow(dpy,xobj->win,xobj->width,xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); }
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]); }
/* * Fonction pour PushButton */ void InitPushButton(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i; char *str; /* Enregistrement des couleurs et de la police */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask = 0; Attr.cursor = XCreateFontCursor(dpy, XC_hand2); mask |= CWCursor; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; /* Epaisseur de la fenetre = 0 */ xobj->win = XCreateWindow( dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy, xobj->win, 0, NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); if ((xobj->Ffont = FlocaleLoadFont( dpy, xobj->font, ScriptName)) == NULL) { fprintf( stderr, "%s: Couldn't load font. Exiting!\n", ScriptName); exit(1); } if (xobj->Ffont->font != NULL) XSetFont(dpy, xobj->gc, xobj->Ffont->font->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); /* Redimensionnement du widget */ str = (char*)GetMenuTitle(xobj->title, 1); if (xobj->icon == NULL) { i = xobj->Ffont->height + 12; if (xobj->height < i) xobj->height = i; i = FlocaleTextWidth(xobj->Ffont, str, strlen(str)) + 16; if (xobj->width < i) xobj->width = i; } else if (strlen(str) == 0) { if (xobj->height < xobj->icon_h + 10) xobj->height = xobj->icon_h + 10; if (xobj->width < xobj->icon_w + 10) xobj->width = xobj->icon_w + 10; } else { if (xobj->icon_w + 10 > FlocaleTextWidth( xobj->Ffont, str, strlen(str)) + 16) i = xobj->icon_w + 10; else i = FlocaleTextWidth( xobj->Ffont, str, strlen(str)) + 16; if (xobj->width < i) xobj->width = i; i = xobj->icon_h+ 2 * (xobj->Ffont->height + 10); if (xobj->height < i) xobj->height = i; } XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); xobj->value3 = CountOption(xobj->title); XSelectInput(dpy, xobj->win, ExposureMask); }
void EvtMousePushButton(struct XObj *xobj, XButtonEvent *EvtButton) { static XEvent event; int End = 1; unsigned int modif; int x1,x2,y1,y2,i; Window Win1,Win2,WinPop; Window WinBut = 0; int In = 0; char *str; int x,y,hOpt,yMenu,hMenu,wMenu; int oldvalue = 0,newvalue; unsigned long mask; XSetWindowAttributes Attr; if (EvtButton->button == Button1) { i = (xobj->width - FlocaleTextWidth( xobj->Ffont, xobj->title, strlen(xobj->title)))/2; while (End) { FNextEvent(dpy, &event); switch (event.type) { case EnterNotify: FQueryPointer( dpy, *xobj->ParentWin, &Win1, &Win2, &x1, &y1, &x2, &y2, &modif); if (WinBut == 0) { WinBut = Win2; DrawReliefRect( 0, 0, xobj->width, xobj->height, xobj, shad, hili); DrawIconStr( 0,xobj, True, PUSH_BUTTON_LCR_OFFSETS, NULL, NULL, NULL); In = 1; } else { if (Win2 == WinBut) { DrawReliefRect( 0, 0, xobj->width, xobj->height, xobj, shad, hili); DrawIconStr( 1, xobj, True, PUSH_BUTTON_LCR_OFFSETS, NULL, NULL, NULL); In = 1; } else if (In) { In = 0; DrawReliefRect( 0, 0, xobj->width, xobj->height, xobj, hili, shad); DrawIconStr( 0, xobj, True, PUSH_BUTTON_LCR_OFFSETS, NULL, NULL, NULL); } } break; case LeaveNotify: FQueryPointer( dpy, *xobj->ParentWin, &Win1, &Win2, &x1, &y1, &x2, &y2, &modif); if (Win2 == WinBut) { In = 1; DrawReliefRect( 0, 0, xobj->width, xobj->height, xobj, shad, hili); DrawIconStr( 1, xobj, True, PUSH_BUTTON_LCR_OFFSETS, NULL, NULL, NULL); } else if (In) { DrawReliefRect( 0, 0, xobj->width, xobj->height, xobj, hili, shad); DrawIconStr( 0, xobj, True, PUSH_BUTTON_LCR_OFFSETS, NULL, NULL, NULL); In = 0; } break; case ButtonRelease: End = 0; DrawReliefRect( 0, 0, xobj->width, xobj->height, xobj, hili, shad); DrawIconStr( 0, xobj, True, PUSH_BUTTON_LCR_OFFSETS, NULL, NULL, NULL); if (In) { /* Envoie d'un message vide de type * SingleClic pour un clique souris */ xobj->value = 1; SendMsg(xobj, SingleClic); xobj->value = 0; } break; } } } /* affichage du popup menu / Drawing the popup menu */ else if (EvtButton->button == Button3) { if (xobj->value3 > 1) { hOpt = xobj->Ffont->height + 10; /* Hauteur totale du menu / Total height of the menu */ hMenu = (xobj->value3 - 1) * hOpt; yMenu = xobj->y + xobj->height; wMenu = 0; for (i = 2 ; i <= xobj->value3; i++) { str = (char*)GetMenuTitle(xobj->title, i); if (wMenu < FlocaleTextWidth( xobj->Ffont, str, strlen(str))+34) wMenu = FlocaleTextWidth( xobj->Ffont, str, strlen(str))+34; free(str); } /* Creation de la fenetre menu / create the menu * window */ XTranslateCoordinates(dpy, *xobj->ParentWin, Root, xobj->x, yMenu, &x, &y, &Win1); if (x<0) x = 0; if (y<0) y = 0; if (x + wMenu > XDisplayWidth(dpy, screen)) { x = XDisplayWidth(dpy, screen) - wMenu; } if (y + hMenu > XDisplayHeight(dpy, screen)) { y = y-hMenu-xobj->height; } mask = 0; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; Attr.border_pixel = 0; mask |= CWBorderPixel; Attr.colormap = Pcmap; mask |= CWColormap; Attr.cursor = XCreateFontCursor(dpy, XC_hand2); mask |= CWCursor; /* Curseur pour la fenetre */ Attr.override_redirect = True; mask |= CWOverrideRedirect; WinPop = XCreateWindow( dpy, Root, x, y, wMenu-5, hMenu, 0, Pdepth, InputOutput, Pvisual, mask, &Attr); if (xobj->colorset >= 0) SetWindowBackground( dpy, WinPop, wMenu - 5, hMenu, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XMapRaised(dpy, WinPop); /* Dessin du menu */ DrawPMenu(xobj, WinPop, hOpt, 1); do { FQueryPointer( dpy, Root, &Win1, &Win2, &x1, &y1, &x2, &y2, &modif); /* Determiner l'option courante / Current * option */ y2 = y2 - y; x2 = x2 - x; { /* calcule de xobj->value / Compute * xobj->value */ if ((x2 > 0) && (x2 < wMenu) && (y2 > 0) && (y2 < hMenu)) newvalue = y2 / hOpt+1; else newvalue = 0; if (newvalue!=oldvalue) { UnselectMenu( xobj, WinPop, hOpt, oldvalue, wMenu-5, xobj->Ffont->ascent, 1); SelectMenu( xobj, WinPop, hOpt, newvalue); oldvalue = newvalue; } } } while (!FCheckTypedEvent(dpy, ButtonRelease, &event)); XDestroyWindow(dpy, WinPop); if (newvalue != 0) { xobj->value = newvalue; SendMsg(xobj, SingleClic); xobj->value = 0; } xobj->DrawObj(xobj, NULL); } /* xobj->value3 > 1 */ } /* EvtButton->button == Button3 */ }
static void __map_window(Display *dpy) { rectangle new_g; rectangle screen_g; Window dummy; fscreen_scr_arg *fsarg = NULL; /* for now no xinerama support */ ftips_placement_t placement; int x,y; static int border_width = 1; static Window win_f = None; if (border_width != current_config->border_width) { XSetWindowBorderWidth(dpy, win, current_config->border_width); border_width = current_config->border_width; } FScreenGetScrRect( fsarg, FSCREEN_GLOBAL, &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); new_g.height = ((current_config->Ffont)? current_config->Ffont->height:0) + 1; new_g.width = 4; if (label && current_config->Ffont) { new_g.width += FlocaleTextWidth( current_config->Ffont, label, strlen(label)); } if (current_config->placement != FTIPS_PLACEMENT_AUTO_UPDOWN && current_config->placement != FTIPS_PLACEMENT_AUTO_LEFTRIGHT) { placement = current_config->placement; } else { XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), box.x, box.y, &x, &y, &dummy); if (current_config->placement == FTIPS_PLACEMENT_AUTO_UPDOWN) { if (y + box.height/2 >= screen_g.height/2) { placement = FTIPS_PLACEMENT_UP; } else { placement = FTIPS_PLACEMENT_DOWN; } } else { if (x + box.width/2 >= screen_g.width/2) { placement = FTIPS_PLACEMENT_LEFT; } else { placement = FTIPS_PLACEMENT_RIGHT; } } } if (placement == FTIPS_PLACEMENT_RIGHT || placement == FTIPS_PLACEMENT_LEFT) { if (current_config->justification == FTIPS_JUSTIFICATION_CENTER) { y = box.y + (box.height / 2) - (new_g.height / 2) - current_config->border_width; } else if (current_config->justification == FTIPS_JUSTIFICATION_RIGHT_DOWN) { y = box.y + box.height - new_g.height - (2 * current_config->border_width) - current_config->justification_offset; } else /* LEFT_UP */ { y = box.y + current_config->justification_offset; } } else /* placement == FTIPS_PLACEMENT_DOWN || placement == FTIPS_PLACEMENT_UP */ { if (current_config->justification == FTIPS_JUSTIFICATION_CENTER) { x = box.x + (box.width / 2) - (new_g.width / 2) - current_config->border_width; } else if (current_config->justification == FTIPS_JUSTIFICATION_RIGHT_DOWN) { x = box.x + box.width - new_g.width - (2 * current_config->border_width) - current_config->justification_offset; } else /* LEFT_UP */ { x = box.x + current_config->justification_offset; } } if (placement == FTIPS_PLACEMENT_RIGHT) { x = box.x + box.width + current_config->placement_offset + 1; } else if (placement == FTIPS_PLACEMENT_LEFT) { x = box.x - current_config->placement_offset - new_g.width - (2 * current_config->border_width) - 1; } else if (placement == FTIPS_PLACEMENT_DOWN) { y = box.y + box.height + current_config->placement_offset - 0; } else /* UP */ { y = box.y - current_config->placement_offset - new_g.height + 0 - (2 * current_config->border_width); } XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &new_g.x, &new_g.y, &dummy); if (placement == FTIPS_PLACEMENT_RIGHT || placement == FTIPS_PLACEMENT_LEFT) { int x1,y1,l1,l2; if (new_g.x < 2) { x = box.x + box.width + current_config->placement_offset + 1; XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &x1, &y1, &dummy); /* */ l1 = new_g.width + new_g.x - 2; l2 = screen_g.width - (x1 + new_g.width) - current_config->border_width - 2; if (l2 > l1) { new_g.x = x1; } } else if (new_g.x + new_g.width > screen_g.width - (2 * current_config->border_width) - 2) { x = box.x - current_config->placement_offset - new_g.width - (2 * current_config->border_width) - 1; XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &x1, &y1, &dummy); /* */ l1 = new_g.width + x1 - 2; l2 = screen_g.width - (new_g.x + new_g.width) - (2 * current_config->border_width) - 2; if (l1 > l2) { new_g.x = x1; } } if ( new_g.y < 2 ) { new_g.y = 2; } else if (new_g.y + new_g.height > screen_g.height - (2 * current_config->border_width) - 2) { new_g.y = screen_g.height - new_g.height - (2 * current_config->border_width) - 2; } } else /* placement == FTIPS_PLACEMENT_DOWN || placement == FTIPS_PLACEMENT_UP */ { if (new_g.y < 2) { y = box.y + box.height + current_config->placement_offset - 0; XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &new_g.x, &new_g.y, &dummy); } else if (new_g.y + new_g.height > screen_g.height - (2 * current_config->border_width) - 2) { y = box.y - current_config->placement_offset - new_g.height + 0 - (2 * current_config->border_width); XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &new_g.x, &new_g.y, &dummy); } if ( new_g.x < 2 ) { new_g.x = 2; } else if (new_g.x + new_g.width > screen_g.width - (2 * current_config->border_width) - 2) { new_g.x = screen_g.width - new_g.width - (2 * current_config->border_width) - 2; } } /* make changes to window */ XMoveResizeWindow( dpy, win, new_g.x, new_g.y, new_g.width, new_g.height); __setup_gc(dpy); if (current_config->colorset > -1) { SetWindowBackground( dpy, win, new_g.width, new_g.height, &Colorset[current_config->colorset], Pdepth, gc, True); } else { XSetWindowBackground (dpy, win, current_config->bg); } if (current_config->border_width > 0) { XSetWindowBorder( dpy, win, Colorset[current_config->colorset].fg); } if (state != FVWM_TIPS_MAPPED && win_f != win_for) { long l_win_for; l_win_for = win_for; XChangeProperty( dpy, win, _net_um_for, XA_WINDOW, 32, PropModeReplace, (unsigned char *) &l_win_for, 1); win_f = win_for; } XMapRaised(dpy, win); state = FVWM_TIPS_MAPPED; return; }
void StartButtonInit(int height) { FvwmPicture *p = NULL; int pw; FvwmPictureAttributes fpa; StartAndLaunchButtonItem *tempPtr; fpa.mask = FPAM_NO_ALLOC_PIXELS; /* if no start button params were specified, trick the program into * thinking that they were */ if (First_Start_Button == NULL && !NoDefaultStartButton) { StartButtonParseConfig("*FvwmTaskBarStartName Start"); StartButtonParseConfig("*FvwmTaskBarStartMenu RootMenu"); StartButtonParseConfig("*FvwmTaskBarStartIcon mini.start.xpm"); } /* some defaults */ if (First_Start_Button && First_Start_Button->isStartButton == True) { if (First_Start_Button->buttonCaption == NULL) UpdateString(&(First_Start_Button->buttonCaption), "Start"); if (First_Start_Button->buttonIconFileName == NULL) UpdateString(&(First_Start_Button->buttonIconFileName), "mini-start.xpm"); } tempPtr = First_Start_Button; while(tempPtr != NULL) { p = PGetFvwmPicture( dpy, win, ImagePath, tempPtr->buttonIconFileName, fpa); if (p != NULL && strlen(tempPtr->buttonCaption) != 0) { /* icon and title */ pw = p->width + 12; } else if (p != NULL) { /* just icon */ pw = p->width + 8; } else { /* just title */ pw = 10; } tempPtr->buttonItem = (Button *)ButtonNew( tempPtr->buttonCaption, p, BUTTON_UP,0); if (tempPtr->isStartButton) { StartButton = tempPtr->buttonItem; tempPtr->width = FlocaleTextWidth( FSelButtonFont, tempPtr->buttonCaption, strlen(tempPtr->buttonCaption)) + pw; } else { tempPtr->width = FlocaleTextWidth( FButtonFont, tempPtr->buttonCaption, strlen(tempPtr->buttonCaption)) + pw; } tempPtr->height = height; StartAndLaunchButtonsWidth += tempPtr->width; tempPtr=tempPtr->tail; PFreeFvwmPictureData(p); /* should not destroy of course */ } if (First_Start_Button) { StartAndLaunchButtonsWidth += StartButtonRightMargin; First_Start_Button->height = height; StartAndLaunchButtonsHeight = First_Start_Button->height; } else { StartAndLaunchButtonsWidth = 0; StartButtonRightMargin = 0; if (has_wb_left_margin == 0) { WindowButtonsLeftMargin = 0; } if (has_wb_right_margin == 0) { WindowButtonsRightMargin = 0; } } }
/* 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 EvtMouseTextField(struct XObj *xobj,XButtonEvent *EvtButton) { unsigned int modif; int x1,x2,y1,y2,i; Window Win1,Win2; int PosCurs=0; int SizeBuf; char *str; int NewPos; Atom type; XEvent event; int ButPress=1; int format; unsigned long longueur,octets_restant; unsigned char *donnees=(unsigned char *)""; XRectangle rect; int start_pos, selection_pos, curs_pos; /* On deplace le curseur a la position de la souris */ /* On recupere la position de la souris */ /* We move the cursor at mouse position and we get the mouse position */ switch (EvtButton->button) { case Button1: FQueryPointer( dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2, &modif); x2=x2-xobj->x; /* see where we clicked */ PosCurs=0; /* byte position of first visible character */ start_pos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title, xobj->value3); /* cursor offset in bytes */ curs_pos = 0; while ((curs_pos < strlen(xobj->title + start_pos)) && (x2 > FlocaleTextWidth( xobj->Ffont,xobj->title + start_pos, curs_pos) + 8)) { curs_pos += FlocaleStringNumberOfBytes( xobj->Ffont, xobj->title + start_pos + curs_pos); PosCurs++; } DrawPointTxt(xobj,xobj->TabColor[back]); /* set selection start and end where clicked */ /* first visible char + position clicked */ xobj->value = PosCurs + xobj->value3; xobj->value2 = PosCurs + xobj->value3; /* byte offset corresponding to the above */ start_pos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title, xobj->value3); selection_pos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title, xobj->value3); DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj,NULL); while (ButPress) { FNextEvent(dpy, &event); switch (event.type) { case MotionNotify: FQueryPointer( dpy,*xobj->ParentWin,&Win1,&Win2,&x1, &y1,&x2,&y2,&modif); x2=x2-xobj->x; PosCurs=0; curs_pos = 0; /* determine how far in the mouse is now */ while ((curs_pos < strlen( xobj->title + start_pos)) && (x2 > FlocaleTextWidth( xobj->Ffont,xobj->title+ start_pos, curs_pos) + 8)) { curs_pos += FlocaleStringNumberOfBytes( xobj->Ffont, xobj->title + start_pos + curs_pos); PosCurs++; } /* Limitation de la zone de dessin */ /* limitation of the drawing zone */ /* these 2 if-statements updates current cursor position of the widget if needed */ if (PosCurs > (xobj->value2 - xobj->value3)) { /* select made "forward" */ rect.x= FlocaleTextWidth( xobj->Ffont, xobj->title+ start_pos, selection_pos - start_pos); rect.y=0; rect.width= FlocaleTextWidth( xobj->Ffont, xobj->title+ start_pos, curs_pos) -rect.x+1; rect.height=xobj->height; xobj->value2 = PosCurs + xobj->value3; DrawTextField(xobj,NULL); } else if (PosCurs < (xobj->value2 - xobj->value3)) { /* selection made "backwards" */ rect.x=FlocaleTextWidth( xobj->Ffont, xobj->title+ start_pos, curs_pos) - 1; rect.y=0; rect.width=FlocaleTextWidth( xobj->Ffont, xobj->title+ start_pos, selection_pos - start_pos) - rect.x+2; rect.height=xobj->height; xobj->value2= PosCurs + xobj->value3; DrawTextField(xobj,NULL); } break; case ButtonRelease: ButPress=0; break; } } /* Enregistrement de la selection dans le presse papier */ /* Le programme devient proprietaire de la selection */ /* selection stuff: get the selection */ if (xobj->value != xobj->value2) { str=(char*)GetText(xobj, xobj->value2); for (i=0;i<=7;i++) XStoreBuffer(dpy,str,strlen(str),i); Scrapt = (char*)realloc( (void*)Scrapt, (strlen(str)+2)*sizeof(char)); Scrapt = strcpy(Scrapt,str); free(str); x11base->HaveXSelection=True; XSetSelectionOwner( dpy,XA_PRIMARY,x11base->win,EvtButton->time); SelectOneTextField(xobj); } break; case Button2: /* Colle le texte */ /* Si l'application possede pas la selection, elle la demande */ /* sinon elle lit son presse papier */ /* read the selection */ if (!x11base->HaveXSelection) { /* Demande de la selection */ /* ask for the selection */ XConvertSelection( dpy,XA_PRIMARY,XA_STRING,propriete, *xobj->ParentWin, EvtButton->time); while (!(FCheckTypedEvent(dpy,SelectionNotify,&event))) ; if (event.xselection.property!=None) if (event.xselection.selection==XA_PRIMARY) { XGetWindowProperty( dpy,event.xselection.requestor, event.xselection.property,0L, 8192L,False, event.xselection.target,&type, &format, &longueur, &octets_restant,&donnees); if (longueur>0) { Scrapt=(char*)realloc( (void*)Scrapt, (longueur+1)* sizeof(char)); Scrapt=strcpy( Scrapt,(char *)donnees); XDeleteProperty( dpy, event.xselection. requestor, event.xselection. property); XFree(donnees); } } } SizeBuf=strlen(Scrapt); if (SizeBuf>0) { NewPos=InsertText(xobj,Scrapt,SizeBuf); DrawPointTxt(xobj,xobj->TabColor[back]); xobj->value=NewPos; xobj->value2=NewPos; DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj,NULL); SendMsg(xobj,SingleClic); } break; case Button3: /* Appuie sur le troisieme bouton */ FQueryPointer( dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2, &modif); x2=x2-xobj->x; PosCurs=0; while ((PosCurs<strlen(xobj->title))&& (x2>FlocaleTextWidth( xobj->Ffont,xobj->title+xobj->value3, PosCurs)+8)) PosCurs++; if ((PosCurs<xobj->value) && (xobj->value<xobj->value2)) xobj->value=xobj->value2; if ((PosCurs>xobj->value) && (xobj->value>xobj->value2)) xobj->value=xobj->value2; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj,NULL); while (ButPress) { FNextEvent(dpy, &event); switch (event.type) { case MotionNotify: FQueryPointer( dpy,*xobj->ParentWin,&Win1,&Win2,&x1, &y1,&x2,&y2,&modif); x2=x2-xobj->x; while ((PosCurs<strlen(xobj->title))&& (x2 > FlocaleTextWidth( xobj->Ffont, xobj->title+xobj->value3, PosCurs)+8)) PosCurs++; if (PosCurs>xobj->value2) { rect.x= FlocaleTextWidth( xobj->Ffont, xobj->title+ xobj->value3, xobj->value2); rect.y=0; rect.width= FlocaleTextWidth( xobj->Ffont, xobj->title+ xobj->value3,PosCurs+1) -rect.x+1; rect.height=xobj->height; xobj->value2=PosCurs; DrawTextField(xobj,NULL); } else if (PosCurs<xobj->value2) { rect.x=FlocaleTextWidth( xobj->Ffont, xobj->title+ xobj->value3, PosCurs)-1; rect.y=0; rect.width=FlocaleTextWidth( xobj->Ffont, xobj->title+xobj-> value3, xobj->value2+1)- rect.x+2; rect.height=xobj->height; xobj->value2= PosCurs+xobj->value3; DrawTextField(xobj,NULL); } PosCurs=0; break; case ButtonRelease: ButPress=0; break; } } if (xobj->value!=xobj->value2) { str=(char*)GetText(xobj,xobj->value2); for (i=0;i<=7;i++) XStoreBuffer(dpy,str,strlen(str),i); Scrapt=(char*)realloc( (void*)Scrapt,(strlen(str)+2)*sizeof(char)); Scrapt=strcpy(Scrapt,str); free(str); x11base->HaveXSelection=True; XSetSelectionOwner( dpy,XA_PRIMARY,x11base->win,EvtButton->time); } break; } }