--- a/plugins/switcher.c 2008-01-26 16:08:24.000000000 +0100 +++ b/plugins/switcher.c 2008-01-27 11:57:23.000000000 +0100 @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -63,6 +64,7 @@ CompOption opt[SWITCH_DISPLAY_OPTION_NUM]; Atom selectWinAtom; + Bool textAvailable; } SwitchDisplay; #define SWITCH_SCREEN_OPTION_SPEED 0 @@ -77,7 +79,13 @@ #define SWITCH_SCREEN_OPTION_ICON 9 #define SWITCH_SCREEN_OPTION_MINIMIZED 10 #define SWITCH_SCREEN_OPTION_AUTO_ROTATE 11 -#define SWITCH_SCREEN_OPTION_NUM 12 +#define SWITCH_SCREEN_OPTION_WINDOW_TITLE 12 +#define SWITCH_SCREEN_OPTION_TITLE_FONT_BOLD 13 +#define SWITCH_SCREEN_OPTION_TITLE_FONT_SIZE 14 +#define SWITCH_SCREEN_OPTION_TITLE_BACK_COLOR 15 +#define SWITCH_SCREEN_OPTION_TITLE_FONT_COLOR 16 +#define SWITCH_SCREEN_OPTION_TITLE_TEXT_PLACEMENT 17 +#define SWITCH_SCREEN_OPTION_NUM 18 typedef struct _SwitchScreen { PreparePaintScreenProc preparePaintScreen; @@ -119,6 +127,16 @@ float translate; float sTranslate; + + /* text display support */ + CompTexture textTexture; + Pixmap textPixmap; + int textWidth; + int textHeight; + + GLushort color[4]; + GLushort font_color[4]; + Bool allWindows; } SwitchScreen; @@ -182,6 +200,226 @@ #define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption)) + +static void +switchFreeWindowTitle (CompScreen *s) +{ + SWITCH_SCREEN(s); + + if (!ss->textPixmap) + return; + + releasePixmapFromTexture (s, &ss->textTexture); + initTexture (s, &ss->textTexture); + XFreePixmap (s->display->display, ss->textPixmap); + ss->textPixmap = None; +} + + +static void +switchRenderWindowTitle (CompScreen *s) +{ + + + CompTextAttrib tA; + int stride; + void *data; + + SWITCH_SCREEN (s); + SWITCH_DISPLAY (s->display); + + switchFreeWindowTitle (s); + + if (!sd->textAvailable) + return; + + if (!ss->opt[SWITCH_SCREEN_OPTION_WINDOW_TITLE].value.b) + return; + + int ox1, ox2, oy1, oy2; + getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2); + + /* 75% of the output device as maximum width */ + tA.maxWidth = (ox2 - ox1) * 3 / 4; + tA.maxHeight = 100; + tA.screen = s; + tA.size = ss->opt[SWITCH_SCREEN_OPTION_TITLE_FONT_SIZE].value.i; + tA.color[0] = ss->font_color[0]; + tA.color[1] = ss->font_color[1]; + tA.color[2] = ss->font_color[2]; + tA.color[3] = ss->font_color[3]; + tA.style = (ss->opt[SWITCH_SCREEN_OPTION_TITLE_FONT_BOLD].value.b) ? + TEXT_STYLE_BOLD : TEXT_STYLE_NORMAL; + + tA.family = "Sans"; + tA.ellipsize = TRUE; + + if (ss->allWindows) + tA.renderMode = TextRenderWindowTitleWithViewport; + else + tA.renderMode = TextRenderWindowTitle; + + tA.data = (void*)ss->selectedWindow; + + initTexture (s, &ss->textTexture); + + if ((*s->display->fileToImage) (s->display, TEXT_ID, (char *)&tA, + &ss->textWidth, &ss->textHeight, + &stride, &data)) + { + ss->textPixmap = (Pixmap)data; + bindPixmapToTexture (s, &ss->textTexture, ss->textPixmap, + ss->textWidth, ss->textHeight, 32); + } + else + { + ss->textPixmap = None; + ss->textWidth = 0; + ss->textHeight = 0; + } +} + +static void +switchDrawWindowTitle (CompScreen *s) +{ + SWITCH_SCREEN(s); + SWITCH_DISPLAY (s->display); + + if (!ss->opt[SWITCH_SCREEN_OPTION_WINDOW_TITLE].value.b) + return; + + if (!sd->textAvailable) + return; + + GLboolean wasBlend; + GLint oldBlendSrc, oldBlendDst; + + float width = ss->textWidth; + float height = ss->textHeight; + float border = 10.0f; + + int ox1, ox2, oy1, oy2; + getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2); + + float x = ox1 + ((ox2 - ox1) / 2) - (ss->textWidth / 2); + float y; + + switch (ss->allWindows && ss->opt[SWITCH_SCREEN_OPTION_TITLE_TEXT_PLACEMENT].value.i) + { + case 0: + y = oy1 + ((oy2 - oy1) / 2) + (height / 2) + (height / 4) + 150; + break; + case 1: + case 2: + { + XRectangle workArea; + getWorkareaForOutput (s, s->currentOutputDev, &workArea); + + if (ss->allWindows && ss->opt[SWITCH_SCREEN_OPTION_TITLE_TEXT_PLACEMENT].value.i == 1) + y = oy1 + workArea.y + (2 * border) + height; + else + y = oy1 + workArea.y + workArea.height - (2 * border); + } + break; + default: + return; + break; + } + + x = floor(x); + y = floor(y); + + glGetIntegerv (GL_BLEND_SRC, &oldBlendSrc); + glGetIntegerv (GL_BLEND_DST, &oldBlendDst); + wasBlend = glIsEnabled (GL_BLEND); + + if (!wasBlend) + glEnable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + + glColor4us (ss->color[0], ss->color[1], ss->color[2], ss->color[3]); + + glPushMatrix (); + + glTranslatef (x, y - height, 0.0f); + glRectf (0.0f, height, width, 0.0f); + glRectf (0.0f, 0.0f, width, -border); + glRectf (0.0f, height + border, width, height); + glRectf (-border, height, 0.0f, 0.0f); + glRectf (width, height, width + border, 0.0f); + glTranslatef (-border, -border, 0.0f); + +#define CORNER(a,b) \ + for (k = a; k < b; k++) \ + {\ + float rad = k * (3.14 / 180.0f);\ + glVertex2f (0.0f, 0.0f);\ + glVertex2f (cos (rad) * border, sin (rad) * border);\ + glVertex2f (cos ((k - 1) * (3.14 / 180.0f)) * border, \ + sin ((k - 1) * (3.14 / 180.0f)) * border);\ + } + + /* Rounded corners */ + int k; + + glTranslatef (border, border, 0.0f); + glBegin (GL_TRIANGLES); + CORNER (180, 270) glEnd (); + glTranslatef (-border, -border, 0.0f); + + glTranslatef (width + border, border, 0.0f); + glBegin (GL_TRIANGLES); + CORNER (270, 360) glEnd (); + glTranslatef (-(width + border), -border, 0.0f); + + glTranslatef (border, height + border, 0.0f); + glBegin (GL_TRIANGLES); + CORNER (90, 180) glEnd (); + glTranslatef (-border, -(height + border), 0.0f); + + glTranslatef (width + border, height + border, 0.0f); + glBegin (GL_TRIANGLES); + CORNER (0, 90) glEnd (); + glTranslatef (-(width + border), -(height + border), 0.0f); + + glPopMatrix (); + +#undef CORNER + + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f (1.0, 1.0, 1.0, 1.0); + + enableTexture (s, &ss->textTexture, COMP_TEXTURE_FILTER_GOOD); + + CompMatrix *m = &ss->textTexture.matrix; + + glBegin (GL_QUADS); + + glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m ,0)); + glVertex2f (x, y - height); + glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m, height)); + glVertex2f (x, y); + glTexCoord2f (COMP_TEX_COORD_X (m, width), COMP_TEX_COORD_Y (m, height)); + glVertex2f (x + width, y); + glTexCoord2f (COMP_TEX_COORD_X (m, width), COMP_TEX_COORD_Y (m, 0)); + glVertex2f (x + width, y - height); + + glEnd (); + + disableTexture (s, &ss->textTexture); + glColor4usv (defaultColor); + + if (!wasBlend) + glDisable (GL_BLEND); + + glBlendFunc (oldBlendSrc, oldBlendDst); +} + + + + + static CompOption * switchGetScreenOptions (CompPlugin *plugin, CompScreen *screen, @@ -226,6 +464,22 @@ return TRUE; } break; + case SWITCH_SCREEN_OPTION_TITLE_BACK_COLOR: + if (compSetColorOption (o, value)) + { + memcpy (ss->color, o->value.c, sizeof (ss->color)); + damageScreen (screen); + return TRUE; + } + break; + case SWITCH_SCREEN_OPTION_TITLE_FONT_COLOR: + if (compSetColorOption (o, value)) + { + memcpy (ss->font_color, o->value.c, sizeof (ss->font_color)); + damageScreen (screen); + return TRUE; + } + break; default: return compSetScreenOption (screen, o, value); } @@ -488,6 +742,7 @@ setSelectedWindowHint (s); } + switchRenderWindowTitle (s); addWindowDamage (w); if (old) @@ -572,7 +827,11 @@ if (count < 1) return; - if (!ss->popupWindow && showPopup) + enableTexture (s, &ss->textTexture,COMP_TEXTURE_FILTER_GOOD); + + //CompMatrix *m = &ss->textTexture.matrix; + + if (!ss->popupWindow && showPopup) { Display *dpy = s->display->display; XSizeHints xsh; @@ -673,6 +932,7 @@ damageScreen (s); + disableTexture (s, &ss->textTexture); ss->switching = TRUE; ss->moreAdjust = 1; } @@ -1378,7 +1638,7 @@ (*s->paintWindow) (switcher, &switcher->paint, &sTransform, &infiniteRegion, 0); } - + switchDrawWindowTitle (s); glPopMatrix (); } } @@ -1852,8 +2112,14 @@ if (!checkPluginABI ("core", CORE_ABIVERSION)) return FALSE; - + + sd = malloc (sizeof (SwitchDisplay)); + sd->textAvailable = checkPluginABI ("text", TEXT_ABIVERSION); + + if (!sd->textAvailable) + compLogMessage (d, "ring", CompLogLevelWarn, + "No compatible text plugin found."); if (!sd) return FALSE; @@ -1897,7 +2163,7 @@ compFiniDisplayOptions (d, sd->opt, SWITCH_DISPLAY_OPTION_NUM); free (sd); -} +} static const CompMetadataOptionInfo switchScreenOptionInfo[] = { { "speed", "float", "0.1", 0, 0 }, @@ -1911,7 +2177,15 @@ { "zoom", "float", "0", 0, 0 }, { "icon", "bool", 0, 0, 0 }, { "minimized", "bool", 0, 0, 0 }, - { "auto_rotate", "bool", 0, 0, 0 } + { "auto_rotate", "bool", 0, 0, 0 }, + { "window_title", "bool", "true", 0, 0 }, + { "title_font_bold", "bool", "true", 0, 0 }, + { "title_font_size", "int", "16696", 0, 0 }, + { "title_back_color", "color", "#feffc7ff", 0, 0 }, +//"0x00000x00000x00000x9999", 0, 0 }, + { "title_font_color", "color", "#f2ffc7ff", 0, 0 }, +//"0xffff0xffff0xffff0xffff", 0, 0 }, + { "title_text_placement", "int", "202", 0, 0 } }; static Bool @@ -1998,6 +2272,8 @@ if (ss->windowsSize) free (ss->windows); + switchFreeWindowTitle (s); + compFiniScreenOptions (s, ss->opt, SWITCH_SCREEN_OPTION_NUM); free (ss); --- a/metadata/switcher.xml.in 2008-01-27 12:02:24.000000000 +0100 +++ b/metadata/switcher.xml.in 2008-01-27 10:40:47.000000000 +0100 @@ -132,6 +132,65 @@ <_long>Rotate to the selected window while switching false + + <_short>Window title display + + + + + + +