Implement auto-creation of ICS logon file
[xboard.git] / winboard / winboard.c
index cc4b5a9..8420e3b 100644 (file)
@@ -164,7 +164,7 @@ BoardSize boardSize;
 Boolean chessProgram;\r
 //static int boardX, boardY;\r
 int  minX, minY; // [HGM] placement: volatile limits on upper-left corner\r
-int squareSize, lineGap, minorSize;\r
+int squareSize, lineGap, minorSize, border;\r
 static int winW, winH;\r
 static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo\r
 static int logoHeight = 0;\r
@@ -1006,8 +1006,14 @@ LoadLogo(ChessProgramState *cps, int n, Boolean ics)
       }\r
   } else if(appData.autoLogo) {\r
       if(ics) { // [HGM] logo: in ICS mode second can be used for ICS\r
-       sprintf(buf, "logos\\%s.bmp", appData.icsHost);\r
-       cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+       char *opponent = "";\r
+       if(gameMode == IcsPlayingWhite) opponent = gameInfo.black;\r
+       if(gameMode == IcsPlayingBlack) opponent = gameInfo.white;\r
+       sprintf(buf, "logos\\%s\\%s.bmp", appData.icsHost, opponent);\r
+       if(!*opponent || !(cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ))) {\r
+           sprintf(buf, "logos\\%s.bmp", appData.icsHost);\r
+           cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+       }\r
       } else\r
       if(appData.directory[n] && appData.directory[n][0]) {\r
         SetCurrentDirectory(appData.directory[n]);\r
@@ -1024,6 +1030,7 @@ InitTextures()
   backTextureSquareSize = 0; // kludge to force recalculation of texturemode\r
   \r
   if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) {\r
+      if(liteBackTexture) DeleteObject(liteBackTexture);\r
       liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
       liteBackTextureMode = appData.liteBackTextureMode;\r
 \r
@@ -1033,6 +1040,7 @@ InitTextures()
   }\r
   \r
   if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) {\r
+      if(darkBackTexture) DeleteObject(darkBackTexture);\r
       darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
       darkBackTextureMode = appData.darkBackTextureMode;\r
 \r
@@ -2107,9 +2115,15 @@ void CreatePiecesFromFont()
 HBITMAP\r
 DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix)\r
 {\r
-  char name[128];\r
+  char name[128], buf[MSG_SIZ];\r
 \r
     snprintf(name, sizeof(name)/sizeof(name[0]), "%s%d%s", piece, squareSize, suffix);\r
+  if(appData.pieceDirectory[0]) {\r
+    HBITMAP res;\r
+    snprintf(buf, MSG_SIZ, "%s\\%s.bmp", appData.pieceDirectory, name);\r
+    res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+    if(res) return res;\r
+  }\r
   if (gameInfo.event &&\r
       strcmp(gameInfo.event, "Easter Egg Hunt") == 0 &&\r
       strcmp(name, "k80s") == 0) {\r
@@ -2269,6 +2283,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   squareSize = sizeInfo[boardSize].squareSize;\r
   lineGap = sizeInfo[boardSize].lineGap;\r
   minorSize = 0; /* [HGM] Kludge to see if demagnified pieces need to be shifted  */\r
+  border = appData.useBorder && appData.border[0] ? squareSize/2 : 0;\r
 \r
   if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) {\r
       lineGap = appData.overrideLineGap;\r
@@ -2293,8 +2308,8 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     DrawMenuBar(hwndMain);\r
   }\r
 \r
-  boardWidth  = BoardWidth(boardSize, BOARD_WIDTH);\r
-  boardHeight = BoardWidth(boardSize, BOARD_HEIGHT);\r
+  boardWidth  = BoardWidth(boardSize, BOARD_WIDTH) + 2*border;\r
+  boardHeight = BoardWidth(boardSize, BOARD_HEIGHT) + 2*border;\r
 \r
   /* Get text area sizes */\r
   hdc = GetDC(hwndMain);\r
@@ -2465,20 +2480,20 @@ InitDrawingSizes(BoardSize boardSize, int flags)
 \r
     /* [HGM] Loop had to be split in part for vert. and hor. lines */\r
     for (i = 0; i < BOARD_HEIGHT + 1; i++) {\r
-      gridEndpoints[i*2].x = boardRect.left + lineGap / 2;\r
+      gridEndpoints[i*2].x = boardRect.left + lineGap / 2 + border;\r
       gridEndpoints[i*2].y = gridEndpoints[i*2 + 1].y =\r
-       boardRect.top + lineGap / 2 + (i * (squareSize + lineGap));\r
+       boardRect.top + lineGap / 2 + (i * (squareSize + lineGap)) + border;\r
       gridEndpoints[i*2 + 1].x = boardRect.left + lineGap / 2 +\r
-        BOARD_WIDTH * (squareSize + lineGap);\r
+        BOARD_WIDTH * (squareSize + lineGap) + border;\r
       gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
     }\r
     for (i = 0; i < BOARD_WIDTH + 1; i++) {\r
-      gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].y = boardRect.top + lineGap / 2;\r
+      gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].y = boardRect.top + lineGap / 2 + border;\r
       gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].x =\r
         gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].x = boardRect.left +\r
