<commit_before>//===========================================
//  Lumina-DE source code
//  Copyright (c) 2014, Ken Moore
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "LPlugins.h"

#include <LuminaUtils.h>

LPlugins::LPlugins(){
  LoadPanelPlugins();
  LoadDesktopPlugins();
  LoadMenuPlugins();
  LoadColorItems();
}

LPlugins::~LPlugins(){
}

//Plugin lists
QStringList LPlugins::panelPlugins(){
  QStringList pan = PANEL.keys();
    pan.sort();
  return pan;
}
QStringList LPlugins::desktopPlugins(){
  QStringList desk = DESKTOP.keys();
	desk.sort();
  return desk;
}
QStringList LPlugins::menuPlugins(){
    QStringList men = MENU.keys();
	men.sort();
  return men;
}
QStringList LPlugins::colorItems(){
  return COLORS.keys();
}
//Information on individual plugins
LPI LPlugins::panelPluginInfo(QString plug){
  if(PANEL.contains(plug)){ return PANEL[plug]; }
  else{ return LPI(); }
}
LPI LPlugins::desktopPluginInfo(QString plug){
  if(DESKTOP.contains(plug)){ return DESKTOP[plug]; }
  else{ return LPI(); }
}
LPI LPlugins::menuPluginInfo(QString plug){
  if(MENU.contains(plug)){ return MENU[plug]; }
  else{ return LPI(); }
}
LPI LPlugins::colorInfo(QString item){
  if(COLORS.contains(item)){ return COLORS[item]; }
  else{ return LPI(); }
}

//===================
//             PLUGINS
//===================
void LPlugins::LoadPanelPlugins(){
  PANEL.clear();
  //User Button
  LPI info;
    info.name = QObject::tr("User Button");
    info.description = QObject::tr("This is the main system access button for the user (applications, directories, settings, log out).");
    info.ID = "userbutton";
    info.icon = "user-identity";
  PANEL.insert(info.ID, info);
   //Application Menu
  info = LPI(); //clear it
    info.name = QObject::tr("Application Menu");
    info.description = QObject::tr("This provides instant-access to application that are installed on the system.");
    info.ID = "appmenu";
    info.icon = "format-list-unordered";
  PANEL.insert(info.ID, info);
  //Desktop Bar
  info = LPI(); //clear it
    info.name = QObject::tr("Desktop Bar");
    info.description = QObject::tr("This provides shortcuts to everything in the desktop folder - allowing easy access to all your favorite files/applications.");
    info.ID = "desktopbar";
    info.icon = "user-desktop";
  PANEL.insert(info.ID, info);
  //Spacer
  info = LPI(); //clear it
    info.name = QObject::tr("Spacer");
    info.description = QObject::tr("Invisible spacer to separate plugins.");
    info.ID = "spacer";
    info.icon = "transform-move";
  PANEL.insert(info.ID, info);
  //Line
  info = LPI(); //clear it
    info.name = QObject::tr("Line");
    info.description = QObject::tr("Simple line to provide visual separation between items.");
    info.ID = "line";
    info.icon = "insert-horizontal-rule";
  PANEL.insert(info.ID, info);
  //Desktop Switcher
  info = LPI(); //clear it
    info.name = QObject::tr("Workspace Switcher");
    info.description = QObject::tr("Controls for switching between the various virtual desktops.");
    info.ID = "desktopswitcher";
    info.icon = "preferences-desktop-display-color";
  PANEL.insert(info.ID, info);
  //Battery
  info = LPI(); //clear it
    info.name = QObject::tr("Battery Monitor");
    info.description = QObject::tr("Keep track of your battery status.");
    info.ID = "battery";
    info.icon = "battery-charging";
  PANEL.insert(info.ID, info);
  //Clock
  info = LPI(); //clear it
    info.name = QObject::tr("Time/Date");
    info.description = QObject::tr("View the current time and date.");
    info.ID = "clock";
    info.icon = "preferences-system-time";
  PANEL.insert(info.ID, info);
  //System Dachboard plugin
  info = LPI(); //clear it
    info.name = QObject::tr("System Dashboard");
    info.description = QObject::tr("View or change system settings (audio volume, screen brightness, battery life, virtual desktops).");
    info.ID = "systemdashboard";
    info.icon = "dashboard-show";
  PANEL.insert(info.ID, info);
  //Task Manager
  info = LPI(); //clear it
    info.name = QObject::tr("Task Manager");
    info.description = QObject::tr("View and control any running application windows (every application has a button)");
    info.ID = "taskmanager";
    info.icon = "preferences-system-windows";
  PANEL.insert(info.ID, info);
  //Task Manager
  info = LPI(); //clear it
    info.name = QObject::tr("Task Manager (No Groups)");
    info.description = QObject::tr("View and control any running application windows (every window has a button)");
    info.ID = "taskmanager-nogroups";
    info.icon = "preferences-system-windows";
  PANEL.insert(info.ID, info);
  //System Tray
  info = LPI(); //clear it
    info.name = QObject::tr("System Tray");
    info.description = QObject::tr("Display area for dockable system applications");
    info.ID = "systemtray";
    info.icon = "preferences-system-windows-actions";
  PANEL.insert(info.ID, info);
  //Home Button
  info = LPI(); //clear it
    info.name = QObject::tr("Show Desktop");
    info.description = QObject::tr("Hide all open windows and show the desktop");
    info.ID = "homebutton";
    info.icon = "user-desktop";
  PANEL.insert(info.ID, info);
  //Start Menu
  info = LPI(); //clear it
    info.name = QObject::tr("Start Menu");
    info.description = QObject::tr("Unified system access and application launch menu.");
    info.ID = "systemstart";
    info.icon = "Lumina-DE";
  PANEL.insert(info.ID, info);
  //Application Launcher
  info = LPI(); //clear it
    info.name = QObject::tr("Application Launcher");
    info.description = QObject::tr("Pin an application shortcut directly to the panel");
    info.ID = "applauncher";
    info.icon = "quickopen";
  PANEL.insert(info.ID, info);
}

void LPlugins::LoadDesktopPlugins(){
  DESKTOP.clear();
  //Calendar Plugin
  LPI info;
    info.name = QObject::tr("Calendar");
    info.description = QObject::tr("Display a calendar on the desktop");
    info.ID = "calendar";
    info.icon = "view-calendar";
  DESKTOP.insert(info.ID, info);
  //Application Launcher Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("Application Launcher");
    info.description = QObject::tr("Desktop button for launching an application");
    info.ID = "applauncher";
    info.icon = "quickopen";
  DESKTOP.insert(info.ID, info);
  //Desktop View Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("Desktop Icons View");
    info.description = QObject::tr("Area for automatically showing desktop icons");
    info.ID = "desktopview";
    info.icon = "preferences-desktop-icons";
  DESKTOP.insert(info.ID, info);
  //Notepad Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("Note Pad");
    info.description = QObject::tr("Keep simple text notes on your desktop");
    info.ID = "notepad";
    info.icon = "text-enriched";
  DESKTOP.insert(info.ID, info);
  //Audio Player Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("Audio Player");
    info.description = QObject::tr("Play through lists of audio files");
    info.ID = "audioplayer";
    info.icon = "media-playback-start";
  DESKTOP.insert(info.ID, info);
  //System Monitor Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("System Monitor");
    info.description = QObject::tr("Keep track of system statistics such as CPU/Memory usage and CPU temperatures.");
    info.ID = "systemmonitor";
    info.icon = "cpu";
  DESKTOP.insert(info.ID, info);
  //Available QtQuick scripts
  /*QStringList quickID = LUtils::listQuickPlugins();
  for(int i=0; i<quickID.length(); i++){
    QStringList quickinfo = LUtils::infoQuickPlugin(quickID[i]); //Returns: [name, description, icon]
    if(quickinfo.length() < 3){ continue; } //invalid file (unreadable/other)
    info = LPI();
      info.name = quickinfo[0];
      info.description = quickinfo[1];
      info.ID = "quick-"+quickID[i]; //the "quick-" prefix is required for the desktop plugin syntax
      info.icon = quickinfo[2];
    DESKTOP.insert(info.ID, info);
  }*/
}

void LPlugins::LoadMenuPlugins(){
  MENU.clear();
  //Terminal
  LPI info;
    info.name = QObject::tr("Terminal");
    info.description = QObject::tr("Start the default system terminal.");
    info.ID = "terminal";
    info.icon = "utilities-terminal";
  MENU.insert(info.ID, info);
  //File Manager
  info = LPI(); //clear it
    info.name = QObject::tr("File Manager");
    info.description = QObject::tr("Browse the system with the default file manager.");
    info.ID = "filemanager";
    info.icon = "Insight-FileManager";
  MENU.insert(info.ID, info);
  //Applications
  info = LPI(); //clear it
    info.name = QObject::tr("Applications");
    info.description = QObject::tr("Show the system applications menu.");
    info.ID = "applications";
    info.icon = "system-run";
  MENU.insert(info.ID, info);
  //Line seperator
  info = LPI(); //clear it
    info.name = QObject::tr("Separator");
    info.description = QObject::tr("Static horizontal line.");
    info.ID = "line";
    info.icon = "insert-horizontal-rule";
  MENU.insert(info.ID, info);
  //Settings
  info = LPI(); //clear it
    info.name = QObject::tr("Settings");
    info.description = QObject::tr("Show the desktop settings menu.");
    info.ID = "settings";
    info.icon = "configure";
  MENU.insert(info.ID, info);
  //Window List
  info = LPI(); //clear it
    info.name = QObject::tr("Window List");
    info.description = QObject::tr("List the open application windows");
    info.ID = "windowlist";
    info.icon = "preferences-system-windows";
  MENU.insert(info.ID, info);
  //Custom Apps
  info = LPI(); //clear it
    info.name = QObject::tr("Custom App");
    info.description = QObject::tr("Start a custom application");
    info.ID = "app";
    info.icon = "application-x-desktop";
  MENU.insert(info.ID, info);
}

void LPlugins::LoadColorItems(){
  COLORS.clear();
  //Text Color
  LPI info;
    info.name = QObject::tr("Text");
    info.description = QObject::tr("Color to use for all visible text.");
    info.ID = "TEXTCOLOR";
  COLORS.insert(info.ID, info);
  //Text Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Text (Disabled)");
    info.description = QObject::tr("Text color for disabled or inactive items.");
    info.ID = "TEXTDISABLECOLOR";
  COLORS.insert(info.ID, info);
  //Text Color (Highlighted)
  info = LPI(); //clear it
    info.name = QObject::tr("Text (Highlighted)");
    info.description = QObject::tr("Text color when selection is highlighted.");
    info.ID = "TEXTHIGHLIGHTCOLOR";
  COLORS.insert(info.ID, info);
  //Base Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Base Window Color");
    info.description = QObject::tr("Main background color for the window/dialog.");
    info.ID = "BASECOLOR";
  COLORS.insert(info.ID, info);
  //Base Color (Alternate)
  info = LPI(); //clear it
    info.name = QObject::tr("Base Window Color (Alternate)");
    info.description = QObject::tr("Main background color for widgets that list or display collections of items.");
    info.ID = "ALTBASECOLOR";
  COLORS.insert(info.ID, info);
  //Primary Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Primary Color");
    info.description = QObject::tr("Dominant color for the theme.");
    info.ID = "PRIMARYCOLOR";
  COLORS.insert(info.ID, info);
  //Primary Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Primary Color (Disabled)");
    info.description = QObject::tr("Dominant color for the theme (more subdued).");
    info.ID = "PRIMARYDISABLECOLOR";
  COLORS.insert(info.ID, info);
  //Secondary Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Secondary Color");
    info.description = QObject::tr("Alternate color for the theme.");
    info.ID = "SECONDARYCOLOR";
  COLORS.insert(info.ID, info);
  //Secondary Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Secondary Color (Disabled)");
    info.description = QObject::tr("Alternate color for the theme (more subdued).");
    info.ID = "SECONDARYDISABLECOLOR";
  COLORS.insert(info.ID, info);
  //Accent Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Accent Color");
    info.description = QObject::tr("Color used for borders or other accents.");
    info.ID = "ACCENTCOLOR";
  COLORS.insert(info.ID, info);
  //Accent Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Accent Color (Disabled)");
    info.description = QObject::tr("Color used for borders or other accents (more subdued).");
    info.ID = "ACCENTDISABLECOLOR";
  COLORS.insert(info.ID, info);
  //Highlight Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Highlight Color");
    info.description = QObject::tr("Color used for highlighting an item.");
    info.ID = "HIGHLIGHTCOLOR";
  COLORS.insert(info.ID, info);
  //Highlight Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Highlight Color (Disabled)");
    info.description = QObject::tr("Color used for highlighting an item (more subdued).");
    info.ID = "HIGHLIGHTDISABLECOLOR";
  COLORS.insert(info.ID, info);
}<commit_msg>Add the new RSS reader to the known plugins in lumina-config.<commit_after>//===========================================
//  Lumina-DE source code
//  Copyright (c) 2014, Ken Moore
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "LPlugins.h"

