Example #1
0
bool csConsoleOutput::Initialize (iObjectRegistry *object_reg)
{
  csConsoleOutput::object_reg = object_reg;
  G3D = csQueryRegistry<iGraphics3D> (object_reg);
  if (!G3D) return false;
  G2D = G3D->GetDriver2D ();

  csConfigAccess Config (object_reg, "/config/standardcon.cfg");
  const char* fontname = Config->GetStr ("StandardConsole.ConFont", "auto");
  int fontsize = Config->GetInt ("StandardConsole.ConFontSize", 10);
  transparent = Config->GetBool ("StandardConsole.TranspBG", false);

  // Initialize the display rectangle to the entire display
  size.Set (0, 0, G2D->GetWidth () - 1, G2D->GetHeight () - 1);
  invalid.Set (size); // Invalidate the entire console
  int fw, fh;
  csRef<iFontServer> fserv = G2D->GetFontServer();
  if (fserv)
  {
    if (!strcasecmp (fontname, "auto"))
    {
      // choose a font that allows at least 80 columns of text
      if (G2D->GetWidth () <= 560)
        fontname = CSFONT_SMALL;
      else if (G2D->GetWidth () <= 640)
        fontname = CSFONT_COURIER;
      else
        fontname = CSFONT_LARGE;
      fontsize = 10;
    }
    font = fserv->LoadFont (fontname, fontsize);
    font->GetMaxSize (fw, fh);
  }
  else
  {
    fw = fh = 20;
    csReport (object_reg, CS_REPORTER_SEVERITY_WARNING,
      "crystalspace.console.output.standard",
      "csConsoleOutput: Unable to locate iFontServer");
  }
  // Create the backbuffer (4096 lines max)
  buffer = new csConsoleBuffer (4096, (size.Height() / (fh + 2)));
  // Initialize flash_time for flashing cursors
  flash_time = csGetTicks ();

  // We want to see broadcast events
  CS_INITIALIZE_SYSTEM_EVENT_SHORTCUTS (object_reg);
  if (!eventHandler)
    eventHandler.AttachNew (new EventHandler (this));
  csRef<iEventQueue> q (csQueryRegistry<iEventQueue> (object_reg));
  if (q.IsValid())
  {
    csEventID events[3] = { SystemOpen, SystemClose, CS_EVENTLIST_END };
    q->RegisterListener (eventHandler, events);
  }
  return true;
}
Example #2
0
File: win32.cpp Project: garinh/cs
Win32Assistant::Win32Assistant (iObjectRegistry* r) 
  : scfImplementationType (this),
  ApplicationActive (true),
  ModuleHandle (0),
  console_window (false),  
  is_console_app(false),
  cmdline_help_wanted(false),
  EventOutlet (0),
  mouseButtons(0)
{
  ModuleHandle = GetModuleHandle(0);
  STARTUPINFO startupInfo;
  GetStartupInfo (&startupInfo);
  if (startupInfo.dwFlags & STARTF_USESHOWWINDOW)
    ApplicationShow = startupInfo.wShowWindow;
  else
    ApplicationShow = SW_SHOWNORMAL;

// Cygwin has problems with freopen()
#if defined(CS_DEBUG) || defined(__CYGWIN__)
  console_window = true;
#else
  console_window = false;
#endif

  use_own_message_loop = true;

  csRef<iCommandLineParser> cmdline (csQueryRegistry<iCommandLineParser> (r));
  console_window = cmdline->GetBoolOption ("console", console_window);

  cmdline_help_wanted = (cmdline->GetOption ("help") != 0);

  /*
     to determine if we are actually a console app we look up
     the subsystem field in the PE header.
   */
  PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)ModuleHandle;
  PIMAGE_NT_HEADERS NTheader = (PIMAGE_NT_HEADERS)((uint8*)dosHeader + dosHeader->e_lfanew);
  if (NTheader->Signature == 0x00004550) // check for PE sig
  {
    is_console_app = 
      (NTheader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
  }

  /*
    - console apps won't do anything about their console... yet. 
    - GUI apps will open a console window if desired.
   */
  if (!is_console_app)
  {
    if (console_window || cmdline_help_wanted)
    {
      AllocConsole ();
      /* "Redirect" C runtime standard files to console, if not redirected 
       * by the user. */
      if (!IsStdHandleRedirected (STD_ERROR_HANDLE)) 
        freopen("CONOUT$", "a", stderr);
      if (!IsStdHandleRedirected (STD_OUTPUT_HANDLE)) 
        freopen("CONOUT$", "a", stdout);
      if (!IsStdHandleRedirected (STD_INPUT_HANDLE)) 
        freopen("CONIN$", "r", stdin);
    }
  }

  /*
    In case we're a console app, set up a control handler so
    console window closing, user logoff and system shutdown
    cause CS to properly shut down.
   */
  if (is_console_app || console_window || cmdline_help_wanted)
  {
    SetConsoleCtrlHandler (&ConsoleHandlerRoutine, TRUE);
  }

  // experimental UC stuff.
  // Retrieve old codepage.
  //oldCP = GetConsoleOutputCP ();
  // Try to set console codepage to UTF-8.
  // @@@ The drawback of UTF8 is that it requires a TrueType console
  // font to work properly. However, default is "raster font" :/
  // In this case, text output w/ non-ASCII chars will appear broken, tho
  // this is really a Windows issue. (see MS KB 99795)
  // @@@ Maybe a command line param to set a different con cp could be useful.
  // * Don't change the codepage, for now.
  //SetConsoleOutputCP (CP_UTF8);
  //

  registry = r;

  HICON appIcon;

  // try the app icon...
  appIcon = LoadIcon (ModuleHandle, MAKEINTRESOURCE (1));
  // not? maybe executable.ico?
  if (!appIcon) 
  {
    char apppath[MAX_PATH];
    GetModuleFileName (0, apppath, sizeof(apppath));

    char *dot = strrchr (apppath, '.');
    if (dot) 
    {
      strcpy (dot, ".ico");
    }
    else
    {
      strcat (apppath, ".ico");
    }
    appIcon = (HICON)LoadImageA (ModuleHandle, apppath, IMAGE_ICON,
      0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
  }
  // finally the default one
  if (!appIcon) appIcon = LoadIcon (0, IDI_APPLICATION);
  
  csString wndClass;
  wndClass.Format ("CrystalSpaceWin32_%p", (void*)this);

  bool bResult = false;
  HBRUSH backBrush = (HBRUSH)::GetStockObject (BLACK_BRUSH);
  if (cswinIsWinNT ())
  {
    WNDCLASSEXW wc;
    
    windowClass = new uint8[(wndClass.Length()+1) * sizeof (WCHAR)];
    csUnicodeTransform::UTF8toWC ((wchar_t*)windowClass,
      wndClass.Length()+1, (utf8_char*)(wndClass.GetData()), (size_t)-1);

    wc.cbSize	      = sizeof (wc);
    wc.hCursor        = 0;
    wc.hIcon          = appIcon;
    wc.lpszMenuName   = 0;
    wc.lpszClassName  = (WCHAR*)windowClass;
    wc.hbrBackground  = backBrush;
    wc.hInstance      = ModuleHandle;
    wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc    = WindowProc;
    wc.cbClsExtra     = 0;
    wc.cbWndExtra     = 2*sizeof (LONG_PTR);
    wc.hIconSm	      = 0;
    bResult = RegisterClassExW (&wc) != 0;
  }
  else
  {
    WNDCLASSEXA wc;
    
    windowClass = new uint8[wndClass.Length()+1];
    strcpy ((char*)windowClass, wndClass);

    wc.cbSize	      = sizeof (wc);
    wc.hCursor        = 0;
    wc.hIcon          = appIcon;
    wc.lpszMenuName   = 0;
    wc.lpszClassName  = (char*)windowClass;
    wc.hbrBackground  = backBrush;
    wc.hInstance      = ModuleHandle;
    wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc    = WindowProc;
    wc.cbClsExtra     = 0;
    wc.cbWndExtra     = 2*sizeof (LONG_PTR);
    wc.hIconSm	      = 0;
    bResult = RegisterClassExA (&wc) != 0;
  }

  if (!bResult)
  {
    SystemFatalError ("Failed to register window class!");
  }

  m_hCursor = LoadCursor (0, IDC_ARROW);

  csRef<iEventQueue> q (csQueryRegistry<iEventQueue> (registry));
  CS_ASSERT (q != 0);
  csEventID events[] = {
    csevFrame (registry),
    csevSystemOpen (registry),
    csevSystemClose (registry),
    csevCommandLineHelp (registry),
    CS_EVENTLIST_END
  };
  q->RegisterListener (this, events);
  CS_INITIALIZE_SYSTEM_EVENT_SHORTCUTS (registry);
  CS_INITIALIZE_FRAME_EVENT_SHORTCUTS (registry);
  Quit = csevQuit (registry);
  CommandLineHelp = csevCommandLineHelp (registry);
  FocusGained = csevFocusGained (registry);
  FocusLost = csevFocusLost (registry);
  //CanvasExposed = csevCanvasExposed (registry, "graph2d");
  //CanvasHidden = csevCanvasHidden (registry, "graph2d");

  // Put our own keyboard driver in place.
#include "csutil/custom_new_disable.h"
  kbdDriver.AttachNew (new csWin32KeyboardDriver (r));
  if (kbdDriver == 0)
  {
    SystemFatalError ("Failed to create keyboard driver!");
  }

  csRef<iBase> currentKbd = 
    csQueryRegistryTag (r, "iKeyboardDriver");
  if (currentKbd != 0)
  {
    // Bit hacky: remove old keyboard driver
    csRef<iEventHandler> eh =  
      scfQueryInterface<iEventHandler> (currentKbd);
    q->RemoveListener (eh);
    r->Unregister (currentKbd, "iKeyboardDriver");
  }
  r->Register (kbdDriver, "iKeyboardDriver");
}