-       lineGap / 2 + (i * (squareSize + lineGap));\r
+       lineGap / 2 + (i * (squareSize + lineGap)) + border;\r
       gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].y =\r
-        boardRect.top + BOARD_HEIGHT * (squareSize + lineGap);\r
+        boardRect.top + BOARD_HEIGHT * (squareSize + lineGap) + border;\r
       gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
     }\r
   }\r
@@ -2731,11 +2746,11 @@ VOID
 SquareToPos(int row, int column, int * x, int * y)\r
 {\r
   if (flipView) {\r
-    *x = boardRect.left + lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);\r
-    *y = boardRect.top + lineGap + row * (squareSize + lineGap);\r
+    *x = boardRect.left + lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap) + border;\r
+    *y = boardRect.top + lineGap + row * (squareSize + lineGap) + border;\r
   } else {\r
-    *x = boardRect.left + lineGap + column * (squareSize + lineGap);\r
-    *y = boardRect.top + lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
+    *x = boardRect.left + lineGap + column * (squareSize + lineGap) + border;\r
+    *y = boardRect.top + lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap) + border;\r
   }\r
 }\r
 \r
@@ -2762,15 +2777,23 @@ DrawCoordsOnDC(HDC hdc)
   y = boardRect.top + lineGap;\r
   x = boardRect.left + lineGap + gameInfo.holdingsWidth*(squareSize + lineGap);\r
 \r
+  if(border) {\r
+    SetTextAlign(hdc, TA_RIGHT|TA_TOP);\r
+    x += border - lineGap - 4; y += squareSize - 6;\r
+  } else\r
   SetTextAlign(hdc, TA_LEFT|TA_TOP);\r
   for (i = 0; i < BOARD_HEIGHT; i++) {\r
     str[0] = files[start + i];\r
-    ExtTextOut(hdc, x + 2, y + 1, 0, NULL, str, 1, NULL);\r
+    ExtTextOut(hdc, x + 2 - (border ? gameInfo.holdingsWidth * (squareSize + lineGap) : 0), y + 1, 0, NULL, str, 1, NULL);\r
     y += squareSize + lineGap;\r
   }\r
 \r
   start = flipView ? 23-(BOARD_RGHT-BOARD_LEFT) : 23;\r
 \r