#include <LuminaUtils.h>

LPlugins::LPlugins(){
  LoadPanelPlugins();
  LoadDesktopPlugins();
  LoadMenuPlugins();
  LoadColorItems();
}

LPlugins::~LPlugins(){
}

//Plugin lists
QStringList LPlugins::panelPlugins(){
  QStringList pan = PANEL.keys();
    pan.sort();
  return pan;
}
QStringList LPlugins::desktopPlugins(){
  QStringList desk = DESKTOP.keys();
	desk.sort();
  return desk;
}
QStringList LPlugins::menuPlugins(){
    QStringList men = MENU.keys();
	men.sort();
  return men;
}
QStringList LPlugins::colorItems(){
  return COLORS.keys();
}
//Information on individual plugins
LPI LPlugins::panelPluginInfo(QString plug){
  if(PANEL.contains(plug)){ return PANEL[plug]; }
  else{ return LPI(); }
}
LPI LPlugins::desktopPluginInfo(QString plug){
  if(DESKTOP.contains(plug)){ return DESKTOP[plug]; }
  else{ return LPI(); }
}
LPI LPlugins::menuPluginInfo(QString plug){
  if(MENU.contains(plug)){ return MENU[plug]; }
  else{ return LPI(); }
}
LPI LPlugins::colorInfo(QString item){
  if(COLORS.contains(item)){ return COLORS[item]; }
  else{ return LPI(); }
}

//===================
//             PLUGINS
//===================
void LPlugins::LoadPanelPlugins(){
  PANEL.clear();
  //User Button
  LPI info;
    info.name = QObject::tr("User Button");
    info.description = QObject::tr("This is the main system access button for the user (applications, directories, settings, log out).");
    info.ID = "userbutton";
    info.icon = "user-identity";
  PANEL.insert(info.ID, info);
   //Application Menu
  info = LPI(); //clear it
    info.name = QObject::tr("Application Menu");
    info.description = QObject::tr("This provides instant-access to application that are installed on the system.");
    info.ID = "appmenu";
    info.icon = "format-list-unordered";
  PANEL.insert(info.ID, info);
  //Desktop Bar
  info = LPI(); //clear it
    info.name = QObject::tr("Desktop Bar");
    info.description = QObject::tr("This provides shortcuts to everything in the desktop folder - allowing easy access to all your favorite files/applications.");
    info.ID = "desktopbar";
    info.icon = "user-desktop";
  PANEL.insert(info.ID, info);
  //Spacer
  info = LPI(); //clear it
    info.name = QObject::tr("Spacer");
    info.description = QObject::tr("Invisible spacer to separate plugins.");
    info.ID = "spacer";
    info.icon = "transform-move";
  PANEL.insert(info.ID, info);
  //Line
  info = LPI(); //clear it
    info.name = QObject::tr("Line");
    info.description = QObject::tr("Simple line to provide visual separation between items.");
    info.ID = "line";
    info.icon = "insert-horizontal-rule";
  PANEL.insert(info.ID, info);
  //Desktop Switcher
  info = LPI(); //clear it
    info.name = QObject::tr("Workspace Switcher");
    info.description = QObject::tr("Controls for switching between the various virtual desktops.");
    info.ID = "desktopswitcher";
    info.icon = "preferences-desktop-display-color";
  PANEL.insert(info.ID, info);
  //Battery
  info = LPI(); //clear it
    info.name = QObject::tr("Battery Monitor");
    info.description = QObject::tr("Keep track of your battery status.");
    info.ID = "battery";
    info.icon = "battery-charging";
  PANEL.insert(info.ID, info);
  //Clock
  info = LPI(); //clear it
    info.name = QObject::tr("Time/Date");
    info.description = QObject::tr("View the current time and date.");
    info.ID = "clock";
    info.icon = "preferences-system-time";
  PANEL.insert(info.ID, info);
  //System Dachboard plugin
  info = LPI(); //clear it
    info.name = QObject::tr("System Dashboard");
    info.description = QObject::tr("View or change system settings (audio volume, screen brightness, battery life, virtual desktops).");
    info.ID = "systemdashboard";
    info.icon = "dashboard-show";
  PANEL.insert(info.ID, info);
  //Task Manager
  info = LPI(); //clear it
    info.name = QObject::tr("Task Manager");
    info.description = QObject::tr("View and control any running application windows (every application has a button)");
    info.ID = "taskmanager";
    info.icon = "preferences-system-windows";
  PANEL.insert(info.ID, info);
  //Task Manager
  info = LPI(); //clear it
    info.name = QObject::tr("Task Manager (No Groups)");
    info.description = QObject::tr("View and control any running application windows (every window has a button)");
    info.ID = "taskmanager-nogroups";
    info.icon = "preferences-system-windows";
  PANEL.insert(info.ID, info);
  //System Tray
  info = LPI(); //clear it
    info.name = QObject::tr("System Tray");
    info.description = QObject::tr("Display area for dockable system applications");
    info.ID = "systemtray";
    info.icon = "preferences-system-windows-actions";
  PANEL.insert(info.ID, info);
  //Home Button
  info = LPI(); //clear it
    info.name = QObject::tr("Show Desktop");
    info.description = QObject::tr("Hide all open windows and show the desktop");
    info.ID = "homebutton";
    info.icon = "user-desktop";
  PANEL.insert(info.ID, info);
  //Start Menu
  info = LPI(); //clear it
    info.name = QObject::tr("Start Menu");
    info.description = QObject::tr("Unified system access and application launch menu.");
    info.ID = "systemstart";
    info.icon = "Lumina-DE";
  PANEL.insert(info.ID, info);
  //Application Launcher
  info = LPI(); //clear it
    info.name = QObject::tr("Application Launcher");
    info.description = QObject::tr("Pin an application shortcut directly to the panel");
    info.ID = "applauncher";
    info.icon = "quickopen";
  PANEL.insert(info.ID, info);
}

void LPlugins::LoadDesktopPlugins(){
  DESKTOP.clear();
  //Calendar Plugin
  LPI info;
    info.name = QObject::tr("Calendar");
    info.description = QObject::tr("Display a calendar on the desktop");
    info.ID = "calendar";
    info.icon = "view-calendar";
  DESKTOP.insert(info.ID, info);
  //Application Launcher Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("Application Launcher");
    info.description = QObject::tr("Desktop button for launching an application");
    info.ID = "applauncher";
    info.icon = "quickopen";
  DESKTOP.insert(info.ID, info);
  //Desktop View Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("Desktop Icons View");
    info.description = QObject::tr("Area for automatically showing desktop icons");
    info.ID = "desktopview";
    info.icon = "preferences-desktop-icons";
  DESKTOP.insert(info.ID, info);
  //Notepad Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("Note Pad");
    info.description = QObject::tr("Keep simple text notes on your desktop");
    info.ID = "notepad";
    info.icon = "text-enriched";
  DESKTOP.insert(info.ID, info);
  //Audio Player Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("Audio Player");
    info.description = QObject::tr("Play through lists of audio files");
    info.ID = "audioplayer";
    info.icon = "media-playback-start";
  DESKTOP.insert(info.ID, info);
  //System Monitor Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("System Monitor");
    info.description = QObject::tr("Keep track of system statistics such as CPU/Memory usage and CPU temperatures.");
    info.ID = "systemmonitor";
    info.icon = "cpu";
  DESKTOP.insert(info.ID, info);
  //RSS Reader Plugin
  info = LPI(); //clear it
    info.name = QObject::tr("RSS Reader");
    info.description = QObject::tr("Monitor RSS Feeds (Requires internet connection)");
    info.ID = "rssfeeder";
    info.icon = "application-rss+xml";
  DESKTOP.insert(info.ID, info);
  //Available QtQuick scripts
  /*QStringList quickID = LUtils::listQuickPlugins();
  for(int i=0; i<quickID.length(); i++){
    QStringList quickinfo = LUtils::infoQuickPlugin(quickID[i]); //Returns: [name, description, icon]
    if(quickinfo.length() < 3){ continue; } //invalid file (unreadable/other)
    info = LPI();
      info.name = quickinfo[0];
      info.description = quickinfo[1];
      info.ID = "quick-"+quickID[i]; //the "quick-" prefix is required for the desktop plugin syntax
      info.icon = quickinfo[2];
    DESKTOP.insert(info.ID, info);
  }*/
}

void LPlugins::LoadMenuPlugins(){
  MENU.clear();
  //Terminal
  LPI info;
    info.name = QObject::tr("Terminal");
    info.description = QObject::tr("Start the default system terminal.");
    info.ID = "terminal";
    info.icon = "utilities-terminal";
  MENU.insert(info.ID, info);
  //File Manager
  info = LPI(); //clear it
    info.name = QObject::tr("File Manager");
    info.description = QObject::tr("Browse the system with the default file manager.");
    info.ID = "filemanager";
    info.icon = "Insight-FileManager";
  MENU.insert(info.ID, info);
  //Applications
  info = LPI(); //clear it
    info.name = QObject::tr("Applications");
    info.description = QObject::tr("Show the system applications menu.");
    info.ID = "applications";
    info.icon = "system-run";
  MENU.insert(info.ID, info);
  //Line seperator
  info = LPI(); //clear it
    info.name = QObject::tr("Separator");
    info.description = QObject::tr("Static horizontal line.");
    info.ID = "line";
    info.icon = "insert-horizontal-rule";
  MENU.insert(info.ID, info);
  //Settings
  info = LPI(); //clear it
    info.name = QObject::tr("Settings");
    info.description = QObject::tr("Show the desktop settings menu.");
    info.ID = "settings";
    info.icon = "configure";
  MENU.insert(info.ID, info);
  //Window List
  info = LPI(); //clear it
    info.name = QObject::tr("Window List");
    info.description = QObject::tr("List the open application windows");
    info.ID = "windowlist";
    info.icon = "preferences-system-windows";
  MENU.insert(info.ID, info);
  //Custom Apps
  info = LPI(); //clear it
    info.name = QObject::tr("Custom App");
    info.description = QObject::tr("Start a custom application");
    info.ID = "app";
    info.icon = "application-x-desktop";
  MENU.insert(info.ID, info);
}

