Exemplo n.º 1
0
/**
 * @brief Renders a button widget.
 *
 *    @param btn WIDGET_BUTTON widget to render.
 *    @param bx Base X position.
 *    @param by Base Y position.
 */
static void btn_render( Widget* btn, double bx, double by )
{
   glColour *c, *dc, *lc;
   double x, y;

   x = bx + btn->x;
   y = by + btn->y;

   /* set the colours */
   if (btn->dat.btn.disabled==1) {
      lc = &cGrey60;
      c = &cGrey20;
      dc = &cGrey40;
   }
   else {
      switch (btn->status) {
         case WIDGET_STATUS_NORMAL:
            lc = &cGrey80;
            c = &cGrey60;
            dc = &cGrey40;
            break;
         case WIDGET_STATUS_MOUSEOVER:
            lc = &cGrey90;
            c = &cGrey70;
            dc = &cGrey50;
            break;
         case WIDGET_STATUS_MOUSEDOWN:
            lc = &cGrey90;
            c = &cGrey50;
            dc = &cGrey70;
            break;
         default:
            break;
      }
   }


   /* shaded base */
   if (btn->dat.btn.disabled==1) {
      toolkit_drawRect( x, y,            btn->w, 0.4*btn->h, dc, NULL );
      toolkit_drawRect( x, y+0.4*btn->h, btn->w, 0.6*btn->h, dc, c );
   }
   else {
      toolkit_drawRect( x, y,            btn->w, 0.6*btn->h, dc, c );
      toolkit_drawRect( x, y+0.6*btn->h, btn->w, 0.4*btn->h, c, NULL );
   }
   
   /* inner outline */
   toolkit_drawOutline( x, y, btn->w, btn->h, 0., lc, c );
   /* outter outline */
   toolkit_drawOutline( x, y, btn->w, btn->h, 1., &cBlack, NULL );

   gl_printMidRaw( NULL, (int)btn->w,
         bx + (double)SCREEN_W/2. + btn->x,
         by + (double)SCREEN_H/2. + btn->y + (btn->h - gl_defFont.h)/2.,
         &cDarkRed, btn->dat.btn.display );
}
Exemplo n.º 2
0
Arquivo: list.c Projeto: ekrumme/naev
/**
 * @brief Renders a list widget.
 *
 *    @param lst List widget to render.
 *    @param bx Base X position.
 *    @param by Base Y position.
 */
static void lst_render( Widget* lst, double bx, double by )
{
   int i;
   double x,y, tx,ty, miny;
   double w, scroll_pos;

   w = lst->w;
   x = bx + lst->x;
   y = by + lst->y;

   /* lst bg */
   toolkit_drawRect( x, y, lst->w, lst->h, &cGrey90, NULL );

   /* inner outline */
   toolkit_drawOutline( x, y, lst->w, lst->h, 0.,
         toolkit_colLight, toolkit_col );
   /* outter outline */
   toolkit_drawOutline( x, y, lst->w, lst->h, 1., toolkit_colDark, NULL );

   /* Draw scrollbar. */
   if (lst->dat.lst.height > 0) {
      /* We need to make room for list. */
      w -= 10.;

      scroll_pos  = (double)(lst->dat.lst.pos * (2 + gl_defFont.h));
      scroll_pos /= (double)lst->dat.lst.height - lst->h;
      /* XXX lst->h is off by one */
      toolkit_drawScrollbar( x + lst->w - 10. + 1, y, 10., lst->h + 1, scroll_pos );
   }

   /* draw selected */
   toolkit_drawRect( x, y - 1. + lst->h -
         (1 + lst->dat.lst.selected - lst->dat.lst.pos)*(gl_defFont.h+2.),
         w-1, gl_defFont.h + 2., &cHilight, NULL );

   /* draw content */
   tx = (double)SCREEN_W/2. + x + 2.;
   ty = (double)SCREEN_H/2. + y + lst->h - 2. - gl_defFont.h;
   miny = ty - lst->h + 2 + gl_defFont.h;
   y = ty - 2.;
   w -= 4;
   for (i=lst->dat.lst.pos; i<lst->dat.lst.noptions; i++) {
      gl_printMaxRaw( &gl_defFont, (int)w,
            tx, ty, &cBlack, lst->dat.lst.options[i] );
      ty -= 2 + gl_defFont.h;

      /* Check if out of bounds. */
      if (ty < miny)
         break;
   }
}
Exemplo n.º 3
0
Arquivo: toolkit.c Projeto: Delll/naev
/**
 * @brief Draws a scrollbar.
 *
 *    @param x X position of scrollbar.
 *    @param y Y position of scrollbar.
 *    @param w Width of the scrollbar.
 *    @param h Height of the scrollbar.
 *    @param pos Position at [0:1].
 */