+  if(border) {\r
+    SetTextAlign(hdc, TA_LEFT|TA_TOP);\r
+    x += -border + 4; y += border - squareSize + 6;\r
+  } else\r
   SetTextAlign(hdc, TA_RIGHT|TA_BOTTOM);\r
   for (i = 0; i < BOARD_RGHT - BOARD_LEFT; i++) {\r
     str[0] = ranks[start + i];\r
@@ -2807,14 +2830,14 @@ DrawHighlightOnDC(HDC hdc, BOOLEAN on, int x, int y, int pen)
   if (lineGap == 0) return;\r
   if (flipView) {\r
     x1 = boardRect.left +\r
-      lineGap/2 + ((BOARD_WIDTH-1)-x) * (squareSize + lineGap);\r
+      lineGap/2 + ((BOARD_WIDTH-1)-x) * (squareSize + lineGap) + border;\r
     y1 = boardRect.top +\r
-      lineGap/2 + y * (squareSize + lineGap);\r
+      lineGap/2 + y * (squareSize + lineGap) + border;\r
   } else {\r
     x1 = boardRect.left +\r
-      lineGap/2 + x * (squareSize + lineGap);\r
+      lineGap/2 + x * (squareSize + lineGap) + border;\r
     y1 = boardRect.top +\r
-      lineGap/2 + ((BOARD_HEIGHT-1)-y) * (squareSize + lineGap);\r
+      lineGap/2 + ((BOARD_HEIGHT-1)-y) * (squareSize + lineGap) + border;\r
   }\r
   hPen = pen ? premovePen : highlightPen;\r
   oldPen = SelectObject(hdc, on ? hPen : gridPen);\r
@@ -2892,7 +2915,9 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
     BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0,\r
           sqcolor ? SRCCOPY : NOTSRCCOPY);\r
   } else {\r
+    HBRUSH xBrush = whitePieceBrush;\r
     tmpSize = squareSize;\r
+    if(appData.pieceDirectory[0]) xBrush = GetStockObject(WHITE_BRUSH);\r
     if(minorSize &&\r
         ((piece >= (int)WhiteNightrider && piece <= WhiteGrasshopper) ||\r
          (piece >= (int)BlackNightrider && piece <= BlackGrasshopper))  ) {\r
@@ -2905,7 +2930,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
     if (color || appData.allWhite ) {\r
       oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE));\r
       if( color )\r
-              oldBrush = SelectObject(hdc, whitePieceBrush);\r
+              oldBrush = SelectObject(hdc, xBrush);\r
       else    oldBrush = SelectObject(hdc, blackPieceBrush);\r
       if(appData.upsideDown && color==flipView)\r
         StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A);\r
@@ -2917,6 +2942,18 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
         StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND);\r
       else\r
         BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, SRCAND);\r
+    } else if(appData.pieceDirectory[0]) {\r
+      oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE));\r
+      oldBrush = SelectObject(hdc, xBrush);\r
+      if(appData.upsideDown && color==flipView)\r
+        StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A);\r
+      else\r
+        BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
+      SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE));\r
+      if(appData.upsideDown && color==flipView)\r
+        StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND);\r
+      else\r
+        BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, SRCAND);\r
     } else {\r
       /* Use square color for details of black pieces */\r
       oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE));\r
@@ -3304,6 +3341,38 @@ BOOL DrawPositionNeedsFullRepaint()
     return result;\r
 }\r
 \r