void LPlugins::LoadColorItems(){
  COLORS.clear();
  //Text Color
  LPI info;
    info.name = QObject::tr("Text");
    info.description = QObject::tr("Color to use for all visible text.");
    info.ID = "TEXTCOLOR";
  COLORS.insert(info.ID, info);
  //Text Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Text (Disabled)");
    info.description = QObject::tr("Text color for disabled or inactive items.");
    info.ID = "TEXTDISABLECOLOR";
  COLORS.insert(info.ID, info);
  //Text Color (Highlighted)
  info = LPI(); //clear it
    info.name = QObject::tr("Text (Highlighted)");
    info.description = QObject::tr("Text color when selection is highlighted.");
    info.ID = "TEXTHIGHLIGHTCOLOR";
  COLORS.insert(info.ID, info);
  //Base Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Base Window Color");
    info.description = QObject::tr("Main background color for the window/dialog.");
    info.ID = "BASECOLOR";
  COLORS.insert(info.ID, info);
  //Base Color (Alternate)
  info = LPI(); //clear it
    info.name = QObject::tr("Base Window Color (Alternate)");
    info.description = QObject::tr("Main background color for widgets that list or display collections of items.");
    info.ID = "ALTBASECOLOR";
  COLORS.insert(info.ID, info);
  //Primary Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Primary Color");
    info.description = QObject::tr("Dominant color for the theme.");
    info.ID = "PRIMARYCOLOR";
  COLORS.insert(info.ID, info);
  //Primary Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Primary Color (Disabled)");
    info.description = QObject::tr("Dominant color for the theme (more subdued).");
    info.ID = "PRIMARYDISABLECOLOR";
  COLORS.insert(info.ID, info);
  //Secondary Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Secondary Color");
    info.description = QObject::tr("Alternate color for the theme.");
    info.ID = "SECONDARYCOLOR";
  COLORS.insert(info.ID, info);
  //Secondary Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Secondary Color (Disabled)");
    info.description = QObject::tr("Alternate color for the theme (more subdued).");
    info.ID = "SECONDARYDISABLECOLOR";
  COLORS.insert(info.ID, info);
  //Accent Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Accent Color");
    info.description = QObject::tr("Color used for borders or other accents.");
    info.ID = "ACCENTCOLOR";
  COLORS.insert(info.ID, info);
  //Accent Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Accent Color (Disabled)");
    info.description = QObject::tr("Color used for borders or other accents (more subdued).");
    info.ID = "ACCENTDISABLECOLOR";
  COLORS.insert(info.ID, info);
  //Highlight Color (Normal)
  info = LPI(); //clear it
    info.name = QObject::tr("Highlight Color");
    info.description = QObject::tr("Color used for highlighting an item.");
    info.ID = "HIGHLIGHTCOLOR";
  COLORS.insert(info.ID, info);
  //Highlight Color (Disabled)
  info = LPI(); //clear it
    info.name = QObject::tr("Highlight Color (Disabled)");
    info.description = QObject::tr("Color used for highlighting an item (more subdued).");
    info.ID = "HIGHLIGHTDISABLECOLOR";
  COLORS.insert(info.ID, info);
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// \file h5_handler.cc
/// \brief main program source.
///
/// \author Muqun Yang (ymuqun@ncsa.uiuc.edu)
/// \author Hyo-Kyung Lee <hyoklee@hdfgroup.org>
///
/// Copyright (C) 2007	HDF Group, Inc.
///
/// Copyright (C) 1999	National Center for Supercomputing Applications.
///		All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// #define DODS_DEBUG
#include "h5_handler.h"

/// The default CGI version of handler.
const static string cgi_version = "3.0";

/// An external object that handles NASA EOS HDF5 files for grid generation
/// and meta data parsing.
extern H5EOS eos;

///////////////////////////////////////////////////////////////////////////////
/// \fn main(int argc, char *argv[])
/// main function for HDF5 data handler.
/// This function processes options and generates the corresponding DAP outputs requested by the user.
/// @param argc number of arguments
/// @param argv command line arguments for options
/// @return 0 if success
/// @return 1 if error
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
  DBG(cerr << "Starting the HDF handler." << endl);

  try {
    DODSFilter df(argc, argv);
    if (df.get_cgi_version() == "")
      df.set_cgi_version(cgi_version);

    // Handle the version info as a special case since there's no need to
    // open the hdf5 file. This makes it possible to move the file open
    // and close code out of the individual case statements.
    // jhrg 02/04/04
    if (df.get_response() == DODSFilter::Version_Response) {
      df.send_version_info();
      return 0;
    }

    hid_t file1 = get_fileid(df.get_dataset_name().c_str());

    if (file1 < 0)
      throw Error(no_such_file, string("Could not open hdf5 file: ")
		  + df.get_dataset_name());

    // Check if it is EOS file.
    DBG(cerr << "checking EOS file" << endl);
    if(eos.check_eos(file1)){
      DBG(cerr << "eos file is detected" << endl);
      eos.set_dimension_array();
    }
    else{
      DBG(cerr << "eos file is not detected" << endl);
    }

    switch (df.get_response()) {

    case DODSFilter::DAS_Response:{
      DAS das;
      find_gloattr(file1, das);
      depth_first(file1, "/", das);

      df.send_das(das);

      break;
    }

    case DODSFilter::DDS_Response:{
      DAS das;
      HDF5TypeFactory factory;
      DDS dds(&factory);
      ConstraintEvaluator ce;

      depth_first(file1, "/", dds,
		  df.get_dataset_name().c_str());

      DBG(cerr << ">df.send_dds()" << endl);
      df.send_dds(dds, ce, true);
      break;
    }

    case DODSFilter::DataDDS_Response:{

      HDF5TypeFactory factory;
      DDS dds(&factory);
      ConstraintEvaluator ce;
      DAS das;

      depth_first(file1, "/", dds,
		  df.get_dataset_name().c_str());

      df.send_data(dds, ce, stdout);
      break;
    }

    case DODSFilter::DDX_Response:{
      HDF5TypeFactory factory;
      DDS dds(&factory);
      ConstraintEvaluator ce;
      DAS das;

      depth_first(file1, "/", dds,
		  df.get_dataset_name().c_str());
      find_gloattr(file1, das);
      dds.transfer_attributes(&das);
      df.send_ddx(dds, ce, stdout);
      break;
    }

    case DODSFilter::Version_Response:{
      df.send_version_info();

      break;
    }

    default:
      df.print_usage();   // Throws Error
    }

    if (H5Fclose(file1) < 0)
      throw Error(unknown_error,
		  string("Could not close the HDF5 file: ")
		  + df.get_dataset_name());

  }
  catch(Error & e) {
    string s;
    s = string("h5_handler: ") + e.get_error_message() + "\n";
    ErrMsgT(s);
    set_mime_text(stdout, dods_error, cgi_version);
    e.print(stdout);
    return 1;
  }
  catch(...) {
    string s("h5_handler: Unknown exception");
    ErrMsgT(s);
    Error e(unknown_error, s);
    set_mime_text(stdout, dods_error, cgi_version);
    e.print(stdout);
    return 1;
  }

  DBG(cerr << "HDF5 server exitied successfully." << endl);
  return 0;
}
// $Log$
<commit_msg>Attributes were not being added to the dds when requesting the ddx response. Fixed this. M    h5_handler.cc<commit_after>////////////////////////////////////////////////////////////////////////////////
/// \file h5_handler.cc
/// \brief main program source.
///
/// \author Muqun Yang (ymuqun@ncsa.uiuc.edu)
/// \author Hyo-Kyung Lee <hyoklee@hdfgroup.org>
///
/// Copyright (C) 2007	HDF Group, Inc.
///
/// Copyright (C) 1999	National Center for Supercomputing Applications.
///		All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// #define DODS_DEBUG
#include "h5_handler.h"

/// The default CGI version of handler.
const static string cgi_version = "3.0";

/// An external object that handles NASA EOS HDF5 files for grid generation
/// and meta data parsing.
extern H5EOS eos;

///////////////////////////////////////////////////////////////////////////////
/// \fn main(int argc, char *argv[])
/// main function for HDF5 data handler.
/// This function processes options and generates the corresponding DAP outputs requested by the user.
/// @param argc number of arguments
/// @param argv command line arguments for options
/// @return 0 if success
/// @return 1 if error
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
  DBG(cerr << "Starting the HDF handler." << endl);

  try {
    DODSFilter df(argc, argv);
    if (df.get_cgi_version() == "")
      df.set_cgi_version(cgi_version);

    // Handle the version info as a special case since there's no need to
    // open the hdf5 file. This makes it possible to move the file open
    // and close code out of the individual case statements.
    // jhrg 02/04/04
    if (df.get_response() == DODSFilter::Version_Response) {
      df.send_version_info();
      return 0;
    }

    hid_t file1 = get_fileid(df.get_dataset_name().c_str());

    if (file1 < 0)
      throw Error(no_such_file, string("Could not open hdf5 file: ")
		  + df.get_dataset_name());

    // Check if it is EOS file.
    DBG(cerr << "checking EOS file" << endl);
    if(eos.check_eos(file1)){
      DBG(cerr << "eos file is detected" << endl);
      eos.set_dimension_array();
    }
    else{
      DBG(cerr << "eos file is not detected" << endl);
    }

    switch (df.get_response()) {

    case DODSFilter::DAS_Response:{
      DAS das;
      find_gloattr(file1, das);
      depth_first(file1, "/", das);

      df.send_das(das);

      break;
    }

    case DODSFilter::DDS_Response:{
      DAS das;
      HDF5TypeFactory factory;
      DDS dds(&factory);
      ConstraintEvaluator ce;

      depth_first(file1, "/", dds,
		  df.get_dataset_name().c_str());

      DBG(cerr << ">df.send_dds()" << endl);
      df.send_dds(dds, ce, true);
      break;
    }

    case DODSFilter::DataDDS_Response:{

      HDF5TypeFactory factory;
      DDS dds(&factory);
      ConstraintEvaluator ce;
      DAS das;

      depth_first(file1, "/", dds,
		  df.get_dataset_name().c_str());

      df.send_data(dds, ce, stdout);
      break;
    }

    case DODSFilter::DDX_Response:{
      HDF5TypeFactory factory;
      DDS dds(&factory);
      ConstraintEvaluator ce;
      DAS das;

      depth_first(file1, "/", dds,
		  df.get_dataset_name().c_str());
      find_gloattr(file1, das);
      depth_first(file1, "/", das);
      dds.transfer_attributes(&das);
      df.send_ddx(dds, ce, stdout);
      break;
    }

    case DODSFilter::Version_Response:{
      df.send_version_info();

      break;
    }

    default:
      df.print_usage();   // Throws Error
    }

    if (H5Fclose(file1) < 0)
      throw Error(unknown_error,
		  string("Could not close the HDF5 file: ")
		  + df.get_dataset_name());

  }
  catch(Error & e) {
    string s;
    s = string("h5_handler: ") + e.get_error_message() + "\n";
    ErrMsgT(s);
    set_mime_text(stdout, dods_error, cgi_version);
    e.print(stdout);
    return 1;
  }
  catch(...) {
    string s("h5_handler: Unknown exception");
    ErrMsgT(s);
    Error e(unknown_error, s);
    set_mime_text(stdout, dods_error, cgi_version);
    e.print(stdout);
    return 1;
  }

  DBG(cerr << "HDF5 server exitied successfully." << endl);
  return 0;
}
// $Log$
<|endoftext|>


<commit_before>
// Bindings
#include "CPyCppyy.h"
#include "PyROOTPythonize.h"
#include "CPPInstance.h"
#include "ProxyWrappers.h"
#include "Converters.h"
#include "Utility.h"

// ROOT
#include "TClass.h"
#include "TTree.h"
#include "TBranch.h"
#include "TBranchElement.h"
#include "TBranchObject.h"
#include "TLeaf.h"
#include "TLeafElement.h"
#include "TLeafObject.h"
#include "TStreamerElement.h"
#include "TStreamerInfo.h"

using namespace CPyCppyy;

static TClass *OP2TCLASS(CPPInstance *pyobj)
{
   return TClass::GetClass(Cppyy::GetFinalName(pyobj->ObjectIsA()).c_str());
}

