code: /*--------------------------------------------------------------*
    Copyright (C) 2006-2015 OpenSim Ltd.
  
    This file is distributed WITHOUT ANY WARRANTY. See the file
    'License' for details on this and other legal matters.
  *--------------------------------------------------------------*/
  
  package org.omnetpp.common.util;
  
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.graphics.Color;
  import org.eclipse.swt.widgets.Display;
  import org.eclipse.swt.widgets.Listener;
  import org.omnetpp.common.color.ColorFactory;
  
  public class DisplayUtils {
      public static void runNowOrAsyncInUIThread(Runnable runnable) {
          if (Display.getCurrent() == null)
              Display.getDefault().asyncExec(runnable);
          else
              runnable.run();
      }
  
      public static void runNowOrSyncInUIThread(Runnable runnable) {
          if (Display.getCurrent() == null)
              Display.getDefault().syncExec(runnable);
          else
              runnable.run();
      }
  
      /**
       * Adds an event filter in front of existing filters. This is needed if you want
       * to receive all keypresses including hotkeys, because then you want to be in
       * front of the key binding service (which is also an event filter on Display,
       * and it translates keypress events that correspond to hotkeys to something else).
       */
      public static void addAsFirstFilter(int eventType, Listener listener) {
          // first, make room in the table (this adds the listener at the end of the table)
          Display display = Display.getDefault();
          display.addFilter(eventType, listener);
  
          // shift everything up, then add our listener to slot 0. Sorry about the reflection,
          // there seem to be no other way
          Object filterTable = ReflectionUtils.getFieldValue(display, "filterTable");
          int[] types = (int[]) ReflectionUtils.getFieldValue(filterTable, "types");
          Listener[] listeners = (Listener[]) ReflectionUtils.getFieldValue(filterTable, "listeners");
          System.arraycopy(types, 0, types, 1, types.length-1);
          System.arraycopy(listeners, 0, listeners, 1, listeners.length-1);
          types[0] = eventType;
          listeners[0] = listener;
          for (int i = 1; i < types.length; i++) {
              if (types[i] == eventType && listeners[i] == listener) {
                  types[i] = 0; listeners[i] = null; break; // remove instance added first
              }
          }
      }
  
      public static boolean isDarkTheme() {
          Display display= Display.getCurrent();
          if (display == null)
              return false;
          Color bgColor = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
          double brightness = bgColor.getRed()*0.299 + bgColor.getGreen()*0.587 + bgColor.getBlue()*0.114;
          return brightness < 128.0;
      }
  
      public static Color getForegroundColor() {
          var display = Display.getCurrent();
          if (display == null)
              return ColorFactory.BLACK;
  
          return display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
      }
  }
  