2015-04-04 23:54:38 +00:00
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* This module is all original code */
|
2020-12-19 17:35:02 +00:00
|
|
|
|
/* by TakaC Hasegawa (tac.hasegawa@gmail.com) */
|
2015-04-04 23:54:38 +00:00
|
|
|
|
/* Copyright 1996, TakaC Hasegawa */
|
|
|
|
|
/* You may use this code for any purpose, as long as the original */
|
|
|
|
|
/* copyright remains in the source code and all documentation */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
|
|
#include "mlvwm.h"
|
|
|
|
|
#include "screen.h"
|
|
|
|
|
#include "menus.h"
|
|
|
|
|
#include "event.h"
|
|
|
|
|
#include "functions.h"
|
|
|
|
|
#include "misc.h"
|
|
|
|
|
#include "add_window.h"
|
|
|
|
|
#include "borders.h"
|
|
|
|
|
|
|
|
|
|
#include <X11/Xatom.h>
|
|
|
|
|
#include <X11/Xresource.h>
|
|
|
|
|
|
|
|
|
|
#include <X11/extensions/shape.h>
|
|
|
|
|
|
|
|
|
|
void RedrawMenu( MenuLabel *m, Bool onoroff )
|
|
|
|
|
{
|
|
|
|
|
GC tmp_f_GC, tmp_b_GC;
|
|
|
|
|
int width, offset;
|
|
|
|
|
unsigned long gcm;
|
|
|
|
|
XGCValues gcv;
|
|
|
|
|
Pixel fore_pixel, back_pixel;
|
|
|
|
|
|
|
|
|
|
if( Scr.flags&SYSTEM8 ){
|
|
|
|
|
gcm = GCForeground;
|
|
|
|
|
if( !XGetGCValues( dpy, Scr.MenuBlueGC, gcm, &gcv ) ){
|
|
|
|
|
fprintf( stderr, "Sorry Can not get GC Values Blue\n");
|
|
|
|
|
gcv.foreground = WhitePixel( dpy, Scr.screen );
|
|
|
|
|
}
|
|
|
|
|
fore_pixel = gcv.foreground;
|
|
|
|
|
if( !XGetGCValues( dpy, Scr.MenuSelectBlueGC, gcm, &gcv ) ){
|
|
|
|
|
fprintf( stderr, "Sorry Can not get GC Values SelectBlue\n");
|
|
|
|
|
gcv.foreground = WhitePixel( dpy, Scr.screen );
|
|
|
|
|
}
|
|
|
|
|
back_pixel = gcv.foreground;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
fore_pixel = WhitePixel( dpy, Scr.screen );
|
|
|
|
|
back_pixel = BlackPixel( dpy, Scr.screen );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( onoroff )
|
|
|
|
|
XSetWindowBackground( dpy, m->LabelWin, back_pixel );
|
|
|
|
|
else
|
|
|
|
|
XSetWindowBackground( dpy, m->LabelWin, fore_pixel );
|
|
|
|
|
XClearWindow( dpy, m->LabelWin );
|
|
|
|
|
|
|
|
|
|
if( m->LabelStr )
|
|
|
|
|
StrWidthHeight( MENUBARFONT, &width, NULL, &offset,
|
|
|
|
|
m->LabelStr, strlen(m->LabelStr));
|
|
|
|
|
|
|
|
|
|
if( onoroff ){
|
|
|
|
|
tmp_f_GC = Scr.WhiteGC;
|
|
|
|
|
tmp_b_GC = Scr.BlackGC;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
tmp_f_GC = Scr.BlackGC;
|
|
|
|
|
tmp_b_GC = Scr.WhiteGC;
|
|
|
|
|
}
|
|
|
|
|
if( !(m->flags&ACTIVE) && Scr.d_depth>1 )
|
|
|
|
|
tmp_f_GC = Scr.Gray3GC;
|
|
|
|
|
if( !m->xpm ){
|
|
|
|
|
if( m->LabelStr ){
|
|
|
|
|
XDRAWSTRING( dpy, m->LabelWin, MENUBARFONT, tmp_f_GC,
|
|
|
|
|
(m->LabelWidth-width)/2,
|
|
|
|
|
(MENUB_H-2)/2-offset,
|
|
|
|
|
m->LabelStr, strlen(m->LabelStr) );
|
|
|
|
|
/* Mask String for Mono Display */
|
|
|
|
|
if( !(m->flags&ACTIVE) && Scr.d_depth<2 ){
|
|
|
|
|
if( onoroff ) gcv.function = GXand;
|
|
|
|
|
else gcv.function = GXor;
|
|
|
|
|
gcm = GCFunction;
|
|
|
|
|
XChangeGC( dpy, Scr.BlackGC, gcm, &gcv );
|
|
|
|
|
XSetFillStyle( dpy, Scr.BlackGC, FillTiled );
|
|
|
|
|
XFillRectangle( dpy, m->LabelWin, Scr.BlackGC, 0, 0,
|
|
|
|
|
m->LabelWidth, MENUB_H);
|
|
|
|
|
XSetFillStyle( dpy, Scr.BlackGC, FillSolid );
|
|
|
|
|
gcv.function = GXcopy;
|
|
|
|
|
XChangeGC( dpy, Scr.BlackGC, gcm, &gcv );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
if( m->xpm->kind==PIXMAP ){
|
|
|
|
|
XSetClipMask( dpy, tmp_f_GC, m->xpm->mask );
|
|
|
|
|
XSetClipOrigin( dpy, tmp_f_GC,
|
|
|
|
|
(m->LabelWidth-m->xpm->width)/2,
|
|
|
|
|
(MENUB_H-2-m->xpm->height)/2 );
|
|
|
|
|
XCopyArea( dpy, m->xpm->icon, m->LabelWin, tmp_f_GC, 0, 0,
|
|
|
|
|
m->xpm->width, m->xpm->height,
|
|
|
|
|
(m->LabelWidth-m->xpm->width)/2,
|
|
|
|
|
(MENUB_H-2-m->xpm->height)/2 );
|
|
|
|
|
XSetClipMask( dpy, tmp_f_GC, None );
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
XCopyArea( dpy, onoroff?m->xpm->mask:m->xpm->icon, m->LabelWin,
|
|
|
|
|
tmp_f_GC, 0, 0,
|
|
|
|
|
m->xpm->width, m->xpm->height,
|
|
|
|
|
(m->LabelWidth-m->xpm->width)/2,
|
|
|
|
|
(MENUB_H-2-m->xpm->height)/2 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RedrawMenuBar( void )
|
|
|
|
|
{
|
|
|
|
|
int lp;
|
|
|
|
|
|
|
|
|
|
if( Scr.flags&SYSTEM8 )
|
|
|
|
|
DrawShadowBox( 0, 0, Scr.MyDisplayWidth, MENUB_H, Scr.MenuBar, 1,
|
|
|
|
|
Scr.WhiteGC, Scr.Gray1GC, SHADOW_ALL );
|
|
|
|
|
XFillRectangle( dpy, Scr.MenuBar, Scr.BlackGC, 0, 0, 7, 7 );
|
|
|
|
|
XFillRectangle( dpy, Scr.MenuBar,
|
|
|
|
|
Scr.BlackGC, Scr.MyDisplayWidth-7, 0, 7, 7 );
|
|
|
|
|
if( Scr.flags&SYSTEM8 && !(Scr.flags&STARTING) ){
|
|
|
|
|
for( lp=0; lp<2; lp++ ){
|
|
|
|
|
XDrawArc( dpy, Scr.MenuBar, Scr.WhiteGC, 0, 0,
|
|
|
|
|
14-lp, 14-lp, 180*64, -(90*64) );
|
|
|
|
|
XDrawArc( dpy, Scr.MenuBar, Scr.Gray1GC, Scr.MyDisplayWidth-15, 0,
|
|
|
|
|
14-lp, 14-lp, 0, 90*64 );
|
|
|
|
|
}
|
|
|
|
|
XFillArc( dpy, Scr.MenuBar, Scr.MenuBlueGC, 0, 0,
|
|
|
|
|
14, 14, 180*64, -(90*64) );
|
|
|
|
|
XFillArc( dpy, Scr.MenuBar, Scr.MenuBlueGC, Scr.MyDisplayWidth-15, 0,
|
|
|
|
|
14, 14, 0, 90*64 );
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
XFillArc( dpy, Scr.MenuBar, Scr.WhiteGC, 0, 0,
|
|
|
|
|
14, 14, 180*64, -(90*64) );
|
|
|
|
|
XFillArc( dpy, Scr.MenuBar, Scr.WhiteGC, Scr.MyDisplayWidth-15, 0,
|
|
|
|
|
14, 14, 0, 90*64 );
|
|
|
|
|
}
|
|
|
|
|
if( !(Scr.flags&SYSTEM8) )
|
|
|
|
|
XDrawLine( dpy, Scr.MenuBar, Scr.BlackGC,
|
|
|
|
|
0, MENUB_H-1, Scr.MyDisplayWidth, MENUB_H-1 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DrawStringMenuBar( char *str )
|
|
|
|
|
{
|
|
|
|
|
static int width=0;
|
|
|
|
|
int offset;
|
|
|
|
|
|
|
|
|
|
if( width!=0 ){
|
|
|
|
|
XFillRectangle( dpy, Scr.MenuBar, Scr.WhiteGC,
|
|
|
|
|
(Scr.MyDisplayWidth-width)/2, 0, width, MENUB_H-1 );
|
|
|
|
|
}
|
|
|
|
|
if( strlen( str )!=0 ){
|
|
|
|
|
StrWidthHeight( MENUBARFONT, &width, NULL, &offset,
|
|
|
|
|
str, strlen(str));
|
|
|
|
|
XDRAWSTRING( dpy, Scr.MenuBar, MENUBARFONT, Scr.BlackGC,
|
|
|
|
|
(Scr.MyDisplayWidth-width)/2,
|
|
|
|
|
MENUB_H/2-offset, str, strlen(str) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
XClearWindow( dpy, Scr.MenuBar );
|
|
|
|
|
RedrawMenuBar();
|
|
|
|
|
XSync( dpy, 0 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* X ɸ<><C9B8><EFBFBD>δؿ<CEB4><D8BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD>ǽ */
|
|
|
|
|
Bool isRect( int px, int py, int x, int y, int width, int height )
|
|
|
|
|
{
|
|
|
|
|
if( px>x && px<x+width && py>y && py<y+height ) return True;
|
|
|
|
|
else return False;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DrawCheckMark( MenuLabel *ml, GC gc, int topy )
|
|
|
|
|
{
|
|
|
|
|
XPoint check[] = {{3,5},{7,9},{16,0},{16,1},{7,10},{3,6}};
|
|
|
|
|
int lp;
|
|
|
|
|
|
|
|
|
|
for( lp=0; lp<6; lp++ )
|
|
|
|
|
check[lp].y += (topy+ml->ItemHeight/2-5);
|
|
|
|
|
XDrawLines( dpy, ml->PullWin, gc, check, 6, CoordModeOrigin );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DrawSubMenuMark( MenuLabel *ml, GC gc, int topy )
|
|
|
|
|
{
|
|
|
|
|
XPoint mark[] = {{15, -7}, {15, 7}, {7,0}};
|
|
|
|
|
int lp;
|
|
|
|
|
|
|
|
|
|
for( lp=0; lp<3; lp++ ){
|
|
|
|
|
mark[lp].x = ml->MenuWidth-mark[lp].x;
|
|
|
|
|
mark[lp].y += (topy+ml->ItemHeight/2);
|
|
|
|
|
}
|
|
|
|
|
XFillPolygon( dpy, ml->PullWin, gc, mark, 3, Convex, CoordModeOrigin );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MenuLabel *DrawMenuItem( MenuLabel *ml, int sel, Bool on )
|
|
|
|
|
{
|
|
|
|
|
GC r_tmpGC, s_tmpGC;
|
|
|
|
|
int label_p, top_y, lp, width, offset;
|
|
|
|
|
Pixmap icon;
|
|
|
|
|
MenuItem *mi;
|
|
|
|
|
unsigned long gcm;
|
|
|
|
|
XGCValues gcv;
|
|
|
|
|
char dots[] = { 2, 2 };
|
|
|
|
|
|
|
|
|
|
for( lp=0, mi = ml->m_item; lp<sel-1; lp++, mi=mi->next );
|
|
|
|
|
if( !(mi->mode&SELECTON) && on ) return NULL;
|
|
|
|
|
|
|
|
|
|
top_y = ml->ItemHeight*(sel-1);
|
|
|
|
|
label_p = ml->ItemHeight==0?20:20+ml->ItemHeight+5;
|
|
|
|
|
|
|
|
|
|
if( on ){
|
|
|
|
|
r_tmpGC = Scr.flags&SYSTEM8?Scr.MenuSelectBlueGC:Scr.BlackGC;
|
|
|
|
|
s_tmpGC = Scr.WhiteGC;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
r_tmpGC = Scr.flags&SYSTEM8?Scr.MenuBlueGC:Scr.WhiteGC;
|
|
|
|
|
s_tmpGC = Scr.BlackGC;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( mi->mode&STRGRAY && Scr.d_depth>2 )
|
|
|
|
|
s_tmpGC = Scr.Gray3GC;
|
|
|
|
|
XFillRectangle( dpy, ml->PullWin, r_tmpGC,
|
|
|
|
|
0+(Scr.flags&SYSTEM8?1:0), top_y,
|
|
|
|
|
ml->MenuWidth-(Scr.flags&SYSTEM8?2:0), ml->ItemHeight );
|
|
|
|
|
|
|
|
|
|
/** Draw Check Mark. **/
|
|
|
|
|
if( mi->mode & CHECKON )
|
|
|
|
|
DrawCheckMark( ml, s_tmpGC, top_y );
|
|
|
|
|
/** Draw Submenu Mark **/
|
|
|
|
|
if( mi->submenu )
|
|
|
|
|
DrawSubMenuMark( ml, s_tmpGC, top_y );
|
|
|
|
|
/** Draw Icon. **/
|
|
|
|
|
if( mi->xpm ){
|
|
|
|
|
if( mi->mode&STRGRAY || mi->mode&ICONGRAY)
|
|
|
|
|
icon = mi->xpm->lighticon;
|
|
|
|
|
else
|
|
|
|
|
icon = mi->xpm->icon;
|
|
|
|
|
if( mi->xpm->kind==PIXMAP ){
|
|
|
|
|
XSetClipMask( dpy, s_tmpGC, mi->xpm->mask );
|
|
|
|
|
XSetClipOrigin( dpy, s_tmpGC,
|
|
|
|
|
20+(ml->IconWidth-mi->xpm->width)/2,
|
|
|
|
|
top_y+(ml->ItemHeight-mi->xpm->height)/2);
|
|
|
|
|
XCopyArea( dpy, icon, ml->PullWin, s_tmpGC, 0, 0,
|
|
|
|
|
mi->xpm->width, mi->xpm->height,
|
|
|
|
|
20+(ml->IconWidth-mi->xpm->width)/2,
|
|
|
|
|
top_y+(ml->ItemHeight-mi->xpm->height)/2);
|
|
|
|
|
XSetClipMask( dpy, s_tmpGC, None );
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
XCopyArea( dpy, on?mi->xpm->mask:mi->xpm->icon,
|
|
|
|
|
ml->PullWin, s_tmpGC, 0, 0,
|
|
|
|
|
mi->xpm->width, mi->xpm->height,
|
|
|
|
|
20+(ml->IconWidth-mi->xpm->width)/2,
|
|
|
|
|
top_y+(ml->ItemHeight-mi->xpm->height)/2);
|
|
|
|
|
if( mi->mode&ICONGRAY ){
|
|
|
|
|
if( on ) gcv.function = GXand;
|
|
|
|
|
else gcv.function = GXor;
|
|
|
|
|
gcm = GCFunction;
|
|
|
|
|
XChangeGC( dpy, Scr.BlackGC, gcm, &gcv );
|
|
|
|
|
XSetFillStyle( dpy, Scr.BlackGC, FillTiled );
|
|
|
|
|
XFillRectangle( dpy, ml->PullWin, Scr.BlackGC, 21, top_y,
|
|
|
|
|
mi->xpm->width, ml->ItemHeight );
|
|
|
|
|
XSetFillStyle( dpy, Scr.BlackGC, FillSolid );
|
|
|
|
|
gcv.function = GXcopy;
|
|
|
|
|
XChangeGC( dpy, Scr.BlackGC, gcm, &gcv );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/** Draw Label String. **/
|
|
|
|
|
if( mi->label ){
|
|
|
|
|
StrWidthHeight( MENUFONT, &width, NULL, &offset,
|
|
|
|
|
mi->label, strlen(mi->label));
|
|
|
|
|
XDRAWSTRING( dpy, ml->PullWin, MENUFONT, s_tmpGC,
|
|
|
|
|
(mi->xpm!=NULL?label_p:20),
|
|
|
|
|
top_y+ml->ItemHeight/2-offset,
|
|
|
|
|
mi->label, strlen(mi->label) );
|
|
|
|
|
/* Mask String for Mono Display */
|
|
|
|
|
if( mi->mode&STRGRAY && Scr.d_depth<2 ){
|
|
|
|
|
if( on ) gcv.function = GXand;
|
|
|
|
|
else gcv.function = GXor;
|
|
|
|
|
gcm = GCFunction;
|
|
|
|
|
XChangeGC( dpy, Scr.BlackGC, gcm, &gcv );
|
|
|
|
|
XSetFillStyle( dpy, Scr.BlackGC, FillTiled );
|
|
|
|
|
XFillRectangle( dpy, ml->PullWin, Scr.BlackGC, 0, top_y,
|
|
|
|
|
ml->MenuWidth, ml->ItemHeight );
|
|
|
|
|
XSetFillStyle( dpy, Scr.BlackGC, FillSolid );
|
|
|
|
|
gcv.function = GXcopy;
|
|
|
|
|
XChangeGC( dpy, Scr.BlackGC, gcm, &gcv );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( mi->label && mi->label[0]=='\0' ){
|
|
|
|
|
if( Scr.d_depth>1 ){
|
|
|
|
|
if( Scr.flags&SYSTEM8 ){
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.Gray2GC,
|
|
|
|
|
2, top_y+ml->ItemHeight/2,
|
|
|
|
|
ml->MenuWidth-3, top_y+ml->ItemHeight/2);
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.WhiteGC,
|
|
|
|
|
3, top_y+ml->ItemHeight/2+1,
|
|
|
|
|
ml->MenuWidth-2, top_y+ml->ItemHeight/2+1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.Gray2GC,
|
|
|
|
|
0, top_y+ml->ItemHeight/2,
|
|
|
|
|
ml->MenuWidth, top_y+ml->ItemHeight/2);
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
gcm = GCLineStyle;
|
|
|
|
|
gcv.line_style = LineOnOffDash;
|
|
|
|
|
XChangeGC( dpy, Scr.BlackGC, gcm, &gcv );
|
|
|
|
|
XSetDashes( dpy, Scr.BlackGC, 0, dots, 2 );
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.BlackGC,
|
|
|
|
|
0, top_y+ml->ItemHeight/2,
|
|
|
|
|
ml->MenuWidth, top_y+ml->ItemHeight/2);
|
|
|
|
|
gcm = GCLineStyle;
|
|
|
|
|
gcv.line_style = FillSolid;
|
|
|
|
|
XChangeGC( dpy, Scr.BlackGC, gcm, &gcv );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mi->submenu;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SortMenuItem( MenuLabel *m, MenuItem *start )
|
|
|
|
|
{
|
|
|
|
|
MenuItem *fence, *lastSwap, *i, *j, *k;
|
|
|
|
|
|
|
|
|
|
for(fence = NULL; fence != start; fence = lastSwap )
|
|
|
|
|
for(j = (lastSwap = i = start)->next;
|
|
|
|
|
(k = j->next) != fence;
|
|
|
|
|
i = j, j = k ){
|
|
|
|
|
if ( strcmp( j->label, k->label ) > 0 ){
|
|
|
|
|
i->next = k;
|
|
|
|
|
j->next = k->next;
|
|
|
|
|
lastSwap = k->next = j;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************
|
|
|
|
|
MenuLabel *m Menu Label of Target
|
|
|
|
|
int left left side position of menu
|
|
|
|
|
int right right side position of menu
|
|
|
|
|
int y Height of menu
|
|
|
|
|
Bool side True left(Tear off right)
|
|
|
|
|
False right(Tear off left)
|
|
|
|
|
*****************************************************************/
|
|
|
|
|
Bool MapMenu( MenuLabel *m, int left, int right, int y, Bool side )
|
|
|
|
|
{
|
|
|
|
|
int lp, items=0;
|
|
|
|
|
int label_w, local_mw=0, height;
|
|
|
|
|
MenuItem *mi;
|
|
|
|
|
|
|
|
|
|
if( m->LabelWin!=None ) RedrawMenu( m, True );
|
|
|
|
|
|
|
|
|
|
if( m == &Scr.IconMenu && Scr.iconAnchor->next )
|
|
|
|
|
SortMenuItem( &Scr.IconMenu, Scr.iconAnchor );
|
|
|
|
|
|
|
|
|
|
m->MenuWidth = 0;
|
|
|
|
|
m->MenuHeight = 0;
|
|
|
|
|
m->ItemHeight = 0;
|
|
|
|
|
m->IconWidth = 0;
|
|
|
|
|
m->SelectNum = -1;
|
|
|
|
|
|
|
|
|
|
for( mi = m->m_item; mi; mi=mi->next ){
|
|
|
|
|
StrWidthHeight( MENUFONT, &label_w, &height, NULL,
|
|
|
|
|
mi->label, strlen(mi->label));
|
|
|
|
|
m->ItemHeight = max( height, m->ItemHeight );
|
|
|
|
|
if( mi->iconname && !(mi->xpm) )
|
|
|
|
|
mi->xpm = ReadIcon( mi->iconname, NULL, False );
|
|
|
|
|
if( mi->xpm ){
|
|
|
|
|
m->ItemHeight = max( mi->xpm->height, m->ItemHeight );
|
|
|
|
|
m->IconWidth = max( mi->xpm->width, m->IconWidth );
|
|
|
|
|
local_mw = 20+mi->xpm->width+5+label_w+10;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
local_mw = 20+label_w+10;
|
|
|
|
|
if( mi->submenu ) local_mw += 15;
|
|
|
|
|
m->MenuWidth = max( local_mw, m->MenuWidth );
|
|
|
|
|
if( (mi->label && mi->label[0]) || mi->next )
|
|
|
|
|
items++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m->ItemHeight+=2;
|
|
|
|
|
m->MenuHeight = m->ItemHeight*items;
|
|
|
|
|
|
|
|
|
|
if( side )
|
|
|
|
|
m->MenuX = left;
|
|
|
|
|
else
|
|
|
|
|
m->MenuX = right-m->MenuWidth;
|
|
|
|
|
|
|
|
|
|
if( m->MenuX+m->MenuWidth > Scr.MyDisplayWidth ){
|
|
|
|
|
m->MenuX = right-m->MenuWidth;
|
|
|
|
|
side = False;
|
|
|
|
|
}
|
|
|
|
|
if( m->MenuX < 0 ){
|
|
|
|
|
m->MenuX = 0;
|
|
|
|
|
side = True;
|
|
|
|
|
}
|
|
|
|
|
m->MenuY = y+m->MenuHeight<Scr.MyDisplayHeight ?
|
|
|
|
|
y : Scr.MyDisplayHeight-m->MenuHeight;
|
|
|
|
|
m->MenuY = m->MenuY<MENUB_H-1 ? MENUB_H-1 : m->MenuY;
|
|
|
|
|
if( Scr.flags&SYSTEM8 ){
|
|
|
|
|
m->MenuWidth+=2;
|
|
|
|
|
m->MenuHeight+=1;
|
|
|
|
|
}
|
|
|
|
|
XMoveResizeWindow( dpy, m->PullWin, m->MenuX, m->MenuY,
|
|
|
|
|
m->MenuWidth+2, m->MenuHeight+2 );
|
|
|
|
|
{
|
|
|
|
|
XRectangle rect[7];
|
|
|
|
|
int point=0;
|
|
|
|
|
|
|
|
|
|
rect[point].x = -1; rect[point].y = -1;
|
|
|
|
|
rect[point].width = m->MenuWidth+1;
|
|
|
|
|
rect[point].height = m->MenuHeight+1;
|
|
|
|
|
point++;
|
|
|
|
|
for( lp=1; lp<4; lp++ ){
|
|
|
|
|
rect[point].x = m->MenuWidth+lp-1; rect[point].y = lp-1;
|
|
|
|
|
rect[point].width = 1; rect[point].height = m->MenuHeight+2-lp+1;
|
|
|
|
|
point++;
|
|
|
|
|
}
|
|
|
|
|
for( lp=1; lp<4; lp++ ){
|
|
|
|
|
rect[point].x = lp-1; rect[point].y = m->MenuHeight+lp-1;
|
|
|
|
|
rect[point].width = m->MenuWidth+2-lp+1; rect[point].height = 1;
|
|
|
|
|
point++;
|
|
|
|
|
}
|
|
|
|
|
XShapeCombineRectangles(dpy,m->PullWin,ShapeBounding,
|
|
|
|
|
0,0,rect,point,ShapeSet,Unsorted);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XMapRaised( dpy, m->PullWin );
|
|
|
|
|
|
|
|
|
|
return side;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UnmapMenu( MenuLabel *m, int mode )
|
|
|
|
|
{
|
|
|
|
|
if( mode&UNMAP_WINDOW ){
|
|
|
|
|
XUnmapWindow( dpy, m->PullWin );
|
|
|
|
|
m->SelectNum = -1;
|
|
|
|
|
}
|
|
|
|
|
if( mode&UNMAP_LABEL )
|
|
|
|
|
RedrawMenu( m, False );
|
|
|
|
|
XSync( dpy, 0 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ExecMenu( MenuLabel *m, int selected )
|
|
|
|
|
{
|
|
|
|
|
int lp;
|
|
|
|
|
MenuItem *tmp_item;
|
|
|
|
|
|
|
|
|
|
for( lp=0, tmp_item = m->m_item; lp<selected-1;
|
|
|
|
|
lp++,tmp_item=tmp_item->next );
|
|
|
|
|
if( !(tmp_item->mode&SELECTON) || !(tmp_item->action ))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for( lp=0; lp<Scr.flush_times; lp++ ){
|
|
|
|
|
DrawMenuItem( m, selected, False ); XFlush( dpy );
|
|
|
|
|
sleep_a_little( Scr.flush_time );
|
|
|
|
|
DrawMenuItem( m, selected, True ); XFlush( dpy );
|
|
|
|
|
sleep_a_little( Scr.flush_time );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DrawMenuItem( m, selected, True );
|
|
|
|
|
XFlush( dpy );
|
|
|
|
|
UnmapMenu( m, UNMAP_WINDOW );
|
|
|
|
|
ExecuteFunction( tmp_item->action );
|
|
|
|
|
UnmapMenu( m, UNMAP_LABEL );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DrawMenuItemAll( MenuLabel *ml )
|
|
|
|
|
{
|
|
|
|
|
int lp;
|
|
|
|
|
MenuItem *tmp_item;
|
|
|
|
|
|
|
|
|
|
for( lp=0, tmp_item=ml->m_item; tmp_item; lp++,tmp_item=tmp_item->next )
|
|
|
|
|
DrawMenuItem( ml, lp+1, lp+1==ml->SelectNum?True:False );
|
|
|
|
|
for( lp=0; lp<2; lp++ ){
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.BlackGC,
|
|
|
|
|
lp, ml->MenuHeight+lp, ml->MenuWidth+1, ml->MenuHeight+lp );
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.BlackGC,
|
|
|
|
|
ml->MenuWidth+lp, lp, ml->MenuWidth+lp, ml->MenuHeight);
|
|
|
|
|
}
|
|
|
|
|
if( Scr.flags&SYSTEM8 ){
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.WhiteGC,
|
|
|
|
|
0, 0, 0, ml->MenuHeight );
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.Gray2GC,
|
|
|
|
|
0, ml->MenuHeight-1, ml->MenuWidth-1, ml->MenuHeight-1 );
|
|
|
|
|
XDrawLine( dpy, ml->PullWin, Scr.Gray2GC,
|
|
|
|
|
ml->MenuWidth-1, 0, ml->MenuWidth-1, ml->MenuHeight-1 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool ChoiseMenu( MenuLabel *m, Window *entwin, int ignore, Bool side )
|
|
|
|
|
{
|
|
|
|
|
Bool isEnd = False, finishall=False, Release=False, ChildSide=True;
|
|
|
|
|
XEvent Event;
|
|
|
|
|
MenuLabel *mapped=NULL, *tmp_menu;
|
|
|
|
|
|
|
|
|
|
while( !isEnd && !finishall){
|
2015-04-05 00:01:23 +00:00
|
|
|
|
XMaskEvent( dpy, ExposureMask | ButtonReleaseMask | ButtonPressMask|
|
|
|
|
|
EnterWindowMask | PointerMotionMask | ButtonMotionMask,
|
|
|
|
|
&Event );
|
|
|
|
|
// XNextEvent( dpy, &Event );
|
2015-04-04 23:54:38 +00:00
|
|
|
|
switch( Event.type ){
|
|
|
|
|
case Expose:
|
|
|
|
|
if( XFindContext( dpy, Event.xany.window, MenuContext,
|
|
|
|
|
(caddr_t *)&tmp_menu )!=XCNOENT ){
|
|
|
|
|
if( Event.xexpose.count==0 ) DrawMenuItemAll( tmp_menu );
|
|
|
|
|
}
|
|
|
|
|
else handle_expose( &Event );
|
|
|
|
|
break;
|
|
|
|
|
case EnterNotify:
|
|
|
|
|
if( XFindContext( dpy, Event.xcrossing.window, MenuContext,
|
|
|
|
|
(caddr_t *)&tmp_menu )!=XCNOENT ){
|
|
|
|
|
if( tmp_menu==mapped ){
|
|
|
|
|
finishall = ChoiseMenu( mapped, entwin, ignore, ChildSide );
|
|
|
|
|
if( *entwin!=m->PullWin ) isEnd = True;
|
|
|
|
|
}
|
|
|
|
|
else if( tmp_menu!=m || Event.xcrossing.window==m->LabelWin ){
|
|
|
|
|
isEnd = True;
|
|
|
|
|
*entwin = Event.xcrossing.window;
|
|
|
|
|
if( m->SelectNum != -1 ){
|
|
|
|
|
DrawMenuItem( m, m->SelectNum, False );
|
|
|
|
|
m->SelectNum = -1;
|
|
|
|
|
if( mapped ){
|
|
|
|
|
UnmapMenu( mapped, UNMAP_ALL );
|
|
|
|
|
mapped = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( Event.xcrossing.window == Scr.MenuBar &&
|
|
|
|
|
Event.xcrossing.detail!=NotifyNonlinearVirtual ){
|
|
|
|
|
isEnd = True;
|
|
|
|
|
*entwin = Scr.MenuBar;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ButtonRelease:
|
|
|
|
|
if( ignore ){
|
|
|
|
|
isEnd = True;
|
|
|
|
|
finishall = True;
|
|
|
|
|
Release = True;
|
|
|
|
|
}
|
|
|
|
|
else ignore++;
|
|
|
|
|
break;
|
|
|
|
|
case MotionNotify:
|
|
|
|
|
if(isRect( Event.xbutton.x, Event.xbutton.y, 0, 0,
|
|
|
|
|
m->MenuWidth, m->MenuHeight ) &&
|
|
|
|
|
Event.xany.window == m->PullWin ){
|
|
|
|
|
if( m->SelectNum != (Event.xbutton.y-3)/m->ItemHeight+1 ){
|
|
|
|
|
if( m->SelectNum != -1 ){
|
|
|
|
|
DrawMenuItem( m, m->SelectNum, False);
|
|
|
|
|
if( mapped ){
|
|
|
|
|
UnmapMenu( mapped, UNMAP_ALL );
|
|
|
|
|
mapped = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m->SelectNum = (Event.xbutton.y-3)/m->ItemHeight+1;
|
|
|
|
|
mapped=DrawMenuItem( m, m->SelectNum, True );
|
|
|
|
|
if( mapped ){
|
|
|
|
|
ChildSide = MapMenu( mapped,
|
|
|
|
|
m->MenuX+m->MenuWidth-5, m->MenuX+5,
|
|
|
|
|
(m->MenuY==MENUB_H-1 && m->SelectNum==1) ?
|
|
|
|
|
m->MenuY+m->ItemHeight/2 :
|
|
|
|
|
m->MenuY+m->ItemHeight*(m->SelectNum-1),
|
|
|
|
|
side );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( m->SelectNum != -1 ){
|
|
|
|
|
DrawMenuItem( m, m->SelectNum, False );
|
|
|
|
|
m->SelectNum = -1;
|
|
|
|
|
if( mapped ){
|
|
|
|
|
UnmapMenu( mapped, UNMAP_ALL );
|
|
|
|
|
mapped = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( mapped ){
|
|
|
|
|
UnmapMenu( mapped, UNMAP_ALL );
|
|
|
|
|
DrawMenuItemAll( m );
|
|
|
|
|
}
|
|
|
|
|
if( Release && m->SelectNum!=-1 ){
|
|
|
|
|
UnGrabEvent();
|
|
|
|
|
ExecMenu( m, m->SelectNum );
|
|
|
|
|
if( !GrabEvent( DEFAULT ) ){
|
|
|
|
|
XBell( dpy, 30 );
|
|
|
|
|
return finishall;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return finishall;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void press_menu( MenuLabel *m )
|
|
|
|
|
{
|
|
|
|
|
Bool isEnd = False, Side=True;
|
|
|
|
|
XEvent Event;
|
|
|
|
|
MenuLabel *mapped, *tmp_menu;
|
|
|
|
|
int x, y, JunkX, JunkY;
|
|
|
|
|
unsigned int JunkMask;
|
|
|
|
|
Window JunkRoot, JunkChild, entwin;
|
|
|
|
|
int ignore;
|
|
|
|
|
|
|
|
|
|
if( m!=NULL )
|
|
|
|
|
Side=MapMenu( m, m->LabelX, m->LabelX+m->LabelWidth, MENUB_H-1, True );
|
|
|
|
|
|
|
|
|
|
if( !GrabEvent( DEFAULT ) ){
|
|
|
|
|
XBell( dpy, 30 );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( Scr.flags&ONECLICKMENU ) ignore=0;
|
|
|
|
|
else ignore=1;
|
|
|
|
|
|
|
|
|
|
mapped = m;
|
|
|
|
|
while( !isEnd ){
|
2015-04-05 00:01:23 +00:00
|
|
|
|
XMaskEvent( dpy, ExposureMask | ButtonReleaseMask | ButtonPressMask|
|
|
|
|
|
EnterWindowMask | PointerMotionMask | ButtonMotionMask,
|
|
|
|
|
&Event );
|
|
|
|
|
// XNextEvent( dpy, &Event );
|
2015-04-04 23:54:38 +00:00
|
|
|
|
switch( Event.type ){
|
|
|
|
|
case Expose:
|
|
|
|
|
if( mapped && Event.xany.window==mapped->PullWin &&
|
|
|
|
|
Event.xexpose.count==0 )
|
|
|
|
|
DrawMenuItemAll( mapped );
|
|
|
|
|
else
|
|
|
|
|
handle_expose( &Event );
|
|
|
|
|
break;
|
|
|
|
|
case ButtonRelease:
|
|
|
|
|
if( ignore ) isEnd = True;
|
|
|
|
|
else ignore++;
|
|
|
|
|
break;
|
|
|
|
|
case EnterNotify:
|
|
|
|
|
if( XFindContext( dpy, Event.xcrossing.window,
|
|
|
|
|
MenuContext, (caddr_t *)&tmp_menu )
|
|
|
|
|
!=XCNOENT ){
|
|
|
|
|
if( mapped != tmp_menu ){
|
|
|
|
|
if( mapped ) UnmapMenu( mapped, UNMAP_ALL );
|
|
|
|
|
mapped = tmp_menu;
|
|
|
|
|
Side = MapMenu( mapped, mapped->LabelX,
|
|
|
|
|
mapped->LabelX+mapped->LabelWidth,
|
|
|
|
|
MENUB_H-1, True );
|
|
|
|
|
}
|
|
|
|
|
else if( Event.xcrossing.window==mapped->PullWin ){
|
|
|
|
|
isEnd = ChoiseMenu( mapped, &entwin, ignore, Side );
|
|
|
|
|
if( entwin == Scr.MenuBar ){
|
|
|
|
|
UnmapMenu( mapped, UNMAP_ALL );
|
|
|
|
|
mapped = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( Event.xcrossing.window==Scr.MenuBar &&
|
|
|
|
|
Event.xcrossing.detail!=NotifyVirtual ){
|
|
|
|
|
if( mapped!=NULL ){
|
|
|
|
|
XQueryPointer( dpy, mapped->PullWin,
|
|
|
|
|
&JunkRoot, &JunkChild,
|
|
|
|
|
&x, &y,&JunkX, &JunkY,&JunkMask);
|
|
|
|
|
if( !isRect( x, y, 0, 0,
|
|
|
|
|
mapped->MenuWidth, mapped->MenuHeight ) &&
|
|
|
|
|
!isRect( x-mapped->LabelX, y, 0, 0,
|
|
|
|
|
mapped->LabelWidth, MENUB_H )){
|
|
|
|
|
UnmapMenu( mapped, UNMAP_ALL );
|
|
|
|
|
mapped = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( mapped ) UnmapMenu( mapped, UNMAP_ALL );
|
|
|
|
|
UnGrabEvent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool SwallowMenu( MenuLabel *ml )
|
|
|
|
|
{
|
|
|
|
|
XEvent ev;
|
|
|
|
|
XClassHint class;
|
|
|
|
|
XSizeHints hints;
|
|
|
|
|
MlvwmWindow *tmp_win;
|
|
|
|
|
Bool done=True;
|
|
|
|
|
char *name, *comm, *fullpath;
|
|
|
|
|
long supplied=0;
|
|
|
|
|
Atom *protocols = NULL, *ap;
|
|
|
|
|
int n, lp;
|
|
|
|
|
XWindowAttributes attr;
|
|
|
|
|
XTextProperty text_prop;
|
|
|
|
|
#ifdef USE_LOCALE
|
|
|
|
|
int num;
|
|
|
|
|
char **list;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
stripquote( ml->action, &comm );
|
|
|
|
|
if( comm==NULL ){
|
|
|
|
|
ml->flags &= ~SWALLOW;
|
|
|
|
|
|
|
|
|
|
return False;
|
|
|
|
|
}
|
|
|
|
|
if( (fullpath=LookUpFiles( getenv("PATH"), comm, X_OK ))==NULL ){
|
|
|
|
|
ml->flags &= ~SWALLOW;
|
|
|
|
|
DrawErrMsgOnMenu( "Swallow Falied(Can't Exec) ", comm );
|
|
|
|
|
return False;
|
|
|
|
|
}
|
|
|
|
|
free( fullpath );
|
|
|
|
|
free( comm );
|
|
|
|
|
ExecuteFunction( ml->action );
|
|
|
|
|
|
|
|
|
|
do{
|
|
|
|
|
XMaskEvent( dpy, SubstructureRedirectMask |
|
|
|
|
|
StructureNotifyMask | SubstructureNotifyMask, &ev );
|
|
|
|
|
if( ev.type==MapRequest ){
|
|
|
|
|
if( XGetWMName( dpy, ev.xmaprequest.window, &text_prop) != 0 ){
|
|
|
|
|
#ifdef USE_LOCALE
|
|
|
|
|
if(text_prop.value)
|
|
|
|
|
text_prop.nitems = strlen(text_prop.value);
|
|
|
|
|
if(XmbTextPropertyToTextList(dpy, &text_prop, &list, &num)
|
|
|
|
|
>= Success
|
|
|
|
|
&& num > 0 && *list)
|
|
|
|
|
name = *list;
|
|
|
|
|
else
|
|
|
|
|
name = NoName;
|
|
|
|
|
#else
|
|
|
|
|
name = (char *)text_prop.value;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
name = NoName;
|
|
|
|
|
|
|
|
|
|
XGetClassHint(dpy, ev.xmaprequest.window, &class);
|
|
|
|
|
if( !strcmp( name, ml->name ) ||
|
|
|
|
|
!strcmp( class.res_name, ml->name ) ||
|
|
|
|
|
!strcmp( class.res_class, ml->name ) ){
|
|
|
|
|
done = False;
|
|
|
|
|
XGetWindowAttributes( dpy, ev.xmaprequest.window, &attr );
|
|
|
|
|
|
|
|
|
|
if(!XGetWMNormalHints( dpy, ev.xmaprequest.window, &hints,
|
|
|
|
|
&supplied ))
|
|
|
|
|
hints.flags = 0;
|
2015-04-04 23:58:04 +00:00
|
|
|
|
if((USSize | PSize ) & hints.flags ){
|
2015-04-04 23:54:38 +00:00
|
|
|
|
ml->LabelWidth = hints.width;
|
2015-04-04 23:58:04 +00:00
|
|
|
|
ml->LabelHeight = hints.height;
|
|
|
|
|
}
|
|
|
|
|
else{
|
2015-04-04 23:54:38 +00:00
|
|
|
|
ml->LabelWidth = attr.width;
|
2015-04-04 23:58:04 +00:00
|
|
|
|
ml->LabelHeight = attr.height;
|
|
|
|
|
}
|
2015-04-04 23:54:38 +00:00
|
|
|
|
ml->LabelWin = ev.xmaprequest.window;
|
|
|
|
|
ml->flags &= ~CANDELETE;
|
|
|
|
|
if(XGetWMProtocols (dpy, ml->LabelWin, &protocols, &n)){
|
|
|
|
|
for( lp=0, ap=protocols; lp<n; lp++, ap++)
|
|
|
|
|
if(*ap == (Atom)_XA_WM_DELETE_WINDOW)
|
|
|
|
|
ml->flags |= CANDELETE;
|
|
|
|
|
}
|
|
|
|
|
if (protocols) XFree ((char *) protocols);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
HandleEvents( ev );
|
|
|
|
|
if( name!=NoName ) XFree( name );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
HandleEvents( ev );
|
|
|
|
|
if( ev.type==MapNotify &&
|
2015-04-04 23:58:04 +00:00
|
|
|
|
XFindContext(dpy, ev.xany.window, MlvwmContext, (caddr_t *)&tmp_win)
|
2015-04-04 23:54:38 +00:00
|
|
|
|
!=XCNOENT)
|
|
|
|
|
DrawStringMenuBar( tmp_win->name );
|
|
|
|
|
}
|
|
|
|
|
while( done );
|
|
|
|
|
return True;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CreateMenuLabel( MenuLabel *ml )
|
|
|
|
|
{
|
|
|
|
|
unsigned long valuemask;
|
|
|
|
|
XSetWindowAttributes attributes;
|
|
|
|
|
int width;
|
|
|
|
|
|
|
|
|
|
if( ml->flags&SWALLOW ){
|
|
|
|
|
if( SwallowMenu( ml ) ){
|
|
|
|
|
XSetWindowBorderWidth( dpy, ml->LabelWin, 0 );
|
2015-04-04 23:58:04 +00:00
|
|
|
|
// XResizeWindow( dpy, ml->LabelWin, ml->LabelWidth, MENUB_H-2 );
|
2015-04-04 23:54:38 +00:00
|
|
|
|
XReparentWindow( dpy, ml->LabelWin, Scr.MenuBar, 0, 0 );
|
2015-04-04 23:58:04 +00:00
|
|
|
|
ml->LabelWidth += 6;
|
2015-04-04 23:54:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else{
|
2015-04-04 23:58:04 +00:00
|
|
|
|
if( ml->xpm ){
|
2015-04-04 23:54:38 +00:00
|
|
|
|
ml->LabelWidth = ml->xpm->width+16;
|
2015-04-04 23:58:04 +00:00
|
|
|
|
ml->LabelHeight = ml->xpm->height;
|
|
|
|
|
}
|
2015-04-04 23:54:38 +00:00
|
|
|
|
else{
|
2015-04-04 23:58:04 +00:00
|
|
|
|
ml->LabelHeight = 0;
|
2015-04-04 23:54:38 +00:00
|
|
|
|
if( ml->LabelStr ){
|
|
|
|
|
StrWidthHeight( MENUBARFONT, &width, NULL, NULL,
|
|
|
|
|
ml->LabelStr, strlen(ml->LabelStr));
|
|
|
|
|
ml->LabelWidth = width+16;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
ml->LabelWidth = 16;
|
|
|
|
|
}
|
|
|
|
|
valuemask = CWCursor | CWEventMask | CWBackPixel;
|
|
|
|
|
attributes.background_pixel = WhitePixel( dpy, Scr.screen );
|
|
|
|
|
attributes.cursor = Scr.MlvwmCursors[DEFAULT];
|
|
|
|
|
attributes.event_mask = (ButtonPressMask | ButtonReleaseMask |
|
|
|
|
|
EnterWindowMask | ExposureMask |
|
|
|
|
|
OwnerGrabButtonMask | PointerMotionMask);
|
|
|
|
|
ml->LabelWin = XCreateWindow( dpy, Scr.MenuBar, 0, 1,
|
|
|
|
|
ml->LabelWidth, MENUB_H-2, 0,
|
|
|
|
|
CopyFromParent, InputOutput,
|
|
|
|
|
CopyFromParent,
|
|
|
|
|
valuemask, &attributes );
|
|
|
|
|
XSaveContext( dpy, ml->LabelWin, MenuContext, (caddr_t)ml );
|
2015-04-04 23:58:04 +00:00
|
|
|
|
|
|
|
|
|
valuemask = CWCursor | CWEventMask | CWBackPixel;
|
|
|
|
|
attributes.background_pixel = WhitePixel( dpy, Scr.screen );
|
|
|
|
|
attributes.cursor = Scr.MlvwmCursors[DEFAULT];
|
|
|
|
|
attributes.event_mask = (SubstructureRedirectMask | ExposureMask |
|
|
|
|
|
SubstructureNotifyMask | PointerMotionMask |
|
|
|
|
|
EnterWindowMask | LeaveWindowMask );
|
|
|
|
|
ml->PullWin = XCreateWindow( dpy, Scr.Root, 0, 0, 10, 10 , 1,
|
|
|
|
|
CopyFromParent, InputOutput,
|
|
|
|
|
CopyFromParent,
|
|
|
|
|
valuemask, &attributes );
|
|
|
|
|
XSaveContext( dpy, ml->PullWin, MenuContext, (caddr_t)ml );
|
2015-04-04 23:54:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AddMenuItem( MenuLabel *ml, char *label, char *action, char *icon, Icon *miniicon, MenuLabel *submenu, int mode )
|
|
|
|
|
{
|
|
|
|
|
MenuItem *tmpitem, *newitem;
|
|
|
|
|
|
|
|
|
|
newitem = calloc( 1, sizeof( MenuItem ) );
|
|
|
|
|
|
|
|
|
|
if( ml->m_item == NULL )
|
|
|
|
|
ml->m_item = newitem;
|
|
|
|
|
else{
|
|
|
|
|
for( tmpitem=ml->m_item; tmpitem->next; tmpitem=tmpitem->next );
|
|
|
|
|
tmpitem->next = newitem;
|
|
|
|
|
}
|
|
|
|
|
newitem->label = strdup( label );
|
|
|
|
|
newitem->action = action ? strdup( action ) : action ;
|
|
|
|
|
newitem->iconname = icon ? strdup( icon ) : icon ;
|
|
|
|
|
newitem->mode = mode;
|
|
|
|
|
newitem->submenu = submenu;
|
|
|
|
|
newitem->xpm = miniicon;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DelMenuItem( MenuLabel *ml, char *action )
|
|
|
|
|
{
|
|
|
|
|
MenuItem *mi, *prev;
|
|
|
|
|
|
|
|
|
|
for( mi=ml->m_item, prev=NULL;
|
|
|
|
|
strcmp( mi->action, action )!=0 && mi;
|
|
|
|
|
prev=mi, mi=mi->next );
|
|
|
|
|
if( !mi ) return;
|
|
|
|
|
|
|
|
|
|
free( mi->label );
|
|
|
|
|
if( mi->action ) free( mi->action );
|
|
|
|
|
if( mi->iconname ) free( mi->iconname );
|
|
|
|
|
if( prev ) prev->next = mi->next;
|
|
|
|
|
free( mi );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CreateMenuItems( void )
|
|
|
|
|
{
|
|
|
|
|
MenuLabel *tmpmenu;
|
|
|
|
|
|
|
|
|
|
Scr.IconMenu.flags = ACTIVE | STICKLABEL;
|
|
|
|
|
Scr.IconMenu.xpm = Scr.SystemIcon;
|
|
|
|
|
Scr.IconMenu.name = strdup( "ICON" );
|
|
|
|
|
Scr.IconMenu.LabelStr = NULL;
|
|
|
|
|
CreateMenuLabel( &Scr.IconMenu );
|
|
|
|
|
|
|
|
|
|
for(tmpmenu=Scr.MenuLabelRoot;tmpmenu!=NULL;tmpmenu=tmpmenu->next)
|
|
|
|
|
CreateMenuLabel( tmpmenu );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetItemGrayString( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
*mode |= STRGRAY;
|
|
|
|
|
|
|
|
|
|
return str+4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetItemBlackString( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
*mode &= ~STRGRAY;
|
|
|
|
|
|
|
|
|
|
return str+5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetItemCheckMark( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
*mode |= CHECKON;
|
|
|
|
|
|
|
|
|
|
return str+5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetItemNonCheckMark( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
*mode &= ~CHECKON;
|
|
|
|
|
|
|
|
|
|
return str+8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetItemSelect( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
*mode |= SELECTON;
|
|
|
|
|
|
|
|
|
|
return str+6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetItemNonSelect( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
*mode &= ~SELECTON;
|
|
|
|
|
|
|
|
|
|
return str+9;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetItemIcon( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
char *name, *stop, tmp[5], *path;
|
|
|
|
|
|
|
|
|
|
if( *icon )
|
|
|
|
|
free( *icon );
|
|
|
|
|
|
|
|
|
|
if( (stop = strchr( str, ',' ))!=NULL )
|
|
|
|
|
*stop = '\0';
|
|
|
|
|
name = calloc( strlen(str)-4, 1 );
|
|
|
|
|
sscanf( str, "%s%s", tmp, name );
|
|
|
|
|
|
|
|
|
|
*icon = name;
|
|
|
|
|
if((path = LookUpFiles( Scr.IconPath, name, R_OK ))==NULL )
|
|
|
|
|
DrawErrMsgOnMenu( "Can't Find file ", name );
|
|
|
|
|
else
|
|
|
|
|
free( path );
|
|
|
|
|
|
|
|
|
|
if( stop!=NULL )
|
|
|
|
|
stop++;
|
|
|
|
|
else
|
|
|
|
|
stop = str+strlen(str);
|
|
|
|
|
|
|
|
|
|
return stop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetItemAction( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
char *stop, *top;
|
|
|
|
|
|
|
|
|
|
if( *action ) free( *action );
|
|
|
|
|
top = SkipSpace( str+6 );
|
|
|
|
|
if( (stop = strchr( str, ',' ))!=NULL )
|
|
|
|
|
*stop = '\0';
|
|
|
|
|
else
|
|
|
|
|
str[strlen(str)-1]='\0';
|
|
|
|
|
*action = strdup( top );
|
|
|
|
|
|
|
|
|
|
if( stop!=NULL )
|
|
|
|
|
stop++;
|
|
|
|
|
else
|
|
|
|
|
stop = str+strlen(str);
|
|
|
|
|
|
|
|
|
|
return stop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetSubMenu( char *str, char **action, int *mode, char **icon, MenuLabel **submenu )
|
|
|
|
|
{
|
|
|
|
|
char *stop, *top;
|
|
|
|
|
MenuLabel *tmp_l;
|
|
|
|
|
|
|
|
|
|
top = SkipSpace( str+7 );
|
|
|
|
|
if( (stop = strchr( str, ',' ))!=NULL )
|
|
|
|
|
*stop = '\0';
|
|
|
|
|
else
|
|
|
|
|
str[strlen(str)-1]='\0';
|
|
|
|
|
|
|
|
|
|
for( tmp_l=Scr.MenuLabelRoot;
|
|
|
|
|
tmp_l && strcmp( top, tmp_l->name ); tmp_l=tmp_l->next );
|
|
|
|
|
|
|
|
|
|
if( tmp_l )
|
|
|
|
|
*submenu = tmp_l;
|
|
|
|
|
else
|
|
|
|
|
DrawErrMsgOnMenu( "Configuration Error(SubMenu)! ", str );
|
|
|
|
|
|
|
|
|
|
if( stop!=NULL )
|
|
|
|
|
stop++;
|
|
|
|
|
else
|
|
|
|
|
stop = str+strlen(str);
|
|
|
|
|
|
|
|
|
|
return stop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
menu_item_func MenuItemFunc[]={
|
|
|
|
|
{"Gray", SetItemGrayString },
|
|
|
|
|
{"Black", SetItemBlackString },
|
|
|
|
|
{"Check", SetItemCheckMark },
|
|
|
|
|
{"NonCheck", SetItemNonCheckMark },
|
|
|
|
|
{"Select", SetItemSelect },
|
|
|
|
|
{"NonSelect", SetItemNonSelect },
|
|
|
|
|
{"SubMenu", SetSubMenu },
|
|
|
|
|
{"Icon", SetItemIcon },
|
|
|
|
|
{"Action", SetItemAction },
|
|
|
|
|
{NULL, 0}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *SetLabelIconName( MenuLabel *ml, char *str )
|
|
|
|
|
{
|
|
|
|
|
char *name, *stop, tmp[5];
|
|
|
|
|
|
|
|
|
|
if( (stop = strchr( str, ',' ))!=NULL )
|
|
|
|
|
*stop = '\0';
|
|
|
|
|
name = calloc( strlen(str)-4, 1 );
|
|
|
|
|
sscanf( str, "%s%s", tmp, name );
|
|
|
|
|
ml->xpm = ReadIcon( name, NULL, True );
|
|
|
|
|
free( name );
|
|
|
|
|
|
|
|
|
|
if( stop!=NULL )
|
|
|
|
|
stop++;
|
|
|
|
|
else
|
|
|
|
|
stop = str+strlen(str);
|
|
|
|
|
|
|
|
|
|
return stop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetLabelStick( MenuLabel *ml, char *str )
|
|
|
|
|
{
|
|
|
|
|
ml->flags |= STICKLABEL;
|
|
|
|
|
|
|
|
|
|
return str+5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetLabelNonStick( MenuLabel *ml, char *str )
|
|
|
|
|
{
|
|
|
|
|
ml->flags &= ~STICKLABEL;
|
|
|
|
|
|
|
|
|
|
return str+8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetLabelRight( MenuLabel *ml, char *str )
|
|
|
|
|
{
|
|
|
|
|
ml->flags &= ~LEFTSIDE;
|
|
|
|
|
|
|
|
|
|
return str+5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetLabelLeft( MenuLabel *ml, char *str )
|
|
|
|
|
{
|
|
|
|
|
ml->flags |= LEFTSIDE;
|
|
|
|
|
|
|
|
|
|
return str+5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetMenuLabelLabel( MenuLabel *ml, char *str )
|
|
|
|
|
{
|
|
|
|
|
char *top;
|
|
|
|
|
|
|
|
|
|
top = stripquote( str+6, &(ml->LabelStr) );
|
|
|
|
|
|
|
|
|
|
return top;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *SetSwallowAction( MenuLabel *ml, char *str )
|
|
|
|
|
{
|
|
|
|
|
char *stop, *top;
|
|
|
|
|
|
|
|
|
|
top = SkipSpace( str+6 );
|
|
|
|
|
if( (stop = strchr( str, ',' ))!=NULL )
|
|
|
|
|
*stop = '\0';
|
|
|
|
|
else
|
|
|
|
|
str[strlen(str)-1]='\0';
|
|
|
|
|
ml->action = strdup( top );
|
|
|
|
|
|
|
|
|
|
if( stop!=NULL )
|
|
|
|
|
stop++;
|
|
|
|
|
else
|
|
|
|
|
stop = str+strlen(str);
|
|
|
|
|
|
|
|
|
|
return stop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
menu_func MenuLabelFunc[]={
|
|
|
|
|
{"Action", SetSwallowAction},
|
|
|
|
|
{"Icon", SetLabelIconName},
|
|
|
|
|
{"Label", SetMenuLabelLabel },
|
|
|
|
|
{"Left", SetLabelLeft},
|
|
|
|
|
{"Right", SetLabelRight},
|
|
|
|
|
{"Stick", SetLabelStick},
|
|
|
|
|
{"NonStick", SetLabelNonStick},
|
|
|
|
|
{NULL, 0}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void SetSwallow( char *line, FILE *fp )
|
|
|
|
|
{
|
|
|
|
|
char str[256], *top;
|
|
|
|
|
MenuLabel *tmpmenu, *last_m;
|
|
|
|
|
int lp;
|
|
|
|
|
|
|
|
|
|
tmpmenu = calloc( 1, sizeof( MenuLabel ) );
|
|
|
|
|
|
|
|
|
|
if( Scr.MenuLabelRoot==NULL ) Scr.MenuLabelRoot = tmpmenu;
|
|
|
|
|
else{
|
|
|
|
|
for( last_m=Scr.MenuLabelRoot;
|
|
|
|
|
last_m->next!=NULL;
|
|
|
|
|
last_m=(MenuLabel *)last_m->next );
|
|
|
|
|
last_m->next = tmpmenu;
|
|
|
|
|
}
|
|
|
|
|
top = stripquote( line, &(tmpmenu->name) );
|
|
|
|
|
tmpmenu->flags = SWALLOW | ACTIVE | STICKLABEL;
|
|
|
|
|
|
|
|
|
|
while( *top!='\n' && *top!='\0' ){
|
|
|
|
|
for( ; !isalpha( *top ) && *top!='\n' && *top!='\0'; top++ );
|
|
|
|
|
if( *top=='\n' || *top=='\0' ) break;
|
|
|
|
|
for( lp=0; MenuLabelFunc[lp].label!=NULL; lp++ ){
|
|
|
|
|
if( !strncmp( top, MenuLabelFunc[lp].label,
|
|
|
|
|
strlen(MenuLabelFunc[lp].label) )){
|
|
|
|
|
top=MenuLabelFunc[lp].action( tmpmenu, top );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( !MenuLabelFunc[lp].label ){
|
|
|
|
|
DrawErrMsgOnMenu( "Configuration Error(Swallow)! ", str );
|
|
|
|
|
for( ; *top!=',' && *top!='\n' && *top!='\0'; top++ );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SetMenu( char *line, FILE *fp )
|
|
|
|
|
{
|
|
|
|
|
char str[256], *top, tmp[5];
|
|
|
|
|
MenuLabel *tmpmenu, *last_m, *submenu;
|
|
|
|
|
int mode;
|
|
|
|
|
char *action, *label;
|
|
|
|
|
char *icon;
|
|
|
|
|
int lp;
|
|
|
|
|
|
|
|
|
|
tmpmenu = calloc( 1, sizeof( MenuLabel ) );
|
|
|
|
|
|
|
|
|
|
if( Scr.MenuLabelRoot==NULL ) Scr.MenuLabelRoot = tmpmenu;
|
|
|
|
|
else{
|
|
|
|
|
for( last_m=Scr.MenuLabelRoot;
|
|
|
|
|
last_m->next!=NULL;
|
|
|
|
|
last_m=(MenuLabel *)last_m->next );
|
|
|
|
|
last_m->next = tmpmenu;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( (top = strchr( line, ',' ))!=NULL )
|
|
|
|
|
*top = '\0';
|
|
|
|
|
tmpmenu->name = calloc( strlen(line)-4, 1 );
|
|
|
|
|
sscanf( line, "%s%s", tmp, tmpmenu->name );
|
|
|
|
|
if( top ) top++;
|
|
|
|
|
else top = line+strlen( line );
|
|
|
|
|
|
|
|
|
|
tmpmenu->flags = LEFTSIDE;
|
|
|
|
|
|
|
|
|
|
while( *top!='\n' && *top!='\0' ){
|
|
|
|
|
for( ; !isalpha( *top ) && *top!='\n' && *top!='\0'; top++ );
|
|
|
|
|
if( *top=='\n' || *top=='\0' ) break;
|
|
|
|
|
for( lp=0; MenuLabelFunc[lp].label!=NULL; lp++ ){
|
|
|
|
|
if( !strncmp( top, MenuLabelFunc[lp].label,
|
|
|
|
|
strlen(MenuLabelFunc[lp].label) )){
|
|
|
|
|
top=MenuLabelFunc[lp].action( tmpmenu, top );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( !MenuLabelFunc[lp].label ){
|
|
|
|
|
DrawErrMsgOnMenu( "Configuration Error(Menu)! ", str );
|
|
|
|
|
for( ; *top!=',' && *top!='\n' && *top!='\0'; top++ );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-04 23:58:04 +00:00
|
|
|
|
while( fgetline( str, 256, fp )!=NULL && strncmp( str, "END", 3) ){
|
2015-04-04 23:54:38 +00:00
|
|
|
|
if( str[0]=='#' ) continue;
|
|
|
|
|
mode = SELECTON;
|
|
|
|
|
label = NULL;
|
|
|
|
|
action = NULL;
|
|
|
|
|
icon = NULL;
|
|
|
|
|
submenu = NULL;
|
|
|
|
|
|
|
|
|
|
top = stripquote( str, &label );
|
|
|
|
|
if( !label ){
|
|
|
|
|
DrawErrMsgOnMenu( "Configuration Error! ", str );
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
while( *top!='\n' && *top!='\0' ){
|
|
|
|
|
for( ; !isalpha( *top ) && *top!='\n' && *top!='\0'; top++ );
|
|
|
|
|
if( *top=='\n' || *top=='\0' ) break;
|
|
|
|
|
for( lp=0; MenuItemFunc[lp].label!=NULL; lp++ ){
|
|
|
|
|
if( !strncmp( top, MenuItemFunc[lp].label,
|
|
|
|
|
strlen(MenuItemFunc[lp].label) )){
|
|
|
|
|
top = MenuItemFunc[lp].action( top, &action,
|
|
|
|
|
&mode, &icon, &submenu );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( !MenuItemFunc[lp].label ){
|
|
|
|
|
DrawErrMsgOnMenu( "Configuration Error(MenuItem)! ", str );
|
|
|
|
|
for( ; *top!=',' && *top!='\n' && *top!='\0'; top++ );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
AddMenuItem( tmpmenu, label, action, icon, NULL, submenu, mode );
|
|
|
|
|
if( label ) free( label );
|
|
|
|
|
if( action ) free( action );
|
|
|
|
|
if( icon ) free( icon );
|
|
|
|
|
if( mode&SELECTON ) tmpmenu->flags |= ACTIVE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SetMenuBar( char *line, FILE *fp )
|
|
|
|
|
{
|
|
|
|
|
char str[256], *top, tmp[8];
|
|
|
|
|
Menu *tmp_m, *last_m;
|
|
|
|
|
MenuLink **tmp_link;
|
|
|
|
|
MenuLabel *tmp_l;
|
|
|
|
|
|
|
|
|
|
tmp_m = calloc( 1, sizeof( Menu ) );
|
|
|
|
|
|
|
|
|
|
if( Scr.MenuRoot==NULL ) Scr.MenuRoot = tmp_m;
|
|
|
|
|
else{
|
|
|
|
|
for( last_m=Scr.MenuRoot;
|
|
|
|
|
last_m->next!=NULL;
|
|
|
|
|
last_m=last_m->next );
|
|
|
|
|
last_m->next = tmp_m;
|
|
|
|
|
}
|
|
|
|
|
if( (top = strchr( line, ',' ))!=NULL )
|
|
|
|
|
*top = '\0';
|
|
|
|
|
tmp_m->name = calloc( strlen(line)-7, 1 );
|
|
|
|
|
sscanf( line, "%s%s", tmp, tmp_m->name );
|
|
|
|
|
|
|
|
|
|
if( top ) top++;
|
|
|
|
|
else top = line+strlen( line );
|
|
|
|
|
tmp_link = &tmp_m->link;
|
|
|
|
|
|
|
|
|
|
for( tmp_l=Scr.MenuLabelRoot; tmp_l; tmp_l=tmp_l->next ){
|
|
|
|
|
if( tmp_l->flags&STICKLABEL ){
|
|
|
|
|
*tmp_link = calloc( 1, sizeof( MenuLink ) );
|
|
|
|
|
(*tmp_link)->link = tmp_l;
|
|
|
|
|
tmp_link = &(*tmp_link)->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-04-04 23:58:04 +00:00
|
|
|
|
while( fgetline( str, 256, fp )!=NULL && strncmp( str, "END", 3) ){
|
2015-04-04 23:54:38 +00:00
|
|
|
|
if( str[0]=='#' ) continue;
|
|
|
|
|
str[ strlen(str)-1] = '\0';
|
|
|
|
|
for( tmp_l=Scr.MenuLabelRoot;
|
|
|
|
|
tmp_l && strcmp( str, tmp_l->name ); tmp_l=tmp_l->next );
|
|
|
|
|
if( tmp_l ){
|
|
|
|
|
*tmp_link = calloc( 1, sizeof( MenuLink ) );
|
|
|
|
|
(*tmp_link)->link = tmp_l;
|
|
|
|
|
tmp_link = &(*tmp_link)->next;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
DrawErrMsgOnMenu( "MenuBar Falied(Can't find) ", str );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Window PixmapWin (char **data_xpm, Window root, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
static XpmAttributes attributes;
|
|
|
|
|
|
|
|
|
|
Pixmap pixmap;
|
|
|
|
|
Pixmap shapemask;
|
|
|
|
|
Window w;
|
|
|
|
|
XSetWindowAttributes attr;
|
|
|
|
|
|
|
|
|
|
XpmCreatePixmapFromData( dpy, root, data_xpm,
|
|
|
|
|
&pixmap, &shapemask, &attributes );
|
|
|
|
|
x = x<0? x + Scr.MyDisplayWidth - attributes.width : x-1;
|
|
|
|
|
y = y<0? y + Scr.MyDisplayHeight - attributes.height : y-1;
|
|
|
|
|
|
|
|
|
|
attr.background_pixel = BlackPixel( dpy, DefaultScreen(dpy) );
|
|
|
|
|
attr.override_redirect = True;
|
|
|
|
|
w = XCreateWindow( dpy, root, x, y,
|
|
|
|
|
attributes.width, attributes.height, 1,
|
|
|
|
|
CopyFromParent, InputOutput, CopyFromParent,
|
|
|
|
|
CWBackPixel | CWOverrideRedirect, &attr );
|
|
|
|
|
XShapeCombineMask( dpy, w, ShapeBounding, 0, 0, shapemask, ShapeSet );
|
|
|
|
|
|
|
|
|
|
XFreePixmap( dpy, pixmap );
|
|
|
|
|
XFreePixmap( dpy, shapemask );
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CreateMenuBar( void )
|
|
|
|
|
{
|
|
|
|
|
static char *lbot_xpm[] = {
|
|
|
|
|
"7 7 2 1",
|
|
|
|
|
" c none s none",
|
|
|
|
|
"# c black",
|
|
|
|
|
"# ",
|
|
|
|
|
"# ",
|
|
|
|
|
"# ",
|
|
|
|
|
"## ",
|
|
|
|
|
"### ",
|
|
|
|
|
"#### ",
|
|
|
|
|
"#######"
|
|
|
|
|
};
|
|
|
|
|
static char *rbot_xpm[] = {
|
|
|
|
|
"7 7 2 1",
|
|
|
|
|
" c none s none",
|
|
|
|
|
"# c black",
|
|
|
|
|
" #",
|
|
|
|
|
" #",
|
|
|
|
|
" #",
|
|
|
|
|
" ##",
|
|
|
|
|
" ###",
|
|
|
|
|
" ####",
|
|
|
|
|
"#######"
|
|
|
|
|
};
|
|
|
|
|
unsigned long valuemask;
|
|
|
|
|
XSetWindowAttributes attributes;
|
|
|
|
|
|
|
|
|
|
valuemask = CWCursor | CWBackPixel | CWEventMask;
|
|
|
|
|
attributes.cursor = Scr.MlvwmCursors[DEFAULT];
|
|
|
|
|
attributes.background_pixel = WhitePixel( dpy, Scr.screen );
|
|
|
|
|
attributes.event_mask = (SubstructureRedirectMask | ButtonPressMask |
|
|
|
|
|
EnterWindowMask | ExposureMask |
|
|
|
|
|
OwnerGrabButtonMask | ButtonReleaseMask );
|
|
|
|
|
Scr.MenuBar = XCreateWindow( dpy, Scr.Root, 0, 0,
|
|
|
|
|
Scr.MyDisplayWidth, MENUB_H ,0,
|
|
|
|
|
CopyFromParent, InputOutput, CopyFromParent,
|
|
|
|
|
valuemask, &attributes );
|
|
|
|
|
XMapWindow( dpy, Scr.MenuBar );
|
|
|
|
|
Scr.lbCorner = PixmapWin( lbot_xpm, Scr.Root, 0, -1 );
|
|
|
|
|
XMapWindow( dpy, Scr.lbCorner );
|
|
|
|
|
|
|
|
|
|
Scr.rbCorner = PixmapWin( rbot_xpm, Scr.Root, -1, -1 );
|
|
|
|
|
XMapWindow( dpy, Scr.rbCorner );
|
|
|
|
|
RedrawMenuBar( );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MapMenuBar( MlvwmWindow *win )
|
|
|
|
|
{
|
|
|
|
|
int left, right;
|
|
|
|
|
MenuLabel *tmpml;
|
|
|
|
|
MenuLink *mlink;
|
|
|
|
|
styles *style;
|
|
|
|
|
static Bool Mapped=False;
|
|
|
|
|
|
|
|
|
|
if( Scr.flags&STARTING ) return;
|
|
|
|
|
left = 10;
|
|
|
|
|
right = Scr.MyDisplayWidth-Scr.IconMenu.LabelWidth-10;
|
|
|
|
|
|
|
|
|
|
XMoveWindow( dpy, Scr.IconMenu.LabelWin, right, 1 );
|
|
|
|
|
Scr.IconMenu.LabelX = right;
|
|
|
|
|
right--;
|
|
|
|
|
|
|
|
|
|
if( Scr.MenuRoot==NULL ){
|
|
|
|
|
if( Mapped ) return;
|
|
|
|
|
|
|
|
|
|
for( tmpml=Scr.MenuLabelRoot; tmpml; tmpml=tmpml->next ){
|
|
|
|
|
if( tmpml->flags&LEFTSIDE ){
|
|
|
|
|
tmpml->LabelX = left;
|
|
|
|
|
left += tmpml->LabelWidth+1;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
tmpml->LabelX = right-tmpml->LabelWidth-1;
|
|
|
|
|
right = tmpml->LabelX;
|
|
|
|
|
}
|
2015-04-04 23:58:04 +00:00
|
|
|
|
if( tmpml->LabelHeight )
|
|
|
|
|
XMoveWindow( dpy, tmpml->LabelWin,
|
|
|
|
|
tmpml->LabelX+3, (MENUB_H-tmpml->LabelHeight)/2 );
|
2015-04-04 23:54:38 +00:00
|
|
|
|
else
|
|
|
|
|
XMoveWindow( dpy, tmpml->LabelWin, tmpml->LabelX, 1 );
|
|
|
|
|
}
|
|
|
|
|
XMapSubwindows( dpy, Scr.MenuBar );
|
|
|
|
|
Mapped = True;
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if((!win || (style = lookupstyles( win->name, &win->class ))==NULL) ||
|
|
|
|
|
!(style->menubar) )
|
|
|
|
|
if( (style = lookupstyles( "*", NULL ))==NULL )
|
|
|
|
|
return;
|
|
|
|
|
if( !(style->menubar) ) return;
|
|
|
|
|
if( Scr.ActiveMenu==style->menubar ) return;
|
|
|
|
|
|
|
|
|
|
XGrabServer (dpy);
|
|
|
|
|
for( mlink=style->menubar->link; mlink; mlink=mlink->next ){
|
|
|
|
|
if( mlink->link->flags&LEFTSIDE ){
|
|
|
|
|
mlink->link->LabelX = left;
|
|
|
|
|
left += mlink->link->LabelWidth+1;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
mlink->link->LabelX = right-mlink->link->LabelWidth-1;
|
|
|
|
|
right = mlink->link->LabelX;
|
|
|
|
|
}
|
|
|
|
|
if( mlink->link->flags&SWALLOW )
|
2015-04-04 23:58:04 +00:00
|
|
|
|
XMoveWindow( dpy, mlink->link->LabelWin,
|
|
|
|
|
mlink->link->LabelX+3, (MENUB_H-mlink->link->LabelHeight)/2 );
|
2015-04-04 23:54:38 +00:00
|
|
|
|
else
|
|
|
|
|
XMoveWindow( dpy, mlink->link->LabelWin, mlink->link->LabelX, 1 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( Scr.ActiveMenu )
|
|
|
|
|
for( mlink=Scr.ActiveMenu->link; mlink; mlink=mlink->next )
|
|
|
|
|
if( !(mlink->link->flags&STICKLABEL) )
|
|
|
|
|
XUnmapWindow( dpy, mlink->link->LabelWin );
|
|
|
|
|
|
|
|
|
|
XMapWindow( dpy, Scr.IconMenu.LabelWin );
|
|
|
|
|
for( mlink=style->menubar->link; mlink; mlink=mlink->next ){
|
|
|
|
|
XMapWindow( dpy, mlink->link->LabelWin );
|
|
|
|
|
RedrawMenu( mlink->link, False );
|
|
|
|
|
}
|
|
|
|
|
Scr.ActiveMenu = style->menubar;
|
|
|
|
|
XSync( dpy, 0 );
|
|
|
|
|
XUngrabServer (dpy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ChangeMenuLabel( MenuLabel *ml, char *newl, Icon *miniicon )
|
|
|
|
|
{
|
|
|
|
|
if( newl==NULL && ml->xpm==miniicon ) return;
|
|
|
|
|
if( ml->LabelStr && !strcmp(ml->LabelStr, newl )){
|
|
|
|
|
if( ml->LabelStr )
|
|
|
|
|
free( ml->LabelStr );
|
|
|
|
|
ml->LabelStr = newl;
|
|
|
|
|
}
|
|
|
|
|
ml->xpm = miniicon;
|
|
|
|
|
RedrawMenu( ml, False );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ChangeMenuItemLabel( char *name, char *oldl, char *newl, char *action, int mm, int sm )
|
|
|
|
|
{
|
|
|
|
|
MenuItem *tmpitem;
|
|
|
|
|
MenuLabel *tmplabel;
|
|
|
|
|
|
|
|
|
|
if( oldl==NULL || *oldl=='\0' ) return;
|
|
|
|
|
if( !strcmp( name, "ICON" ) ) tmplabel = &(Scr.IconMenu);
|
|
|
|
|
else{
|
|
|
|
|
for( tmplabel = Scr.MenuLabelRoot;
|
|
|
|
|
tmplabel && strcmp( name, tmplabel->name );
|
|
|
|
|
tmplabel=tmplabel->next );
|
|
|
|
|
if( tmplabel==NULL ) return;
|
|
|
|
|
}
|
|
|
|
|
for( tmpitem = tmplabel->m_item;
|
|
|
|
|
tmpitem && (strcmp( oldl, tmpitem->label ) ||
|
|
|
|
|
(action==NULL?False:strcmp(tmpitem->action, action)));
|
|
|
|
|
tmpitem=tmpitem->next );
|
|
|
|
|
if( tmpitem==NULL ) return;
|
|
|
|
|
switch( sm ){
|
|
|
|
|
case M_COPY: tmpitem->mode = mm; break;
|
|
|
|
|
case M_AND: tmpitem->mode &= mm; break;
|
|
|
|
|
case M_OR: tmpitem->mode |= mm; break;
|
|
|
|
|
}
|
|
|
|
|
if( oldl==newl || !strcmp( oldl, newl ) ) return;
|
|
|
|
|
if( tmpitem->label!=NULL )
|
|
|
|
|
free( tmpitem->label );
|
|
|
|
|
tmpitem->label = strdup( newl );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeMenuItems( MenuLabel *ml, Bool FreeIcon )
|
|
|
|
|
{
|
|
|
|
|
MenuItem *tmpitem, *next;
|
|
|
|
|
|
|
|
|
|
tmpitem = ml->m_item;
|
|
|
|
|
while( tmpitem!=NULL ){
|
|
|
|
|
next = tmpitem->next;
|
|
|
|
|
if( tmpitem->label ) free( tmpitem->label );
|
|
|
|
|
if( tmpitem->action ) free( tmpitem->action );
|
|
|
|
|
if( FreeIcon && tmpitem->xpm ){
|
|
|
|
|
XFreePixmap( dpy, tmpitem->xpm->icon );
|
|
|
|
|
XFreePixmap( dpy, tmpitem->xpm->lighticon );
|
|
|
|
|
if( tmpitem->xpm->mask!=None )
|
|
|
|
|
XFreePixmap( dpy, tmpitem->xpm->mask );
|
|
|
|
|
free( tmpitem->xpm );
|
|
|
|
|
free( tmpitem->iconname );
|
|
|
|
|
}
|
|
|
|
|
free( tmpitem );
|
|
|
|
|
tmpitem = next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeMenuLabels( MenuLabel *ml, Bool all )
|
|
|
|
|
{
|
|
|
|
|
Bool cont=True;
|
|
|
|
|
XWindowAttributes winattrs;
|
|
|
|
|
unsigned long eventMask;
|
|
|
|
|
XEvent ev;
|
|
|
|
|
|
|
|
|
|
FreeMenuItems( ml, all );
|
|
|
|
|
free( ml->name );
|
|
|
|
|
if( ml->LabelStr ) free( ml->LabelStr );
|
|
|
|
|
if( ml->xpm ){
|
|
|
|
|
XFreePixmap( dpy, ml->xpm->icon );
|
|
|
|
|
XFreePixmap( dpy, ml->xpm->lighticon );
|
|
|
|
|
if( ml->xpm->mask!=None ) XFreePixmap( dpy, ml->xpm->mask );
|
|
|
|
|
free( ml->xpm );
|
|
|
|
|
}
|
|
|
|
|
if( !(ml->flags&SWALLOW) ){
|
|
|
|
|
if( ml->action )
|
|
|
|
|
free( ml->action );
|
|
|
|
|
if( ml->LabelWin!=None )
|
|
|
|
|
XDestroyWindow( dpy, ml->LabelWin );
|
|
|
|
|
if( ml->PullWin!=None )
|
|
|
|
|
XDestroyWindow( dpy, ml->PullWin );
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
if( XGetWindowAttributes(dpy, ml->LabelWin, &winattrs) ){
|
|
|
|
|
eventMask = winattrs.your_event_mask;
|
|
|
|
|
XMoveWindow( dpy, ml->LabelWin, ml->LabelX, -MENUB_H );
|
|
|
|
|
XMapWindow( dpy, ml->LabelWin );
|
|
|
|
|
XSelectInput(dpy, ml->LabelWin, eventMask | StructureNotifyMask);
|
|
|
|
|
|
|
|
|
|
if( ml->flags&CANDELETE )
|
|
|
|
|
send_clientmessage( ml->LabelWin, _XA_WM_DELETE_WINDOW,
|
|
|
|
|
CurrentTime);
|
|
|
|
|
else
|
|
|
|
|
XKillClient( dpy, ml->LabelWin );
|
|
|
|
|
do{
|
|
|
|
|
XMaskEvent( dpy, StructureNotifyMask|SubstructureNotifyMask,
|
|
|
|
|
&ev );
|
|
|
|
|
if( (ev.type==UnmapNotify || ev.type==DestroyNotify) &&
|
|
|
|
|
(ev.xany.window==ml->LabelWin ||
|
|
|
|
|
ev.xunmap.window==ml->LabelWin) ){
|
|
|
|
|
cont = False;
|
|
|
|
|
XUnmapWindow( dpy, ev.xany.window );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
HandleEvents( ev );
|
|
|
|
|
}
|
|
|
|
|
while( cont );
|
|
|
|
|
}
|
|
|
|
|
free( ml->action );
|
|
|
|
|
}
|
|
|
|
|
if( all ) free( ml );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeMenu( void )
|
|
|
|
|
{
|
|
|
|
|
Menu *tmpm, *nextm;
|
|
|
|
|
MenuLink *tmplink, *nextlink;
|
|
|
|
|
MenuLabel *tmpml, *nextl;
|
|
|
|
|
|
|
|
|
|
tmpm = Scr.MenuRoot;
|
|
|
|
|
while( tmpm ){
|
|
|
|
|
nextm = tmpm->next;
|
|
|
|
|
tmplink = tmpm->link;
|
|
|
|
|
while( tmplink ){
|
|
|
|
|
nextlink = tmplink->next;
|
|
|
|
|
free( tmplink );
|
|
|
|
|
tmplink = nextlink;
|
|
|
|
|
}
|
|
|
|
|
free( tmpm->name );
|
|
|
|
|
free( tmpm );
|
|
|
|
|
tmpm = nextm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tmpml = Scr.MenuLabelRoot;
|
|
|
|
|
while( tmpml ){
|
|
|
|
|
nextl = tmpml->next;
|
|
|
|
|
FreeMenuLabels( tmpml, True );
|
|
|
|
|
tmpml = nextl;
|
|
|
|
|
}
|
|
|
|
|
ChangeMenuLabel( &(Scr.IconMenu), NULL, Scr.SystemIcon );
|
|
|
|
|
FreeMenuLabels( &Scr.IconMenu, False );
|
|
|
|
|
XUnmapWindow( dpy, Scr.MenuBar );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeShortCut( void )
|
|
|
|
|
{
|
|
|
|
|
ShortCut *now, *next;
|
|
|
|
|
|
|
|
|
|
now = Scr.ShortCutRoot;
|
|
|
|
|
for( ;now!=NULL; now = next ){
|
|
|
|
|
next = now->next;
|
|
|
|
|
free( now->action );
|
|
|
|
|
free( now );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void KeepOnTop( void )
|
|
|
|
|
{
|
|
|
|
|
MlvwmWindow *tmp;
|
|
|
|
|
|
|
|
|
|
if( Scr.flags&STARTING ) return;
|
|
|
|
|
for (tmp = Scr.MlvwmRoot.next; tmp != NULL; tmp = tmp->next)
|
|
|
|
|
if( tmp->flags&ONTOP )
|
|
|
|
|
RaiseMlvwmWindow( tmp );
|
|
|
|
|
XRaiseWindow( dpy, Scr.MenuBar );
|
|
|
|
|
XRaiseWindow( dpy, Scr.lbCorner );
|
|
|
|
|
XRaiseWindow( dpy, Scr.rbCorner );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CreateSimpleMenu( void )
|
|
|
|
|
{
|
|
|
|
|
Scr.MenuLabelRoot = calloc( 1, sizeof( MenuLabel ) );
|
|
|
|
|
Scr.MenuLabelRoot->flags = LEFTSIDE | ACTIVE;
|
|
|
|
|
Scr.MenuLabelRoot->name = strdup( "Default" );
|
|
|
|
|
Scr.MenuLabelRoot->LabelStr = strdup( "File" );
|
|
|
|
|
|
|
|
|
|
Scr.MenuLabelRoot->m_item = calloc( 1, sizeof( MenuItem ) );
|
|
|
|
|
Scr.MenuLabelRoot->m_item->mode = SELECTON;
|
|
|
|
|
Scr.MenuLabelRoot->m_item->label = strdup( "Quit" );
|
|
|
|
|
Scr.MenuLabelRoot->m_item->action = strdup( "Exit" );
|
2015-04-04 23:58:04 +00:00
|
|
|
|
|
|
|
|
|
Scr.MenuRoot = calloc( 1, sizeof(Menu) );
|
|
|
|
|
Scr.MenuRoot->link = calloc( 1, sizeof(MenuLink) );
|
|
|
|
|
Scr.MenuRoot->link->link = Scr.MenuLabelRoot;
|
|
|
|
|
if( !Scr.style_list ){
|
|
|
|
|
Scr.style_list = calloc( 1, sizeof( styles ) );
|
|
|
|
|
Scr.style_list->name = strdup("*");
|
|
|
|
|
Scr.style_list->flags = NORMALWIN;
|
|
|
|
|
Scr.style_list->maxmizescale = 90;
|
|
|
|
|
Scr.style_list->menubar = Scr.MenuRoot;
|
|
|
|
|
}
|
2015-04-04 23:54:38 +00:00
|
|
|
|
}
|