// Allow access to branches/leaves as if they were data members
PyObject *GetAttr(CPPInstance *self, PyObject *pyname)
{
   const char *name1 = CPyCppyy_PyUnicode_AsString(pyname);
   if (!name1)
      return 0;

   // get hold of actual tree
   TTree *tree = (TTree *)OP2TCLASS(self)->DynamicCast(TTree::Class(), self->GetObject());

   if (!tree) {
      PyErr_SetString(PyExc_ReferenceError, "attempt to access a null-pointer");
      return 0;
   }

   // deal with possible aliasing
   const char *name = tree->GetAlias(name1);
   if (!name)
      name = name1;

   // search for branch first (typical for objects)
   TBranch *branch = tree->GetBranch(name);
   if (!branch) {
      // for benefit of naming of sub-branches, the actual name may have a trailing '.'
      branch = tree->GetBranch((std::string(name) + '.').c_str());
   }

   if (branch) {
      // found a branched object, wrap its address for the object it represents

      // for partial return of a split object
      if (branch->InheritsFrom(TBranchElement::Class())) {
         TBranchElement *be = (TBranchElement *)branch;
         if (be->GetCurrentClass() && (be->GetCurrentClass() != be->GetTargetClass()) && (0 <= be->GetID())) {
            Long_t offset = ((TStreamerElement *)be->GetInfo()->GetElements()->At(be->GetID()))->GetOffset();
            return BindCppObjectNoCast(be->GetObject() + offset, Cppyy::GetScope(be->GetCurrentClass()->GetName()));
         }
      }

      // for return of a full object
      if (branch->IsA() == TBranchElement::Class() || branch->IsA() == TBranchObject::Class()) {
         TClass *klass = TClass::GetClass(branch->GetClassName());
         if (klass && branch->GetAddress())
            return BindCppObjectNoCast(*(void **)branch->GetAddress(), Cppyy::GetScope(branch->GetClassName()));

         // try leaf, otherwise indicate failure by returning a typed null-object
         TObjArray *leaves = branch->GetListOfLeaves();
         if (klass && !tree->GetLeaf(name) && !(leaves->GetSize() && (leaves->First() == leaves->Last())))
            return BindCppObjectNoCast(NULL, Cppyy::GetScope(branch->GetClassName()));
      }
   }

   // if not, try leaf
   TLeaf *leaf = tree->GetLeaf(name);
   if (branch && !leaf) {
      leaf = branch->GetLeaf(name);
      if (!leaf) {
         TObjArray *leaves = branch->GetListOfLeaves();
         if (leaves->GetSize() && (leaves->First() == leaves->Last())) {
            // i.e., if unambiguously only this one
            leaf = (TLeaf *)leaves->At(0);
         }
      }
   }

   if (leaf) {
      // found a leaf, extract value and wrap
      if (1 < leaf->GetLenStatic() || leaf->GetLeafCount()) {
         // array types
         std::string typeName = leaf->GetTypeName();
         Converter *pcnv = CreateConverter(typeName + '*', leaf->GetNdata());

         void *address = 0;
         if (leaf->GetBranch())
            address = (void *)leaf->GetBranch()->GetAddress();
         if (!address)
            address = (void *)leaf->GetValuePointer();

         PyObject *value = pcnv->FromMemory(&address);
         delete pcnv;

         return value;
      } else if (leaf->GetValuePointer()) {
         // value types
         Converter *pcnv = CreateConverter(leaf->GetTypeName());
         PyObject *value = 0;
         if (leaf->IsA() == TLeafElement::Class() || leaf->IsA() == TLeafObject::Class())
            value = pcnv->FromMemory((void *)*(void **)leaf->GetValuePointer());
         else
            value = pcnv->FromMemory((void *)leaf->GetValuePointer());
         delete pcnv;

         return value;
      }
   }

   // confused
   PyErr_Format(PyExc_AttributeError, "\'%s\' object has no attribute \'%s\'", tree->IsA()->GetName(), name);
   return 0;
}

// Public function
PyObject *PyROOT::PythonizeTTree(PyObject *, PyObject *args)
{
   PyObject *pyclass = PyTuple_GetItem(args, 0);
   Utility::AddToClass(pyclass, "__getattr__", (PyCFunction)GetAttr, METH_O);
   Py_RETURN_NONE;
}
<commit_msg>Follow ROOT naming convention<commit_after>
// Bindings
#include "CPyCppyy.h"
#include "PyROOTPythonize.h"
#include "CPPInstance.h"
#include "ProxyWrappers.h"
#include "Converters.h"
#include "Utility.h"

// ROOT
#include "TClass.h"
#include "TTree.h"
#include "TBranch.h"
#include "TBranchElement.h"
#include "TBranchObject.h"
#include "TLeaf.h"
#include "TLeafElement.h"
#include "TLeafObject.h"
#include "TStreamerElement.h"
#include "TStreamerInfo.h"

using namespace CPyCppyy;

static TClass *GetClass(CPPInstance *pyobj)
{
   return TClass::GetClass(Cppyy::GetFinalName(pyobj->ObjectIsA()).c_str());
}

// Allow access to branches/leaves as if they were data members
PyObject *GetAttr(CPPInstance *self, PyObject *pyname)
{
   const char *name1 = CPyCppyy_PyUnicode_AsString(pyname);
   if (!name1)
      return 0;

   // get hold of actual tree
   TTree *tree = (TTree *)GetClass(self)->DynamicCast(TTree::Class(), self->GetObject());

   if (!tree) {
      PyErr_SetString(PyExc_ReferenceError, "attempt to access a null-pointer");
      return 0;
   }

   // deal with possible aliasing
   const char *name = tree->GetAlias(name1);
   if (!name)
      name = name1;

   // search for branch first (typical for objects)
   TBranch *branch = tree->GetBranch(name);
   if (!branch) {
      // for benefit of naming of sub-branches, the actual name may have a trailing '.'
      branch = tree->GetBranch((std::string(name) + '.').c_str());
   }

   if (branch) {
      // found a branched object, wrap its address for the object it represents

      // for partial return of a split object
      if (branch->InheritsFrom(TBranchElement::Class())) {
         TBranchElement *be = (TBranchElement *)branch;
         if (be->GetCurrentClass() && (be->GetCurrentClass() != be->GetTargetClass()) && (0 <= be->GetID())) {
            Long_t offset = ((TStreamerElement *)be->GetInfo()->GetElements()->At(be->GetID()))->GetOffset();
            return BindCppObjectNoCast(be->GetObject() + offset, Cppyy::GetScope(be->GetCurrentClass()->GetName()));
         }
      }

      // for return of a full object
      if (branch->IsA() == TBranchElement::Class() || branch->IsA() == TBranchObject::Class()) {
         TClass *klass = TClass::GetClass(branch->GetClassName());
         if (klass && branch->GetAddress())
            return BindCppObjectNoCast(*(void **)branch->GetAddress(), Cppyy::GetScope(branch->GetClassName()));

         // try leaf, otherwise indicate failure by returning a typed null-object
         TObjArray *leaves = branch->GetListOfLeaves();
         if (klass && !tree->GetLeaf(name) && !(leaves->GetSize() && (leaves->First() == leaves->Last())))
            return BindCppObjectNoCast(NULL, Cppyy::GetScope(branch->GetClassName()));
      }
   }

   // if not, try leaf
   TLeaf *leaf = tree->GetLeaf(name);
   if (branch && !leaf) {
      leaf = branch->GetLeaf(name);
      if (!leaf) {
         TObjArray *leaves = branch->GetListOfLeaves();
         if (leaves->GetSize() && (leaves->First() == leaves->Last())) {
            // i.e., if unambiguously only this one
            leaf = (TLeaf *)leaves->At(0);
         }
      }
   }

   if (leaf) {
      // found a leaf, extract value and wrap
      if (1 < leaf->GetLenStatic() || leaf->GetLeafCount()) {
         // array types
         std::string typeName = leaf->GetTypeName();
         Converter *pcnv = CreateConverter(typeName + '*', leaf->GetNdata());

         void *address = 0;
         if (leaf->GetBranch())
            address = (void *)leaf->GetBranch()->GetAddress();
         if (!address)
            address = (void *)leaf->GetValuePointer();

         PyObject *value = pcnv->FromMemory(&address);
         delete pcnv;

         return value;
      } else if (leaf->GetValuePointer()) {
         // value types
         Converter *pcnv = CreateConverter(leaf->GetTypeName());
         PyObject *value = 0;
         if (leaf->IsA() == TLeafElement::Class() || leaf->IsA() == TLeafObject::Class())
            value = pcnv->FromMemory((void *)*(void **)leaf->GetValuePointer());
         else
            value = pcnv->FromMemory((void *)leaf->GetValuePointer());
         delete pcnv;

         return value;
      }
   }

   // confused
   PyErr_Format(PyExc_AttributeError, "\'%s\' object has no attribute \'%s\'", tree->IsA()->GetName(), name);
   return 0;
}

// Public function
PyObject *PyROOT::PythonizeTTree(PyObject *, PyObject *args)
{
   PyObject *pyclass = PyTuple_GetItem(args, 0);
   Utility::AddToClass(pyclass, "__getattr__", (PyCFunction)GetAttr, METH_O);
   Py_RETURN_NONE;
}
<|endoftext|>


<commit_before>#include "Audio3DSample.h"
#include "Grid.h"
#include "SamplesGame.h"

#if defined(ADD_SAMPLE)
    ADD_SAMPLE("Media", "Audio 3D", Audio3DSample, 1);
#endif

static const unsigned int MOVE_FORWARD = 1;
static const unsigned int MOVE_BACKWARD = 2;
static const unsigned int MOVE_LEFT = 4;
static const unsigned int MOVE_RIGHT = 8;
static const unsigned int MOVE_UP = 16;
static const unsigned int MOVE_DOWN = 32;
static const float MOVE_SPEED = 15.0f;
static const float UP_DOWN_SPEED = 10.0f;

Audio3DSample::Audio3DSample()
    : _font(NULL), _scene(NULL), _cubeNode(NULL), _gamepad(NULL), _moveFlags(0), _prevX(0), _prevY(0), _buttonPressed(false)
{
}

void Audio3DSample::initialize()
{
    setMultiTouch(true);
    _font = Font::create("res/ui/arial.gpb");
    // Load game scene from file
    _scene = Scene::load("res/common/box.gpb");

    // Get light node
    Node* lightNode = _scene->findNode("directionalLight1");
    Light* light = lightNode->getLight();
    lightNode->setRotation(Vector3(1, 0, 0), -MATH_DEG_TO_RAD(45));

    // Initialize box model
    Node* boxNode = _scene->findNode("box");
    Model* boxModel = dynamic_cast<Model*>(boxNode->getDrawable());
    Material* boxMaterial = boxModel->setMaterial("res/common/box.material#lambert1");

    boxMaterial->getParameter("u_directionalLightColor[0]")->setValue(light->getColor());
    boxMaterial->getParameter("u_directionalLightDirection[0]")->setValue(lightNode->getForwardVectorView());

    // Remove the cube from the scene but keep a reference to it.
    _cubeNode = boxNode;
    _cubeNode->addRef();
    _scene->removeNode(_cubeNode);

    loadGrid(_scene);

    // Initialize cameraa
    Vector3 cameraPosition(5, 5, 1);
    if (Camera* camera = _scene->getActiveCamera())
    {
        camera->getNode()->getTranslation(&cameraPosition);
    }

    _fpCamera.initialize();
    _fpCamera.setPosition(cameraPosition);
    _scene->addNode(_fpCamera.getRootNode());
    _scene->setActiveCamera(_fpCamera.getCamera());

    _gamepad = getGamepad(0);
    // This is needed because the virtual gamepad is shared between all samples.
    // SamplesGame always ensures the virtual gamepad is disabled when a sample is exited.
    if (_gamepad && _gamepad->isVirtual())
        _gamepad->getForm()->setEnabled(true);
}

