X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=80db3980ec7cef890d92a0eb9f7c4c63ea8857bf;hb=919bb8ce56406c6059ec9d3221d1bc96ad388d1c;hp=e4aec1910f5a476d04e52313193ac41e8c4865a9;hpb=2af7c68549b9aeb85ddce753062604f54f0b0b49;p=xboard.git diff --git a/xboard.c b/xboard.c index e4aec19..80db398 100644 --- a/xboard.c +++ b/xboard.c @@ -273,6 +273,7 @@ void CreateGrid P((void)); int EventToSquare P((int x, int limit)); void DrawSquare P((int row, int column, ChessSquare piece, int do_flash)); void EventProc P((Widget widget, caddr_t unused, XEvent *event)); +void DelayedDrag P((void)); void MoveTypeInProc P((Widget widget, caddr_t unused, XEvent *event)); void HandleUserMove P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); @@ -443,6 +444,10 @@ void SaveSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms) void SaveOnExitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void GuideProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void HomePageProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void NewsPageProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void BugReportProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); @@ -785,6 +790,11 @@ MenuItem helpMenu[] = { {N_("Info XBoard"), "Info XBoard", InfoProc}, {N_("Man XBoard F1"), "Man XBoard", ManProc}, {"----", NULL, NothingProc}, + {N_("XBoard Home Page"), "Home Page", HomePageProc}, + {N_("On-line User Guide"), "User Guide", GuideProc}, + {N_("Development News"), "News Page", NewsPageProc}, + {N_("e-Mail Bug Report"), "Bug Report", BugReportProc}, + {"----", NULL, NothingProc}, {N_("About XBoard"), "About XBoard", AboutProc}, {NULL, NULL, NULL} }; @@ -1125,7 +1135,9 @@ char boardTranslations[] = : HandleUserMove(0) \n \ : AnimateUserMove() \n \ : HandlePV() \n \ + : HandlePV() \n \ : PieceMenuPopup(menuB) \n \ + : PieceMenuPopup(menuB) \n \ Shift: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\ PieceMenuPopup(menuB) \n \ Any: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \ @@ -1553,6 +1565,7 @@ ParseCommPortSettings (char *s) } extern Widget engineOutputShell; +int frameX, frameY; void GetActualPlacement (Widget wg, WindowPlacement *wp) @@ -1560,20 +1573,20 @@ GetActualPlacement (Widget wg, WindowPlacement *wp) Arg args[16]; Dimension w, h; Position x, y; - int i; + XWindowAttributes winAt; + Window win, dummy; + int i, rx, ry; if(!wg) return; - i = 0; - XtSetArg(args[i], XtNx, &x); i++; - XtSetArg(args[i], XtNy, &y); i++; - XtSetArg(args[i], XtNwidth, &w); i++; - XtSetArg(args[i], XtNheight, &h); i++; - XtGetValues(wg, args, i); - wp->x = x - 4; - wp->y = y - 23; - wp->height = h; - wp->width = w; + win = XtWindow(wg); + XGetWindowAttributes(xDisplay, win, &winAt); // this works, where XtGetValues on XtNx, XtNy does not! + XTranslateCoordinates (xDisplay, win, winAt.root, -winAt.border_width, -winAt.border_width, &rx, &ry, &dummy); + wp->x = rx - winAt.x; + wp->y = ry - winAt.y; + wp->height = winAt.height; + wp->width = winAt.width; + frameX = winAt.x; frameY = winAt.y; // remember to decide if windows touch } void @@ -1743,6 +1756,9 @@ InitDrawingSizes (BoardSize boardSize, int flags) shellArgs[4].value = shellArgs[2].value = w; shellArgs[5].value = shellArgs[3].value = h; XtSetValues(shellWidget, &shellArgs[0], 6); + + XSync(xDisplay, False); + DelayedDrag(); } // [HGM] pieces: tailor piece bitmaps to needs of specific variant @@ -1816,6 +1832,8 @@ InitDrawingSizes (BoardSize boardSize, int flags) } } } + oldMono = -10; // kludge to force recreation of animation masks + oldVariant = gameInfo.variant; } #if HAVE_LIBXPM if(appData.monoMode != oldMono) @@ -2659,6 +2677,8 @@ XBoard square size (hint): %d\n\ /* end why */ XtAddEventHandler(formWidget, KeyPressMask, False, (XtEventHandler) MoveTypeInProc, NULL); + XtAddEventHandler(shellWidget, StructureNotifyMask, False, + (XtEventHandler) EventProc, NULL); /* [AS] Restore layout */ if( wpMoveHistory.visible ) { @@ -3894,7 +3914,7 @@ MenuBarSelect (Widget w, caddr_t addr, caddr_t index) static void MenuEngineSelect (Widget w, caddr_t addr, caddr_t index) { - RecentEngineEvent((int) addr); + RecentEngineEvent((int) (intptr_t) addr); } void @@ -3906,7 +3926,7 @@ AppendEnginesToMenu (Widget menu, char *list) Arg args[16]; char *p; - if(appData.recentEngines <= 0) return; + if(appData.icsActive || appData.recentEngines <= 0) return; recentEngines = strdup(list); j = 0; XtSetArg(args[j], XtNleftMargin, 20); j++; @@ -3919,7 +3939,7 @@ AppendEnginesToMenu (Widget menu, char *list) entry = XtCreateManagedWidget("engine", smeBSBObjectClass, menu, args, j+1); XtAddCallback(entry, XtNcallback, (XtCallbackProc) MenuEngineSelect, - (caddr_t) i); + (caddr_t) (intptr_t) i); i++; *p = '\n'; list = p + 1; } } @@ -4081,6 +4101,7 @@ CreatePieceMenus () whitePieceMenu = CreatePieceMenu("menuW", 0); blackPieceMenu = CreatePieceMenu("menuB", 1); + if(appData.pieceMenu) // [HGM] sweep: no idea what this was good for, but it stopped reporting button events outside the window XtRegisterGrabAction(PieceMenuPopup, True, (unsigned)(ButtonPressMask|ButtonReleaseMask), GrabModeAsync, GrabModeAsync); @@ -4642,6 +4663,75 @@ DrawSquare (int row, int column, ChessSquare piece, int do_flash) } } +double +Fraction (int x, int start, int stop) +{ + double f = ((double) x - start)/(stop - start); + if(f > 1.) f = 1.; else if(f < 0.) f = 0.; + return f; +} + +static WindowPlacement wpNew; + +void +CoDrag (Widget sh, WindowPlacement *wp) +{ + Arg args[16]; + int j=0, touch=0, fudge = 2; + GetActualPlacement(sh, wp); + if(abs(wpMain.x + wpMain.width + 2*frameX - wp->x) < fudge) touch = 1; else // right touch + if(abs(wp->x + wp->width + 2*frameX - wpMain.x) < fudge) touch = 2; else // left touch + if(abs(wpMain.y + wpMain.height + frameX + frameY - wp->y) < fudge) touch = 3; else // bottom touch + if(abs(wp->y + wp->height + frameX + frameY - wpMain.y) < fudge) touch = 4; // top touch + if(!touch ) return; // only windows that touch co-move + if(touch < 3 && wpNew.height != wpMain.height) { // left or right and height changed + int heightInc = wpNew.height - wpMain.height; + double fracTop = Fraction(wp->y, wpMain.y, wpMain.y + wpMain.height + frameX + frameY); + double fracBot = Fraction(wp->y + wp->height + frameX + frameY + 1, wpMain.y, wpMain.y + wpMain.height + frameX + frameY); + wp->y += fracTop * heightInc; + heightInc = (int) (fracBot * heightInc) - (int) (fracTop * heightInc); + if(heightInc) XtSetArg(args[j], XtNheight, wp->height + heightInc), j++; + } else if(touch > 2 && wpNew.width != wpMain.width) { // top or bottom and width changed + int widthInc = wpNew.width - wpMain.width; + double fracLeft = Fraction(wp->x, wpMain.x, wpMain.x + wpMain.width + 2*frameX); + double fracRght = Fraction(wp->x + wp->width + 2*frameX + 1, wpMain.x, wpMain.x + wpMain.width + 2*frameX); + wp->y += fracLeft * widthInc; + widthInc = (int) (fracRght * widthInc) - (int) (fracLeft * widthInc); + if(widthInc) XtSetArg(args[j], XtNwidth, wp->width + widthInc), j++; + } + wp->x += wpNew.x - wpMain.x; + wp->y += wpNew.y - wpMain.y; + if(touch == 1) wp->x += wpNew.width - wpMain.width; else + if(touch == 3) wp->y += wpNew.height - wpMain.height; + XtSetArg(args[j], XtNx, wp->x); j++; + XtSetArg(args[j], XtNy, wp->y); j++; + XtSetValues(sh, args, j); +} + +void +DragProc () +{ + GetActualPlacement(shellWidget, &wpNew); + if(wpNew.x == wpMain.x && wpNew.y == wpMain.y && // not moved + wpNew.width == wpMain.width && wpNew.height == wpMain.height) // not sized + return; // false alarm + if(EngineOutputIsUp()) CoDrag(engineOutputShell, &wpEngineOutput); + if(MoveHistoryIsUp()) CoDrag(shells[7], &wpMoveHistory); + if(EvalGraphIsUp()) CoDrag(evalGraphShell, &wpEvalGraph); + if(GameListIsUp()) CoDrag(gameListShell, &wpGameList); + wpMain = wpNew; + XDrawPosition(boardWidget, True, NULL); +} + + +void +DelayedDrag () +{ + static XtIntervalId delayedDragID = 0; + if(delayedDragID) XtRemoveTimeOut(delayedDragID); // cancel pending + delayedDragID = + XtAppAddTimeOut(appContext, 50, (XtTimerCallbackProc) DragProc, (XtPointer) 0); // and schedule new one 50 msec later +} /* Why is this needed on some versions of X? */ void @@ -4649,8 +4739,11 @@ EventProc (Widget widget, caddr_t unused, XEvent *event) { if (!XtIsRealized(widget)) return; - switch (event->type) { + case ConfigureNotify: // main window is being dragged: drag attached windows with it + if(appData.useStickyWindows) + DelayedDrag(); // as long as events keep coming in faster than 50 msec, they destroy each other + break; case Expose: if (event->xexpose.count > 0) return; /* no clipping is done */ XDrawPosition(widget, True, NULL); @@ -5221,7 +5314,7 @@ PromotionCallback (Widget w, XtPointer client_data, XtPointer call_data) void ErrorCallback (Widget w, XtPointer client_data, XtPointer call_data) { - errorUp = False; + dialogError = errorUp = False; XtPopdown(w = XtParent(XtParent(XtParent(w)))); XtDestroyWidget(w); if (errorExitStatus != -1) ExitEvent(errorExitStatus); @@ -5232,7 +5325,7 @@ void ErrorPopDown () { if (!errorUp) return; - errorUp = False; + dialogError = errorUp = False; XtPopdown(errorShell); XtDestroyWidget(errorShell); if (errorExitStatus != -1) ExitEvent(errorExitStatus); @@ -5255,7 +5348,7 @@ ErrorPopUp (char *title, char *label, int modal) XtSetArg(args[i], XtNtitle, title); i++; errorShell = XtCreatePopupShell("errorpopup", transientShellWidgetClass, - shellWidget, args, i); + shellUp[0] ? (dialogError = modal = TRUE, shells[0]) : shellWidget, args, i); layout = XtCreateManagedWidget(layoutName, formWidgetClass, errorShell, layoutArgs, XtNumber(layoutArgs)); @@ -5613,6 +5706,12 @@ CopyPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) NULL/* transfer_done_proc */); } +void +CopyFENToClipboard () +{ // wrapper to make call from back-end possible + CopyPositionProc(NULL, NULL, NULL, NULL); +} + /* function called when the data to Paste is ready */ static void PastePositionCB (Widget w, XtPointer client_data, Atom *selection, @@ -6571,9 +6670,41 @@ BookProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) } void -AboutProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +BugReportProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) { char buf[MSG_SIZ]; + snprintf(buf, MSG_SIZ, "%s mailto:bug-xboard@gnu.org", appData.sysOpen); + system(buf); +} + +void +GuideProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +{ + char buf[MSG_SIZ]; + snprintf(buf, MSG_SIZ, "%s http://www.gnu.org/software/xboard/user_guide/UserGuide.html", appData.sysOpen); + system(buf); +} + +void +HomePageProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +{ + char buf[MSG_SIZ]; + snprintf(buf, MSG_SIZ, "%s http://www.gnu.org/software/xboard/", appData.sysOpen); + system(buf); +} + +void +NewsPageProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +{ + char buf[MSG_SIZ]; + snprintf(buf, MSG_SIZ, "%s http://www.gnu.org/software/xboard/whats_new/portal.html", appData.sysOpen); + system(buf); +} + +void +AboutProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +{ + char buf[2 * MSG_SIZ]; #if ZIPPY char *zippy = _(" (with Zippy code)"); #else @@ -6582,10 +6713,14 @@ AboutProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) snprintf(buf, sizeof(buf), _("%s%s\n\n" "Copyright 1991 Digital Equipment Corporation\n" -"Enhancements Copyright 1992-2009 Free Software Foundation\n" +"Enhancements Copyright 1992-2012 Free Software Foundation\n" "Enhancements Copyright 2005 Alessandro Scotti\n\n" "%s is free software and carries NO WARRANTY;" -"see the file COPYING for more information."), +"see the file COPYING for more information.\n\n" +"Visit XBoard on the web at: http://www.gnu.org/software/xboard/\n" +"Check out the newest features at: http://www.gnu.org/software/xboard/whats_new.html\n\n" +"Report bugs via email at: \n\n" + ), programVersion, zippy, PACKAGE); ErrorPopUp(_("About XBoard"), buf, FALSE); } @@ -7343,7 +7478,7 @@ StartChildProcess (char *cmdLine, char *dir, ProcRef *pr) char buf[MSG_SIZ]; if (appData.debugMode) { - fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine); + fprintf(debugFP, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine); } /* We do NOT feed the cmdLine to the shell; we just