void toolkit_drawScrollbar( int x, int y, int w, int h, double pos )
{
   double sy;

   /* scrollbar background */
   toolkit_drawRect( x, y, w, h, toolkit_colDark, toolkit_col );
   /* toolkit_drawOutline( x, y, w, h,  0., toolkit_colDark, NULL ); */
   /* toolkit_drawOutline( x, y, w, h, 0., toolkit_colLight, toolkit_col ); */

   /* Bar itself. */
   sy = y + (h - 30.) * (1.-pos);
   toolkit_drawRect( x, sy, w, 30., toolkit_colLight, toolkit_col );
   toolkit_drawOutline( x, sy, w, 30., 0., toolkit_colDark, NULL );
}
Exemplo n.º 4
0
/**
 * @brief Renders a button widget.
 *
 *    @param chk WIDGET_BUTTON widget to render.
 *    @param bx Base X position.
 *    @param by Base Y position.
 */
static void chk_render( Widget* chk, double bx, double by )
{
   /*glColour *c;*/
   glColour *dc, *lc;
   double x, y;

   x = bx + chk->x;
   y = by + chk->y;

   /* set the colours */
   switch (chk->status) {
      case WIDGET_STATUS_NORMAL:
         lc = &cGrey80;
         /*c = &cGrey60;*/
         dc = &cGrey40;
         break;
      case WIDGET_STATUS_MOUSEOVER:
         lc = &cWhite;
         /*c = &cGrey80;*/
         dc = &cGrey60;
         break;
      case WIDGET_STATUS_MOUSEDOWN:
         lc = &cGreen;
         /*c = &cGreen;*/
         dc = &cGrey40;
         break;
      default:
         break;
   }

   /* Draw rect. */
   toolkit_drawRect( x-1, y-1 + (chk->h-10.)/2., 12., 12., &cGrey40, NULL );
   toolkit_drawRect( x, y + (chk->h-10.)/2., 10., 10., &cGrey90, NULL );
   if (chk->dat.chk.state)
      toolkit_drawRect( x+1., y+1. + (chk->h-10.)/2., 8., 8., &cGrey20, NULL );

   /* Inner outline */
   /*  toolkit_drawOutline( x, y + (chk->h-10.)/2., 10, 10, 0., lc, c ); */
   /* Outter outline */
   /*toolkit_drawOutline( x, y + (chk->h-10.)/2., 10, 10, 1., &cBlack, NULL );*/

   /* Draw the txt. */
   gl_printMaxRaw( NULL, chk->w - 20,
         bx + chk->x + 15,
         by + chk->y + (chk->h - gl_defFont.h)/2.,
         &cBlack, chk->dat.chk.display );
}
Exemplo n.º 5
0
Arquivo: tabwin.c Projeto: Delll/naev
/**
 * @brief Renders a button widget.
 *
 *    @param tab WIDGET_BUTTON widget to render.
 *    @param bx Base X position.
 *    @param by Base Y position.
 */