void Audio3DSample::finalize()
{
    SAFE_RELEASE(_scene);
    SAFE_RELEASE(_font);
    SAFE_RELEASE(_cubeNode);
    for (std::map<std::string, Node*>::iterator it = _audioNodes.begin(); it != _audioNodes.end(); ++it)
    {
        it->second->release();
    }
    _audioNodes.clear();
}

void Audio3DSample::update(float elapsedTime)
{
    float time = (float)elapsedTime / 1000.0f;

    Vector2 move;

    if (_moveFlags != 0)
    {
        // Forward motion
        if (_moveFlags & MOVE_FORWARD)
        {
            move.y = 1;
        }
        else if (_moveFlags & MOVE_BACKWARD)
        {
            move.y = -1;
        }
        // Strafing
        if (_moveFlags & MOVE_LEFT)
        {
            move.x = 1;
        }
        else if (_moveFlags & MOVE_RIGHT)
        {
            move.x = -1;
        }
        move.normalize();

        // Up and down
        if (_moveFlags & MOVE_UP)
        {
            _fpCamera.moveUp(time * UP_DOWN_SPEED);
        }
        else if (_moveFlags & MOVE_DOWN)
        {
            _fpCamera.moveDown(time * UP_DOWN_SPEED);
        }
    }
    else if (_gamepad->getJoystickCount() > 0)
    {
        _gamepad->getJoystickValues(0, &move);
        move.x = -move.x;
    }
    if (_gamepad->getJoystickCount() > 1)
    {
        Vector2 joy2;
        _gamepad->getJoystickValues(1, &joy2);
        _fpCamera.rotate(MATH_DEG_TO_RAD(joy2.x * 2.0f), MATH_DEG_TO_RAD(joy2.y * 2.0f));
    }

    if (!move.isZero())
    {
        move.scale(time * MOVE_SPEED);
        _fpCamera.moveForward(move.y);
        _fpCamera.moveLeft(move.x);
    }

    if (!_buttonPressed && _gamepad->isButtonDown(Gamepad::BUTTON_A))
    {
        addSound("footsteps.wav");
    }
    _buttonPressed = _gamepad->isButtonDown(Gamepad::BUTTON_A);
}

void Audio3DSample::render(float elapsedTime)
{
    // Clear the color and depth buffers
    clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);

    // Visit all the nodes in the scene for drawing
    _scene->visit(this, &Audio3DSample::drawScene);

    drawDebugText(5, 20, 18);

    _gamepad->draw();
    drawFrameRate(_font, Vector4(0, 0.5f, 1, 1), 5, 1, getFrameRate());
}

bool Audio3DSample::drawScene(Node* node)
{
    Drawable* drawable = node->getDrawable();
    if (drawable)
        drawable->draw();
    return true;
}

void Audio3DSample::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
    switch (evt)
    {
    case Touch::TOUCH_PRESS:
    {
        if (x < 75 && y < 50)
        {
            // Toggle Vsync if the user touches the top left corner
            setVsync(!isVsync());
        }
        _prevX = x;
        _prevY = y;
        break;
    }
    case Touch::TOUCH_RELEASE:
    {
        _prevX = 0;
        _prevY = 0;
        break;
     }
    case Touch::TOUCH_MOVE:
    {
        int deltaX = x - _prevX;
        int deltaY = y - _prevY;
        _prevX = x;
        _prevY = y;
        float pitch = -MATH_DEG_TO_RAD(deltaY * 0.5f);
        float yaw = MATH_DEG_TO_RAD(deltaX * 0.5f);
        _fpCamera.rotate(yaw, pitch);
        break;
    }
    };
}

void Audio3DSample::keyEvent(Keyboard::KeyEvent evt, int key)
{
    if (evt == Keyboard::KEY_PRESS)
    {
        switch (key)
        {
        case Keyboard::KEY_W:
            _moveFlags |= MOVE_FORWARD;
            break;
        case Keyboard::KEY_S:
            _moveFlags |= MOVE_BACKWARD;
            break;
        case Keyboard::KEY_A:
            _moveFlags |= MOVE_LEFT;
            break;
        case Keyboard::KEY_D:
            _moveFlags |= MOVE_RIGHT;
            break;

        case Keyboard::KEY_Q:
            _moveFlags |= MOVE_DOWN;
            break;
        case Keyboard::KEY_E:
            _moveFlags |= MOVE_UP;
            break;
        case Keyboard::KEY_PG_UP:
            _fpCamera.rotate(0, MATH_PIOVER4);
            break;
        case Keyboard::KEY_PG_DOWN:
            _fpCamera.rotate(0, -MATH_PIOVER4);
            break;

        case Keyboard::KEY_ONE:
        case Keyboard::KEY_SPACE:
            addSound("footsteps.wav");
            break;
        }
    }
    else if (evt == Keyboard::KEY_RELEASE)
    {
        switch (key)
        {
        case Keyboard::KEY_W:
            _moveFlags &= ~MOVE_FORWARD;
            break;
        case Keyboard::KEY_S:
            _moveFlags &= ~MOVE_BACKWARD;
            break;
        case Keyboard::KEY_A:
            _moveFlags &= ~MOVE_LEFT;
            break;
        case Keyboard::KEY_D:
            _moveFlags &= ~MOVE_RIGHT;
            break;
        case Keyboard::KEY_Q:
            _moveFlags &= ~MOVE_DOWN;
            break;
        case Keyboard::KEY_E:
            _moveFlags &= ~MOVE_UP;
            break;
        }
    }
}

bool Audio3DSample::mouseEvent(Mouse::MouseEvent evt, int x, int y, float wheelDelta)
{
    switch (evt)
    {
    case Mouse::MOUSE_WHEEL:
        _fpCamera.moveForward(wheelDelta * MOVE_SPEED / 2.0f );
        return true;
    }
    return false;
}

void Audio3DSample::addSound(const std::string& file)
{
    std::string path("res/common/");
    path.append(file);

    Node* node = NULL;
    std::map<std::string, Node*>::iterator it = _audioNodes.find(path);
    if (it != _audioNodes.end())
    {
        node = it->second->clone();
    }
    else
    {
        AudioSource* audioSource = AudioSource::create(path.c_str());
        assert(audioSource);
        audioSource->setLooped(true);

        node = _cubeNode->clone();
        node->setId(file.c_str());
        node->setAudioSource(audioSource);
        audioSource->release();

        _audioNodes[path] = node;
        node->addRef();
    }
    assert(node);
    Node* cameraNode = _scene->getActiveCamera()->getNode();
    // Position the sound infront of the user
    node->setTranslation(cameraNode->getTranslationWorld());
    Vector3 dir = cameraNode->getForwardVectorWorld().normalize();
    dir.scale(2);
    node->translate(dir);
    _scene->addNode(node);
    node->getAudioSource()->play();
    node->release();
}

void Audio3DSample::drawDebugText(int x, int y, unsigned int fontSize)
{
    _font->start();
    static const int V_SPACE = 16;
    AudioListener* audioListener = AudioListener::getInstance();
    drawVector3("Position", audioListener->getPosition(), x, y);
    drawVector3("Forward", audioListener->getOrientationForward(), x, y += fontSize);
    drawVector3("Orientation", audioListener->getOrientationUp(), x, y += fontSize);
    drawVector3("Velocity", audioListener->getVelocity(), x, y += fontSize);
    _font->finish();
}

void Audio3DSample::drawVector3(const char* str, const Vector3& vector, int x, int y)
{
    wchar_t buffer[255];
    swprintf(buffer, 255, L"%s: (%f, %f, %f)", str, vector.x, vector.y, vector.z);
    _font->drawText(buffer, x, y, Vector4::one(), _font->getSize());
}

void Audio3DSample::loadGrid(Scene* scene)
{
    assert(scene);
    Model* gridModel = createGridModel();
    assert(gridModel);
    gridModel->setMaterial("res/common/grid.material");
    Node* node = scene->addNode("grid");
    node->setDrawable(gridModel);
    SAFE_RELEASE(gridModel);
}

void Audio3DSample::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
{
    switch(evt)
    {
    case Gamepad::CONNECTED_EVENT:
    case Gamepad::DISCONNECTED_EVENT:
        _gamepad = getGamepad(0);
        // This is needed because the virtual gamepad is shared between all samples.
        // SamplesGame always ensures the virtual gamepad is disabled when a sample is exited.
        if (_gamepad && _gamepad->isVirtual())
            _gamepad->getForm()->setEnabled(true);
        break;
    }
}<commit_msg>fixed incorrect usage of %s format string<commit_after>#include "Audio3DSample.h"
#include "Grid.h"
#include "SamplesGame.h"

#if defined(ADD_SAMPLE)
    ADD_SAMPLE("Media", "Audio 3D", Audio3DSample, 1);
#endif

static const unsigned int MOVE_FORWARD = 1;
static const unsigned int MOVE_BACKWARD = 2;
static const unsigned int MOVE_LEFT = 4;
static const unsigned int MOVE_RIGHT = 8;
static const unsigned int MOVE_UP = 16;
static const unsigned int MOVE_DOWN = 32;
static const float MOVE_SPEED = 15.0f;
static const float UP_DOWN_SPEED = 10.0f;

Audio3DSample::Audio3DSample()
    : _font(NULL), _scene(NULL), _cubeNode(NULL), _gamepad(NULL), _moveFlags(0), _prevX(0), _prevY(0), _buttonPressed(false)
{
}

void Audio3DSample::initialize()
{
    setMultiTouch(true);
    _font = Font::create("res/ui/arial.gpb");
    // Load game scene from file
    _scene = Scene::load("res/common/box.gpb");

    // Get light node
    Node* lightNode = _scene->findNode("directionalLight1");
    Light* light = lightNode->getLight();
    lightNode->setRotation(Vector3(1, 0, 0), -MATH_DEG_TO_RAD(45));

    // Initialize box model
    Node* boxNode = _scene->findNode("box");
    Model* boxModel = dynamic_cast<Model*>(boxNode->getDrawable());
    Material* boxMaterial = boxModel->setMaterial("res/common/box.material#lambert1");

    boxMaterial->getParameter("u_directionalLightColor[0]")->setValue(light->getColor());
    boxMaterial->getParameter("u_directionalLightDirection[0]")->setValue(lightNode->getForwardVectorView());

    // Remove the cube from the scene but keep a reference to it.
    _cubeNode = boxNode;
    _cubeNode->addRef();
    _scene->removeNode(_cubeNode);

    loadGrid(_scene);

    // Initialize cameraa
    Vector3 cameraPosition(5, 5, 1);
    if (Camera* camera = _scene->getActiveCamera())
    {
        camera->getNode()->getTranslation(&cameraPosition);
    }

    _fpCamera.initialize();
    _fpCamera.setPosition(cameraPosition);
    _scene->addNode(_fpCamera.getRootNode());
    _scene->setActiveCamera(_fpCamera.getCamera());

    _gamepad = getGamepad(0);
    // This is needed because the virtual gamepad is shared between all samples.
    // SamplesGame always ensures the virtual gamepad is disabled when a sample is exited.
    if (_gamepad && _gamepad->isVirtual())
        _gamepad->getForm()->setEnabled(true);
}

void Audio3DSample::finalize()
{
    SAFE_RELEASE(_scene);
    SAFE_RELEASE(_font);
    SAFE_RELEASE(_cubeNode);
    for (std::map<std::string, Node*>::iterator it = _audioNodes.begin(); it != _audioNodes.end(); ++it)
    {
        it->second->release();
    }
    _audioNodes.clear();
}