+static HBITMAP borderBitmap;\r
+\r
+VOID\r
+DrawBackgroundOnDC(HDC hdc)\r
+{\r
+  \r
+  BITMAP bi;\r
+  HDC tmphdc;\r
+  HBITMAP hbm;\r
+  static char oldBorder[MSG_SIZ];\r
+  int w = 600, h = 600;\r
+\r
+  if(strcmp(appData.border, oldBorder)) { // load new one when old one no longer valid\r
+    strncpy(oldBorder, appData.border, MSG_SIZ-1);\r
+    borderBitmap = LoadImage( 0, appData.border, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );        \r
+  }\r
+  if(borderBitmap == NULL) { // loading failed, use white\r
+    FillRect( hdc, &boardRect, whitePieceBrush );\r
+    return;\r
+  }\r
+  tmphdc = CreateCompatibleDC(hdc);\r
+  hbm = SelectObject(tmphdc, borderBitmap);\r
+  if( GetObject( borderBitmap, sizeof(bi), &bi ) > 0 ) {\r
+            w = bi.bmWidth;\r
+            h = bi.bmHeight;\r
+  }\r
+  StretchBlt(hdc, boardRect.left, boardRect.top, boardRect.right - boardRect.left, \r
+                  boardRect.bottom - boardRect.top, tmphdc, 0, 0, w, h, SRCCOPY);\r
+  SelectObject(tmphdc, hbm);\r
+  DeleteDC(tmphdc);\r
+}\r
+\r
 VOID\r
 DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)\r
 {\r
@@ -3822,6 +3891,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
        Ellipse(hdcmem, x-r, y-r, x+r, y+r);\r
        SelectObject(hdcmem, oldBrush);\r
   } else {\r
+    if(border) DrawBackgroundOnDC(hdcmem);\r
     DrawGridOnDC(hdcmem);\r
     if(nr == 0) { // [HGM] dual: decide which highlights to draw\r
        DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN);\r
@@ -4075,11 +4145,11 @@ PaintProc(HWND hwnd)
 int EventToSquare(x, limit)\r
      int x, limit;\r
 {\r
-  if (x <= 0)\r
+  if (x <= border)\r
     return -2;\r
-  if (x < lineGap)\r
+  if (x < lineGap + border)\r
     return -1;\r
-  x -= lineGap;\r
+  x -= lineGap + border;\r
   if ((x % (squareSize + lineGap)) >= squareSize)\r
     return -1;\r
   x /= (squareSize + lineGap);\r
@@ -5135,6 +5205,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       BoardOptionsPopup(hwnd);\r
       break;\r
 \r
+    case IDM_ThemeOptions:\r
+      ThemeOptionsPopup(hwnd);\r
+      break;\r
+\r
     case IDM_EnginePlayOptions:\r
       EnginePlayOptionsPopup(hwnd);\r
       break;\r
@@ -9690,7 +9764,7 @@ CmailSigHandlerCallBack(InputSourceRef isr, VOIDSTAR closure,
 /* see wedittags.c for Edit Tags functions */\r
 \r
 \r
-VOID\r
+int\r
 ICSInitScript()\r
 {\r
   FILE *f;\r
@@ -9702,8 +9776,10 @@ ICSInitScript()
     if (f != NULL) {\r
       ProcessICSInitScript(f);\r
       fclose(f);\r
+      return TRUE;\r
     }\r
   }\r
+  return FALSE;\r
 }\r
 \r
 \r
@@ -9859,11 +9935,11 @@ ScreenSquare(column, row, pt)
      int column; int row; POINT * pt;\r
 {\r
   if (flipView) {\r
-    pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);\r
-    pt->y = lineGap + row * (squareSize + lineGap);\r
+    pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap) + border;\r
+    pt->y = lineGap + row * (squareSize + lineGap) + border;\r
   } else {\r
-    pt->x = lineGap + column * (squareSize + lineGap);\r
-    pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
+    pt->x = lineGap + column * (squareSize + lineGap) + border;\r
+    pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap) + border;\r
   }\r
 }\r
 \r
@@ -9931,3 +10007,24 @@ int flock(int fid, int code)
     }\r
     return 0;\r
 }\r
+\r
+char *\r
+Col2Text (int n)\r
+{\r
+    static int i=0;\r
+    static char col[8][20];\r
+    COLORREF color = *(COLORREF *) colorVariable[n];\r
+    i = i+1 & 7;\r
+    snprintf(col[i], 20, "#%02lx%02lx%02lx", color&0xff, (color>>8)&0xff, (color>>16)&0xff);\r
+    return col[i];\r
+}\r
+\r
+void\r
+ActivateTheme (int new)\r
+{   // Redo initialization of features depending on options that can occur in themes\r
+   InitTextures();\r
+   if(new) InitDrawingColors();\r
+   fontBitmapSquareSize = 0; // request creation of new font pieces\r
+   InitDrawingSizes(-2, 0);\r
+   InvalidateRect(hwndMain, NULL, TRUE);\r
+}\r