static void tab_render( Widget* tab, double bx, double by )
{
   int i, x;
   Window *wdw;
   glColour *c, *lc;

   /** Get window. */
   wdw = window_wget( tab->dat.tab.windows[ tab->dat.tab.active ] );
   if (wdw == NULL) {
      WARN("Active window in widget '%s' not found in stack.", tab->name);
      return;
   }

   /* Render the active window. */
   window_render( wdw );

   /* Render tabs ontop. */
   x = 20;
   for (i=0; i<tab->dat.tab.ntabs; i++) {
      if (i!=tab->dat.tab.active) {
         lc = toolkit_col;
         c  = toolkit_colDark;

         /* Draw border. */
         toolkit_drawRect( bx+x, by+0, tab->dat.tab.namelen[i] + 10,
               TAB_HEIGHT, lc, c );
         toolkit_drawOutline( bx+x+1, by+1, tab->dat.tab.namelen[i] + 8,
               TAB_HEIGHT-1, 1., c, &cBlack );
      }
      else {
         if (i==0)
            toolkit_drawRect( bx+x-1, by+0,
                  1, TAB_HEIGHT+1, toolkit_colDark, &cGrey20 );
         else if (i==tab->dat.tab.ntabs-1)
            toolkit_drawRect( bx+x+tab->dat.tab.namelen[i]+9, by+0,
                  1, TAB_HEIGHT+1, toolkit_colDark, &cGrey20 );
      }
      /* Draw text. */
      gl_printRaw( &gl_defFont, bx+x + 5 + SCREEN_W/2,
            by + (TAB_HEIGHT-gl_defFont.h)/2 + SCREEN_H/2, &cBlack,
            tab->dat.tab.tabnames[i] );

      /* Go to next line. */
      x += 10 + tab->dat.tab.namelen[i];
   }
}
Exemplo n.º 6
0
Arquivo: info.c Projeto: AvanWolf/naev
/**
 * @brief Renders the legend.
 */
static void weapons_renderLegend( double bx, double by, double bw, double bh, void* data )
{
   (void) data;
   (void) bw;
   (void) bh;
   double y;

   y = by+bh-20;
   gl_print( &gl_defFont, bx, y, &cBlack, "Legend" );

   y -= 20.;
   toolkit_drawRect( bx, y, 10, 10, &cFontYellow, NULL );
   gl_print( &gl_smallFont, bx+20, y, &cBlack, "Secondary Weapon (Right click toggles)" );

   y -= 15.;
   toolkit_drawRect( bx, y, 10, 10, &cFontRed, NULL );
   gl_print( &gl_smallFont, bx+20, y, &cBlack, "Primary Weapon (Left click toggles)" );
}
Exemplo n.º 7
0
/**
 * @brief Renders a input widget.
 *
 *    @param inp Input widget to render.
 *    @param bx Base X position.
 *    @param by Base Y position.
 */
static void inp_render( Widget* inp, double bx, double by )
{
   double x, y, ty;
   char buf[ PATH_MAX ];
   int w;
   int m;

   x = bx + inp->x;
   y = by + inp->y;

   /* main background */
   toolkit_drawRect( x, y, inp->w, inp->h, &cWhite, NULL );

   /* center vertically */
   if (inp->dat.inp.oneline)
      ty = y - (inp->h - gl_smallFont.h)/2.;
   else {
      WARN("Multi-line input widgets unsupported atm.");
      return;
   }

   /* Draw text. */
   gl_printTextRaw( inp->dat.inp.font, inp->w-10., inp->h,
         x+5., ty, &cBlack, &inp->dat.inp.input[ inp->dat.inp.view ] );

   /* Draw cursor. */
   if (wgt_isFlag( inp, WGT_FLAG_FOCUSED )) {
      m = MIN( inp->dat.inp.pos - inp->dat.inp.view, PATH_MAX-1 );
      strncpy( buf, &inp->dat.inp.input[ inp->dat.inp.view ], m );
      buf[ m ] = '\0';
      w = gl_printWidthRaw( inp->dat.inp.font, buf );
      toolkit_drawRect( x+5.+w, y + (inp->h - inp->dat.inp.font->h - 4.)/2.,
            1., inp->dat.inp.font->h + 4., &cBlack, &cBlack );
   }

   /* inner outline */
   toolkit_drawOutline( x, y, inp->w, inp->h, 0.,
         toolkit_colLight, toolkit_col );
   /* outter outline */
   toolkit_drawOutline( x, y, inp->w, inp->h, 1.,
         toolkit_colDark, NULL );
}
Exemplo n.º 8
0
Arquivo: toolkit.c Projeto: Delll/naev
/**
 * @brief Draws an alt text.
 *
 *    @param bx X position to draw at.
 *    @param by Y position to draw at.
 *    @param alt Text to draw.
 */