void Audio3DSample::update(float elapsedTime)
{
    float time = (float)elapsedTime / 1000.0f;

    Vector2 move;

    if (_moveFlags != 0)
    {
        // Forward motion
        if (_moveFlags & MOVE_FORWARD)
        {
            move.y = 1;
        }
        else if (_moveFlags & MOVE_BACKWARD)
        {
            move.y = -1;
        }
        // Strafing
        if (_moveFlags & MOVE_LEFT)
        {
            move.x = 1;
        }
        else if (_moveFlags & MOVE_RIGHT)
        {
            move.x = -1;
        }
        move.normalize();

        // Up and down
        if (_moveFlags & MOVE_UP)
        {
            _fpCamera.moveUp(time * UP_DOWN_SPEED);
        }
        else if (_moveFlags & MOVE_DOWN)
        {
            _fpCamera.moveDown(time * UP_DOWN_SPEED);
        }
    }
    else if (_gamepad->getJoystickCount() > 0)
    {
        _gamepad->getJoystickValues(0, &move);
        move.x = -move.x;
    }
    if (_gamepad->getJoystickCount() > 1)
    {
        Vector2 joy2;
        _gamepad->getJoystickValues(1, &joy2);
        _fpCamera.rotate(MATH_DEG_TO_RAD(joy2.x * 2.0f), MATH_DEG_TO_RAD(joy2.y * 2.0f));
    }

    if (!move.isZero())
    {
        move.scale(time * MOVE_SPEED);
        _fpCamera.moveForward(move.y);
        _fpCamera.moveLeft(move.x);
    }

    if (!_buttonPressed && _gamepad->isButtonDown(Gamepad::BUTTON_A))
    {
        addSound("footsteps.wav");
    }
    _buttonPressed = _gamepad->isButtonDown(Gamepad::BUTTON_A);
}

void Audio3DSample::render(float elapsedTime)
{
    // Clear the color and depth buffers
    clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);

    // Visit all the nodes in the scene for drawing
    _scene->visit(this, &Audio3DSample::drawScene);

    drawDebugText(5, 20, 18);

    _gamepad->draw();
    drawFrameRate(_font, Vector4(0, 0.5f, 1, 1), 5, 1, getFrameRate());
}

bool Audio3DSample::drawScene(Node* node)
{
    Drawable* drawable = node->getDrawable();
    if (drawable)
        drawable->draw();
    return true;
}

void Audio3DSample::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
    switch (evt)
    {
    case Touch::TOUCH_PRESS:
    {
        if (x < 75 && y < 50)
        {
            // Toggle Vsync if the user touches the top left corner
            setVsync(!isVsync());
        }
        _prevX = x;
        _prevY = y;
        break;
    }
    case Touch::TOUCH_RELEASE:
    {
        _prevX = 0;
        _prevY = 0;
        break;
     }
    case Touch::TOUCH_MOVE:
    {
        int deltaX = x - _prevX;
        int deltaY = y - _prevY;
        _prevX = x;
        _prevY = y;
        float pitch = -MATH_DEG_TO_RAD(deltaY * 0.5f);
        float yaw = MATH_DEG_TO_RAD(deltaX * 0.5f);
        _fpCamera.rotate(yaw, pitch);
        break;
    }
    };
}

void Audio3DSample::keyEvent(Keyboard::KeyEvent evt, int key)
{
    if (evt == Keyboard::KEY_PRESS)
    {
        switch (key)
        {
        case Keyboard::KEY_W:
            _moveFlags |= MOVE_FORWARD;
            break;
        case Keyboard::KEY_S:
            _moveFlags |= MOVE_BACKWARD;
            break;
        case Keyboard::KEY_A:
            _moveFlags |= MOVE_LEFT;
            break;
        case Keyboard::KEY_D:
            _moveFlags |= MOVE_RIGHT;
            break;

        case Keyboard::KEY_Q:
            _moveFlags |= MOVE_DOWN;
            break;
        case Keyboard::KEY_E:
            _moveFlags |= MOVE_UP;
            break;
        case Keyboard::KEY_PG_UP:
            _fpCamera.rotate(0, MATH_PIOVER4);
            break;
        case Keyboard::KEY_PG_DOWN:
            _fpCamera.rotate(0, -MATH_PIOVER4);
            break;

        case Keyboard::KEY_ONE:
        case Keyboard::KEY_SPACE:
            addSound("footsteps.wav");
            break;
        }
    }
    else if (evt == Keyboard::KEY_RELEASE)
    {
        switch (key)
        {
        case Keyboard::KEY_W:
            _moveFlags &= ~MOVE_FORWARD;
            break;
        case Keyboard::KEY_S:
            _moveFlags &= ~MOVE_BACKWARD;
            break;
        case Keyboard::KEY_A:
            _moveFlags &= ~MOVE_LEFT;
            break;
        case Keyboard::KEY_D:
            _moveFlags &= ~MOVE_RIGHT;
            break;
        case Keyboard::KEY_Q:
            _moveFlags &= ~MOVE_DOWN;
            break;
        case Keyboard::KEY_E:
            _moveFlags &= ~MOVE_UP;
            break;
        }
    }
}

bool Audio3DSample::mouseEvent(Mouse::MouseEvent evt, int x, int y, float wheelDelta)
{
    switch (evt)
    {
    case Mouse::MOUSE_WHEEL:
        _fpCamera.moveForward(wheelDelta * MOVE_SPEED / 2.0f );
        return true;
    }
    return false;
}

void Audio3DSample::addSound(const std::string& file)
{
    std::string path("res/common/");
    path.append(file);

    Node* node = NULL;
    std::map<std::string, Node*>::iterator it = _audioNodes.find(path);
    if (it != _audioNodes.end())
    {
        node = it->second->clone();
    }
    else
    {
        AudioSource* audioSource = AudioSource::create(path.c_str());
        assert(audioSource);
        audioSource->setLooped(true);

        node = _cubeNode->clone();
        node->setId(file.c_str());
        node->setAudioSource(audioSource);
        audioSource->release();

        _audioNodes[path] = node;
        node->addRef();
    }
    assert(node);
    Node* cameraNode = _scene->getActiveCamera()->getNode();
    // Position the sound infront of the user
    node->setTranslation(cameraNode->getTranslationWorld());
    Vector3 dir = cameraNode->getForwardVectorWorld().normalize();
    dir.scale(2);
    node->translate(dir);
    _scene->addNode(node);
    node->getAudioSource()->play();
    node->release();
}

void Audio3DSample::drawDebugText(int x, int y, unsigned int fontSize)
{
    _font->start();
    static const int V_SPACE = 16;
    AudioListener* audioListener = AudioListener::getInstance();
    drawVector3("Position", audioListener->getPosition(), x, y);
    drawVector3("Forward", audioListener->getOrientationForward(), x, y += fontSize);
    drawVector3("Orientation", audioListener->getOrientationUp(), x, y += fontSize);
    drawVector3("Velocity", audioListener->getVelocity(), x, y += fontSize);
    _font->finish();
}

void Audio3DSample::drawVector3(const char* str, const Vector3& vector, int x, int y)
{
    wchar_t buffer[255];
    swprintf(buffer, 255, L"%S: (%f, %f, %f)", str, vector.x, vector.y, vector.z);
    _font->drawText(buffer, x, y, Vector4::one(), _font->getSize());
}

void Audio3DSample::loadGrid(Scene* scene)
{
    assert(scene);
    Model* gridModel = createGridModel();
    assert(gridModel);
    gridModel->setMaterial("res/common/grid.material");
    Node* node = scene->addNode("grid");
    node->setDrawable(gridModel);
    SAFE_RELEASE(gridModel);
}

void Audio3DSample::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
{
    switch(evt)
    {
    case Gamepad::CONNECTED_EVENT:
    case Gamepad::DISCONNECTED_EVENT:
        _gamepad = getGamepad(0);
        // This is needed because the virtual gamepad is shared between all samples.
        // SamplesGame always ensures the virtual gamepad is disabled when a sample is exited.
        if (_gamepad && _gamepad->isVirtual())
            _gamepad->getForm()->setEnabled(true);
        break;
    }
}<|endoftext|>


<commit_before>#include "common.h"

#define GL_GLEXT_PROTOTYPES

#include "GLES/gl.h"
#include "GLES2/gl2.h"

#include <cstdlib>		// EXIT_SUCCESS, etc
#include <cstdint>		// uint8_t, etc
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

#include "lodepng.h"
#include "json.hpp"
using json = nlohmann::json;

#define COMPILE_ERROR_EXIT_CODE (101)
#define LINK_ERROR_EXIT_CODE (102)
#define RENDER_ERROR_EXIT_CODE (103)

#define CHANNELS (4)
#define DELAY (2)

const float vertices[] = {
  -1.0f,  1.0f,
  -1.0f, -1.0f,
   1.0f, -1.0f,
   1.0f,  1.0f
};

const GLubyte indices[] = {
  0, 1, 2,
  2, 3, 0
};

const char* vertex_shader_wo_version =
"attribute vec2 vert2d;\n"
"void main(void) {\n"
"  gl_Position = vec4(vert2d, 0.0, 1.0);\n"
"}";

bool readFile(const std::string& fileName, std::string& contentsOut) {
  std::ifstream ifs(fileName.c_str());
  if(!ifs) {
    std::cerr << "File " << fileName << " not found" << std::endl;
    return false;
  }
  std::stringstream ss;
  ss << ifs.rdbuf();
  contentsOut = ss.str();
  return true;
}

void printProgramError(GLuint program) {
  GLint length = 0;
  glGetShaderiv(program, GL_INFO_LOG_LENGTH, &length);

  // The maxLength includes the NULL character

  std::vector<GLchar> errorLog((size_t) length, 0);

  glGetShaderInfoLog(program, length, &length, &errorLog[0]);
  if(length > 0) {
    std::string s(&errorLog[0]);
    std::cout << s << std::endl;
  }
}

