Example #1
0
File: FTips.c Project: fvwmorg/fvwm
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;
}
Example #2
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 */
}
Example #3
0
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));
	}
Example #4
0
/*
 *
 *  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;
}
Example #5
0
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]);
}