void toolkit_drawAltText( int bx, int by, const char *alt )
{
   double w, h;
   double x, y, o;
   glColour c;
   glColour c2;

   /* Get dimensions. */
   w = 160.;
   h = gl_printHeightRaw( &gl_smallFont, w, alt );
   /* One check to make bigger. */
   if (h > 160.) {
      w = 200;
      h = gl_printHeightRaw( &gl_smallFont, w, alt );
   }

   /* Choose position. */
   x = bx + 10.;
   y = by - h - gl_smallFont.h - 10.;
   if (y < -SCREEN_H/2+10) {
      o  = -(SCREEN_H/2 + y) + 10;
      y += o;
   }

   /* Set colours. */
   c.r = cGrey80.r;
   c.g = cGrey80.g;
   c.b = cGrey80.b;
   c.a = 0.8;
   c2.r = cGrey30.r;
   c2.g = cGrey30.g;
   c2.b = cGrey30.b;
   c2.a = 0.7;
   toolkit_drawRect( x-1, y-5, w+6, h+6, &c2, NULL );
   toolkit_drawRect( x-3, y-3, w+6, h+6, &c, NULL );
   gl_printTextRaw( &gl_smallFont, w, h, x+SCREEN_W/2, y+SCREEN_H/2, &cBlack, alt );
}
Exemplo n.º 9
0
/**
 * @brief Renders a rectangle widget.
 *
 *    @param wct Rectangle widget to render.
 *    @param bx Base X position.
 *    @param by Base Y position.
 */
static void rct_render( Widget* rct, double bx, double by )
{
   double x, y;

   x = bx + rct->x;
   y = by + rct->y;

   if (rct->dat.rct.fill) /* draw rect only if it exists */
      toolkit_drawRect( x, y, rct->w, rct->h, &rct->dat.rct.colour, NULL );

   if (rct->dat.rct.border) {
      /* inner outline */
      toolkit_drawOutline( x, y, rct->w, rct->h, 0.,
            toolkit_colLight, toolkit_col );
      /* outer outline */
      toolkit_drawOutline( x, y, rct->w, rct->h, 1.,
            toolkit_colDark, NULL );
   }
}
Exemplo n.º 10
0
/**
 * @brief Renders a row of ship slots.
 */
static void shipyard_renderSlotsRow( double bx, double by, double bw, char *str, ShipOutfitSlot *s, int n )
{
   (void) bw;
   int i;
   double x;
   const glColour *c;

   x = bx;

   /* Print text. */
   gl_print( &gl_smallFont, bx, by, &cBlack, str );

   /* Draw squares. */
   for (i=0; i<n; i++) {
      c = outfit_slotSizeColour( &s[i].slot );
      if (c == NULL)
         c = &cBlack;

      x += 15.;
      toolkit_drawRect( x, by, 10, 10, c, NULL );
   }
}
Exemplo n.º 11
0
/**
 * @brief Renders an image array.
 *
 *    @param iar Image array widget to render.
 *    @param bx Base X position.
 *    @param by Base Y position.
 */
