Loading ...
Sorry, an error occurred while loading the content.
 

Re: transparency scope

Expand Messages
  • Eckehard Berns
    Hi! I have updated my patch for a transparent background. It fixes some drawing problems and improves speed a bit. Resizing the window works as expected now,
    Message 1 of 8 , Jan 31, 2004
      Hi!

      I have updated my patch for a transparent background. It fixes some
      drawing problems and improves speed a bit. Resizing the window works
      as expected now, besides a small area at the bottom of the window
      (a few pixels high), which might under certain circumstances be
      drawn in opaque white.

      diff -cr ../vim62.215/src/gui_mac.c ./src/gui_mac.c
      *** ../vim62.215/src/gui_mac.c Mon Jan 26 18:16:14 2004
      --- ./src/gui_mac.c Sat Jan 31 15:35:25 2004
      ***************
      *** 82,87 ****
      --- 82,94 ----
      # endif
      #endif

      + #ifdef USE_CARBONIZED
      + # undef USE_TRANSPARENTBACKGROUND
      + # define USE_TRANSPARENTBACKGROUND
      + static float mytrans_alpha = 1.0f;
      + static CGContextRef mytrans_context;
      + #endif
      +
      /* Debugging feature: start Vim window OFFSETed */
      #undef USE_OFFSETED_WINDOW

      ***************
      *** 321,326 ****
      --- 328,336 ----
      #ifdef USE_AEVENT
      OSErr HandleUnusedParms (const AppleEvent *theAEvent);
      #endif
      + #ifdef USE_TRANSPARENCY
      + static void carbon_set_transparency(WindowRef w, float alpha);
      + #endif

      /*
      * ------------------------------------------------------------
      ***************
      *** 1813,1818 ****
      --- 1823,1860 ----
      * ------------------------------------------------------------
      */

      + #ifdef USE_TRANSPARENTBACKGROUND
      + /*
      + * A transparent version of EraseRect
      + */
      + static void
      + EraseRectTrans(Rect *r)
      + {
      + CGrafPtr p;
      + CGRect cgr;
      + Rect pb;
      + RGBColor rgb;
      +
      + if (mytrans_alpha == 1.0f) {
      + EraseRect(r);
      + return;
      + }
      +
      + p = GetWindowPort(gui.VimWindow);
      + GetPortBounds(p, &pb);
      + cgr = CGRectMake(pb.left + r->left, pb.bottom - r->bottom,
      + r->right - r->left, r->bottom - r->top);
      + CGContextClearRect(mytrans_context, cgr);
      + GetBackColor(&rgb);
      + CGContextSetRGBFillColor(mytrans_context,
      + (float)rgb.red / 65535.0f,
      + (float)rgb.green / 65535.0f,
      + (float)rgb.blue / 65535.0f,
      + mytrans_alpha);
      + CGContextFillRect(mytrans_context, cgr);
      + }
      + #endif /* defined(USE_TRANSPARENTBACKGROUND) */
      +
      /*
      * Handle the Update Event
      */
      ***************
      *** 1849,1855 ****
      --- 1891,1904 ----

      /* Select the Window's Port */
      #ifdef USE_CARBONIZED
      + #ifdef USE_TRANSPARENTBACKGROUND
      + CGContextFlush(mytrans_context);
      + CGContextRelease(mytrans_context);
      + #endif
      SetPortWindowPort (whichWindow);
      + #ifdef USE_TRANSPARENTBACKGROUND
      + CreateCGContextForPort(GetWindowPort(gui.VimWindow), &mytrans_context);
      + #endif
      #else
      SetPort (whichWindow);
      #endif
      ***************
      *** 1884,1889 ****
      --- 1933,1942 ----
      #else
      updateRectPtr = &(*updateRgn)->rgnBBox;
      #endif
      + #ifdef USE_TRANSPARENTBACKGROUND
      + if (mytrans_alpha != 1.0f)
      + ClipCGContextToRegion(mytrans_context, updateRectPtr, updateRgn);
      + #endif
      /* Update the content (i.e. the text) */
      gui_redraw(updateRectPtr->left, updateRectPtr->top,
      updateRectPtr->right - updateRectPtr->left,
      ***************
      *** 1893,1916 ****
      --- 1946,1985 ----
      if (updateRectPtr->left < FILL_X(0))
      {
      SetRect (&rc, 0, 0, FILL_X(0), FILL_Y(Rows));
      + #ifdef USE_TRANSPARENTBACKGROUND
      + EraseRectTrans(&rc);
      + #else
      EraseRect (&rc);
      + #endif
      }
      if (updateRectPtr->top < FILL_Y(0))
      {
      SetRect (&rc, 0, 0, FILL_X(Columns), FILL_Y(0));
      + #ifdef USE_TRANSPARENTBACKGROUND
      + EraseRectTrans(&rc);
      + #else
      EraseRect (&rc);
      + #endif
      }
      if (updateRectPtr->right > FILL_X(Columns))
      {
      SetRect (&rc, FILL_X(Columns), 0,
      FILL_X(Columns) + gui.border_offset, FILL_Y(Rows));
      + #ifdef USE_TRANSPARENTBACKGROUND
      + EraseRectTrans(&rc);
      + #else
      EraseRect (&rc);
      + #endif
      }
      if (updateRectPtr->bottom > FILL_Y(Rows))
      {
      SetRect (&rc, 0, FILL_Y(Rows), FILL_X(Columns) + gui.border_offset,
      FILL_Y(Rows) + gui.border_offset);
      + #ifdef USE_TRANSPARENTBACKGROUND
      + EraseRectTrans(&rc);
      + #else
      EraseRect (&rc);
      + #endif
      }
      HUnlock ((Handle) updateRgn);
      #ifdef USE_CARBONIZED
      ***************
      *** 1937,1942 ****
      --- 2006,2026 ----
      DisposeRgn (saveRgn);
      EndUpdate (whichWindow);

      + #ifdef USE_TRANSPARENTBACKGROUND
      + /*
      + * TODO: I don't know how to reset the clipping path after
      + * ClipCGContextToRegion(), so I just create a new context for the
      + * current port.
      + * The header files state that the clipping path cannot be restored
      + * by a SaveGState/RestoreGState pair.
      + */
      + if (mytrans_alpha != 1.0f) {
      + CGContextFlush(mytrans_context);
      + CGContextRelease(mytrans_context);
      + CreateCGContextForPort(GetWindowPort(gui.VimWindow), &mytrans_context);
      + }
      + #endif
      +
      /* Restore original Port */
      SetPort (savePort);
      }
      ***************
      *** 1954,1960 ****
      --- 2038,2067 ----
      whichWindow = (WindowPtr) event->message;
      if ((event->modifiers) & activeFlag)
      /* Activate */
      + #ifdef USE_TRANSPARENTBACKGROUND
      + {
      gui_focus_change(TRUE);
      + if (mytrans_alpha != 1.0f) {
      + /*
      + * in case the activate event is caused by showing Vim after
      + * it has been hidden, the whole window has to be redrawn
      + *
      + * TODO: distinguish between a normal focus change and a show
      + * application
      + */
      + Rect r;
      + GetWindowBounds(gui.VimWindow, kWindowContentRgn, &r);
      + r.right -= r.left;
      + r.left = 0;
      + r.bottom -= r.top;
      + r.top = 0;
      + gui_mch_set_bg_color(gui.back_pixel);
      + InvalWindowRect(gui.VimWindow, &r);
      + }
      + }
      + #else
      + gui_focus_change(TRUE);
      + #endif
      else
      {
      /* Deactivate */
      ***************
      *** 2707,2712 ****
      --- 2814,2858 ----
      return noErr;
      }

      + #if defined(USE_TRANSPARENTBACKGROUND)
      + /*
      + * this handler does nothing more than return an empty region if
      + * the system asks for the kWindowOpaqueRgn of the window. Everythin
      + * else is passed through to the next handler.
      + */
      + static OSStatus
      + gui_mac_window_getrgn(EventHandlerCallRef inHandlerCallRef,
      + EventRef inEvent, void *inUserData)
      + {
      + OSStatus err;
      + RgnHandle rgn, contentRgn;
      + WindowRegionCode rgnCode;
      +
      + if (mytrans_alpha == 1.0f)
      + goto nextHandler;
      +
      + if (kEventClassWindow != GetEventClass(inEvent) ||
      + kEventWindowGetRegion != GetEventKind(inEvent))
      + goto nextHandler;
      + if (noErr != GetEventParameter(inEvent, kEventParamWindowRegionCode,
      + typeWindowRegionCode, NULL, sizeof(WindowRegionCode), NULL,
      + &rgnCode))
      + goto nextHandler;
      + if (rgnCode != kWindowOpaqueRgn)
      + goto nextHandler;
      + err = CallNextEventHandler(inHandlerCallRef, inEvent);
      + if (noErr != GetEventParameter(inEvent, kEventParamRgnHandle,
      + typeQDRgnHandle, NULL, sizeof(RgnHandle), NULL, &rgn))
      + goto nextHandler;
      + contentRgn = NewRgn();
      + GetWindowRegion(gui.VimWindow, kWindowContentRgn, contentRgn);
      + SetEmptyRgn(rgn);
      + return err;
      + nextHandler:
      + return CallNextEventHandler(inHandlerCallRef, inEvent);
      + }
      + #endif /* defined(USE_TRANSPARENTBACKGROUND) */
      +
      /*
      * Initialise the GUI. Create all the windows, set up all the call-backs
      * etc.
      ***************
      *** 2778,2784 ****
      --- 2924,2947 ----
      InstallReceiveHandler((DragReceiveHandlerUPP)receiveHandler,
      gui.VimWindow, NULL);
      #ifdef USE_CARBONIZED
      + #ifdef USE_TRANSPARENTBACKGROUND
      + {
      + /* install the event handler for kEventWindowGetRegion */
      + EventTypeSpec ets[] = {
      + { kEventClassWindow, kEventWindowGetRegion }
      + };
      + EventHandlerRef ehr;
      + EventHandlerUPP handlerUPP = NewEventHandlerUPP(gui_mac_window_getrgn);
      + if (noErr != InstallEventHandler(
      + GetWindowEventTarget(gui.VimWindow),
      + handlerUPP, 1, ets, NULL, &ehr))
      + printf("couldn't install handler for kEventWindowGetRegion\n");
      + }
      + #endif
      SetPortWindowPort ( gui.VimWindow );
      + #ifdef USE_TRANSPARENCY
      + carbon_set_transparency(gui.VimWindow, 1.0f);
      + #endif
      #else
      SetPort(gui.VimWindow);
      #endif
      ***************
      *** 2878,2883 ****
      --- 3041,3049 ----
      int
      gui_mch_open()
      {
      + #ifdef USE_TRANSPARENTBACKGROUND
      + CreateCGContextForPort(GetWindowPort(gui.VimWindow), &mytrans_context);
      + #endif
      ShowWindow(gui.VimWindow);

      if (gui_win_x != -1 && gui_win_y != -1)
      ***************
      *** 3327,3332 ****
      --- 3493,3501 ----
      int len;
      int flags;
      {
      + #ifdef USE_TRANSPARENTBACKGROUND
      + Rect r;
      + #endif

      #if defined(FEAT_GUI) && defined(MACOS_X)
      /*
      ***************
      *** 3370,3376 ****
      --- 3539,3549 ----
      rc.top = FILL_Y(row);
      rc.right = FILL_X(col + len) + (col + len == Columns);
      rc.bottom = FILL_Y(row + 1);
      + #ifdef USE_TRANSPARENTBACKGROUND
      + EraseRectTrans(&rc);
      + #else
      EraseRect(&rc);
      + #endif
      }

      MoveTo(TEXT_X(col), TEXT_Y(row));
      ***************
      *** 3389,3394 ****
      --- 3562,3577 ----
      {
      TextMode (srcOr);
      }
      + #ifdef USE_TRANSPARENTBACKGROUND
      + else if (mytrans_alpha != 1.1f) {
      + r.left = TEXT_X(col);
      + r.top = row * gui.char_height + gui.border_width;
      + r.right = TEXT_X(col + len);
      + r.bottom = (row + 1) * gui.char_height + gui.border_width;
      + EraseRectTrans(&r);
      + TextMode(srcOr /* transparent */);
      + }
      + #endif

      MoveTo (TEXT_X(col), TEXT_Y(row));
      DrawText ((char *)s, 0, len);
      ***************
      *** 3449,3455 ****

      ui_delay((long)msec, TRUE); /* wait for some msec */

      ! InvertRect(&rc);
      }

      /*
      --- 3632,3649 ----

      ui_delay((long)msec, TRUE); /* wait for some msec */

      ! #ifdef USE_TRANSPARENTBACKGROUND
      ! if (mytrans_alpha != 1.0f) {
      ! Rect r;
      ! GetWindowBounds(gui.VimWindow, kWindowContentRgn, &r);
      ! r.right -= r.left;
      ! r.left = 0;
      ! r.bottom -= r.top;
      ! r.top = 0;
      ! InvalWindowRect(gui.VimWindow, &r);
      ! } else
      ! #endif
      ! InvertRect(&rc);
      }

      /*
      ***************
      *** 3464,3469 ****
      --- 3658,3667 ----
      {
      Rect rc;

      + #if defined(USE_TRANSPARENTBACKGROUND) && 1
      + printf("gui_mch_invert_rectangle called\n");
      + #endif
      +
      /*
      * Note: InvertRect() excludes right and bottom of rectangle.
      */
      ***************
      *** 3683,3688 ****
      --- 3881,3891 ----
      gui_mch_flush()
      {
      /* TODO: Is anything needed here? */
      + #if defined(USE_TRANSPARENTBACKGROUND) && 1
      + if (mytrans_alpha != 1.0f) {
      + CGContextSynchronize(mytrans_context);
      + }
      + #endif
      }

      /*
      ***************
      *** 3708,3714 ****
      --- 3911,3921 ----
      rc.bottom = FILL_Y(row2 + 1);

      gui_mch_set_bg_color(gui.back_pixel);
      + #ifdef USE_TRANSPARENTBACKGROUND
      + EraseRectTrans(&rc);
      + #else
      EraseRect (&rc);
      + #endif
      }

      /*
      ***************
      *** 3725,3731 ****
      --- 3932,3942 ----
      rc.bottom = Rows * gui.char_height + 2 * gui.border_width;

      gui_mch_set_bg_color(gui.back_pixel);
      + #ifdef USE_TRANSPARENTBACKGROUND
      + EraseRectTrans(&rc);
      + #else
      EraseRect(&rc);
      + #endif
      /* gui_mch_set_fg_color(gui.norm_pixel);
      FrameRect(&rc);
      */
      ***************
      *** 4397,4402 ****
      --- 4608,4617 ----
      int w;
      int h;
      {
      + #ifdef USE_TRANSPARENTBACKGROUND
      + Rect r;
      + #endif
      +
      gui_mch_set_bg_color(gui.back_pixel);
      /* if (gui.which_scrollbars[SBAR_LEFT])
      {
      ***************
      *** 4416,4426 ****
      --- 4631,4654 ----
      if (gui.which_scrollbars[SBAR_LEFT])
      x -= 15;

      + #ifdef USE_TRANSPARENTBACKGROUND
      + if (mytrans_alpha != 1.0f) {
      + GetControlBounds(sb->id, &r);
      + }
      + #endif
      +
      MoveControl (sb->id, x, y);
      SizeControl (sb->id, w, h);
      #ifdef DEBUG_MAC_SB
      printf ("size_sb (%x) %x, %x, %x, %x\n",sb->id, x, y, w, h);
      #endif
      +
      + #ifdef USE_TRANSPARENTBACKGROUND
      + if (mytrans_alpha != 1.0f) {
      + if (r.left < x)
      + EraseRectTrans(&r);
      + }
      + #endif
      }

      void
      ***************
      *** 5566,5568 ****
      --- 5794,5834 ----
      && script == GetScriptManagerVariable(smSysScript)) ? 1 : 0;
      }
      #endif /* defined(USE_IM_CONTROL) || defined(PROTO) */
      +
      + #ifdef USE_TRANSPARENCY
      + void
      + carbon_set_transparency(WindowRef w, float alpha)
      + {
      + if (!w)
      + w = gui.VimWindow;
      + #ifdef USE_TRANSPARENTBACKGROUND
      + /*
      + * if we want a transparent window background the system must be fooled
      + * that the window isn't fully opaque. I do this by setting the alpha
      + * value a bit below 1.0f
      + */
      + if (alpha == 1.0f)
      + SetWindowAlpha(w, 1.0f);
      + else
      + SetWindowAlpha(w, 0.9999999f);
      + mytrans_alpha = alpha;
      + {
      + Rect r;
      + GetWindowBounds(gui.VimWindow, kWindowContentRgn, &r);
      + r.right -= r.left;
      + r.left = 0;
      + r.bottom -= r.top;
      + r.top = 0;
      + InvalWindowRect(gui.VimWindow, &r);
      + }
      + #else
      + SetWindowAlpha(w, alpha);
      + #endif
      + }
      +
      + void
      + gui_mch_set_transparency(int alpha)
      + {
      + carbon_set_transparency(NULL, (float)alpha / 255);
      + }
      + #endif
      diff -cr ../vim62.215/src/option.c ./src/option.c
      *** ../vim62.215/src/option.c Mon Jan 26 18:16:14 2004
      --- ./src/option.c Fri Jan 30 18:27:27 2004
      ***************
      *** 2103,2108 ****
      --- 2103,2113 ----
      (char_u *)&p_tbis, PV_NONE,
      {(char_u *)"small", (char_u *)0L}},
      #endif
      + #ifdef USE_TRANSPARENCY
      + {"transparency", "tra", P_NUM|P_VI_DEF,
      + (char_u *)&p_transparency, PV_NONE,
      + {(char_u *)255L, (char_u *)0L}},
      + #endif
      {"ttimeout", NULL, P_BOOL|P_VI_DEF|P_VIM,
      (char_u *)&p_ttimeout, PV_NONE,
      {(char_u *)FALSE, (char_u *)0L}},
      ***************
      *** 6561,6566 ****
      --- 6566,6580 ----
      foldUpdateAll(curwin);
      }
      #endif /* FEAT_FOLDING */
      +
      + #ifdef USE_TRANSPARENCY
      + else if ((long *)varp == &p_transparency)
      + {
      + if (p_transparency < 1 || p_transparency > 255)
      + p_transparency = 255;
      + gui_mch_set_transparency(p_transparency);
      + }
      + #endif

      else if (pp == &curbuf->b_p_iminsert)
      {
      diff -cr ../vim62.215/src/option.h ./src/option.h
      *** ../vim62.215/src/option.h Mon Jan 26 18:16:14 2004
      --- ./src/option.h Fri Jan 30 18:27:27 2004
      ***************
      *** 691,696 ****
      --- 691,699 ----
      #ifdef FEAT_INS_EXPAND
      EXTERN char_u *p_tsr; /* 'thesaurus' */
      #endif
      + #ifdef USE_TRANSPARENCY
      + EXTERN long p_transparency; /* 'transparency'*/
      + #endif
      EXTERN int p_ttimeout; /* 'ttimeout' */
      EXTERN long p_ttm; /* 'ttimeoutlen' */
      EXTERN int p_tbi; /* 'ttybuiltin' */
      diff -cr ../vim62.215/src/os_mac.h ./src/os_mac.h
      *** ../vim62.215/src/os_mac.h Tue Jan 20 19:39:52 2004
      --- ./src/os_mac.h Fri Jan 30 18:27:27 2004
      ***************
      *** 118,123 ****
      --- 118,124 ----
      #if defined(TARGET_API_MAC_OSX) && TARGET_API_MAC_OSX
      # undef COLON_AS_PATHSEP
      # define USE_UNIXFILENAME
      + # define USE_TRANSPARENCY
      #else
      # define COLON_AS_PATHSEP
      # define DONT_ADD_PATHSEP_TO_DIR
      diff -cr ../vim62.215/src/proto/gui_mac.pro ./src/proto/gui_mac.pro
      *** ../vim62.215/src/proto/gui_mac.pro Tue Jan 20 19:39:52 2004
      --- ./src/proto/gui_mac.pro Fri Jan 30 18:27:27 2004
      ***************
      *** 134,139 ****
      --- 134,140 ----
      void gui_mac_doMouseDownEvent __ARGS((EventRecord *theEvent));
      void gui_mac_doMouseMovedEvent __ARGS((EventRecord *event));
      void gui_mac_doMouseUpEvent __ARGS((EventRecord *theEvent));
      + void gui_mch_set_transparency __ARGS((int alpha));

      int C2PascalString (char_u *CString, Str255 *PascalString);
      int GetFSSpecFromPath ( char_u *file, FSSpec *fileFSSpec);

      --
      Eckehard Berns
    Your message has been successfully submitted and would be delivered to recipients shortly.