int checkForGLError(const char loc[]) {
  GLenum res = glGetError();
  if(res != GL_NO_ERROR) {
    std::cerr << loc << ": glGetError: " << std::hex << res << std::endl;
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}

#define CHECK_ERROR(loc) \
do { \
  if(checkForGLError(loc) == EXIT_FAILURE) { \
    return EXIT_FAILURE; \
  } \
} while(false)

int render(
    EGLDisplay display,
    EGLSurface surface,
    int width,
    int height,
    bool animate,
    int numFrames,
    bool& saved,
    const std::string& output,
    GLint resolutionLocation,
    GLint timeLocation) {

  glViewport(0, 0, width, height);
  CHECK_ERROR("After glViewport");

  if(resolutionLocation != -1) {
    glUniform2f(resolutionLocation, width, height);
    CHECK_ERROR("After glUniform2f");
  }

  if(animate && timeLocation != -1 && numFrames > DELAY) {
    glUniform1f(timeLocation, numFrames / 10.0f);
    CHECK_ERROR("After glUniform1f");
  }

  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  CHECK_ERROR("After glClearColor");
  glClear(GL_COLOR_BUFFER_BIT);
  CHECK_ERROR("After glClear");

  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
  CHECK_ERROR("After glDrawElements");

  glFlush();
  CHECK_ERROR("After glFlush");

  eglSwapBuffers(display, surface);
  CHECK_ERROR("After swapBuffers");

  return EXIT_SUCCESS;
}

int setUniformsFromJSON(const std::string& jsonFilename, const GLuint& program) {
  std::string jsonContent;
  if (!readFile(jsonFilename, jsonContent)) {
    return EXIT_FAILURE;
  }
  json j = json::parse(jsonContent);

  for (json::iterator it = j.begin(); it != j.end(); ++it) {
    std::string uniformName = it.key();
    json uniformInfo = it.value();

    // Check presence of func and args entries
    if (uniformInfo.find("func") == uniformInfo.end()) {
      std::cerr << "Error: malformed JSON: no \"func\" entry for uniform: " << uniformName << std::endl;
      return EXIT_FAILURE;
    }
    if (uniformInfo.find("args") == uniformInfo.end()) {
      std::cerr << "Error: malformed JSON: no \"args\" entry for uniform: " << uniformName << std::endl;
      return EXIT_FAILURE;
    }

    // Get uniform location
    GLint uniformLocation = glGetUniformLocation(program, uniformName.c_str());
    CHECK_ERROR("After glGetUniformLocation");
    if (uniformLocation == -1) {
      std::cerr << "Warning: Cannot find uniform named: " << uniformName << std::endl;
      continue;
    }

    // Dispatch to matching init function
    std::string uniformFunc = uniformInfo["func"];
    json args = uniformInfo["args"];

    // TODO: check that args has the good number of fields and type

    if (uniformFunc == "glUniform1f") {
      glUniform1f(uniformLocation, args[0]);
    } else if (uniformFunc == "glUniform2f") {
      glUniform2f(uniformLocation, args[0], args[1]);
    } else if (uniformFunc == "glUniform3f") {
      glUniform3f(uniformLocation, args[0], args[1], args[2]);
    } else if (uniformFunc == "glUniform4f") {
      glUniform4f(uniformLocation, args[0], args[1], args[2], args[3]);
    }

    else if (uniformFunc == "glUniform1i") {
      glUniform1i(uniformLocation, args[0]);
    } else if (uniformFunc == "glUniform2i") {
      glUniform2i(uniformLocation, args[0], args[1]);
    } else if (uniformFunc == "glUniform3i") {
      glUniform3i(uniformLocation, args[0], args[1], args[2]);
    } else if (uniformFunc == "glUniform4i") {
      glUniform4i(uniformLocation, args[0], args[1], args[2], args[3]);
    }

    else {
      std::cerr << "Error: unknown uniform init func: " << uniformFunc << std::endl;
      return EXIT_FAILURE;
    }
    CHECK_ERROR("After uniform initialisation");
  }

  return EXIT_SUCCESS;
}

int main(int argc, char* argv[]) {

  EGLDisplay display = 0;
  EGLConfig config = 0;
  EGLContext context = 0;
  EGLSurface surface = 0;

  const int width = 640;
  const int height = 480;

  bool res = init_gl(
      width,
      height,
      display,
      config,
      context,
      surface
  );

  if(!res) {
    return EXIT_FAILURE;
  }

  bool persist = false;
  bool animate = false;
  bool exit_compile = false;
  bool exit_linking = false;
  std::string output("output.png");
  std::string vertex_shader;
  std::string fragment_shader;

  for(int i = 1; i < argc; i++) {
    std::string curr_arg = std::string(argv[i]);
    if(!curr_arg.compare(0, 2, "--")) {
      if(curr_arg == "--persist") {
        persist = true;
        continue;
      }
      else if(curr_arg == "--animate") {
        animate = true;
        continue;
      }
      else if(curr_arg == "--exit_compile") {
        exit_compile = true;
        continue;
      }
      else if(curr_arg == "--exit_linking") {
        exit_linking = true;
        continue;
      }
      else if(curr_arg == "--output") {
        output = argv[++i];
        continue;
      }
      else if(curr_arg == "--vertex") {
        vertex_shader = argv[++i];
        continue;
      }
      std::cerr << "Unknown argument " << curr_arg << std::endl;
      continue;
    }
    if (fragment_shader.length() == 0) {
      fragment_shader = curr_arg;
    } else {
      std::cerr << "Ignoring extra argument " << curr_arg << std::endl;
    }
  }

  if(fragment_shader.length() == 0) {
    std::cerr << "Requires fragment shader argument!" << std::endl;
    return EXIT_FAILURE;
  }

  GLuint program = glCreateProgram();
  int compileOk = 0;
  const char* temp;

  std::string fragContents;
  if(!readFile(fragment_shader, fragContents)) {
    return EXIT_FAILURE;
  }

  temp = fragContents.c_str();
  GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragmentShader, 1, &temp, NULL);
  glCompileShader(fragmentShader);
  glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error compiling fragment shader." << std::endl;
    printProgramError(program);
    return COMPILE_ERROR_EXIT_CODE;
  }
  std::cerr << "Fragment shader compiled successfully." << std::endl;
  if (exit_compile) {
    std::cout << "Exiting after fragment shader compilation." << std::endl;
    return EXIT_SUCCESS;
  }
  glAttachShader(program, fragmentShader);

  std::string vertexContents;
  if(vertex_shader.length() == 0) {
    // Use embedded vertex shader.
    std::stringstream ss;
    size_t i = fragContents.find('\n');
    if(i != std::string::npos && fragContents[0] == '#') {
      ss << fragContents.substr(0,i);
      ss << "\n";
    } else {
      std::cerr << "Warning: Could not find #version string of fragment shader." << std::endl;
    }
    ss << vertex_shader_wo_version;
    vertexContents = ss.str();
  } else {
    if(!readFile(vertex_shader, vertexContents)) {
      return EXIT_FAILURE;
    }
  }

  GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  temp = vertexContents.c_str();
  glShaderSource(vertexShader, 1, &temp, NULL);
  glCompileShader(vertexShader);
  glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error compiling vertex shader." << std::endl;
    printProgramError(program);
    return EXIT_FAILURE;
  }
  std::cerr << "Vertex shader compiled successfully." << std::endl;

  glAttachShader(program, vertexShader);

  std::cerr << "Linking program." << std::endl;
  glLinkProgram(program);
  glGetProgramiv(program, GL_LINK_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error in linking program." << std::endl;
    printProgramError(program);
    return LINK_ERROR_EXIT_CODE;
  }
  std::cerr << "Program linked successfully." << std::endl;
  if (exit_linking) {
    std::cout << "Exiting after program linking." << std::endl;
    return EXIT_SUCCESS;
  }

  GLint posAttribLocationAttempt = glGetAttribLocation(program, "vert2d");
  if(posAttribLocationAttempt == -1) {
    std::cerr << "Error getting vert2d attribute location." << std::endl;
    return EXIT_FAILURE;
  }
  GLuint posAttribLocation = (GLuint) posAttribLocationAttempt;
  glEnableVertexAttribArray(posAttribLocation);

  glUseProgram(program);

  GLuint vertexBuffer;
  glGenBuffers(1, &vertexBuffer);
  glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  GLuint indicesBuffer;
  glGenBuffers(1, &indicesBuffer);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

  GLint injectionSwitchLocation = glGetUniformLocation(program, "injectionSwitch");
  GLint timeLocation = glGetUniformLocation(program, "time");
  GLint mouseLocation = glGetUniformLocation(program, "mouse");
  GLint resolutionLocation = glGetUniformLocation(program, "resolution");

  if(injectionSwitchLocation != -1) {
    glUniform2f(injectionSwitchLocation, 0.0f, 1.0f);
  }
  if(mouseLocation != -1) {
    glUniform2f(mouseLocation, 0.0f, 0.0f);
  }
  if(timeLocation != -1) {
    glUniform1f(timeLocation, 0.0f);
  }

  glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  glVertexAttribPointer(posAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);

  std::string jsonFilename(fragment_shader);
  jsonFilename.replace(jsonFilename.end()-4, jsonFilename.end(), "json");
  int result = setUniformsFromJSON(jsonFilename, program);
  if(result != EXIT_SUCCESS) {
    return EXIT_FAILURE;
  }
  std::cerr << "Uniforms set successfully." << std::endl;

  int numFrames = 0;
  bool saved = false;

  result = render(
      display,
      surface,
      width,
      height,
      animate,
      numFrames,
      saved,
      output,
      resolutionLocation,
      timeLocation);

  if(result != EXIT_SUCCESS) {
    return EXIT_FAILURE;
  }

//  ++numFrames;

//  if(numFrames == DELAY && !saved) {
  std::cerr << "Capturing frame." << std::endl;
  saved = true;
  unsigned uwidth = (unsigned int) width;
  unsigned uheight = (unsigned int) height;
  std::vector<std::uint8_t> data(uwidth * uheight * CHANNELS);
  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
  CHECK_ERROR("After glReadPixels");
  std::vector<std::uint8_t> flipped_data(uwidth * uheight * CHANNELS);
  for (unsigned int h = 0; h < uheight ; h++)
    for (unsigned int col = 0; col < uwidth * CHANNELS; col++)
      flipped_data[h * uwidth * CHANNELS + col] =
          data[(uheight - h - 1) * uwidth * CHANNELS + col];
  unsigned png_error = lodepng::encode(output, flipped_data, uwidth, uheight);
  if (png_error) {
    std::cerr << "Error producing PNG file: " << lodepng_error_text(png_error) << std::endl;
    return EXIT_FAILURE;
  }
  if (!persist) {
    return EXIT_SUCCESS;
  }
//  }

  return EXIT_SUCCESS;
}
<commit_msg>Add support for glUniformXfv and glUniformXiv<commit_after>#include "common.h"

#define GL_GLEXT_PROTOTYPES

#include "GLES/gl.h"
#include "GLES2/gl2.h"

#include <cstdlib>		// EXIT_SUCCESS, etc
#include <cstdint>		// uint8_t, etc
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

#include "lodepng.h"
#include "json.hpp"
using json = nlohmann::json;

#define COMPILE_ERROR_EXIT_CODE (101)
#define LINK_ERROR_EXIT_CODE (102)
#define RENDER_ERROR_EXIT_CODE (103)

#define CHANNELS (4)
#define DELAY (2)

const float vertices[] = {
  -1.0f,  1.0f,
  -1.0f, -1.0f,
   1.0f, -1.0f,
   1.0f,  1.0f
};

const GLubyte indices[] = {
  0, 1, 2,
  2, 3, 0
};

const char* vertex_shader_wo_version =
"attribute vec2 vert2d;\n"
"void main(void) {\n"
"  gl_Position = vec4(vert2d, 0.0, 1.0);\n"
"}";

bool readFile(const std::string& fileName, std::string& contentsOut) {
  std::ifstream ifs(fileName.c_str());
  if(!ifs) {
    std::cerr << "File " << fileName << " not found" << std::endl;
    return false;
  }
  std::stringstream ss;
  ss << ifs.rdbuf();
  contentsOut = ss.str();
  return true;
}

void printProgramError(GLuint program) {
  GLint length = 0;
  glGetShaderiv(program, GL_INFO_LOG_LENGTH, &length);

  // The maxLength includes the NULL character

  std::vector<GLchar> errorLog((size_t) length, 0);

  glGetShaderInfoLog(program, length, &length, &errorLog[0]);
  if(length > 0) {
    std::string s(&errorLog[0]);
    std::cout << s << std::endl;
  }
}