static void iar_render( Widget* iar, double bx, double by )
{
   int i,j, pos;
   double x,y, w,h, xcurs,ycurs;
   double scroll_pos;
   int xelem, yelem;
   double xspace;
   glColour *c, *dc, *lc, tc, fontcolour;
   int is_selected;
   int tw;
   double d;

   /*
    * Calculations.
    */
   /* position */
   x = bx + iar->x;
   y = by + iar->y;

   /* element dimensions */
   iar_getDim( iar, &w, &h );

   /* number of elements */
   xelem = iar->dat.iar.xelem;
   yelem = iar->dat.iar.yelem;
   xspace = (double)(((int)iar->w - 10) % (int)w) / (double)(xelem + 1);

   /* background */
   toolkit_drawRect( x, y, iar->w, iar->h, &cBlack, NULL );

   /*
    * Scrollbar.
    */
   d          = h * (yelem - (int)(iar->h / h));
   if (fabs(d) < 1e-05)
      scroll_pos = 0.;
   else
      scroll_pos = iar->dat.iar.pos / d;
   toolkit_drawScrollbar( x + iar->w - 10., y, 10., iar->h, scroll_pos );

   /*
    * Main drawing loop.
    */
   gl_clipRect( x, y, iar->w, iar->h );
   ycurs = y + iar->h - h + iar->dat.iar.pos;
   for (j=0; j<yelem; j++) {
      xcurs = x + xspace;
      for (i=0; i<xelem; i++) {

         /* Get position. */
         pos = j*xelem + i;

         /* Out of elements. */
         if ((pos) >= iar->dat.iar.nelements)
            break;

         is_selected = (iar->dat.iar.selected == pos) ? 1 : 0;

         fontcolour = cWhite;
         /* Draw background. */
         if (is_selected)
            toolkit_drawRect( xcurs + 2.,
                  ycurs + 2.,
                  w - 5., h - 5., &cDConsole, NULL );
         else if (iar->dat.iar.background != NULL) {
            toolkit_drawRect( xcurs + 2.,
                  ycurs + 2.,
                  w - 5., h - 5., &iar->dat.iar.background[pos], NULL );

            tc = iar->dat.iar.background[pos];

            if (((tc.r + tc.g + tc.b) / 3) > 0.5)
               fontcolour = cBlack;
         }

         /* image */
         if (iar->dat.iar.images[pos] != NULL)
            gl_blitScale( iar->dat.iar.images[pos],
                  xcurs + 5., ycurs + gl_smallFont.h + 7.,
                  iar->dat.iar.iw, iar->dat.iar.ih, NULL );

         /* caption */
         if (iar->dat.iar.captions[pos] != NULL)
            gl_printMidRaw( &gl_smallFont, iar->dat.iar.iw, xcurs + 5., ycurs + 5.,
                     (is_selected) ? &cBlack : &fontcolour,
                     iar->dat.iar.captions[pos] );

         /* quantity. */
         if (iar->dat.iar.quantity != NULL) {
            if (iar->dat.iar.quantity[pos] != NULL) {
               /* Rectangle to highlight better. */
               tw = gl_printWidthRaw( &gl_smallFont,
                     iar->dat.iar.quantity[pos] );

               if (is_selected)
                  tc = cDConsole;
               else if (iar->dat.iar.background != NULL)
                  tc = iar->dat.iar.background[pos];
               else
                  tc = cBlack;

               tc.a = 0.75;
               toolkit_drawRect( xcurs + 2.,
                     ycurs + 5. + iar->dat.iar.ih,
                     tw + 4., gl_smallFont.h + 4., &tc, NULL );
               /* Quantity number. */
               gl_printMaxRaw( &gl_smallFont, iar->dat.iar.iw,
                     xcurs + 5., ycurs + iar->dat.iar.ih + 7.,
                     &fontcolour, iar->dat.iar.quantity[pos] );
            }
         }

         /* Slot type. */
         if (iar->dat.iar.slottype != NULL) {
            if (iar->dat.iar.slottype[pos] != NULL) {
               /* Rectangle to highlight better. Width is a hack due to lack of monospace font. */
               tw = gl_printWidthRaw( &gl_smallFont, "M" );

               if (is_selected)
                  tc = cDConsole;
               else if (iar->dat.iar.background != NULL)
                  tc = iar->dat.iar.background[pos];
               else
                  tc = cBlack;

               tc.a = 0.75;
               toolkit_drawRect( xcurs + iar->dat.iar.iw - 6.,
                     ycurs + 5. + iar->dat.iar.ih,
                     tw + 2., gl_smallFont.h + 4., &tc, NULL );
               /* Slot size letter. */
               gl_printMaxRaw( &gl_smallFont, iar->dat.iar.iw,
                     xcurs + iar->dat.iar.iw - 4., ycurs + iar->dat.iar.ih + 7.,
                     &fontcolour, iar->dat.iar.slottype[pos] );
            }
         }

         /* outline */
         if (is_selected) {
            lc = &cWhite;
            c = &cGrey80;
            dc = &cGrey60;
         }
         else {
            lc = toolkit_colLight;
            c = toolkit_col;
            dc = toolkit_colDark;
         }
         toolkit_drawOutline( xcurs + 2.,
               ycurs + 2.,
               w - 4., h - 4., 1., lc, c );
         toolkit_drawOutline( xcurs + 2.,
               ycurs + 2.,
               w - 4., h - 4., 2., dc, NULL );
         xcurs += w + xspace;
      }
      ycurs -= h;
   }
   gl_unclipRect();

   /*
    * Final outline.
    */
   toolkit_drawOutline( x+1, y+1, iar->w-2, iar->h-2, 1., toolkit_colLight, toolkit_col );
   toolkit_drawOutline( x+1, y+1, iar->w-2, iar->h-2, 2., toolkit_colDark, NULL );
}
Exemplo n.º 12
0
Arquivo: toolkit.c Projeto: Delll/naev
/**
 * @brief Renders a window border.
 *
 *    @param w Window to render
 */
