/**************************************************************************** * This module is all new * by Rob Nation ****************************************************************************/ /*********************************************************************** * * fvwm pager handling code * ***********************************************************************/ #include "../../configure.h" #include #include #include #include #include #include #include #include #include "../../fvwm/fvwm.h" #include "FvwmPager.h" extern ScreenInfo Scr; extern Display *dpy; Pixel back_pix, fore_pix, hi_pix; Pixel focus_pix; Pixel focus_fore_pix; extern int window_w, window_h,window_x,window_y,usposition,uselabel; extern int StartIconic; extern int icon_w, icon_h, icon_x, icon_y; XFontStruct *font, *windowFont; GC NormalGC,HiliteGC,rvGC; GC StdGC, FocusGC; extern int StickyIcons; extern PagerWindow *Start; extern PagerWindow *FocusWin; static Atom wm_del_win; extern char *MyName; extern int desk1, desk2, ndesks; extern int Rows,Columns; extern int fd[2]; int desk_w = 0; int desk_h = 0; int label_h = 0; DeskInfo *Desks; int Wait = 0; XErrorHandler FvwmErrorHandler(Display *, XErrorEvent *); /* assorted gray bitmaps for decorative borders */ #define g_width 2 #define g_height 2 static char g_bits[] = {0x02, 0x01}; #define l_g_width 4 #define l_g_height 2 static char l_g_bits[] = {0x08, 0x02}; #define s_g_width 4 #define s_g_height 4 static char s_g_bits[] = {0x01, 0x02, 0x04, 0x08}; Window icon_win; /* icon window */ /*********************************************************************** * * Procedure: * Initialize_pager - creates the pager window, if needed * * Inputs: * x,y location of the window * ***********************************************************************/ char *pager_name = "Fvwm Pager"; XSizeHints sizehints = { (PMinSize | PResizeInc | PBaseSize | PWinGravity), 0, 0, 100, 100, /* x, y, width and height */ 1, 1, /* Min width and height */ 0, 0, /* Max width and height */ 1, 1, /* Width and height increments */ {0, 0}, {0, 0}, /* Aspect ratio - not used */ 1, 1, /* base size */ (NorthWestGravity) /* gravity */ }; void initialize_pager(void) { XTextProperty name; unsigned long valuemask; XSetWindowAttributes attributes; XWMHints wmhints; extern char *PagerFore, *PagerBack, *HilightC; extern char *font_string, *smallFont; extern char *HiBack; extern char *HiFore; int n,m,w,h,i,x,y; XGCValues gcv; unsigned long gcm; XClassHint class1; XSetErrorHandler((XErrorHandler)FvwmErrorHandler); wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); n = Scr.VxMax/Scr.MyDisplayWidth; m = Scr.VyMax/Scr.MyDisplayHeight; /* load the font */ if ((font = XLoadQueryFont(dpy, font_string)) == NULL) { if ((font = XLoadQueryFont(dpy, "fixed")) == NULL) { fprintf(stderr,"%s: No fonts available\n",MyName); exit(1); } }; if(uselabel) label_h = font->ascent + font->descent+2; else label_h = 0; if(smallFont!= NULL) { windowFont= XLoadQueryFont(dpy, smallFont); } else windowFont= NULL; /* Load the colors */ fore_pix = GetColor(PagerFore); back_pix = GetColor(PagerBack); focus_pix = GetColor(HiBack); focus_fore_pix = GetColor(HiFore); hi_pix = GetColor(HilightC); /* Load pixmaps for mono use */ if(Scr.d_depth<2) { Scr.gray_pixmap = XCreatePixmapFromBitmapData(dpy,Scr.Root,g_bits, g_width,g_height, fore_pix,back_pix,Scr.d_depth); Scr.light_gray_pixmap = XCreatePixmapFromBitmapData(dpy,Scr.Root,l_g_bits,l_g_width,l_g_height, fore_pix,back_pix,Scr.d_depth); Scr.sticky_gray_pixmap = XCreatePixmapFromBitmapData(dpy,Scr.Root,s_g_bits,s_g_width,s_g_height, fore_pix,back_pix,Scr.d_depth); } /* Size the window */ if(Rows < 0) { if(Columns < 0) { Columns = ndesks; Rows = 1; } else { Rows = ndesks/Columns; if(Rows*Columns < ndesks) Rows++; } } if(Columns < 0) { Columns = ndesks/Rows; if(Rows*Columns < ndesks) Columns++; } if(Rows*Columns < ndesks) Rows = ndesks/Columns; if(window_w > 0) { window_w = ((window_w - n)/(n+1))*(n+1)+n; Scr.VScale = (Scr.VxMax + Scr.MyDisplayWidth)/window_w; } if(window_h > 0) { window_h = ((window_h - m)/(m+1))*(m+1)+m; Scr.VScale = (Scr.VyMax + Scr.MyDisplayHeight)/(window_h- label_h); } if(window_w <= 0) window_w = Columns*((Scr.VxMax + Scr.MyDisplayWidth)/Scr.VScale + n) + Columns-1; if(window_h <= 0) window_h = Rows*((Scr.VyMax + Scr.MyDisplayHeight)/Scr.VScale + m + label_h + 1)-2; if(window_x < 0) { sizehints.win_gravity = NorthEastGravity; window_x = Scr.MyDisplayWidth - window_w + window_x -2; } if(window_y < 0) { window_y = Scr.MyDisplayHeight - window_h + window_y -2; if(sizehints.win_gravity == NorthEastGravity) sizehints.win_gravity = SouthEastGravity; else sizehints.win_gravity = SouthWestGravity; } if(usposition) sizehints.flags |= USPosition; valuemask = (CWBackPixel | CWBorderPixel | CWEventMask); attributes.background_pixel = back_pix; attributes.border_pixel = fore_pix; attributes.event_mask = (StructureNotifyMask); sizehints.width = window_w; sizehints.height = window_h; sizehints.x = window_x; sizehints.y = window_y; sizehints.width_inc = Columns*(n+1); sizehints.height_inc = Rows*(m+1); sizehints.base_width = Columns * n + Columns - 1; sizehints.base_height = Rows*(m + label_h+1) -2; sizehints.min_width = Columns * n + Columns - 1; sizehints.min_height = Rows*(m + label_h+1) -2; Scr.Pager_w = XCreateWindow (dpy, Scr.Root, window_x, window_y, window_w, window_h, (unsigned int) 1, CopyFromParent, InputOutput, (Visual *) CopyFromParent, valuemask, &attributes); XSetWMProtocols(dpy,Scr.Pager_w,&wm_del_win,1); XSetWMNormalHints(dpy,Scr.Pager_w,&sizehints); if((desk1==desk2)&&(Desks[0].label != NULL)) XStringListToTextProperty(&Desks[0].label,1,&name); else XStringListToTextProperty(&pager_name,1,&name); attributes.event_mask = (StructureNotifyMask| ExposureMask); if(icon_w < 1) icon_w = (window_w - Columns+1)/Columns; if(icon_h < 1) icon_h = (window_h - Rows* label_h - Rows + 1)/Rows; icon_w = (icon_w / (n+1)) *(n+1)+n; icon_h = (icon_h / (m+1)) *(m+1)+m; icon_win = XCreateWindow (dpy, Scr.Root, window_x, window_y, icon_w,icon_h, (unsigned int) 1, CopyFromParent, InputOutput, (Visual *) CopyFromParent, valuemask, &attributes); XGrabButton(dpy, 1, AnyModifier, icon_win, True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XGrabButton(dpy, 2, AnyModifier, icon_win, True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XGrabButton(dpy, 3, AnyModifier, icon_win, True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); if(!StartIconic) wmhints.initial_state = NormalState; else wmhints.initial_state = IconicState; wmhints.flags = 0; if(icon_x > -10000) { if(icon_x < 0) icon_x = Scr.MyDisplayWidth + icon_x - icon_w; if(icon_y > -10000) { if(icon_y < 0) icon_y = Scr.MyDisplayHeight + icon_y - icon_h; } else icon_y = 0; wmhints.icon_x = icon_x; wmhints.icon_y = icon_y; wmhints.flags = IconPositionHint; } wmhints.icon_window = icon_win; wmhints.input = False; wmhints.flags |= InputHint | StateHint | IconWindowHint; class1.res_name = MyName; class1.res_class = "FvwmModule"; XSetWMProperties(dpy,Scr.Pager_w,&name,&name,NULL,0, &sizehints,&wmhints,&class1); XFree((char *)name.value); for(i=0;ifid; NormalGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = hi_pix; if(Scr.d_depth < 2) { gcv.foreground = fore_pix; gcv.background = back_pix; } HiliteGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); if((Scr.d_depth < 2)||(fore_pix == hi_pix)) gcv.foreground = back_pix; else gcv.foreground = fore_pix; rvGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); if(windowFont != NULL) { /* Create GC's for doing window labels */ gcv.foreground = focus_fore_pix; gcv.background = focus_pix; gcv.font = windowFont->fid; StdGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = focus_fore_pix; gcv.background = focus_pix; FocusGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); } } /**************************************************************************** * * Loads a single color * ****************************************************************************/ Pixel GetColor(char *name) { XColor color; XWindowAttributes attributes; XGetWindowAttributes(dpy,Scr.Root,&attributes); color.pixel = 0; if (!XParseColor (dpy, attributes.colormap, name, &color)) { nocolor("parse",name); } else if(!XAllocColor (dpy, attributes.colormap, &color)) { nocolor("alloc",name); } return color.pixel; } void nocolor(char *a, char *b) { fprintf(stderr,"%s: can't %s %s\n", MyName, a,b); } /**************************************************************************** * * Decide what to do about received X events * ****************************************************************************/ void DispatchEvent(XEvent *Event) { int i,x,y; Window JunkRoot, JunkChild; int JunkX, JunkY; unsigned JunkMask; switch(Event->xany.type) { case ConfigureNotify: ReConfigure(); break; case Expose: HandleExpose(Event); break; case ButtonRelease: if((Event->xbutton.button == 1)|| (Event->xbutton.button == 2)) { for(i=0;ixany.window == Desks[i].w) SwitchToDeskAndPage(i,Event); if(Event->xany.window == Desks[i].title_w) SwitchToDesk(i); } if(Event->xany.window == icon_win) { IconSwitchPage(Event); } } else if (Event->xbutton.button == 3) { for(i=0;ixany.window == Desks[i].w) { XQueryPointer(dpy, Desks[i].w, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask); Scroll(i,x,y); } } if(Event->xany.window == icon_win) { XQueryPointer(dpy, icon_win, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask); IconScroll(x,y); } } break; case ButtonPress: if (((Event->xbutton.button == 2)|| ((Event->xbutton.button == 3)&& (Event->xbutton.state & Mod1Mask)))&& (Event->xbutton.subwindow != None)) { MoveWindow(Event); } else if (Event->xbutton.button == 3) { for(i=0;ixany.window == Desks[i].w) { XQueryPointer(dpy, Desks[i].w, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask); Scroll(i,x,y); } } if(Event->xany.window == icon_win) { XQueryPointer(dpy, icon_win, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask); IconScroll(x,y); } } break; case MotionNotify: while(XCheckMaskEvent(dpy, PointerMotionMask | ButtonMotionMask,Event)); if(Event->xmotion.state == Button3MotionMask) { for(i=0;ixany.window == Desks[i].w) { XQueryPointer(dpy, Desks[i].w, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask); Scroll(i,x,y); } } if(Event->xany.window == icon_win) { XQueryPointer(dpy, icon_win, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask); IconScroll(x,y); } } break; case ClientMessage: if ((Event->xclient.format==32) && (Event->xclient.data.l[0]==wm_del_win)) { exit(0); } break; } } void HandleExpose(XEvent *Event) { int i; PagerWindow *t; for(i=0;ixany.window == Desks[i].w) ||(Event->xany.window == Desks[i].title_w)) DrawGrid(i,0); } if(Event->xany.window == icon_win) DrawIconGrid(0); t = Start; while(t!= NULL) { if(t->PagerView == Event->xany.window) { LabelWindow(t); } else if(t->IconView == Event->xany.window) { LabelIconWindow(t); } t = t->next; } } /**************************************************************************** * * Respond to a change in window geometry. * ****************************************************************************/ void ReConfigure(void) { Window root; unsigned border_width, depth; int n,m,w,h,n1,m1,x,y,i,j,k; XGetGeometry(dpy,Scr.Pager_w,&root,&x,&y, (unsigned *)&window_w,(unsigned *)&window_h, &border_width,&depth); n1 = Scr.Vx/Scr.MyDisplayWidth; m1 = Scr.Vy/Scr.MyDisplayHeight; n = (Scr.VxMax)/Scr.MyDisplayWidth; m = (Scr.VyMax)/Scr.MyDisplayHeight; desk_w = (window_w - Columns + 1)/Columns; desk_h = (window_h - Rows*label_h - Rows + 2)/Rows; w = (desk_w - n)/(n+1); h = (desk_h - m)/(m+1); x = (desk_w-n)* Scr.Vx/(Scr.VxMax+Scr.MyDisplayWidth) +n1; y = (desk_h-m)*Scr.Vy/(Scr.VyMax+Scr.MyDisplayHeight) +m1; for(k=0;k= desk1)&&(Scr.CurrentDesk <=desk2)) sptr = Desks[Scr.CurrentDesk -desk1].label; else { sprintf(str,"Desk %d",Scr.CurrentDesk); sptr = &str[0]; } if (XStringListToTextProperty(&sptr,1,&name) == 0) { fprintf(stderr,"%s: cannot allocate window name",MyName); return; } XSetWMIconName(dpy,Scr.Pager_w,&name); } } void ReConfigureAll(void) { PagerWindow *t; t = Start; while(t!= NULL) { MoveResizePagerView(t); t = t->next; } } void ReConfigureIcons(void) { PagerWindow *t; int x,y,w,h,n,m,n1,m1; n = (Scr.VxMax)/Scr.MyDisplayWidth; m = (Scr.VyMax)/Scr.MyDisplayHeight; t = Start; while(t!= NULL) { n1 = (Scr.Vx+t->x)/Scr.MyDisplayWidth; m1 = (Scr.Vy+t->y)/Scr.MyDisplayHeight; x = (Scr.Vx + t->x)*(icon_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; y = (Scr.Vy + t->y)*(icon_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; w = (Scr.Vx + t->x + t->width+2)*(icon_w-n)/ (Scr.VxMax + Scr.MyDisplayWidth) - 2 - x + n1; h = (Scr.Vy + t->y + t->height+2)*(icon_h-m)/ (Scr.VyMax + Scr.MyDisplayHeight) -2 - y +m1; if (w < 1) w = 1; if (h < 1) h = 1; if(Scr.CurrentDesk == t->desk) XMoveResizeWindow(dpy,t->IconView,x,y,w,h); else XMoveResizeWindow(dpy,t->IconView,-1000,-1000,w,h); t = t->next; } } /**************************************************************************** * * Draw grid lines for desk #i * ****************************************************************************/ void DrawGrid(int i, int erase) { int y, y1, y2, x, x1, x2,d,hor_off,w; int MaxW,MaxH; char str[15], *ptr; if((i < 0 ) ||(i >= ndesks)) return; MaxW = (Scr.VxMax + Scr.MyDisplayWidth); MaxH = Scr.VyMax + Scr.MyDisplayHeight; x = Scr.MyDisplayWidth; y1 = 0; y2 = desk_h; while(x < MaxW) { x1 = x*desk_w/MaxW; XDrawLine(dpy,Desks[i].w,NormalGC,x1,y1,x1,y2); x += Scr.MyDisplayWidth; } y = Scr.MyDisplayHeight; x1 = 0; x2 = desk_w; while(y < MaxH) { y1 = y*(desk_h)/MaxH; XDrawLine(dpy,Desks[i].w,NormalGC,x1,y1,x2,y1); y += Scr.MyDisplayHeight; } if((Scr.CurrentDesk - desk1) == i) { if(uselabel) XFillRectangle(dpy,Desks[i].title_w,HiliteGC, 0,0,desk_w,label_h -1); } else { if(uselabel && erase) XClearArea(dpy,Desks[i].title_w, 0,0,desk_w,label_h - 1,False); } d = desk1+i; ptr = Desks[i].label; w=XTextWidth(font,ptr,strlen(ptr)); if( w > desk_w) { sprintf(str,"%d",d); ptr = str; w=XTextWidth(font,ptr,strlen(ptr)); } if((w<= desk_w)&&(uselabel)) { hor_off = (desk_w -w)/2; if(i == (Scr.CurrentDesk - desk1)) XDrawString (dpy, Desks[i].title_w,rvGC,hor_off,font->ascent +1 , ptr, strlen(ptr)); else XDrawString (dpy, Desks[i].title_w,NormalGC,hor_off,font->ascent+1 , ptr, strlen(ptr)); } } void DrawIconGrid(int erase) { int y, y1, y2, x, x1, x2,w,h,n,m,n1,m1; int MaxW,MaxH; MaxW = (Scr.VxMax + Scr.MyDisplayWidth); MaxH = Scr.VyMax + Scr.MyDisplayHeight; if(erase) XClearWindow(dpy,icon_win); x = Scr.MyDisplayWidth; y1 = 0; y2 = icon_h; while(x < MaxW) { x1 = x*icon_w/MaxW; XDrawLine(dpy,icon_win,NormalGC,x1,y1,x1,y2); x += Scr.MyDisplayWidth; } y = Scr.MyDisplayHeight; x1 = 0; x2 = icon_w; while(y < MaxH) { y1 = y*(icon_h)/MaxH; XDrawLine(dpy,icon_win,NormalGC,x1,y1,x2,y1); y += Scr.MyDisplayHeight; } n1 = Scr.Vx/Scr.MyDisplayWidth; m1 = Scr.Vy/Scr.MyDisplayHeight; n = (Scr.VxMax)/Scr.MyDisplayWidth; m = (Scr.VyMax)/Scr.MyDisplayHeight; w = (icon_w - n)/(n+1); h = (icon_h - m)/(m+1); x = (icon_w-n)* Scr.Vx/(Scr.VxMax+Scr.MyDisplayWidth) +n1; y = (icon_h-m)*Scr.Vy/(Scr.VyMax+Scr.MyDisplayHeight) +m1; XFillRectangle(dpy,icon_win,HiliteGC, x,y,w,h); } void SwitchToDesk(int Desk) { char command[256]; sprintf(command,"Desk 0 %d\n",Desk+desk1); SendInfo(fd,command,0); } void SwitchToDeskAndPage(int Desk, XEvent *Event) { char command[256]; SendInfo(fd,"Desk 0 10000\n",0); #ifndef NON_VIRTUAL sprintf(command,"GotoPage %d %d\n", Event->xbutton.x*(Scr.VxMax+Scr.MyDisplayWidth)/ (desk_w*Scr.MyDisplayWidth), Event->xbutton.y*(Scr.VyMax+Scr.MyDisplayHeight)/ (desk_h*Scr.MyDisplayHeight)); SendInfo(fd,command,0); sprintf(command,"Desk 0 %d\n",Desk+desk1); SendInfo(fd,command,0); #endif Wait = 1; } void IconSwitchPage(XEvent *Event) { char command[256]; #ifndef NON_VIRTUAL sprintf(command,"GotoPage %d %d\n", Event->xbutton.x*(Scr.VxMax+Scr.MyDisplayWidth)/ (icon_w*Scr.MyDisplayWidth), Event->xbutton.y*(Scr.VyMax+Scr.MyDisplayHeight)/ (icon_h*Scr.MyDisplayHeight)); SendInfo(fd,command,0); #endif Wait = 1; } void AddNewWindow(PagerWindow *t) { unsigned long valuemask; XSetWindowAttributes attributes; int i,x,y,w,h,n,m,n1,m1; i = t->desk - desk1; n = (Scr.VxMax)/Scr.MyDisplayWidth; m = (Scr.VyMax)/Scr.MyDisplayHeight; n1 = (Scr.Vx+t->x)/Scr.MyDisplayWidth; m1 = (Scr.Vy+t->y)/Scr.MyDisplayHeight; x = (Scr.Vx + t->x)*(desk_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; y = (Scr.Vy + t->y)*(desk_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; w = (Scr.Vx + t->x + t->width+2)*(desk_w-n)/ (Scr.VxMax + Scr.MyDisplayWidth) - 2 - x + n1; h = (Scr.Vy + t->y + t->height+2)*(desk_h-m)/ (Scr.VyMax + Scr.MyDisplayHeight) -2 - y +m1; if(w<1) w = 1; if(h<1) h = 1; valuemask = (CWBackPixel | CWBorderPixel | CWEventMask); attributes.background_pixel = t->back; attributes.border_pixel = fore_pix; attributes.event_mask = (ExposureMask); if((i >= 0)&& (i PagerView = XCreateWindow(dpy,Desks[i].w, x, y, w, h,1, CopyFromParent, InputOutput,CopyFromParent, valuemask,&attributes); XMapRaised(dpy,t->PagerView); } else t->PagerView = None; x = (Scr.Vx + t->x)*(icon_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; y = (Scr.Vy + t->y)*(icon_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; w = (Scr.Vx + t->x + t->width+2)*(icon_w-n)/ (Scr.VxMax + Scr.MyDisplayWidth) - 2 - x + n1; h = (Scr.Vy + t->y + t->height+2)*(icon_h-m)/ (Scr.VyMax + Scr.MyDisplayHeight) -2 - y +m1; if(w<1) w = 1; if(h<1) h = 1; if(Scr.CurrentDesk == t->desk) { t->IconView = XCreateWindow(dpy,icon_win, x, y, w, h,1, CopyFromParent, InputOutput,CopyFromParent, valuemask,&attributes); XGrabButton(dpy, 2, AnyModifier, t->IconView, True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XMapRaised(dpy,t->IconView); } else { t->IconView = XCreateWindow(dpy,icon_win, -1000, -1000, w, h,1, CopyFromParent, InputOutput,CopyFromParent, valuemask,&attributes); XMapRaised(dpy,t->IconView); } Hilight(t,OFF); } void ChangeDeskForWindow(PagerWindow *t,long newdesk) { int i,x,y,w,h,n,m,n1,m1; i = newdesk - desk1; if(t->PagerView == None) { t->desk = newdesk; XDestroyWindow(dpy,t->IconView); AddNewWindow( t); return; } n = (Scr.VxMax)/Scr.MyDisplayWidth; m = (Scr.VyMax)/Scr.MyDisplayHeight; n1 = (Scr.Vx+t->x)/Scr.MyDisplayWidth; m1 = (Scr.Vy+t->y)/Scr.MyDisplayHeight; x = (Scr.Vx + t->x)*(desk_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; y = (Scr.Vy + t->y)*(desk_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; w = (Scr.Vx + t->x + t->width+2)*(desk_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) - 2 - x + n1; h = (Scr.Vy + t->y + t->height+2)*(desk_h-m)/(Scr.VyMax + Scr.MyDisplayHeight) -2 - y +m1; if (w < 1) w = 1; if (h < 1) h = 1; if((i >= 0)&&(i < ndesks)) { XReparentWindow(dpy, t->PagerView, Desks[i].w, x,y); XResizeWindow(dpy,t->PagerView,w,h); } else { XDestroyWindow(dpy,t->PagerView); t->PagerView = None; } t->desk = i+desk1; x = (Scr.Vx + t->x)*(icon_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; y = (Scr.Vy + t->y)*(icon_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; w = (Scr.Vx + t->x + t->width+2)*(icon_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) - 2 - x + n1; h = (Scr.Vy + t->y + t->height+2)*(icon_h-m)/(Scr.VyMax + Scr.MyDisplayHeight) -2 - y +m1; if (w < 1) w = 1; if (h < 1) h = 1; if(Scr.CurrentDesk == t->desk) XMoveResizeWindow(dpy,t->IconView,x,y,w,h); else XMoveResizeWindow(dpy,t->IconView,-1000,-1000,w,h); } void MoveResizePagerView(PagerWindow *t) { int x,y,w,h,n,m,n1,m1; n = (Scr.VxMax)/Scr.MyDisplayWidth; m = (Scr.VyMax)/Scr.MyDisplayHeight; n1 = (Scr.Vx+t->x)/Scr.MyDisplayWidth; m1 = (Scr.Vy+t->y)/Scr.MyDisplayHeight; x = (Scr.Vx + t->x)*(desk_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; y = (Scr.Vy + t->y)*(desk_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; w = (Scr.Vx + t->x + t->width+2)*(desk_w-n)/ (Scr.VxMax + Scr.MyDisplayWidth) - 2 - x + n1; h = (Scr.Vy + t->y + t->height+2)*(desk_h-m)/ (Scr.VyMax + Scr.MyDisplayHeight) -2 - y +m1; if (w < 1) w = 1; if (h < 1) h = 1; if(t->PagerView != None) XMoveResizeWindow(dpy,t->PagerView,x,y,w,h); else if((t->desk >= desk1)&&(t->desk <= desk2)) { XDestroyWindow(dpy,t->IconView); AddNewWindow(t); return; } x = (Scr.Vx + t->x)*(icon_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; y = (Scr.Vy + t->y)*(icon_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; w = (Scr.Vx + t->x + t->width+2)*(icon_w-n)/ (Scr.VxMax + Scr.MyDisplayWidth) - 2 - x + n1; h = (Scr.Vy + t->y + t->height+2)*(icon_h-m)/ (Scr.VyMax + Scr.MyDisplayHeight) -2 - y +m1; if (w < 1) w = 1; if (h < 1) h = 1; if(Scr.CurrentDesk == t->desk) XMoveResizeWindow(dpy,t->IconView,x,y,w,h); else XMoveResizeWindow(dpy,t->IconView,-1000,-1000,w,h); } void MoveStickyWindows(void) { PagerWindow *t; t = Start; while(t!= NULL) { if(((t->flags & ICONIFIED)&&(StickyIcons))|| (t->flags & STICKY)) { if(t->desk != Scr.CurrentDesk) { ChangeDeskForWindow(t,Scr.CurrentDesk); } else { MoveResizePagerView(t); } } t = t->next; } } void Hilight(PagerWindow *t, int on) { if(!t)return; if(Scr.d_depth < 2) { if(on) { if(t->PagerView != None) XSetWindowBackgroundPixmap(dpy,t->PagerView,Scr.gray_pixmap); XSetWindowBackgroundPixmap(dpy,t->IconView,Scr.gray_pixmap); } else { if(t->flags & STICKY) { if(t->PagerView != None) XSetWindowBackgroundPixmap(dpy,t->PagerView, Scr.sticky_gray_pixmap); XSetWindowBackgroundPixmap(dpy,t->IconView, Scr.sticky_gray_pixmap); } else { if(t->PagerView != None) XSetWindowBackgroundPixmap(dpy,t->PagerView, Scr.light_gray_pixmap); XSetWindowBackgroundPixmap(dpy,t->IconView, Scr.light_gray_pixmap); } } } else { if(on) { if(t->PagerView != None) XSetWindowBackground(dpy,t->PagerView,focus_pix); XSetWindowBackground(dpy,t->IconView,focus_pix); } else { if(t->PagerView != None) XSetWindowBackground(dpy,t->PagerView,t->back); XSetWindowBackground(dpy,t->IconView,t->back); } } if(t->PagerView != None) XClearWindow(dpy,t->PagerView); XClearWindow(dpy,t->IconView); LabelWindow(t); LabelIconWindow(t); } void Scroll(int Desk, int x, int y) { #ifndef NON_VIRTUAL char command[256]; int sx, sy; if(Wait == 0) { if(Desk != Scr.CurrentDesk) { return; } if(x < 0) x = 0; if(y < 0) y = 0; if(x > desk_w) x = desk_w; if(y > desk_h) y = desk_h; sx = (100*(x*(Scr.VxMax+Scr.MyDisplayWidth)/desk_w- Scr.Vx))/Scr.MyDisplayWidth; sy = (100*(y*(Scr.VyMax+Scr.MyDisplayHeight)/ desk_h - Scr.Vy))/Scr.MyDisplayHeight; if(sx > 100)sx = 100; if(sx < -100)sx = -100; if(sy < -100)sy = -100; if(sy > 100)sy = 100; sprintf(command,"Scroll %d %d\n",sx,sy); SendInfo(fd,command,0); Wait = 1; } #endif } void IconScroll(int x, int y) { #ifndef NON_VIRTUAL char command[256]; int sx, sy; if(Wait == 0) { if(x < 0) x = 0; if(y < 0) y = 0; if(x > icon_w) x = icon_w; if(y > icon_h) y = icon_h; sx = (100*(x*(Scr.VxMax+Scr.MyDisplayWidth)/icon_w- Scr.Vx))/Scr.MyDisplayWidth; sy = (100*(y*(Scr.VyMax+Scr.MyDisplayHeight)/ icon_h - Scr.Vy))/Scr.MyDisplayHeight; if(sx > 100)sx = 100; if(sx < -100)sx = -100; if(sy < -100)sy = -100; if(sy > 100)sy = 100; sprintf(command,"Scroll %d %d\n",sx,sy); SendInfo(fd,command,0); Wait = 1; } #endif } void MoveWindow(XEvent *Event) { char command[100]; int x1,y1,finished = 0,wx,wy,n,x,y,xi=0,yi=0,wx1,wy1,x2,y2; Window dumwin; PagerWindow *t; int m,n1,m1; int NewDesk,KeepMoving = 0; int moved = 0; int row,column; t = Start; while ((t != NULL)&&(t->PagerView != Event->xbutton.subwindow)) t= t->next; if(t==NULL) { t = Start; while ((t != NULL)&&(t->IconView != Event->xbutton.subwindow)) t= t->next; if(t!=NULL) { IconMoveWindow(Event,t); return; } } if(t == NULL) return; NewDesk = t->desk - desk1; if((NewDesk < 0)||(NewDesk >= ndesks)) return; n = (Scr.VxMax)/Scr.MyDisplayWidth; m = (Scr.VyMax)/Scr.MyDisplayHeight; n1 = (Scr.Vx+t->x)/Scr.MyDisplayWidth; m1 = (Scr.Vy+t->y)/Scr.MyDisplayHeight; wx = (Scr.Vx + t->x)*(desk_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; wy = (Scr.Vy + t->y)*(desk_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; wx1 = wx+(desk_w+1)*(NewDesk%Columns); wy1 = wy + label_h + (desk_h+label_h+1)*(NewDesk/Columns); XReparentWindow(dpy, t->PagerView, Scr.Pager_w,wx1,wy1); XRaiseWindow(dpy,t->PagerView); XTranslateCoordinates(dpy, Event->xany.window, t->PagerView, Event->xbutton.x, Event->xbutton.y, &x1, &y1, &dumwin); xi = x1; yi = y1; while(!finished) { XMaskEvent(dpy,ButtonReleaseMask | ButtonMotionMask|ExposureMask,Event); if(Event->type == MotionNotify) { XTranslateCoordinates(dpy, Event->xany.window, Scr.Pager_w, Event->xmotion.x, Event->xmotion.y, &x, &y, &dumwin); if(moved == 0) { xi = x; yi = y; moved = 1; } if((x < -5)||(y<-5)||(x>window_w+5)||(y>window_h+5)) { KeepMoving = 1; finished = 1; } XMoveWindow(dpy,t->PagerView, x - (x1), y - (y1)); } else if(Event->type == ButtonRelease) { XTranslateCoordinates(dpy, Event->xany.window, Scr.Pager_w, Event->xbutton.x, Event->xbutton.y, &x, &y, &dumwin); XMoveWindow(dpy,t->PagerView, x - (x1), y - (y1)); finished = 1; } else if (Event->type == Expose) { HandleExpose(Event); } } if(moved) { if((x - xi < 3)&&(y - yi < 3)&& (x - xi > -3)&&(y -yi > -3)) moved = 0; } if(KeepMoving) { NewDesk = Scr.CurrentDesk; if(NewDesk != t->desk) { XMoveWindow(dpy,t->w,Scr.MyDisplayWidth+Scr.VxMax, Scr.MyDisplayHeight+Scr.VyMax); XSync(dpy,0); sprintf(command,"WindowsDesk %d", NewDesk); SendInfo(fd,command,t->w); t->desk = NewDesk; } if((NewDesk>=desk1)&&(NewDesk<=desk2)) XReparentWindow(dpy, t->PagerView, Desks[NewDesk-desk1].w,0,0); else { XDestroyWindow(dpy,t->PagerView); t->PagerView = None; } XTranslateCoordinates(dpy, Scr.Pager_w, Scr.Root, x, y, &x1, &y1, &dumwin); if(t->flags & ICONIFIED) { XUngrabPointer(dpy,CurrentTime); XSync(dpy,0); SendInfo(fd,"Move",t->icon_w); } else { XUngrabPointer(dpy,CurrentTime); XSync(dpy,0); SendInfo(fd,"Move",t->w); } return; } else { column = (x/(desk_w+1)); row = (y/(desk_h+ label_h+1)); NewDesk = column + (row)*Columns; if((NewDesk <0)||(NewDesk >=ndesks)) { NewDesk = Scr.CurrentDesk - desk1; x = xi; y = yi; moved = 0; } XTranslateCoordinates(dpy, Scr.Pager_w,Desks[NewDesk].w, x-x1, y-y1, &x2,&y2,&dumwin); n1 = x2*(Scr.VxMax + Scr.MyDisplayWidth)/(desk_w * Scr.MyDisplayWidth); m1 = y2*(Scr.VyMax + Scr.MyDisplayHeight)/(desk_h * Scr.MyDisplayHeight); x = (x2-n1)* (Scr.VxMax + Scr.MyDisplayWidth)/(desk_w-n) - Scr.Vx; y = (y2-m1)* (Scr.VyMax + Scr.MyDisplayHeight)/(desk_h-m) - Scr.Vy; if(x + t->frame_width + Scr.Vx < 0 ) x = -Scr.Vx; if(y+t->frame_height + Scr.Vy< 0) y = -Scr.Vy; if(x + Scr.Vx > Scr.MyDisplayWidth+Scr.VxMax) x = Scr.MyDisplayWidth + Scr.VxMax - t->frame_width - Scr.Vx; if(y +Scr.Vy> Scr.MyDisplayHeight+Scr.VyMax) y = Scr.MyDisplayHeight+ Scr.VyMax - t->frame_height - Scr.Vy; if(((t->flags & ICONIFIED)&&(StickyIcons))|| (t->flags & STICKY)) { NewDesk = Scr.CurrentDesk - desk1; if(x > Scr.MyDisplayWidth -16) x = Scr.MyDisplayWidth - 16; if(y > Scr.MyDisplayHeight-16) y = Scr.MyDisplayHeight - 16; if(x + t->width < 16) x = 16 - t->width; if(y + t->height < 16) y = 16 - t->height; } if(NewDesk +desk1 != t->desk) { if(((t->flags & ICONIFIED)&&(StickyIcons))|| (t->flags & STICKY)) { NewDesk = Scr.CurrentDesk - desk1; if(t->desk != Scr.CurrentDesk) ChangeDeskForWindow(t,Scr.CurrentDesk); } else { sprintf(command,"WindowsDesk %d", NewDesk + desk1); SendInfo(fd,command,t->w); t->desk = NewDesk + desk1; } } if((NewDesk >= 0)&&(NewDesk < ndesks)) { XReparentWindow(dpy, t->PagerView, Desks[NewDesk].w,x,y); if(moved) { if(t->flags & ICONIFIED) XMoveWindow(dpy,t->icon_w,x,y); else XMoveWindow(dpy,t->w,x+t->border_width, y+t->title_height+t->border_width); XSync(dpy,0); } else MoveResizePagerView(t); SendInfo(fd,"Raise",t->w); } if(Scr.CurrentDesk == t->desk) { if(t->flags & ICONIFIED) XSetInputFocus (dpy, t->icon_w, RevertToParent, Event->xbutton.time); else XSetInputFocus (dpy, t->w, RevertToParent, Event->xbutton.time); } } } /*********************************************************************** * * Procedure: * FvwmErrorHandler - displays info on internal errors * ************************************************************************/ XErrorHandler FvwmErrorHandler(Display *dpy, XErrorEvent *event) { return 0; } void LabelWindow(PagerWindow *t) { XGCValues Globalgcv; unsigned long Globalgcm; GC tgc; if(windowFont == NULL) { return; } if(t->icon_name == NULL) { return; } if(t == FocusWin) { tgc = FocusGC; } else { tgc = StdGC; Globalgcv.foreground = t->text; Globalgcv.background = t->back; Globalgcm = GCForeground|GCBackground; XChangeGC(dpy, StdGC,Globalgcm,&Globalgcv); } if(t->PagerView != None) { XClearWindow(dpy, t->PagerView); XDrawImageString (dpy, t->PagerView,tgc,2,windowFont->ascent+2 , t->icon_name, strlen(t->icon_name)); } } void LabelIconWindow(PagerWindow *t) { XGCValues Globalgcv; unsigned long Globalgcm; GC tgc; if(windowFont == NULL) { return; } if(t->icon_name == NULL) { return; } if(t == FocusWin) { tgc = FocusGC; } else { tgc = StdGC; Globalgcv.foreground = t->text; Globalgcv.background = t->back; Globalgcm = GCForeground|GCBackground; XChangeGC(dpy,StdGC,Globalgcm,&Globalgcv); } XClearWindow(dpy, t->IconView); XDrawImageString (dpy, t->IconView,tgc,2,windowFont->ascent+2 , t->icon_name, strlen(t->icon_name)); } void IconMoveWindow(XEvent *Event,PagerWindow *t) { int x1,y1,finished = 0,wx,wy,n,x=0,y=0,xi=0,yi=0; Window dumwin; int m,n1,m1; int moved = 0; int KeepMoving = 0; if(t==NULL) return; n = (Scr.VxMax)/Scr.MyDisplayWidth; m = (Scr.VyMax)/Scr.MyDisplayHeight; n1 = (Scr.Vx+t->x)/Scr.MyDisplayWidth; m1 = (Scr.Vy+t->y)/Scr.MyDisplayHeight; wx = (Scr.Vx + t->x)*(icon_w-n)/(Scr.VxMax + Scr.MyDisplayWidth) +n1; wy = (Scr.Vy + t->y)*(icon_h-m)/(Scr.VyMax + Scr.MyDisplayHeight)+m1; XRaiseWindow(dpy,t->IconView); XTranslateCoordinates(dpy, Event->xany.window, t->IconView, Event->xbutton.x, Event->xbutton.y, &x1, &y1, &dumwin); while(!finished) { XMaskEvent(dpy,ButtonReleaseMask | ButtonMotionMask|ExposureMask,Event); if(Event->type == MotionNotify) { x = Event->xbutton.x; y = Event->xbutton.y; if(moved == 0) { xi = x; yi = y; moved = 1; } XMoveWindow(dpy,t->IconView, x - (x1), y - (y1)); if((x < -5)||(y < -5)||(x>icon_w+5)||(y>icon_h+5)) { finished = 1; KeepMoving = 1; } } else if(Event->type == ButtonRelease) { x = Event->xbutton.x; y = Event->xbutton.y; XMoveWindow(dpy,t->PagerView, x - (x1),y - (y1)); finished = 1; } else if (Event->type == Expose) { HandleExpose(Event); } } if(moved) { if((x - xi < 3)&&(y - yi < 3)&& (x - xi > -3)&&(y -yi > -3)) moved = 0; } if(KeepMoving) { XTranslateCoordinates(dpy, t->IconView, Scr.Root, x, y, &x1, &y1, &dumwin); if(t->flags & ICONIFIED) { XUngrabPointer(dpy,CurrentTime); XSync(dpy,0); SendInfo(fd,"Move",t->icon_w); } else { XUngrabPointer(dpy,CurrentTime); XSync(dpy,0); SendInfo(fd,"Move",t->w); } } else { x = x - x1; y = y - y1; n1 = x*(Scr.VxMax + Scr.MyDisplayWidth)/(icon_w * Scr.MyDisplayWidth); m1 = y*(Scr.VyMax + Scr.MyDisplayHeight)/(icon_h * Scr.MyDisplayHeight); x = (x-n1)* (Scr.VxMax + Scr.MyDisplayWidth)/(icon_w-n) - Scr.Vx; y = (y-m1)* (Scr.VyMax + Scr.MyDisplayHeight)/(icon_h-m) - Scr.Vy; if(((t->flags & ICONIFIED)&&(StickyIcons))|| (t->flags & STICKY)) { if(x > Scr.MyDisplayWidth -16) x = Scr.MyDisplayWidth - 16; if(y > Scr.MyDisplayHeight-16) y = Scr.MyDisplayHeight - 16; if(x + t->width < 16) x = 16 - t->width; if(y + t->height < 16) y = 16 - t->height; } if(moved) { if(t->flags & ICONIFIED) XMoveWindow(dpy,t->icon_w,x,y); else XMoveWindow(dpy,t->w,x,y); XSync(dpy,0); } else { MoveResizePagerView(t); } SendInfo(fd,"Raise",t->w); if(t->flags & ICONIFIED) XSetInputFocus (dpy, t->icon_w, RevertToParent, Event->xbutton.time); else XSetInputFocus (dpy, t->w, RevertToParent, Event->xbutton.time); } }