int checkForGLError(const char loc[]) {
  GLenum res = glGetError();
  if(res != GL_NO_ERROR) {
    std::cerr << loc << ": glGetError: " << std::hex << res << std::endl;
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}

#define CHECK_ERROR(loc) \
do { \
  if(checkForGLError(loc) == EXIT_FAILURE) { \
    return EXIT_FAILURE; \
  } \
} while(false)

int render(
    EGLDisplay display,
    EGLSurface surface,
    int width,
    int height,
    bool animate,
    int numFrames,
    bool& saved,
    const std::string& output,
    GLint resolutionLocation,
    GLint timeLocation) {

  glViewport(0, 0, width, height);
  CHECK_ERROR("After glViewport");

  if(resolutionLocation != -1) {
    glUniform2f(resolutionLocation, width, height);
    CHECK_ERROR("After glUniform2f");
  }

  if(animate && timeLocation != -1 && numFrames > DELAY) {
    glUniform1f(timeLocation, numFrames / 10.0f);
    CHECK_ERROR("After glUniform1f");
  }

  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  CHECK_ERROR("After glClearColor");
  glClear(GL_COLOR_BUFFER_BIT);
  CHECK_ERROR("After glClear");

  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
  CHECK_ERROR("After glDrawElements");

  glFlush();
  CHECK_ERROR("After glFlush");

  eglSwapBuffers(display, surface);
  CHECK_ERROR("After swapBuffers");

  return EXIT_SUCCESS;
}

template<typename T>
T *getArray(const json& j) {
  T *a = new T[j.size()];
  for (int i = 0; i < j.size(); i++) {
    a[i] = j[i];
  }
  return a;
}

#define GLUNIFORM_ARRAYINIT(funcname, uniformloc, gltype, jsonarray)     \
  gltype *a = getArray<gltype>(jsonarray.size()); \
  funcname(uniformloc, jsonarray.size(), a); \
  delete [] a

int setUniformsFromJSON(const std::string& jsonFilename, const GLuint& program) {
  std::string jsonContent;
  if (!readFile(jsonFilename, jsonContent)) {
    return EXIT_FAILURE;
  }
  json j = json::parse(jsonContent);

  for (json::iterator it = j.begin(); it != j.end(); ++it) {
    std::string uniformName = it.key();
    json uniformInfo = it.value();

    // Check presence of func and args entries
    if (uniformInfo.find("func") == uniformInfo.end()) {
      std::cerr << "Error: malformed JSON: no \"func\" entry for uniform: " << uniformName << std::endl;
      return EXIT_FAILURE;
    }
    if (uniformInfo.find("args") == uniformInfo.end()) {
      std::cerr << "Error: malformed JSON: no \"args\" entry for uniform: " << uniformName << std::endl;
      return EXIT_FAILURE;
    }

    // Get uniform location
    GLint uniformLocation = glGetUniformLocation(program, uniformName.c_str());
    CHECK_ERROR("After glGetUniformLocation");
    if (uniformLocation == -1) {
      std::cerr << "Warning: Cannot find uniform named: " << uniformName << std::endl;
      continue;
    }

    // Dispatch to matching init function
    std::string uniformFunc = uniformInfo["func"];
    json args = uniformInfo["args"];

    // TODO: check that args has the good number of fields and type

    if (uniformFunc == "glUniform1f") {
      glUniform1f(uniformLocation, args[0]);
    } else if (uniformFunc == "glUniform2f") {
      glUniform2f(uniformLocation, args[0], args[1]);
    } else if (uniformFunc == "glUniform3f") {
      glUniform3f(uniformLocation, args[0], args[1], args[2]);
    } else if (uniformFunc == "glUniform4f") {
      glUniform4f(uniformLocation, args[0], args[1], args[2], args[3]);
    }

    else if (uniformFunc == "glUniform1i") {
      glUniform1i(uniformLocation, args[0]);
    } else if (uniformFunc == "glUniform2i") {
      glUniform2i(uniformLocation, args[0], args[1]);
    } else if (uniformFunc == "glUniform3i") {
      glUniform3i(uniformLocation, args[0], args[1], args[2]);
    } else if (uniformFunc == "glUniform4i") {
      glUniform4i(uniformLocation, args[0], args[1], args[2], args[3]);
    }

    // Note: no "glUniformXui" variant in OpenGL ES

    // else if (uniformFunc == "glUniform1ui") {
    //   glUniform1ui(uniformLocation, args[0]);
    // } else if (uniformFunc == "glUniform2ui") {
    //   glUniform2ui(uniformLocation, args[0], args[1]);
    // } else if (uniformFunc == "glUniform3ui") {
    //   glUniform3ui(uniformLocation, args[0], args[1], args[2]);
    // } else if (uniformFunc == "glUniform4ui") {
    //   glUniform4ui(uniformLocation, args[0], args[1], args[2], args[3]);
    // }

    else if (uniformFunc == "glUniform1fv") {
      GLUNIFORM_ARRAYINIT(glUniform1fv, uniformLocation, GLfloat, args);
    } else if (uniformFunc == "glUniform2fv") {
      GLUNIFORM_ARRAYINIT(glUniform2fv, uniformLocation, GLfloat, args);
    } else if (uniformFunc == "glUniform3fv") {
      GLUNIFORM_ARRAYINIT(glUniform3fv, uniformLocation, GLfloat, args);
    } else if (uniformFunc == "glUniform4fv") {
      GLUNIFORM_ARRAYINIT(glUniform4fv, uniformLocation, GLfloat, args);
    }

    else if (uniformFunc == "glUniform1iv") {
      GLUNIFORM_ARRAYINIT(glUniform1iv, uniformLocation, GLint, args);
    } else if (uniformFunc == "glUniform2iv") {
      GLUNIFORM_ARRAYINIT(glUniform2iv, uniformLocation, GLint, args);
    } else if (uniformFunc == "glUniform3iv") {
      GLUNIFORM_ARRAYINIT(glUniform3iv, uniformLocation, GLint, args);
    } else if (uniformFunc == "glUniform4iv") {
      GLUNIFORM_ARRAYINIT(glUniform4iv, uniformLocation, GLint, args);
    }

    else {
      std::cerr << "Error: unknown uniform init func: " << uniformFunc << std::endl;
      return EXIT_FAILURE;
    }
    CHECK_ERROR("After uniform initialisation");
  }

  return EXIT_SUCCESS;
}

int main(int argc, char* argv[]) {

  EGLDisplay display = 0;
  EGLConfig config = 0;
  EGLContext context = 0;
  EGLSurface surface = 0;

  const int width = 640;
  const int height = 480;

  bool res = init_gl(
      width,
      height,
      display,
      config,
      context,
      surface
  );

  if(!res) {
    return EXIT_FAILURE;
  }

  bool persist = false;
  bool animate = false;
  bool exit_compile = false;
  bool exit_linking = false;
  std::string output("output.png");
  std::string vertex_shader;
  std::string fragment_shader;

  for(int i = 1; i < argc; i++) {
    std::string curr_arg = std::string(argv[i]);
    if(!curr_arg.compare(0, 2, "--")) {
      if(curr_arg == "--persist") {
        persist = true;
        continue;
      }
      else if(curr_arg == "--animate") {
        animate = true;
        continue;
      }
      else if(curr_arg == "--exit_compile") {
        exit_compile = true;
        continue;
      }
      else if(curr_arg == "--exit_linking") {
        exit_linking = true;
        continue;
      }
      else if(curr_arg == "--output") {
        output = argv[++i];
        continue;
      }
      else if(curr_arg == "--vertex") {
        vertex_shader = argv[++i];
        continue;
      }
      std::cerr << "Unknown argument " << curr_arg << std::endl;
      continue;
    }
    if (fragment_shader.length() == 0) {
      fragment_shader = curr_arg;
    } else {
      std::cerr << "Ignoring extra argument " << curr_arg << std::endl;
    }
  }

  if(fragment_shader.length() == 0) {
    std::cerr << "Requires fragment shader argument!" << std::endl;
    return EXIT_FAILURE;
  }

  GLuint program = glCreateProgram();
  int compileOk = 0;
  const char* temp;

  std::string fragContents;
  if(!readFile(fragment_shader, fragContents)) {
    return EXIT_FAILURE;
  }

  temp = fragContents.c_str();
  GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragmentShader, 1, &temp, NULL);
  glCompileShader(fragmentShader);
  glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error compiling fragment shader." << std::endl;
    printProgramError(program);
    return COMPILE_ERROR_EXIT_CODE;
  }
  std::cerr << "Fragment shader compiled successfully." << std::endl;
  if (exit_compile) {
    std::cout << "Exiting after fragment shader compilation." << std::endl;
    return EXIT_SUCCESS;
  }
  glAttachShader(program, fragmentShader);

  std::string vertexContents;
  if(vertex_shader.length() == 0) {
    // Use embedded vertex shader.
    std::stringstream ss;
    size_t i = fragContents.find('\n');
    if(i != std::string::npos && fragContents[0] == '#') {
      ss << fragContents.substr(0,i);
      ss << "\n";
    } else {
      std::cerr << "Warning: Could not find #version string of fragment shader." << std::endl;
    }
    ss << vertex_shader_wo_version;
    vertexContents = ss.str();
  } else {
    if(!readFile(vertex_shader, vertexContents)) {
      return EXIT_FAILURE;
    }
  }

  GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  temp = vertexContents.c_str();
  glShaderSource(vertexShader, 1, &temp, NULL);
  glCompileShader(vertexShader);
  glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error compiling vertex shader." << std::endl;
    printProgramError(program);
    return EXIT_FAILURE;
  }
  std::cerr << "Vertex shader compiled successfully." << std::endl;

  glAttachShader(program, vertexShader);

  std::cerr << "Linking program." << std::endl;
  glLinkProgram(program);
  glGetProgramiv(program, GL_LINK_STATUS, &compileOk);
  if (!compileOk) {
    std::cerr << "Error in linking program." << std::endl;
    printProgramError(program);
    return LINK_ERROR_EXIT_CODE;
  }
  std::cerr << "Program linked successfully." << std::endl;
  if (exit_linking) {
    std::cout << "Exiting after program linking." << std::endl;
    return EXIT_SUCCESS;
  }

  GLint posAttribLocationAttempt = glGetAttribLocation(program, "vert2d");
  if(posAttribLocationAttempt == -1) {
    std::cerr << "Error getting vert2d attribute location." << std::endl;
    return EXIT_FAILURE;
  }
  GLuint posAttribLocation = (GLuint) posAttribLocationAttempt;
  glEnableVertexAttribArray(posAttribLocation);

  glUseProgram(program);

  GLuint vertexBuffer;
  glGenBuffers(1, &vertexBuffer);
  glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  GLuint indicesBuffer;
  glGenBuffers(1, &indicesBuffer);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

  GLint injectionSwitchLocation = glGetUniformLocation(program, "injectionSwitch");
  GLint timeLocation = glGetUniformLocation(program, "time");
  GLint mouseLocation = glGetUniformLocation(program, "mouse");
  GLint resolutionLocation = glGetUniformLocation(program, "resolution");

  if(injectionSwitchLocation != -1) {
    glUniform2f(injectionSwitchLocation, 0.0f, 1.0f);
  }
  if(mouseLocation != -1) {
    glUniform2f(mouseLocation, 0.0f, 0.0f);
  }
  if(timeLocation != -1) {
    glUniform1f(timeLocation, 0.0f);
  }

  glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  glVertexAttribPointer(posAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);

  std::string jsonFilename(fragment_shader);
  jsonFilename.replace(jsonFilename.end()-4, jsonFilename.end(), "json");
  int result = setUniformsFromJSON(jsonFilename, program);
  if(result != EXIT_SUCCESS) {
    return EXIT_FAILURE;
  }
  std::cerr << "Uniforms set successfully." << std::endl;

  int numFrames = 0;
  bool saved = false;

  result = render(
      display,
      surface,
      width,
      height,
      animate,
      numFrames,
      saved,
      output,
      resolutionLocation,
      timeLocation);

  if(result != EXIT_SUCCESS) {
    return EXIT_FAILURE;
  }

//  ++numFrames;

//  if(numFrames == DELAY && !saved) {
  std::cerr << "Capturing frame." << std::endl;
  saved = true;
  unsigned uwidth = (unsigned int) width;
  unsigned uheight = (unsigned int) height;
  std::vector<std::uint8_t> data(uwidth * uheight * CHANNELS);
  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
  CHECK_ERROR("After glReadPixels");
  std::vector<std::uint8_t> flipped_data(uwidth * uheight * CHANNELS);
  for (unsigned int h = 0; h < uheight ; h++)
    for (unsigned int col = 0; col < uwidth * CHANNELS; col++)
      flipped_data[h * uwidth * CHANNELS + col] =
          data[(uheight - h - 1) * uwidth * CHANNELS + col];
  unsigned png_error = lodepng::encode(output, flipped_data, uwidth, uheight);
  if (png_error) {
    std::cerr << "Error producing PNG file: " << lodepng_error_text(png_error) << std::endl;
    return EXIT_FAILURE;
  }
  if (!persist) {
    return EXIT_SUCCESS;
  }
//  }

  return EXIT_SUCCESS;
}
<|endoftext|>