static void window_renderBorder( Window* w )
{
   int i;
   GLint cx, cy;
   double x, y;
   glColour *lc, *c, *dc, *oc;
   GLint vertex[31*4];
   GLfloat colours[31*4];

   /* position */
   x = w->x - (double)SCREEN_W/2.;
   y = w->y - (double)SCREEN_H/2.;

   /* colours */
   lc = &cGrey90;
   c = &cGrey70;
   dc = &cGrey50;
   oc = &cGrey30;

   /*
    * Case fullscreen.
    */
   if (window_isFlag( w, WINDOW_FULLSCREEN )) {
      /* Background. */
      toolkit_drawRect( x, y,          w->w, 0.6*w->h, dc, c );
      toolkit_drawRect( x, y+0.6*w->h, w->w, 0.4*w->h, c, NULL );
      /* Name. */
      gl_printMidRaw( &gl_defFont, w->w,
            x + (double)SCREEN_W/2.,
            y + w->h - 20. + (double)SCREEN_H/2.,
            &cBlack, w->name );
      return;
   }

   /*
    * window shaded bg
    */
   /* main body */
   toolkit_drawRect( x+21, y,          w->w-42., 0.6*w->h, dc, c );
   toolkit_drawRect( x+21, y+0.6*w->h, w->w-42., 0.4*w->h, c, NULL );

   glShadeModel(GL_SMOOTH);
   /* Both sides. */
   gl_vboActivateOffset( toolkit_vbo, GL_COLOR_ARRAY,
         toolkit_vboColourOffset, 4, GL_FLOAT, 0 );
   gl_vboActivateOffset( toolkit_vbo, GL_VERTEX_ARRAY, 0, 2, GL_INT, 0 );
   /* Colour is shared. */
   colours[0] = c->r;
   colours[1] = c->g;
   colours[2] = c->r;
   colours[3] = c->a;
   for (i=0; i<7; i++) {
      colours[4 + 4*i + 0] = dc->r;
      colours[4 + 4*i + 1] = dc->g;
      colours[4 + 4*i + 2] = dc->r;
      colours[4 + 4*i + 3] = dc->a;
   }
   for (i=0; i<8; i++) {
      colours[32 + 4*i + 0] = c->r;
      colours[32 + 4*i + 1] = c->g;
      colours[32 + 4*i + 2] = c->r;
      colours[32 + 4*i + 3] = c->a;
   }
   gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset,
         sizeof(GLfloat) * 4*16, colours );
   /* Left side vertex. */
   cx = x;
   cy = y;
   vertex[0]  = cx + 21;
   vertex[1]  = cy + 0.6*w->h;
   vertex[2]  = cx + 21;
   vertex[3]  = cy;
   vertex[4]  = cx + 15;
   vertex[5]  = cy + 1;
   vertex[6]  = cx + 10;
   vertex[7]  = cy + 3;
   vertex[8]  = cx + 6;
   vertex[9]  = cy + 6;
   vertex[10] = cx + 3;
   vertex[11] = cy + 10;
   vertex[12] = cx + 1;
   vertex[13] = cy + 15;
   vertex[14] = cx;
   vertex[15] = cy + 21;
   vertex[16] = cx;
   vertex[17] = cy + 0.6*w->h;
   vertex[18] = cx;
   cy = y + w->h;
   vertex[19] = cy - 21;
   vertex[20] = cx + 1;
   vertex[21] = cy - 15;
   vertex[22] = cx + 3;
   vertex[23] = cy - 10;
   vertex[24] = cx + 6;
   vertex[25] = cy - 6;
   vertex[26] = cx + 10;
   vertex[27] = cy - 3;
   vertex[28] = cx + 15;
   vertex[29] = cy - 1;
   vertex[30] = cx + 21;
   vertex[31] = cy;
   gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*16, vertex );
   glDrawArrays( GL_POLYGON, 0, 16 );
   /* Right side vertex. */
   cx = x + w->w;
   cy = y;
   vertex[0]  = cx - 21;
   vertex[1]  = cy + 0.6*w->h;
   vertex[2]  = cx - 21;
   vertex[3]  = cy;
   vertex[4]  = cx - 15;
   vertex[5]  = cy + 1;
   vertex[6]  = cx - 10;
   vertex[7]  = cy + 3;
   vertex[8]  = cx - 6;
   vertex[9]  = cy + 6;
   vertex[10] = cx - 3;
   vertex[11] = cy + 10;
   vertex[12] = cx - 1;
   vertex[13] = cy + 15;
   vertex[14] = cx;
   vertex[15] = cy + 21;
   vertex[16] = cx;
   vertex[17] = cy + 0.6*w->h;
   vertex[18] = cx;
   cy = y + w->h;
   vertex[19] = cy - 21;
   vertex[20] = cx - 1;
   vertex[21] = cy - 15;
   vertex[22] = cx - 3;
   vertex[23] = cy - 10;
   vertex[24] = cx - 6;
   vertex[25] = cy - 6;
   vertex[26] = cx - 10;
   vertex[27] = cy - 3;
   vertex[28] = cx - 15;
   vertex[29] = cy - 1;
   vertex[30] = cx - 21;
   vertex[31] = cy;
   gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*16, vertex );
   glDrawArrays( GL_POLYGON, 0, 16 );


   /* 
    * inner outline
    */
   /* Colour. */
   for (i=0; i<7; i++) {
      colours[4*i + 0] = c->r;
      colours[4*i + 1] = c->g;
      colours[4*i + 2] = c->b;
      colours[4*i + 3] = c->a;
   }
   for (; i<7+16; i++) {
      colours[4*i + 0] = lc->r;
      colours[4*i + 1] = lc->g;
      colours[4*i + 2] = lc->b;
      colours[4*i + 3] = lc->a;
   }
   for (; i<7+16+8; i++) {
      colours[4*i + 0] = c->r;
      colours[4*i + 1] = c->g;
      colours[4*i + 2] = c->b;
      colours[4*i + 3] = c->a;
   }
   gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset,
         sizeof(GLfloat) * 4*31, colours );
   /* Vertex. */
   /* Left side. */
   cx = x + 1;
   cy = y + 1;
   vertex[0]  = cx + 21;
   vertex[1]  = cy;
   vertex[2]  = cx + 15;
   vertex[3]  = cy + 1;
   vertex[4]  = cx + 10;
   vertex[5]  = cy + 3;
   vertex[6]  = cx + 6;
   vertex[7]  = cy + 6;
   vertex[8]  = cx + 3;
   vertex[9]  = cy + 10;
   vertex[10] = cx + 1;
   vertex[11] = cy + 15;
   vertex[12] = cx;
   vertex[13] = cy + 21;
   vertex[14] = cx;
   vertex[15] = cy + 0.6*w->h - 1;
   cy = y + w->h - 1;
   vertex[16] = cx;
   vertex[17] = cy - 21;
   vertex[18] = cx + 1;
   vertex[19] = cy - 15;
   vertex[20] = cx + 3;
   vertex[21] = cy - 10;
   vertex[22] = cx + 6;
   vertex[23] = cy - 6;
   vertex[24] = cx + 10;
   vertex[25] = cy - 3;
   vertex[26] = cx + 15;
   vertex[27] = cy - 1;
   vertex[28] = cx + 21;
   vertex[29] = cy;
   /* Right side via top. */
   cx = x + w->w - 1;
   cy = y + w->h - 1;
   vertex[30] = cx - 21;
   vertex[31] = cy;
   vertex[32] = cx - 15;
   vertex[33] = cy - 1;
   vertex[34] = cx - 10;
   vertex[35] = cy - 3;
   vertex[36] = cx - 6;
   vertex[37] = cy - 6;
   vertex[38] = cx - 3;
   vertex[39] = cy - 10;
   vertex[40] = cx - 1;
   vertex[41] = cy - 15;
   vertex[42] = cx;
   vertex[43] = cy - 21;
   cy = y + 1;
   vertex[44] = cx;
   vertex[45] = cy + 0.6*w->h - 1;
   vertex[46] = cx;
   vertex[47] = cy + 21;
   vertex[48] = cx - 1;
   vertex[49] = cy + 15;
   vertex[50] = cx - 3;
   vertex[51] = cy + 10;
   vertex[52] = cx - 6;
   vertex[53] = cy + 6;
   vertex[54] = cx - 10;
   vertex[55] = cy + 3;
   vertex[56] = cx - 15;
   vertex[57] = cy + 1;
   vertex[58] = cx - 21;
   vertex[59] = cy;
   cx = x + 1;
   cy = y + 1;
   vertex[60] = cx + 21;
   vertex[61] = cy;
   gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*31, vertex );
   glDrawArrays( GL_LINE_LOOP, 0, 31 );


   /*
    * outter outline
    */
   glShadeModel(GL_FLAT);
   /* Colour. */
   for (i=0; i<31; i++) {
      colours[4*i + 0] = oc->r;
      colours[4*i + 1] = oc->g;
      colours[4*i + 2] = oc->b;
      colours[4*i + 3] = oc->a;
   }
   gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset,
         sizeof(GLfloat) * 4*31, colours );
   /* Vertex. */
   /* Left side. */
   cx = x;
   cy = y;
   vertex[0]  = cx + 21;
   vertex[1]  = cy;
   vertex[2]  = cx + 15;
   vertex[3]  = cy + 1;
   vertex[4]  = cx + 10;
   vertex[5]  = cy + 3;
   vertex[6]  = cx + 6;
   vertex[7]  = cy + 6;
   vertex[8]  = cx + 3;
   vertex[9]  = cy + 10;
   vertex[10] = cx + 1;
   vertex[11] = cy + 15;
   vertex[12] = cx;
   vertex[13] = cy + 21;
   vertex[14] = cx;
   vertex[15] = cy + 0.6*w->h;
   cy = y + w->h;
   vertex[16] = cx;
   vertex[17] = cy - 21;
   vertex[18] = cx + 1;
   vertex[19] = cy - 15;
   vertex[20] = cx + 3;
   vertex[21] = cy - 10;
   vertex[22] = cx + 6;
   vertex[23] = cy - 6;
   vertex[24] = cx + 10;
   vertex[25] = cy - 3;
   vertex[26] = cx + 15;
   vertex[27] = cy - 1;
   vertex[28] = cx + 21;
   vertex[29] = cy;
   /* Right side via top. */
   cx = x + w->w;
   cy = y + w->h;
   vertex[30] = cx - 21;
   vertex[31] = cy;
   vertex[32] = cx - 15;
   vertex[33] = cy - 1;
   vertex[34] = cx - 10;
   vertex[35] = cy - 3;
   vertex[36] = cx - 6;
   vertex[37] = cy - 6;
   vertex[38] = cx - 3;
   vertex[39] = cy - 10;
   vertex[40] = cx - 1;
   vertex[41] = cy - 15;
   vertex[42] = cx;
   vertex[43] = cy - 21;
   cy = y;
   vertex[44] = cx;
   vertex[45] = cy + 0.6*w->h;
   vertex[46] = cx;
   vertex[47] = cy + 21;
   vertex[48] = cx - 1;
   vertex[49] = cy + 15;
   vertex[50] = cx - 3;
   vertex[51] = cy + 10;
   vertex[52] = cx - 6;
   vertex[53] = cy + 6;
   vertex[54] = cx - 10;
   vertex[55] = cy + 3;
   vertex[56] = cx - 15;
   vertex[57] = cy + 1;
   vertex[58] = cx - 21;
   vertex[59] = cy;
   cx = x;
   cy = y;
   vertex[60] = cx + 21;
   vertex[61] = cy;
   gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*31, vertex );
   glDrawArrays( GL_LINE_LOOP, 0, 31 );

   /* Clean up. */
   gl_vboDeactivate();

   /*
    * render window name
    */
   gl_printMidRaw( &gl_defFont, w->w,
         x + (double)SCREEN_W/2.,
         y + w->h - 20. + (double)SCREEN_H/2.,
         &cBlack, w->name );
}