/**
     * Update the texture if the native WebView window has changed.
     *
     * @param dc Draw context
     */
    @Override
    protected void updateIfNeeded(DrawContext dc) {
      // Return immediately if the native WebViewWindow object isn't initialized, and wait to update
      // until the
      // native object is initialized. This method is called after the texture is bound, so we'll
      // get another
      // chance to update as long as the WebView generates repaint events when it changes.
      long webViewWindowPtr = WindowsWebView.this.webViewWindowPtr;
      if (webViewWindowPtr == 0) return;

      // Return immediately if the texture isn't in the texture cache, and wait to update until the
      // texture is
      // initialized and placed in the cache. This method is called after the texture is bound, so
      // we'll get
      // another chance to update as long as the WebView generates repaint events when it changes.
      Texture texture = this.getTextureFromCache(dc);
      if (texture == null) return;

      // Load the WebViewWindow's current display pixels into the currently bound OGL texture if our
      // update time
      // is different than the WebViewWindow's update time.
      long newUpdateTime = WindowsWebViewJNI.getUpdateTime(webViewWindowPtr);
      if (newUpdateTime != this.updateTime) {
        WindowsWebViewJNI.loadDisplayInGLTexture(webViewWindowPtr, texture.getTarget());
        this.updateTime = newUpdateTime;
      }
    }
  /** {@inheritDoc} */
  public void dispose() {
    if (this.disposed) // Do not dispose the WebView multiple times
    return;

    try {
      // Remove the notification adapter
      if (webViewWindowPtr != 0 && observerPtr != 0)
        WindowsWebViewJNI.removeWindowUpdateObserver(webViewWindowPtr, observerPtr);
      // Free the native WebView object associated with this Java WebView object.
      if (webViewWindowPtr != 0) {
        WindowsWebViewJNI.releaseWebView(webViewWindowPtr);
        // Decrement the instance counter. Only do this if the webViewWindow pointer was non-zero,
        // indicating
        // that native resources were actually allocated.
        instances.decrementAndGet();
      }
      if (observerPtr != 0) WindowsWebViewJNI.releaseComObject(observerPtr);

      this.webViewWindowPtr = 0;
      this.observerPtr = 0;

      // Terminate the message loop thread if this is the last active instance.
      this.stopMessageLoopIfNoInstances();

      this.disposed = true;
    } catch (Exception e) {
      Logging.logger()
          .log(
              Level.SEVERE,
              Logging.getMessage("generic.ExceptionAttemptingToDisposeRenderable"),
              e);
    }
  }
  /**
   * Create a new WebView.
   *
   * @param frameSize The size of the WebView rectangle.
   * @throws UnsupportedOperationException if this class is instantiated on a non-Windows operating
   *     system.
   * @throws WWRuntimeException if creating the native web browser window fails for any reason. For
   *     example, because the process has run out of User Object handles (see documentation <a
   *     href="#limits">above</a>).
   */
  public WindowsWebView(Dimension frameSize) {
    if (frameSize == null) {
      String message = Logging.getMessage("nullValue.SizeIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    if (!Configuration.isWindowsOS()) {
      String message =
          Logging.getMessage(
              "NativeLib.UnsupportedOperatingSystem",
              "Windows WebView",
              System.getProperty("os.name"));
      Logging.logger().severe(message);
      throw new UnsupportedOperationException(message);
    }

    this.frameSize = frameSize;

    try {
      // Increment the instance counter
      instances.incrementAndGet();

      // Make sure that the message loop thread is running
      this.ensureMessageLoopRunning();

      // Create the web view
      this.webViewWindowPtr = WindowsWebViewJNI.newWebViewWindow(webViewMessageLoop);
      if (this.webViewWindowPtr == 0) {
        String message = Logging.getMessage("WebView.NativeExceptionInitializingWebView");
        Logging.logger().severe(message);
        throw new WWRuntimeException(message);
      }

      WindowsWebViewJNI.setFrameSize(
          this.webViewWindowPtr, this.frameSize.width, this.frameSize.height);

      this.observerPtr = WindowsWebViewJNI.newNotificationAdapter(this);

      WindowsWebViewJNI.addWindowUpdateObserver(this.webViewWindowPtr, observerPtr);
    } catch (RuntimeException e) {
      // If the WebView was not created successfully do not increment the instance counter.
      instances.decrementAndGet();
      this.handleWebViewCreationError();
      throw e;
    } catch (Error e) {
      // If the WebView was not created successfully do not increment the instance counter.
      instances.decrementAndGet();
      this.handleWebViewCreationError();
      throw e;
    }
  }
  /** {@inheritDoc} */
  public Dimension getMinContentSize() {
    if (this.webViewWindowPtr != 0) {
      return WindowsWebViewJNI.getMinContentSize(this.webViewWindowPtr);
    }

    return null;
  }
 /** {@inheritDoc} */
 public Iterable<AVList> getLinks() {
   if (this.webViewWindowPtr != 0) {
     AVList[] links = WindowsWebViewJNI.getLinks(this.webViewWindowPtr);
     if (links != null) return Arrays.asList(links);
   }
   return Collections.emptyList();
 }
  /** {@inheritDoc} */
  public void sendEvent(InputEvent event) {
    if (event != null) {
      // Convert OpenGL coordinates to Windows.
      if (event instanceof MouseEvent) event = convertToWindows((MouseEvent) event);

      // Send the AWT InputEvent to the native WebView object
      if (this.webViewWindowPtr != 0) WindowsWebViewJNI.sendEvent(this.webViewWindowPtr, event);
    }
  }
 /**
  * Terminate the message loop thread if there are no active (non-disposed) WebView instances. Has
  * no effect if there are active instances.
  */
 protected void stopMessageLoopIfNoInstances() {
   synchronized (webViewUILock) {
     if (instances.get() <= 0) {
       WindowsWebViewJNI.releaseMessageLoop(webViewMessageLoop);
       webViewMessageLoop = 0;
       webViewUI = null;
     }
   }
 }
  /** {@inheritDoc} */
  public void setBackgroundColor(Color color) {
    if (color == null) {
      String message = Logging.getMessage("nullValue.ColorIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    // Only set the color if it actually changed
    if (!color.equals(this.getBackgroundColor())) {
      this.backgroundColor = color;

      // Convert the color to an RGB hex triplet string that the WebBrowser will understand
      int rgb =
          (color.getRed() & 0xFF) << 16 | (color.getGreen() & 0xFF) << 8 | (color.getBlue() & 0xFF);
      String colorString = String.format("#%06X", rgb);

      WindowsWebViewJNI.setBackgroundColor(this.webViewWindowPtr, colorString);
    }
  }
 protected void doSetFrameSize(Dimension size) {
   if (this.webViewWindowPtr != 0)
     WindowsWebViewJNI.setFrameSize(this.webViewWindowPtr, size.width, size.height);
 }
 /** {@inheritDoc} */
 public void setHTMLString(String htmlString) {
   if (this.webViewWindowPtr != 0) {
     WindowsWebViewJNI.setHTMLString(this.webViewWindowPtr, htmlString, null);
   }
 }
 /** {@inheritDoc} */
 public void goForward() {
   if (this.webViewWindowPtr != 0) WindowsWebViewJNI.goForward(this.webViewWindowPtr);
 }
 /** {@inheritDoc} */
 public void goBack() {
   if (this.webViewWindowPtr != 0) WindowsWebViewJNI.goBack(this.webViewWindowPtr);
 }
  /**
   * {@inheritDoc}
   *
   * <p>Overridden to apply the active state to the native WebView.
   */
  @Override
  public void setActive(boolean active) {
    super.setActive(active);

    if (this.webViewWindowPtr != 0) WindowsWebViewJNI.setActive(this.webViewWindowPtr, active);
  }
 /** {@inheritDoc} */
 public URL getContentURL() {
   if (this.webViewWindowPtr != 0) {
     return WWIO.makeURL(WindowsWebViewJNI.getContentURL(this.webViewWindowPtr));
   }
   return null;
 }
 /** {@inheritDoc} */
 public void setMinContentSize(Dimension size) {
   if (this.webViewWindowPtr != 0) {
     WindowsWebViewJNI.setMinContentSize(this.webViewWindowPtr, size.width, size.height);
   }
 }
 /** {@inheritDoc} */
 public Dimension getContentSize() {
   return WindowsWebViewJNI.getContentSize(webViewWindowPtr);
 }
 /** {@inheritDoc} */
 public void setHTMLString(String htmlString, WebResourceResolver resourceResolver) {
   if (this.webViewWindowPtr != 0) {
     WindowsWebViewJNI.setHTMLStringWithResourceResolver(
         this.webViewWindowPtr, htmlString, resourceResolver);
   }
 }
 /** {@inheritDoc} */
 public void setHTMLString(String htmlString, URL baseURL) {
   if (this.webViewWindowPtr != 0) {
     WindowsWebViewJNI.setHTMLString(
         this.webViewWindowPtr, htmlString, baseURL != null ? baseURL.toString() : null);
   }
 }