Exemplo n.º 1
0
/** Draw a specific tray. */
void DrawSpecificTray(const TrayType *tp)
{

   TrayComponentType *cp;

   for(cp = tp->components; cp; cp = cp->next) {
      UpdateSpecificTray(tp, cp);
   }

   if(settings.trayDecorations == DECO_MOTIF) {
      JXSetForeground(display, rootGC, colors[COLOR_TRAY_UP]);
      JXDrawLine(display, tp->window, rootGC, 0, 0, tp->width - 1, 0);
      JXDrawLine(display, tp->window, rootGC, 0, tp->height - 1, 0, 0);

      JXSetForeground(display, rootGC, colors[COLOR_TRAY_DOWN]);
      JXDrawLine(display, tp->window, rootGC, 0, tp->height - 1,
                 tp->width - 1, tp->height - 1);
      JXDrawLine(display, tp->window, rootGC, tp->width - 1, 0,
                 tp->width - 1, tp->height - 1);
   } else {
      JXSetForeground(display, rootGC, colors[COLOR_TRAY_DOWN]);
      JXDrawRectangle(display, tp->window, rootGC, 0, 0,
                      tp->width - 1, tp->height - 1);
   }

}
Exemplo n.º 2
0
/** Render the dialog to the pixmap. */
void DrawDialog(void)
{

    int yoffset;
    int x;

    Assert(dialog);

    /* Clear the dialog. */
    JXSetForeground(display, rootGC, colors[COLOR_MENU_BG]);
    JXFillRectangle(display, dialog->pmap, rootGC, 0, 0,
                    dialog->width, dialog->height);

    /* Draw the message. */
    yoffset = 4;
    for(x = 0; x < dialog->lineCount; x++) {
        RenderString(dialog->pmap, FONT_MENU, COLOR_MENU_FG,
                     4, yoffset, dialog->width, dialog->message[x]);
        yoffset += dialog->lineHeight;
    }

    /* Draw the buttons. */
    DrawButtons();

}
Exemplo n.º 3
0
/** Draw a specific tray. */
void DrawSpecificTray(const TrayType *tp) {

   TrayComponentType *cp;
   int x;

   Assert(tp);

   /* Draw components. */
   for(cp = tp->components; cp; cp = cp->next) {
      UpdateSpecificTray(tp, cp);
   }

   /* Draw the border. */
   for(x = 0; x < tp->border; x++) {

      /* Top */
      JXSetForeground(display, rootGC, colors[COLOR_TRAY_UP]);
      JXDrawLine(display, tp->window, rootGC,
         0, x,
         tp->width - x - 1, x);

      /* Bottom */
      JXSetForeground(display, rootGC, colors[COLOR_TRAY_DOWN]);
      JXDrawLine(display, tp->window, rootGC,
         x + 1, tp->height - x - 1,
         tp->width - x - 2, tp->height - x - 1);

      /* Left */
      JXSetForeground(display, rootGC, colors[COLOR_TRAY_UP]);
      JXDrawLine(display, tp->window, rootGC,
         x, x,
         x, tp->height - x - 1);

      /* Right */
      JXSetForeground(display, rootGC, colors[COLOR_TRAY_DOWN]);
      JXDrawLine(display, tp->window, rootGC, 
         tp->width - x - 1, x + 1,
         tp->width - x - 1, tp->height - x - 1);

   }

}
Exemplo n.º 4
0
Arquivo: tray.c Projeto: Nehamkin/jwm
/** Draw the tray background on a drawable. */
void ClearTrayDrawable(const TrayComponentType *cp)
{
   const Drawable d = cp->pixmap != None ? cp->pixmap : cp->window;
   if(colors[COLOR_TRAY_BG1] == colors[COLOR_TRAY_BG2]) {
      JXSetForeground(display, rootGC, colors[COLOR_TRAY_BG1]);
      JXFillRectangle(display, d, rootGC, 0, 0, cp->width, cp->height);
   } else {
      DrawHorizontalGradient(d, rootGC, colors[COLOR_TRAY_BG1],
                             colors[COLOR_TRAY_BG2], 0, 0,
                             cp->width, cp->height);
   }
}
Exemplo n.º 5
0
/** Draw a clock tray component. */
void DrawClock(ClockType *clk, const TimeType *now)
{

   TrayComponentType *cp;
   const char *timeString;
   int width;
   int rwidth;

   /* Only draw if the time changed. */
   if(now->seconds == clk->lastTime.seconds) {
      return;
   }

   /* Clear the area. */
   cp = clk->cp;
   if(colors[COLOR_CLOCK_BG1] == colors[COLOR_CLOCK_BG2]) {
      JXSetForeground(display, rootGC, colors[COLOR_CLOCK_BG1]);
      JXFillRectangle(display, cp->pixmap, rootGC, 0, 0,
                      cp->width, cp->height);
   } else {
      DrawHorizontalGradient(cp->pixmap, rootGC,
                             colors[COLOR_CLOCK_BG1], colors[COLOR_CLOCK_BG2],
                             0, 0, cp->width, cp->height);
   }

   /* Determine if the clock is the right size. */
   timeString = GetTimeString(clk->format, clk->zone);
   width = GetStringWidth(FONT_CLOCK, timeString);
   rwidth = width + 4;
   if(rwidth == clk->cp->requestedWidth || clk->userWidth) {

      /* Draw the clock. */
      RenderString(cp->pixmap, FONT_CLOCK, COLOR_CLOCK_FG,
                   (cp->width - width) / 2,
                   (cp->height - GetStringHeight(FONT_CLOCK)) / 2,
                   cp->width, timeString);

      UpdateSpecificTray(clk->cp->tray, clk->cp);

   } else {

      /* Wrong size. Resize. */
      clk->cp->requestedWidth = rwidth;
      ResizeTray(clk->cp->tray);

   }

}
Exemplo n.º 6
0
/** Load a gradient background. */
void LoadGradientBackground(BackgroundNode *bp) {

   XColor color1;
   XColor color2;
   char *temp;
   char *sep;
   int len;

   sep = strchr(bp->value, ':');
   if(!sep) {
      bp->pixmap = None;
      bp->window = None;
      return;
   }

   /* Get the first color. */
   len = (int)(sep - bp->value);
   temp = AllocateStack(len + 1);
   memcpy(temp, bp->value, len);
   temp[len] = 0;
   ParseColor(temp, &color1);
   ReleaseStack(temp);

   /* Get the second color. */
   len = strlen(sep + 1);
   temp = AllocateStack(len + 1);
   memcpy(temp, sep + 1, len);
   temp[len] = 0;
   ParseColor(temp, &color2);
   ReleaseStack(temp);

   /* Create the window. */
   bp->window = JXCreateSimpleWindow(display, rootWindow, 0, 0,
                                     rootWidth, rootHeight, 0, 0, 0);

   bp->pixmap = JXCreatePixmap(display, bp->window,
                               rootWidth, rootHeight, rootDepth);

   if(color1.pixel == color2.pixel) {
      JXSetForeground(display, rootGC, color1.pixel);
      JXFillRectangle(display, bp->pixmap, rootGC,
                      0, 0, rootWidth, rootHeight);
   } else {
      DrawHorizontalGradient(bp->pixmap, rootGC,
         color1.pixel, color2.pixel, 0, 0, rootWidth, rootHeight);
   }

}
Exemplo n.º 7
0
/** Load an image background. */
void LoadImageBackground(BackgroundNode *bp) {

   IconNode *ip;
   int width, height;

   /* Load the icon. */
   ExpandPath(&bp->value);
   ip = LoadNamedIcon(bp->value);
   if(JUNLIKELY(!ip)) {
      bp->pixmap = None;
      bp->window = None;
      Warning(_("background image not found: \"%s\""), bp->value);
      return;
   }

   /* We can't use render on these. */
   ip->useRender = 0;

   /* Determine the size of the background pixmap. */
   if(bp->type == BACKGROUND_TILE) {
      width = ip->image->width;
      height = ip->image->height;
   } else {
      width = rootWidth;
      height = rootHeight;
   }

   /* Create the window. */
   bp->window = JXCreateSimpleWindow(display, rootWindow, 0, 0,
                                     rootWidth, rootHeight, 0, 0, 0);

   /* Create the pixmap. */
   bp->pixmap = JXCreatePixmap(display, bp->window,
                               width, height, rootDepth);

   /* Clear the pixmap in case it is too small. */
   JXSetForeground(display, rootGC, 0);
   JXFillRectangle(display, bp->pixmap, rootGC, 0, 0, width, height);

   /* Draw the icon on the background pixmap. */
   PutIcon(ip, bp->pixmap, 0, 0, width, height);

   /* We don't need the icon anymore. */
   DestroyIcon(ip);

}
Exemplo n.º 8
0
/** Load a solid background. */
void LoadSolidBackground(BackgroundNode *bp) {

   XColor c;

   ParseColor(bp->value, &c);

   /* Create the window. */
   bp->window = JXCreateSimpleWindow(display, rootWindow, 0, 0,
                                     rootWidth, rootHeight, 0, 0, 0);

   /* Create the pixmap. */
   bp->pixmap = JXCreatePixmap(display, bp->window, 1, 1, rootDepth);

   JXSetForeground(display, rootGC, c.pixel);
   JXDrawPoint(display, bp->pixmap, rootGC, 0, 0);

}
Exemplo n.º 9
0
/** Draw a horizontal gradient. */
void DrawHorizontalGradient(Drawable d, GC g,
                            long fromColor, long toColor,
                            int x, int y,
                            unsigned int width, unsigned int height)
{

   const int shift = 15;
   unsigned int line;
   XColor colors[2];
   int red, green, blue;
   int ared, agreen, ablue;
   int bred, bgreen, bblue;
   int redStep, greenStep, blueStep;

   /* Return if there's nothing to do. */
   if(width == 0 || height == 0) {
      return;
   }

   /* Here we assume that the background was filled elsewhere. */
   if(fromColor == toColor) {
      return;
   }

   /* Query the from/to colors. */
   colors[0].pixel = fromColor;
   colors[1].pixel = toColor;
   JXQueryColors(display, rootColormap, colors, 2);

   /* Set the "from" color. */
   ared = (unsigned int)colors[0].red << shift;
   agreen = (unsigned int)colors[0].green << shift;
   ablue = (unsigned int)colors[0].blue << shift;

   /* Set the "to" color. */
   bred = (unsigned int)colors[1].red << shift;
   bgreen = (unsigned int)colors[1].green << shift;
   bblue = (unsigned int)colors[1].blue << shift;

   /* Determine the step. */
   redStep = (bred - ared) / (int)height;
   greenStep = (bgreen - agreen) / (int)height;
   blueStep = (bblue - ablue) / (int)height;

   /* Loop over each line. */
   red = ared;
   blue = ablue;
   green = agreen;
   for(line = 0; line < height; line++) {

      /* Determine the color for this line. */
      colors[0].red = (unsigned short)(red >> shift);
      colors[0].green = (unsigned short)(green >> shift);
      colors[0].blue = (unsigned short)(blue >> shift);

      GetColor(&colors[0]);

      /* Draw the line. */
      JXSetForeground(display, g, colors[0].pixel);
      JXDrawLine(display, d, g, x, y + line, x + width - 1, y + line);

      red += redStep;
      green += greenStep;
      blue += blueStep;

   }
}
Exemplo n.º 10
0
/** Draw a button. */
void DrawButton(ButtonNode *bp)
{

   ColorType fg;
   long bg1, bg2;
   long up, down;
   DecorationsType decorations;

   Drawable drawable;
   GC gc;
   int x, y;
   int width, height;
   int xoffset, yoffset;

   int iconWidth, iconHeight;
   int textWidth, textHeight;
   
   Assert(bp);

   drawable = bp->drawable;
   x = bp->x;
   y = bp->y;
   width = bp->width;
   height = bp->height;
   gc = JXCreateGC(display, drawable, 0, NULL);

   /* Determine the colors to use. */
   switch(bp->type) {
   case BUTTON_LABEL:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      up = colors[COLOR_MENU_UP];
      down = colors[COLOR_MENU_DOWN];
      decorations = settings.menuDecorations;
      break;
   case BUTTON_MENU_ACTIVE:
      fg = COLOR_MENU_ACTIVE_FG;
      bg1 = colors[COLOR_MENU_ACTIVE_BG1];
      bg2 = colors[COLOR_MENU_ACTIVE_BG2];
      down = colors[COLOR_MENU_ACTIVE_UP];
      up = colors[COLOR_MENU_ACTIVE_DOWN];
      decorations = settings.menuDecorations;
      break;
   case BUTTON_TRAY:
      fg = COLOR_TRAYBUTTON_FG;
      bg1 = colors[COLOR_TRAYBUTTON_BG1];
      bg2 = colors[COLOR_TRAYBUTTON_BG2];
      up = colors[COLOR_TRAYBUTTON_UP];
      down = colors[COLOR_TRAYBUTTON_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_TRAY_ACTIVE:
      fg = COLOR_TRAYBUTTON_ACTIVE_FG;
      bg1 = colors[COLOR_TRAYBUTTON_ACTIVE_BG1];
      bg2 = colors[COLOR_TRAYBUTTON_ACTIVE_BG2];
      down = colors[COLOR_TRAYBUTTON_ACTIVE_UP];
      up = colors[COLOR_TRAYBUTTON_ACTIVE_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_TASK:
      fg = COLOR_TASKLIST_FG;
      bg1 = colors[COLOR_TASKLIST_BG1];
      bg2 = colors[COLOR_TASKLIST_BG2];
      up = colors[COLOR_TASKLIST_UP];
      down = colors[COLOR_TASKLIST_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_TASK_ACTIVE:
      fg = COLOR_TASKLIST_ACTIVE_FG;
      bg1 = colors[COLOR_TASKLIST_ACTIVE_BG1];
      bg2 = colors[COLOR_TASKLIST_ACTIVE_BG2];
      down = colors[COLOR_TASKLIST_ACTIVE_UP];
      up = colors[COLOR_TASKLIST_ACTIVE_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_MENU:
   default:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      up = colors[COLOR_MENU_UP];
      down = colors[COLOR_MENU_DOWN];
      decorations = settings.menuDecorations;
      break;
   }

   /* Draw the background. */
   if(bp->fill) {

      /* Draw the button background. */
      JXSetForeground(display, gc, bg1);
      if(bg1 == bg2) {
         /* single color */
         JXFillRectangle(display, drawable, gc, x, y, width, height);
      } else {
         /* gradient */
         DrawHorizontalGradient(drawable, gc, bg1, bg2,
                                x, y, width, height);
      }

   }

   /* Draw the border. */
   if(bp->border) {
      if(decorations == DECO_MOTIF) {
         JXSetForeground(display, gc, up);
         JXDrawLine(display, drawable, gc, x, y, x + width - 1, y);
         JXDrawLine(display, drawable, gc, x, y, x, y + height - 1);
         JXSetForeground(display, gc, down);
         JXDrawLine(display, drawable, gc, x, y + height - 1,
                    x + width - 1, y + height - 1);
         JXDrawLine(display, drawable, gc, x + width - 1, y,
                    x + width - 1, y + height - 1);
      } else {
         JXSetForeground(display, gc, down);
         JXDrawRectangle(display, drawable, gc, x, y, width - 1, height - 1);
      }
   }

   /* Determine the size of the icon (if any) to display. */
   iconWidth = 0;
   iconHeight = 0;
   if(bp->icon) {
      if(bp->icon == &emptyIcon) {
         iconWidth = Min(width - 4, height - 4);
         iconHeight = iconWidth;
      } else {
         const int ratio = (bp->icon->width << 16) / bp->icon->height;
         iconHeight = height - 4;
         iconWidth = (iconHeight * ratio) >> 16;
         if(iconWidth > width - 4) {
            iconWidth = width - 4;
            iconHeight = (iconWidth << 16) / ratio;
         }
      }
   }

   /* Determine how much room is left for text. */
   textWidth = 0;
   textHeight = 0;
   if(bp->text && (width > height || !bp->icon)) {
      textWidth = GetStringWidth(bp->font, bp->text);
      textHeight = GetStringHeight(bp->font);
      if(iconWidth > 0 && textWidth + iconWidth + 7 > width) {
         textWidth = width - iconWidth - 7;
      } else if(iconWidth == 0 && textWidth + 5 > width) {
         textWidth = width - 5;
      }
      textWidth = textWidth < 0 ? 0 : textWidth;
   }

   /* Determine the offset of the text in the button. */
   if(bp->alignment == ALIGN_CENTER || width <= height) {
      xoffset = (width - iconWidth - textWidth + 1) / 2;
      if(xoffset < 0) {
         xoffset = 0;
      }
   } else {
      xoffset = 2;
   }

   /* Display the icon. */
   if(bp->icon) {
      yoffset = (height - iconHeight + 1) / 2;
      PutIcon(bp->icon, drawable, colors[fg],
              x + xoffset, y + yoffset,
              iconWidth, iconHeight);
      xoffset += iconWidth + 2;
   }

   /* Display the label. */
   if(textWidth > 0) {
      yoffset = (height - textHeight + 1) / 2;
      RenderString(drawable, bp->font, fg,
                   x + xoffset, y + yoffset,
                   textWidth, bp->text);
   }

   JXFreeGC(display, gc);

}
Exemplo n.º 11
0
/** Draw a button. */
void DrawButton(ButtonNode *bp) {

   long outlinePixel;
   long topPixel, bottomPixel;
   ColorType fg;
   long bg1, bg2;

   Drawable drawable;
   GC gc;
   int x, y;
   int width, height;
   int xoffset, yoffset;

   int iconWidth, iconHeight;
   int textWidth, textHeight;
   
   Assert(bp);

   drawable = bp->drawable;
   gc = bp->gc;
   x = bp->x;
   y = bp->y;
   width = bp->width;
   height = bp->height;

   /* Determine the colors to use. */
   switch(bp->type) {
   case BUTTON_LABEL:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      outlinePixel = colors[COLOR_MENU_BG];
      topPixel = colors[COLOR_MENU_BG];
      bottomPixel = colors[COLOR_MENU_BG];
      break;
   case BUTTON_MENU_ACTIVE:
      fg = COLOR_MENU_ACTIVE_FG;
      bg1 = colors[COLOR_MENU_ACTIVE_BG1];
      bg2 = colors[COLOR_MENU_ACTIVE_BG2];
      if(bg1 == bg2) {
         outlinePixel = colors[COLOR_MENU_ACTIVE_OL];
      } else {
         outlinePixel = colors[COLOR_MENU_ACTIVE_DOWN];
      }
      topPixel = colors[COLOR_MENU_ACTIVE_UP];
      bottomPixel = colors[COLOR_MENU_ACTIVE_DOWN];
      break;
   case BUTTON_TASK:
      fg = COLOR_TASK_FG;
      bg1 = colors[COLOR_TASK_BG1];
      bg2 = colors[COLOR_TASK_BG2];
      topPixel = colors[COLOR_TASK_UP];
      bottomPixel = colors[COLOR_TASK_DOWN];
      outlinePixel = bottomPixel;
      break;
   case BUTTON_TASK_ACTIVE:
      fg = COLOR_TASK_ACTIVE_FG;
      bg1 = colors[COLOR_TASK_ACTIVE_BG1];
      bg2 = colors[COLOR_TASK_ACTIVE_BG2];
      topPixel = colors[COLOR_TASK_ACTIVE_DOWN];
      bottomPixel = colors[COLOR_TASK_ACTIVE_UP];
      outlinePixel = bottomPixel;
      break;
   case BUTTON_MENU:
   default:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      outlinePixel = colors[COLOR_MENU_DOWN];
      topPixel = colors[COLOR_MENU_UP];
      bottomPixel = colors[COLOR_MENU_DOWN];
      break;
   }

   /* Draw the background. */
   switch(bp->type) {
   case BUTTON_TASK:
      /* Flat taskbuttons (only icon) for widths < 48 */
      if(width < 48) {
         break;
      }
      /* conditional fallthrough is intended */  
   default:

      /* Draw the button background. */
      JXSetForeground(display, gc, bg1);
      if(bg1 == bg2) {
         /* single color */
         JXFillRectangle(display, drawable, gc,
            x + 1, y + 1, width - 1, height - 1);
      } else {
         /* gradient */
         DrawHorizontalGradient(drawable, gc, bg1, bg2,
            x + 1, y + 1, width - 2, height - 1);
      }

      /* Draw the outline. */
      JXSetForeground(display, gc, outlinePixel);
#ifdef USE_XMU
      XmuDrawRoundedRectangle(display, drawable, gc, x, y, 
         width, height, 3, 3);
#else
      JXDrawRectangle(display, drawable, gc, x, y, width, height);
#endif

      break;
   }

   /* Determine the size of the icon (if any) to display. */
   iconWidth = 0;
   iconHeight = 0;
   if (bp->icon) {
      if(width < height) {
         GetScaledIconSize(bp->icon, width - 5, &iconWidth, &iconHeight);
      } else {
         GetScaledIconSize(bp->icon, height - 5, &iconWidth, &iconHeight);
      }
   }

   /* Determine how much room is left for text. */
   textWidth = 0;
   textHeight = 0;
   if(bp->text) {
      textWidth = GetStringWidth(bp->font, bp->text);
      textHeight = GetStringHeight(bp->font);
      if(textWidth + iconWidth + 8 > width) {
         textWidth = width - iconWidth - 8;
         if(textWidth < 0) {
            textWidth = 0;
         }
      }
   }

   /* Determine the offset of the text in the button. */
   switch(bp->alignment) {
   case ALIGN_CENTER:
      xoffset = width / 2 - (iconWidth + textWidth) / 2;
      if(xoffset < 0) {
         xoffset = 0;
      }
      break;
   case ALIGN_LEFT:
   default:
      xoffset = 3;
      break;
   }

   /* Display the icon. */
   if(bp->icon) {
      yoffset = height / 2 - iconHeight / 2;
      PutIcon(bp->icon, drawable, x + xoffset, y + yoffset,
         iconWidth, iconHeight);
      xoffset += iconWidth + 2;
   }

   /* Display the label. */
   if(bp->text && textWidth) {
      yoffset = height / 2 - textHeight / 2;
      RenderString(drawable, bp->font, fg, x + xoffset, y + yoffset,
         textWidth, NULL, bp->text);
   }

}
Exemplo n.º 12
0
/** Display a string. */
void RenderString(Drawable d, FontType font, ColorType color,
                  int x, int y, int width, const char *str)
{

#ifdef USE_ICONV
   static char isUTF8 = -1;
#endif
   XRectangle rect;
   Region renderRegion;
   int len;
   char *output;
#ifdef USE_FRIBIDI
   FriBidiChar *temp_i;
   FriBidiChar *temp_o;
   FriBidiParType type = FRIBIDI_PAR_ON;
   int unicodeLength;
#endif
#ifdef USE_XFT
   XGlyphInfo extents;
#endif
   char *utf8String;

   /* Early return for empty strings. */
   if(!str || !str[0]) {
      return;
   }

   /* Convert to UTF-8 if necessary. */
   utf8String = GetUTF8String(str);

   /* Get the length of the UTF-8 string. */
   len = strlen(utf8String);

   /* Apply the bidi algorithm if requested. */
#ifdef USE_FRIBIDI
   temp_i = AllocateStack((len + 1) * sizeof(FriBidiChar));
   temp_o = AllocateStack((len + 1) * sizeof(FriBidiChar));
   unicodeLength = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
                                              utf8String, len, temp_i);
   fribidi_log2vis(temp_i, unicodeLength, &type, temp_o, NULL, NULL, NULL);
   output = AllocateStack(4 * len + 1);
   fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, temp_o, unicodeLength,
                              (char*)output);
   len = strlen(output);
#else
   output = utf8String;
#endif

   /* Get the bounds for the string based on the specified width. */
   rect.x = x;
   rect.y = y;
   rect.height = GetStringHeight(font);
#ifdef USE_XFT
   JXftTextExtentsUtf8(display, fonts[font], (const unsigned char*)output,
                       len, &extents);
   rect.width = extents.xOff;
#else
   rect.width = XTextWidth(fonts[font], output, len);
#endif
   rect.width = Min(rect.width, width) + 2;

   /* Combine the width bounds with the region to use. */
   renderRegion = XCreateRegion();
   XUnionRectWithRegion(&rect, renderRegion, renderRegion);

   /* Display the string. */
#ifdef USE_XFT
   JXftDrawChange(xd, d);
   JXftDrawSetClip(xd, renderRegion);
   JXftDrawStringUtf8(xd, GetXftColor(color), fonts[font],
                      x, y + fonts[font]->ascent,
                      (const unsigned char*)output, len);
   JXftDrawChange(xd, rootWindow);
#else
   JXSetForeground(display, fontGC, colors[color]);
   JXSetRegion(display, fontGC, renderRegion);
   JXSetFont(display, fontGC, fonts[font]->fid);
   JXDrawString(display, d, fontGC, x, y + fonts[font]->ascent, output, len);
#endif

   /* Free any memory used for UTF conversion. */
#ifdef USE_FRIBIDI
   ReleaseStack(temp_i);
   ReleaseStack(temp_o);
   ReleaseStack(output);
#endif
   ReleaseUTF8String(utf8String);

   XDestroyRegion(renderRegion);

}
Exemplo n.º 13
0
/** Draw a button. */
void DrawButton(ButtonNode *bp)
{

   ColorType fg;
   long bg1, bg2;
   long up, down;
   DecorationsType decorations;

   Drawable drawable;
   GC gc;
   int x, y;
   int width, height;
   int xoffset, yoffset;

   int iconWidth, iconHeight;
   int textWidth, textHeight;
   
   Assert(bp);

   char *printableName = bp->text;

   /* Check for E2 80 AA (LEFT-TO-RIGHT-EMBEDDING) character
      in the beginning and trim it (for Midori) */
   if(strncmp(printableName, "\xe2\x80\xaa", 3) == 0) {
     printableName += 3;
   }

   drawable = bp->drawable;
   x = bp->x;
   y = bp->y;
   width = bp->width;
   height = bp->height;
   gc = JXCreateGC(display, drawable, 0, NULL);

   /* Determine the colors to use. */
   switch(bp->type) {
   case BUTTON_LABEL:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      up = colors[COLOR_MENU_UP];
      down = colors[COLOR_MENU_DOWN];
      decorations = settings.menuDecorations;
      break;
   case BUTTON_MENU_ACTIVE:
      fg = COLOR_MENU_ACTIVE_FG;
      bg1 = colors[COLOR_MENU_ACTIVE_BG1];
      bg2 = colors[COLOR_MENU_ACTIVE_BG2];
      down = colors[COLOR_MENU_ACTIVE_UP];
      up = colors[COLOR_MENU_ACTIVE_DOWN];
      decorations = settings.menuDecorations;
      break;
   case BUTTON_TRAY:
   case BUTTON_TASK:
      fg = COLOR_TRAY_FG;
      bg1 = colors[COLOR_TRAY_BG1];
      bg2 = colors[COLOR_TRAY_BG2];
      up = colors[COLOR_TRAY_UP];
      down = colors[COLOR_TRAY_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_TRAY_ACTIVE:
   case BUTTON_TASK_ACTIVE:
      fg = COLOR_TRAY_ACTIVE_FG;
      bg1 = colors[COLOR_TRAY_ACTIVE_BG1];
      bg2 = colors[COLOR_TRAY_ACTIVE_BG2];
      down = colors[COLOR_TRAY_ACTIVE_UP];
      up = colors[COLOR_TRAY_ACTIVE_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_MENU:
   default:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      up = colors[COLOR_MENU_UP];
      down = colors[COLOR_MENU_DOWN];
      decorations = settings.menuDecorations;
      break;
   }

   /* Draw the background. */
   if(bp->fill) {

      /* Draw the button background. */
      JXSetForeground(display, gc, bg1);
      /* single color */
      JXFillRectangle(display, drawable, gc, x, y, width, height);

   }

   /* Draw the border. */
   if(bp->border) {
     JXSetForeground(display, gc, down);
     JXDrawRectangle(display, drawable, gc, x, y, width - 1, height - 1);
   }

   /* Determine the size of the icon (if any) to display. */
   iconWidth = 0;
   iconHeight = 0;
   if(bp->icon) {
      if(bp->icon == &emptyIcon) {
         iconWidth = Min(width/2, height/2);
         iconHeight = iconWidth;
      } else {
         const int ratio = (bp->icon->images->width << 16)
                         / bp->icon->images->height;
         iconHeight = height/2;
         iconWidth = (iconHeight * ratio) >> 16;
         if(iconWidth > width/2) {
            iconWidth = width/2;
            iconHeight = (iconWidth << 16) / ratio;
         }
      }
   }

   /* Determine how much room is left for text. */
   textWidth = 0;
   textHeight = 0;
   if(printableName) {
      textWidth = GetStringWidth(bp->font, printableName);
      textHeight = GetStringHeight(bp->font);
      if(iconWidth > 0 && textWidth + iconWidth + 7 > width) {
         textWidth = width - iconWidth - textHeight*3/2;
      } else if(iconWidth == 0 && textWidth + 5 > width) {
         textWidth = width - 5;
      }
      textWidth = textWidth < 0 ? 0 : textWidth;
   }

   /* Determine the offset of the text in the button. */
   if(bp->alignment == ALIGN_CENTER) {
      xoffset = (width - iconWidth - textWidth + 1) / 2;
      if(xoffset < 0) {
         xoffset = 0;
      }
   } else {
      xoffset = textHeight/2;
   }

   /* Display the icon. */
   if(bp->icon) {
      yoffset = (height - iconHeight + 1) / 2;
      PutIcon(bp->icon, drawable, colors[fg],
              x + xoffset, y + yoffset,
              iconWidth, iconHeight);
      xoffset += iconWidth + textHeight/2;
   }

   /* Display the label. */
   if(textWidth > 0) {
      yoffset = (height - textHeight + 1) / 2;
      RenderString(drawable, bp->font, fg,
                   x + xoffset, y + yoffset,
                   textWidth, printableName);
   }

   JXFreeGC(display, gc);

}
Exemplo n.º 14
0
/** Get a scaled icon. */
ScaledIconNode *GetScaledIcon(IconNode *icon, long fg,
                              int rwidth, int rheight)
{

   XColor color;
   XImage *image;
   ScaledIconNode *np;
   GC maskGC;
   int x, y;
   int scalex, scaley;     /* Fixed point. */
   int srcx, srcy;         /* Fixed point. */
   int ratio;              /* Fixed point. */
   int nwidth, nheight;
   unsigned char *data;

   Assert(icon);
   Assert(icon->image);

   if(rwidth == 0) {
      rwidth = icon->image->width;
   }
   if(rheight == 0) {
      rheight = icon->image->height;
   }

   ratio = (icon->image->width << 16) / icon->image->height;
   nwidth = Min(rwidth, (rheight * ratio) >> 16);
   nheight = Min(rheight, (nwidth << 16) / ratio);
   nwidth = (nheight * ratio) >> 16;
   if(nwidth < 1) {
      nwidth = 1;
   }
   if(nheight < 1) {
      nheight = 1;
   }

   /* Check if this size already exists.
    * Note that XRender scales on the fly.
    */
   for(np = icon->nodes; np; np = np->next) {
#ifdef USE_XRENDER
      if(np->imagePicture != None) {
         np->width = nwidth;
         np->height = nheight;
         return np;
      }
#endif
      if(np->width == nwidth && np->height == nheight) {
         if(!icon->image->bitmap || np->fg == fg) {
            return np;
         }
      }
   }

   /* See if we can use XRender to create the icon. */
#ifdef USE_XRENDER
   if(haveRender) {
      np = CreateScaledRenderIcon(icon, fg, nwidth, nheight);

      /* Don't keep the image data around after creating the icon. */
      Release(icon->image->data);
      icon->image->data = NULL;

      return np;
   }
#endif

   /* Create a new ScaledIconNode the old-fashioned way. */
   np = Allocate(sizeof(ScaledIconNode));
   np->fg = fg;
   np->width = nwidth;
   np->height = nheight;
   np->next = icon->nodes;
#ifdef USE_XRENDER
   np->imagePicture = None;
#endif
   icon->nodes = np;

   /* Create a mask. */
   np->mask = JXCreatePixmap(display, rootWindow, nwidth, nheight, 1);
   maskGC = JXCreateGC(display, np->mask, 0, NULL);
   JXSetForeground(display, maskGC, 0);
   JXFillRectangle(display, np->mask, maskGC, 0, 0, nwidth, nheight);
   JXSetForeground(display, maskGC, 1);

   /* Create a temporary XImage for scaling. */
   image = JXCreateImage(display, rootVisual, rootDepth, ZPixmap, 0,
                         NULL, nwidth, nheight, 8, 0);
   image->data = Allocate(sizeof(unsigned long) * nwidth * nheight);

   /* Determine the scale factor. */
   scalex = (icon->image->width << 16) / nwidth;
   scaley = (icon->image->height << 16) / nheight;

   data = icon->image->data;
   srcy = 0;
   for(y = 0; y < nheight; y++) {
      const int yindex = (srcy >> 16) * icon->image->width;
      srcx = 0;
      for(x = 0; x < nwidth; x++) {
         if(icon->image->bitmap) {
            const int index = yindex + (srcx >> 16);
            const int offset = index >> 3;
            const int mask = 1 << (index & 7);
            if(data[offset] & mask) {
               JXDrawPoint(display, np->mask, maskGC, x, y);
               XPutPixel(image, x, y, fg);
            }
         } else {
            const int yindex = (srcy >> 16) * icon->image->width;
            const int index = 4 * (yindex + (srcx >> 16));
            color.red = data[index + 1];
            color.red |= color.red << 8;
            color.green = data[index + 2];
            color.green |= color.green << 8;
            color.blue = data[index + 3];
            color.blue |= color.blue << 8;
            GetColor(&color);
            XPutPixel(image, x, y, color.pixel);
            if(data[index] >= 128) {
               JXDrawPoint(display, np->mask, maskGC, x, y);
            }
         }
         srcx += scalex;
      }
      srcy += scaley;
   }
Exemplo n.º 15
0
Arquivo: popup.c Projeto: kuailexs/jwm
/** Show a popup window. */
void ShowPopup(int x, int y, const char *text,
               const PopupMaskType context)
{

   const ScreenType *sp;

   Assert(text);

   if(!(settings.popupMask & context)) {
      return;
   }

   if(popup.text) {
      if(x == popup.x && y == popup.y && !strcmp(popup.text, text)) {
         // This popup is already shown.
         return;
      }
      Release(popup.text);
      popup.text = NULL;
   }

   if(text[0] == 0) {
      return;
   }

   GetMousePosition(&popup.mx, &popup.my, &popup.mw);
   popup.text = CopyString(text);
   popup.height = GetStringHeight(FONT_POPUP) + 2;
   popup.width = GetStringWidth(FONT_POPUP, popup.text) + 9;

   sp = GetCurrentScreen(x, y);

   if(popup.width > sp->width) {
      popup.width = sp->width;
   }

   popup.x = x;
   if(y + 2 * popup.height + 2 >= sp->height) {
      popup.y = y - popup.height - 2;
   } else {
      popup.y = y + popup.height + 2;
   }

   if(popup.width + popup.x > sp->x + sp->width) {
      popup.x = sp->x + sp->width - popup.width - 2;
   }
   if(popup.height + popup.y > sp->y + sp->height) {
      popup.y = sp->y + sp->height - popup.height - 2;
   }
   if(popup.x < 2) {
      popup.x = 2;
   }
   if(popup.y < 2) {
      popup.y = 2;
   }

   if(popup.window == None) {

      XSetWindowAttributes attr;
      unsigned long attrMask = 0;

      attrMask |= CWEventMask;
      attr.event_mask = ExposureMask
                      | PointerMotionMask | PointerMotionHintMask;

      attrMask |= CWSaveUnder;
      attr.save_under = True;

      attrMask |= CWDontPropagate;
      attr.do_not_propagate_mask = PointerMotionMask
                                 | ButtonPressMask
                                 | ButtonReleaseMask;

      popup.window = JXCreateWindow(display, rootWindow, popup.x, popup.y,
                                    popup.width, popup.height, 0,
                                    CopyFromParent, InputOutput,
                                    CopyFromParent, attrMask, &attr);
      SetAtomAtom(popup.window, ATOM_NET_WM_WINDOW_TYPE,
                  ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION);
      JXMapRaised(display, popup.window);

   } else {

      JXMoveResizeWindow(display, popup.window, popup.x, popup.y,
                         popup.width, popup.height);
      JXFreePixmap(display, popup.pmap);

   }

   popup.pmap = JXCreatePixmap(display, popup.window,
                               popup.width, popup.height,
                               rootDepth);

   JXSetForeground(display, rootGC, colors[COLOR_POPUP_BG]);
   JXFillRectangle(display, popup.pmap, rootGC, 0, 0,
                   popup.width - 1, popup.height - 1);
   JXSetForeground(display, rootGC, colors[COLOR_POPUP_OUTLINE]);
   JXDrawRectangle(display, popup.pmap, rootGC, 0, 0,
                   popup.width - 1, popup.height - 1);
   RenderString(popup.pmap, FONT_POPUP, COLOR_POPUP_FG, 4, 1,
                popup.width, popup.text);
   JXCopyArea(display, popup.pmap, popup.window, rootGC,
              0, 0, popup.width, popup.height, 0, 0);

}