<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"];

    // FIXME: can we use a template to factor the following? Hugues
    // thinks not since it would required the code to be expanded at
    // runtime (not compilation time) from the string obtained when
    // reading the JSON file. Proper meta-programming like in LISP could
    // do it though.

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

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

    else if (uniformFunc == "glUniform1i") {
      glUniform1i(uniformLocation, uniformInfo["args"][0]);
    } else if (uniformFunc == "glUniform2i") {
      glUniform2i(uniformLocation, uniformInfo["args"][0], uniformInfo["args"][1]);
    } else if (uniformFunc == "glUniform3i") {
      glUniform3i(uniformLocation, uniformInfo["args"][0], uniformInfo["args"][1], uniformInfo["args"][2]);
    } else if (uniformFunc == "glUniform4i") {
      glUniform4i(uniformLocation, uniformInfo["args"][0], uniformInfo["args"][1], uniformInfo["args"][2], uniformInfo["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>Factorise code<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;
}

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;
}
<|endoftext|>


<commit_before>/* CUDA device function execution
 *
 * Copyright (C) 2007  Peter Colberg
 *
 * This file is part of HALMD.
 *
 * HALMD is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#if !BOOST_PP_IS_ITERATING

    #ifndef CUDA_FUNCTION_HPP
    #define CUDA_FUNCTION_HPP

    #include <boost/preprocessor/iteration/iterate.hpp>
    #include <boost/preprocessor/repetition/enum_params.hpp>
    #include <boost/preprocessor/repetition/enum_binary_params.hpp>
    #include <boost/preprocessor/repetition/repeat.hpp>
    #include <cuda_runtime.h>

    #ifndef __CUDACC__
    # include <cuda_wrapper/error.hpp>
    # include <cuda_wrapper/stream.hpp>
    #endif

    /* maximum number of arguments passed to device functions */
    #ifndef CUDA_FUNCTION_MAX_ARGS
    #define CUDA_FUNCTION_MAX_ARGS 10
    #endif

    namespace cuda
    {

    /*
     * CUDA execution configuration
     */
    class config
    {
    public:
        /* grid dimensions */
        dim3 grid;
        /* block dimensions */
        dim3 block;
        /* FIXME store useful numbers (no. of threads per grid/block) */

        config()
        {
        }

        config(dim3 grid, dim3 block) : grid(grid), block(block)
        {
            /* FIXME store useful numbers (no. of threads per grid/block) */
        }

        size_t threads() const
        {
            return grid.y * grid.x * block.z * block.y * block.x;
        }

        size_t blocks_per_grid() const
        {
            return grid.y * grid.x;
        }

        size_t threads_per_block() const
        {
            return block.z * block.y * block.x;
        }
    };

    #ifndef __CUDACC__

    /**
     * configure execution parameters
     */
    __inline__ void configure(dim3 const& grid, dim3 const& block, size_t shared_mem = 0)
    {
        CUDA_CALL(cudaConfigureCall(grid, block, shared_mem, 0));
    }

    #if (CUDART_VERSION >= 1010)

    /**
     * configure execution parameters
     */
    __inline__ void configure(dim3 const& grid, dim3 const& block, stream& stream)
    {
        CUDA_CALL(cudaConfigureCall(grid, block, 0, stream.data()));
    }

    /**
     * configure execution parameters
     */
    __inline__ void configure(dim3 const& grid, dim3 const& block, size_t shared_mem, stream& stream)
    {
        CUDA_CALL(cudaConfigureCall(grid, block, shared_mem, stream.data()));
    }

    #endif /* CUDART_VERSION >= 1010 */

    #endif /* ! __CUDACC__ */

    template <typename T>
    class function;

    } // namespace cuda

    #define BOOST_PP_FILENAME_1 <cuda_wrapper/function.hpp>
    #define BOOST_PP_ITERATION_LIMITS (1, CUDA_FUNCTION_MAX_ARGS)
    #include BOOST_PP_ITERATE()

    #endif /* ! CUDA_FUNCTION_HPP */

#elif BOOST_PP_ITERATION_DEPTH() == 1

    #define CUDA_FUNCTION_ARGS BOOST_PP_FRAME_ITERATION(1)

    namespace cuda
    {

    /**
     * CUDA kernel execution wrapper for n-ary device function
     */
    template <BOOST_PP_ENUM_PARAMS(CUDA_FUNCTION_ARGS, typename T)>
    class function<void (BOOST_PP_ENUM_PARAMS(CUDA_FUNCTION_ARGS, T))>
    {
    public:
        typedef void T (BOOST_PP_ENUM_PARAMS(CUDA_FUNCTION_ARGS, T));

    public:
        function(T *f) : f(f) {}

    #ifndef __CUDACC__

        /**
         * execute kernel
         */
        void operator()(BOOST_PP_ENUM_BINARY_PARAMS(CUDA_FUNCTION_ARGS, T, x))
        {
            // properly align CUDA device function arguments
            struct offset
            {
                #define DECL_ARG(z, n, arg) T##n arg##n;
                BOOST_PP_REPEAT(CUDA_FUNCTION_ARGS, DECL_ARG, x)
                #undef DECL_ARG
            };
            offset* __offset = 0;
            // push aligned arguments onto CUDA execution stack
            #define DECL_ARG(z, n, offset) CUDA_CALL(cudaSetupArgument(&x##n, sizeof(T##n), reinterpret_cast<size_t>(&offset->x##n)));
            BOOST_PP_REPEAT(CUDA_FUNCTION_ARGS, DECL_ARG, __offset)
            #undef DECL_ARG
            // launch CUDA device function
            CUDA_CALL(cudaLaunch(reinterpret_cast<const char *>(f)));
        }

    #endif /* ! __CUDACC__ */

    private:
        T *f;
    };

    } // namespace cuda

    #undef CUDA_FUNCTION_ARGS

#endif /* !BOOST_PP_IS_ITERATING */
<commit_msg>Fix use of const cuda::function<commit_after>/* CUDA device function execution
 *
 * Copyright (C) 2007  Peter Colberg
 *
 * This file is part of HALMD.
 *
 * HALMD is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#if !BOOST_PP_IS_ITERATING

    #ifndef CUDA_FUNCTION_HPP
    #define CUDA_FUNCTION_HPP

    #include <boost/preprocessor/iteration/iterate.hpp>
    #include <boost/preprocessor/repetition/enum_params.hpp>
    #include <boost/preprocessor/repetition/enum_binary_params.hpp>
    #include <boost/preprocessor/repetition/repeat.hpp>
    #include <cuda_runtime.h>

    #ifndef __CUDACC__
    # include <cuda_wrapper/error.hpp>
    # include <cuda_wrapper/stream.hpp>
    #endif

    /* maximum number of arguments passed to device functions */
    #ifndef CUDA_FUNCTION_MAX_ARGS
    #define CUDA_FUNCTION_MAX_ARGS 10
    #endif

    namespace cuda
    {

    /*
     * CUDA execution configuration
     */
    class config
    {
    public:
        /* grid dimensions */
        dim3 grid;
        /* block dimensions */
        dim3 block;
        /* FIXME store useful numbers (no. of threads per grid/block) */

        config()
        {
        }

        config(dim3 grid, dim3 block) : grid(grid), block(block)
        {
            /* FIXME store useful numbers (no. of threads per grid/block) */
        }

        size_t threads() const
        {
            return grid.y * grid.x * block.z * block.y * block.x;
        }

        size_t blocks_per_grid() const
        {
            return grid.y * grid.x;
        }

        size_t threads_per_block() const
        {
            return block.z * block.y * block.x;
        }
    };

    #ifndef __CUDACC__

    /**
     * configure execution parameters
     */
    __inline__ void configure(dim3 const& grid, dim3 const& block, size_t shared_mem = 0)
    {
        CUDA_CALL(cudaConfigureCall(grid, block, shared_mem, 0));
    }

    #if (CUDART_VERSION >= 1010)

    /**
     * configure execution parameters
     */
    __inline__ void configure(dim3 const& grid, dim3 const& block, stream& stream)
    {
        CUDA_CALL(cudaConfigureCall(grid, block, 0, stream.data()));
    }

    /**
     * configure execution parameters
     */
    __inline__ void configure(dim3 const& grid, dim3 const& block, size_t shared_mem, stream& stream)
    {
        CUDA_CALL(cudaConfigureCall(grid, block, shared_mem, stream.data()));
    }

    #endif /* CUDART_VERSION >= 1010 */

    #endif /* ! __CUDACC__ */

    template <typename T>
    class function;

    } // namespace cuda

    #define BOOST_PP_FILENAME_1 <cuda_wrapper/function.hpp>
    #define BOOST_PP_ITERATION_LIMITS (1, CUDA_FUNCTION_MAX_ARGS)
    #include BOOST_PP_ITERATE()

    #endif /* ! CUDA_FUNCTION_HPP */

#elif BOOST_PP_ITERATION_DEPTH() == 1

    #define CUDA_FUNCTION_ARGS BOOST_PP_FRAME_ITERATION(1)

    namespace cuda
    {

    /**
     * CUDA kernel execution wrapper for n-ary device function
     */
    template <BOOST_PP_ENUM_PARAMS(CUDA_FUNCTION_ARGS, typename T)>
    class function<void (BOOST_PP_ENUM_PARAMS(CUDA_FUNCTION_ARGS, T))>
    {
    public:
        typedef void T (BOOST_PP_ENUM_PARAMS(CUDA_FUNCTION_ARGS, T));

    public:
        function(T *f) : f(f) {}

    #ifndef __CUDACC__

        /**
         * execute kernel
         */
        void operator()(BOOST_PP_ENUM_BINARY_PARAMS(CUDA_FUNCTION_ARGS, T, x)) const
        {
            // properly align CUDA device function arguments
            struct offset
            {
                #define DECL_ARG(z, n, arg) T##n arg##n;
                BOOST_PP_REPEAT(CUDA_FUNCTION_ARGS, DECL_ARG, x)
                #undef DECL_ARG
            };
            offset* __offset = 0;
            // push aligned arguments onto CUDA execution stack
            #define DECL_ARG(z, n, offset) CUDA_CALL(cudaSetupArgument(&x##n, sizeof(T##n), reinterpret_cast<size_t>(&offset->x##n)));
            BOOST_PP_REPEAT(CUDA_FUNCTION_ARGS, DECL_ARG, __offset)
            #undef DECL_ARG
            // launch CUDA device function
            CUDA_CALL(cudaLaunch(reinterpret_cast<const char *>(f)));
        }

    #endif /* ! __CUDACC__ */

    private:
        T *f;
    };

    } // namespace cuda

    #undef CUDA_FUNCTION_ARGS

#endif /* !BOOST_PP_IS_ITERATING */
<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2010 VMware, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

/*
 * Central place for all GL includes, and respective OS dependent headers.
 */

#ifndef _GLIMPORTS_HPP_
#define _GLIMPORTS_HPP_

#ifdef _WIN32

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif

#include <windows.h>

#else /* !_WIN32 */

#include <X11/Xlib.h>

#endif /* !_WIN32 */

// Prevent including system's glext.h
#define __glext_h_

#include <GL/gl.h>

#undef __glext_h_

#include "glext/glext.h"

#ifndef GL_TEXTURE_INDEX_SIZE_EXT
#define GL_TEXTURE_INDEX_SIZE_EXT         0x80ED
#endif

#ifdef _WIN32

#include "glext/wglext.h"

#define GLAPIENTRY __stdcall

#ifndef PFD_SUPPORT_DIRECTDRAW
#define PFD_SUPPORT_DIRECTDRAW 0x00002000
#endif
#ifndef PFD_SUPPORT_COMPOSITION
#define PFD_SUPPORT_COMPOSITION 0x00008000
#endif

#ifdef __MINGW32__

extern "C"
typedef struct _WGLSWAP
{
    HDC hdc;
    UINT uiFlags;
} WGLSWAP, *PWGLSWAP, FAR *LPWGLSWAP;

#define WGL_SWAPMULTIPLE_MAX 16

#endif /* __MINGW32__ */

#else /* !_WIN32 */

#include <GL/glx.h>
#include "glext/glxext.h"

/* Prevent collision with Trace::Bool */
#undef Bool

#endif /* !_WIN32 */

#endif /* _GLIMPORTS_HPP_ */
<commit_msg>Fix build on Mingw-w64.<commit_after>/**************************************************************************
 *
 * Copyright 2010 VMware, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

/*
 * Central place for all GL includes, and respective OS dependent headers.
 */

#ifndef _GLIMPORTS_HPP_
#define _GLIMPORTS_HPP_

#ifdef _WIN32

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif

#include <windows.h>

#else /* !_WIN32 */

#include <X11/Xlib.h>

#endif /* !_WIN32 */

// Prevent including system's glext.h
#define __glext_h_

#include <GL/gl.h>

#undef __glext_h_

#include "glext/glext.h"

#ifndef GL_TEXTURE_INDEX_SIZE_EXT
#define GL_TEXTURE_INDEX_SIZE_EXT         0x80ED
#endif

#ifdef _WIN32

#include "glext/wglext.h"

#define GLAPIENTRY __stdcall

#ifndef PFD_SUPPORT_DIRECTDRAW
#define PFD_SUPPORT_DIRECTDRAW 0x00002000
#endif
#ifndef PFD_SUPPORT_COMPOSITION
#define PFD_SUPPORT_COMPOSITION 0x00008000
#endif

#ifndef WGL_SWAPMULTIPLE_MAX

extern "C"
typedef struct _WGLSWAP
{
    HDC hdc;
    UINT uiFlags;
} WGLSWAP, *PWGLSWAP, FAR *LPWGLSWAP;

#define WGL_SWAPMULTIPLE_MAX 16

#endif /* !WGL_SWAPMULTIPLE_MAX */

#else /* !_WIN32 */

#include <GL/glx.h>
#include "glext/glxext.h"

/* Prevent collision with Trace::Bool */
#undef Bool

#endif /* !_WIN32 */

#endif /* _GLIMPORTS_HPP_ */
<|endoftext|>


<commit_before>#include "resources.h"

#include <SFML/System.hpp>
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <dirent.h>
#endif
#include <cstdio>
#include <filesystem>

PVector<ResourceProvider> resourceProviders;

ResourceProvider::ResourceProvider()
{
    resourceProviders.push_back(this);
}

bool ResourceProvider::searchMatch(const string name, const string searchPattern)
{
    std::vector<string> parts = searchPattern.split("*");
    int pos = 0;
    if (parts[0].length() > 0)
    {
        if (name.find(parts[0]) != 0)
            return false;
    }
    for(unsigned int n=1; n<parts.size(); n++)
    {
        int offset = name.find(parts[n], pos);
        if (offset < 0)
            return false;
        pos = offset + parts[n].length();
    }
    return pos == int(name.length());
}

string ResourceStream::readLine()
{
    string ret;
    char c;
    while(true)
    {
        if (read(&c, 1) < 1)
            return ret;
        if (c == '\n')
            return ret;
        ret += string(c);
    }
}

class FileResourceStream : public ResourceStream
{
    sf::FileInputStream stream;
    bool open_success;
public:
    FileResourceStream(string filename)
    {
#ifndef ANDROID
        std::error_code ec;
        if(!std::filesystem::is_regular_file(filename.c_str(), ec))
        {
            if(ec)
            {
                LOG(ERROR) << "OS error on file check : " << ec.message();
            }
            open_success = false;
        }
        else
            open_success = stream.open(filename);
#else
        //Android reads from the assets bundle, so we cannot check if the file exists and is a regular file
        open_success = stream.open(filename);
#endif
    }
    virtual ~FileResourceStream()
    {
    }

    bool isOpen()
    {
        return open_success;
    }

    virtual sf::Int64 read(void* data, sf::Int64 size)
    {
        return stream.read(data, size);
    }
    virtual sf::Int64 seek(sf::Int64 position)
    {
        return stream.seek(position);
    }
    virtual sf::Int64 tell()
    {
        return stream.tell();
    }
    virtual sf::Int64 getSize()
    {
        return stream.getSize();
    }
};

DirectoryResourceProvider::DirectoryResourceProvider(string basepath)
: basepath(basepath)
{
}

P<ResourceStream> DirectoryResourceProvider::getResourceStream(string filename)
{
    P<FileResourceStream> stream = new FileResourceStream(basepath + filename);
    if (stream->isOpen())
        return stream;
    return nullptr;
}

std::vector<string> DirectoryResourceProvider::findResources(string searchPattern)
{
    std::vector<string> found_files;
    findResources(found_files, "", searchPattern);
    return found_files;
}

void DirectoryResourceProvider::findResources(std::vector<string>& found_files, const string path, const string searchPattern)
{
#ifdef _MSC_VER
    WIN32_FIND_DATAA data;
    string search_root(basepath + path);
    if (!search_root.endswith("/"))
    {
        search_root += "/";
    }
    HANDLE handle = FindFirstFileA((search_root + "*").c_str(), &data);
    if (handle == INVALID_HANDLE_VALUE)
        return;
    do
    {
        if (data.cFileName[0] == '.')
            continue;
        string name = path + string(data.cFileName);
        if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            findResources(found_files, name + "/", searchPattern);
        }
        else
        {
            if (searchMatch(name, searchPattern))
                found_files.push_back(name);
        }
    } while (FindNextFileA(handle, &data));

    FindClose(handle);
#else
    DIR* dir = opendir((basepath + path).c_str());
    if (!dir)
        return;

    struct dirent *entry;
    while ((entry = readdir(dir)) != nullptr)
    {
        if (entry->d_name[0] == '.')
            continue;
        string name = path + string(entry->d_name);
        if (searchMatch(name, searchPattern))
            found_files.push_back(name);
        findResources(found_files, path + string(entry->d_name) + "/", searchPattern);
    }
    closedir(dir);
#endif
}

P<ResourceStream> getResourceStream(string filename)
{
    foreach(ResourceProvider, rp, resourceProviders)
    {
        P<ResourceStream> stream = rp->getResourceStream(filename);
        if (stream)
            return stream;
    }
    return NULL;
}

std::vector<string> findResources(string searchPattern)
{
    std::vector<string> foundFiles;
    foreach(ResourceProvider, rp, resourceProviders)
    {
        std::vector<string> res = rp->findResources(searchPattern);
        foundFiles.insert(foundFiles.end(), res.begin(), res.end());
    }
    return foundFiles;
}
<commit_msg>Update resources.cpp (#99)<commit_after>#include "resources.h"

#include <SFML/System.hpp>
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <dirent.h>
#endif
#include <cstdio>
#include <filesystem>

PVector<ResourceProvider> resourceProviders;

ResourceProvider::ResourceProvider()
{
    resourceProviders.push_back(this);
}

bool ResourceProvider::searchMatch(const string name, const string searchPattern)
{
    std::vector<string> parts = searchPattern.split("*");
    int pos = 0;
    if (parts[0].length() > 0)
    {
        if (name.find(parts[0]) != 0)
            return false;
    }
    for(unsigned int n=1; n<parts.size(); n++)
    {
        int offset = name.find(parts[n], pos);
        if (offset < 0)
            return false;
        pos = offset + static_cast<int>(parts[n].length());
    }
    return pos == static_cast<int>(name.length());
}

string ResourceStream::readLine()
{
    string ret;
    char c;
    while(true)
    {
        if (read(&c, 1) < 1)
            return ret;
        if (c == '\n')
            return ret;
        ret += string(c);
    }
}

class FileResourceStream : public ResourceStream
{
    sf::FileInputStream stream;
    bool open_success;
public:
    FileResourceStream(string filename)
    {
#ifndef ANDROID
        std::error_code ec;
        if(!std::filesystem::is_regular_file(filename.c_str(), ec))
        {
            if(ec)
            {
                LOG(ERROR) << "OS error on file check : " << ec.message();
            }
            open_success = false;
        }
        else
            open_success = stream.open(filename);
#else
        //Android reads from the assets bundle, so we cannot check if the file exists and is a regular file
        open_success = stream.open(filename);
#endif
    }
    virtual ~FileResourceStream()
    {
    }

    bool isOpen()
    {
        return open_success;
    }

    virtual sf::Int64 read(void* data, sf::Int64 size)
    {
        return stream.read(data, size);
    }
    virtual sf::Int64 seek(sf::Int64 position)
    {
        return stream.seek(position);
    }
    virtual sf::Int64 tell()
    {
        return stream.tell();
    }
    virtual sf::Int64 getSize()
    {
        return stream.getSize();
    }
};

DirectoryResourceProvider::DirectoryResourceProvider(string basepath)
: basepath(basepath)
{
}

P<ResourceStream> DirectoryResourceProvider::getResourceStream(string filename)
{
    P<FileResourceStream> stream = new FileResourceStream(basepath + filename);
    if (stream->isOpen())
        return stream;
    return nullptr;
}

std::vector<string> DirectoryResourceProvider::findResources(string searchPattern)
{
    std::vector<string> found_files;
    findResources(found_files, "", searchPattern);
    return found_files;
}

void DirectoryResourceProvider::findResources(std::vector<string>& found_files, const string path, const string searchPattern)
{
#ifdef _MSC_VER
    WIN32_FIND_DATAA data;
    string search_root(basepath + path);
    if (!search_root.endswith("/"))
    {
        search_root += "/";
    }
    HANDLE handle = FindFirstFileA((search_root + "*").c_str(), &data);
    if (handle == INVALID_HANDLE_VALUE)
        return;
    do
    {
        if (data.cFileName[0] == '.')
            continue;
        string name = path + string(data.cFileName);
        if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            findResources(found_files, name + "/", searchPattern);
        }
        else
        {
            if (searchMatch(name, searchPattern))
                found_files.push_back(name);
        }
    } while (FindNextFileA(handle, &data));

    FindClose(handle);
#else
    DIR* dir = opendir((basepath + path).c_str());
    if (!dir)
        return;

    struct dirent *entry;
    while ((entry = readdir(dir)) != nullptr)
    {
        if (entry->d_name[0] == '.')
            continue;
        string name = path + string(entry->d_name);
        if (searchMatch(name, searchPattern))
            found_files.push_back(name);
        findResources(found_files, path + string(entry->d_name) + "/", searchPattern);
    }
    closedir(dir);
#endif
}

P<ResourceStream> getResourceStream(string filename)
{
    foreach(ResourceProvider, rp, resourceProviders)
    {
        P<ResourceStream> stream = rp->getResourceStream(filename);
        if (stream)
            return stream;
    }
    return NULL;
}

std::vector<string> findResources(string searchPattern)
{
    std::vector<string> foundFiles;
    foreach(ResourceProvider, rp, resourceProviders)
    {
        std::vector<string> res = rp->findResources(searchPattern);
        foundFiles.insert(foundFiles.end(), res.begin(), res.end());
    }
    return foundFiles;
}
<|endoftext|>


<commit_before>#pragma ident "$Id$"

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

//============================================================================
//
//This software developed by Applied Research Laboratories at the University of
//Texas at Austin, under contract to an agency or agencies within the U.S.
//Department of Defense. The U.S. Government retains all rights to use,
//duplicate, distribute, disclose, or release this software.
//
//Pursuant to DoD Directive 523024
//
// DISTRIBUTION STATEMENT A: This software has been approved for public
//                           release, distribution is unlimited.
//
//=============================================================================

#include <termios.h> /* POSIX terminal control definitions */

#include "StringUtils.hpp"
#include "FDStreamBuff.hpp"
#include "TCPStreamBuff.hpp"

#include "DeviceStream.hpp"

using namespace std;

namespace gpstk
{
   DeviceStream::DeviceStream(void)
      : fdbuff(NULL)
   {
      open("");
   };

   DeviceStream::DeviceStream(const string& target, ios::openmode mode)
      : fdbuff(NULL),
        target(target)
   {
      open(target, mode);
   };

   DeviceStream::~DeviceStream()
   {
      if (fdbuff)
         delete fdbuff;
   }

   void DeviceStream::open(const char* p, ios::openmode mode)
   {
      open(string(p), mode);
   }

   void DeviceStream::open(const string& target, ios::openmode mode)
   {
      this->target = target;
      if (target != "")
      {
         if (target.substr(0, 4) == "tcp:")
         {
            string ifn=target;
            int port = 25;
            ifn.erase(0,4);
            string::size_type i = ifn.find(":");
            if (i<ifn.size())
            {
               port = StringUtils::asInt(ifn.substr(i+1));
               ifn.erase(i);
            }

            TCPStreamBuff *tcpbuff = new TCPStreamBuff();

            SocketAddr client(ifn, port);
            if (tcpbuff->connect(client))
            {
               cout << "Could not connect to " << ifn << endl;
               exit(-1);
            }

            deviceType = dtTCP;
            fdbuff = tcpbuff;
            basic_ios<char>::rdbuf(fdbuff);
         }
         else if (target.substr(0, 4) == "ser:") // A serial port
         {
            string ifn=target;
            ifn.erase(0,4);
            int fd = ::open(ifn.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);

            if (fd<0)
               return;

            int rtn = fcntl(fd, F_SETFL, 0);

            struct termios options;

            options.c_iflag = 0x00 | IGNBRK;// | IGNPAR; // 0x1;
            options.c_lflag = 0x00;
            options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
            options.c_oflag = 0x00;
            options.c_cflag =  0x00 | CS8 | CSIZE | CREAD | HUPCL | CLOCAL; // 0x1cb2;
            cfsetispeed(&options, B115200);

            // Final step... apply them
            tcsetattr(fd, TCSANOW, &options);

            deviceType = dtSerial;
            fdbuff = new FDStreamBuff(fd);
            basic_ios<char>::rdbuf(fdbuff);
         }
         else // a regular file
         {
            fstream::open(target.c_str(), mode);
            deviceType = dtFile;
         }
      }
      else  // Use standard input/output
      {
         if (mode && ios::in)
         {
            copyfmt(cin);
            clear(cin.rdstate());
            basic_ios<char>::rdbuf(cin.rdbuf());
            this->target = "<stdin>";
         }
         else
         {
            copyfmt(cin);
            clear(cin.rdstate());
            basic_ios<char>::rdbuf(cin.rdbuf());
            this->target = "<stdout>";
         }
         deviceType = dtStdio;

      }
   }

}
<commit_msg>Hack fix for opening a file<commit_after>#pragma ident "$Id$"

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

//============================================================================
//
//This software developed by Applied Research Laboratories at the University of
//Texas at Austin, under contract to an agency or agencies within the U.S.
//Department of Defense. The U.S. Government retains all rights to use,
//duplicate, distribute, disclose, or release this software.
//
//Pursuant to DoD Directive 523024
//
// DISTRIBUTION STATEMENT A: This software has been approved for public
//                           release, distribution is unlimited.
//
//=============================================================================

#include <termios.h> /* POSIX terminal control definitions */

#include "StringUtils.hpp"
#include "FDStreamBuff.hpp"
#include "TCPStreamBuff.hpp"

#include "DeviceStream.hpp"

using namespace std;

namespace gpstk
{
   DeviceStream::DeviceStream(void)
      : fdbuff(NULL)
   {
      open("");
   };

   DeviceStream::DeviceStream(const string& target, ios::openmode mode)
      : fdbuff(NULL),
        target(target)
   {
      open(target, mode);
   };

   DeviceStream::~DeviceStream()
   {
      if (fdbuff)
         delete fdbuff;
   }

   void DeviceStream::open(const char* p, ios::openmode mode)
   {
      open(string(p), mode);
   }

   void DeviceStream::open(const string& target, ios::openmode mode)
   {
      this->target = target;
      if (target != "")
      {
         if (target.substr(0, 4) == "tcp:")
         {
            string ifn=target;
            int port = 25;
            ifn.erase(0,4);
            string::size_type i = ifn.find(":");
            if (i<ifn.size())
            {
               port = StringUtils::asInt(ifn.substr(i+1));
               ifn.erase(i);
            }

            TCPStreamBuff *tcpbuff = new TCPStreamBuff();

            SocketAddr client(ifn, port);
            if (tcpbuff->connect(client))
            {
               cerr << "Could not connect to " << ifn << endl;
               exit(-1);
            }

            deviceType = dtTCP;
            fdbuff = tcpbuff;
            basic_ios<char>::rdbuf(fdbuff);
         }
         else if (target.substr(0, 4) == "ser:") // A serial port
         {
            string ifn=target;
            ifn.erase(0,4);
            int fd = ::open(ifn.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);

            if (fd<0)
               return;

            int rtn = fcntl(fd, F_SETFL, 0);

            struct termios options;

            options.c_iflag = 0x00 | IGNBRK;// | IGNPAR; // 0x1;
            options.c_lflag = 0x00;
            options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
            options.c_oflag = 0x00;
            options.c_cflag =  0x00 | CS8 | CSIZE | CREAD | HUPCL | CLOCAL; // 0x1cb2;
            cfsetispeed(&options, B115200);

            // Final step... apply them
            tcsetattr(fd, TCSANOW, &options);

            deviceType = dtSerial;
            fdbuff = new FDStreamBuff(fd);
            basic_ios<char>::rdbuf(fdbuff);
         }
         else // a regular file
         {
            int fd = ::open(target.c_str(), mode);
            if (fd<0)
            {
               cerr << "Could not open: " << target.c_str() << endl;
               return;
            }
            fdbuff = new FDStreamBuff(fd);
            basic_ios<char>::rdbuf(fdbuff);

            deviceType = dtFile;
         }
      }
      else  // Use standard input/output
      {
         if (mode && ios::in)
         {
            copyfmt(cin);
            clear(cin.rdstate());
            basic_ios<char>::rdbuf(cin.rdbuf());
            this->target = "<stdin>";
         }
         else
         {
            copyfmt(cout);
            clear(cin.rdstate());
            basic_ios<char>::rdbuf(cout.rdbuf());
            this->target = "<stdout>";
         }
         deviceType = dtStdio;
      }
   }

}
<|endoftext|>


<commit_before>#include "scheduler.h"
#include "thread_state.h"
#include "util.h"
#include <future>
#include <thread>
#include <chrono>
#include <cassert>

using std::future;
using std::unique_lock;
using std::mutex;
using std::make_shared;

class LocalThreadScheduler : public Scheduler
{
public:
  LocalThreadScheduler(uint num_threads_ = 0);

  void add_task(shared_ptr<LocalTask> t) override;

  /* blocks until all current tasks are complete. */
  void complete_pending() override;

  ~LocalThreadScheduler();

private:
  class SchedulerTask
  {
  public:
    virtual bool run(uint worker)
    {
      return false;
    }
    SchedulerTask() { }
  };

  class LocalTaskWrapper : public SchedulerTask
  {
  public:
    LocalTaskWrapper(shared_ptr<LocalTask> task_) : task(task_) { }

    bool run(uint worker) override
    {
      task->run(worker);
      return true;
    }

  private:
    shared_ptr<LocalTask> task;
  };

  static void worker(LocalThreadScheduler& sched, int worker_id);

  void add_task(shared_ptr<SchedulerTask> t);

  void on_task_started(int worker_id, const shared_ptr<SchedulerTask>& task);
  void on_task_completed(int worker_id, const shared_ptr<SchedulerTask>& task);

  std::queue<shared_ptr<SchedulerTask>> task_queue;
  std::mutex queue_mutex;
  std::atomic<uint> pending_task_count;

  std::atomic<uint> num_threads_free;

  std::vector<std::thread> pool;
};

/**
 * The blocking scheduler is the baseline, stupid scheduler. It runs tasks as
 * soon as they are added, on the same thread.
 */
class BlockingScheduler : public Scheduler
{
public:
  BlockingScheduler()
  {
    register_thread();
  }

  void add_task(shared_ptr<LocalTask> t) override
  {
    t->run(0);
  }

  void complete_pending() override { }

  ~BlockingScheduler() { }
};

void LocalThreadScheduler::worker(LocalThreadScheduler& scheduler, int worker_id)
{
  bool keep_running = true;

  register_thread();

  while (keep_running)
  {
    uint task_count = scheduler.pending_task_count;
    if (task_count == 0)
    {
      std::this_thread::yield();
      continue;
    }

    if (std::atomic_compare_exchange_weak(&scheduler.pending_task_count, &task_count, task_count - 1))
    {
      std::unique_lock<std::mutex> lock(scheduler.queue_mutex);

      auto task = scheduler.task_queue.front();
      scheduler.task_queue.pop();
      lock.unlock();

      scheduler.on_task_started(worker_id, task);
      keep_running = task->run(worker_id);
      scheduler.on_task_completed(worker_id, task);
    }
  }
}

LocalThreadScheduler::LocalThreadScheduler(uint num_threads_) : pending_task_count(0)
{
  if (num_threads_ == 0)
    num_threads_ = num_system_procs();

  for (auto i = 0u; i < num_threads_; ++i)
    pool.emplace_back(LocalThreadScheduler::worker, std::ref(*this), i);

  num_threads_free = num_threads_;
}

void LocalThreadScheduler::add_task(shared_ptr<SchedulerTask> task)
{
  {
    unique_lock<std::mutex> lock(queue_mutex);
    task_queue.push(task);
  }
  ++pending_task_count;
}

void LocalThreadScheduler::add_task(shared_ptr<LocalTask> task)
{
  add_task(std::make_shared<LocalTaskWrapper>(task));
}

void LocalThreadScheduler::on_task_started(int worker_id, const shared_ptr<SchedulerTask>& task)
{
  --num_threads_free;
}

void LocalThreadScheduler::on_task_completed(int worker_id, const shared_ptr<SchedulerTask>& task)
{
  ++num_threads_free;
}

void LocalThreadScheduler::complete_pending()
{
  // wait for the queue to be empty
  while (true)
  {
    unique_lock<std::mutex> queue_lock(queue_mutex, std::try_to_lock);

    if (queue_lock && task_queue.empty())
      break;
  }

  // wait for all of the threads to be free
  while (num_threads_free != pool.size())
    std::this_thread::yield();
}

LocalThreadScheduler::~LocalThreadScheduler()
{
  for (auto& thread: pool)
    add_task(std::make_shared<SchedulerTask>());

  for (auto& thread: pool)
    thread.join();
}

////////////////////////////////////////////////////////////////////////////////

shared_ptr<Scheduler> make_scheduler(uint num_threads)
{
  assert(num_threads > 0);
  if (num_threads == 1)
  {
    return make_shared<BlockingScheduler>();
  }
  else
  {
    return make_shared<LocalThreadScheduler>(num_threads);
  }
}
<commit_msg>changes type of pending_task_count<commit_after>#include "scheduler.h"
#include "thread_state.h"
#include "util.h"
#include <future>
#include <thread>
#include <chrono>
#include <cassert>

using std::future;
using std::unique_lock;
using std::mutex;
using std::make_shared;

class LocalThreadScheduler : public Scheduler
{
public:
  LocalThreadScheduler(uint num_threads_ = 0);

  void add_task(shared_ptr<LocalTask> t) override;

  /* blocks until all current tasks are complete. */
  void complete_pending() override;

  ~LocalThreadScheduler();

private:
  class SchedulerTask
  {
  public:
    virtual bool run(uint worker)
    {
      return false;
    }
    SchedulerTask() { }
  };

  class LocalTaskWrapper : public SchedulerTask
  {
  public:
    LocalTaskWrapper(shared_ptr<LocalTask> task_) : task(task_) { }

    bool run(uint worker) override
    {
      task->run(worker);
      return true;
    }

  private:
    shared_ptr<LocalTask> task;
  };

  static void worker(LocalThreadScheduler& sched, int worker_id);

  void add_task(shared_ptr<SchedulerTask> t);

  void on_task_started(int worker_id, const shared_ptr<SchedulerTask>& task);
  void on_task_completed(int worker_id, const shared_ptr<SchedulerTask>& task);

  std::queue<shared_ptr<SchedulerTask>> task_queue;
  std::mutex queue_mutex;
  std::atomic<int> pending_task_count;

  std::atomic<uint> num_threads_free;

  std::vector<std::thread> pool;
};

/**
 * The blocking scheduler is the baseline, stupid scheduler. It runs tasks as
 * soon as they are added, on the same thread.
 */
class BlockingScheduler : public Scheduler
{
public:
  BlockingScheduler()
  {
    register_thread();
  }

  void add_task(shared_ptr<LocalTask> t) override
  {
    t->run(0);
  }

  void complete_pending() override { }

  ~BlockingScheduler() { }
};

void LocalThreadScheduler::worker(LocalThreadScheduler& scheduler, int worker_id)
{
  bool keep_running = true;

  register_thread();

  while (keep_running)
  {
    int task_count = scheduler.pending_task_count;
    if (task_count == 0)
    {
      std::this_thread::yield();
      continue;
    }

    if (std::atomic_compare_exchange_weak(&scheduler.pending_task_count, &task_count, task_count - 1))
    {
      std::unique_lock<std::mutex> lock(scheduler.queue_mutex);

      auto task = scheduler.task_queue.front();
      scheduler.task_queue.pop();
      lock.unlock();

      scheduler.on_task_started(worker_id, task);
      keep_running = task->run(worker_id);
      scheduler.on_task_completed(worker_id, task);
    }
  }
}

LocalThreadScheduler::LocalThreadScheduler(uint num_threads_) : pending_task_count(0)
{
  if (num_threads_ == 0)
    num_threads_ = num_system_procs();

  for (auto i = 0u; i < num_threads_; ++i)
    pool.emplace_back(LocalThreadScheduler::worker, std::ref(*this), i);

  num_threads_free = num_threads_;
}

void LocalThreadScheduler::add_task(shared_ptr<SchedulerTask> task)
{
  {
    unique_lock<std::mutex> lock(queue_mutex);
    task_queue.push(task);
  }
  ++pending_task_count;
}

void LocalThreadScheduler::add_task(shared_ptr<LocalTask> task)
{
  add_task(std::make_shared<LocalTaskWrapper>(task));
}

void LocalThreadScheduler::on_task_started(int worker_id, const shared_ptr<SchedulerTask>& task)
{
  --num_threads_free;
}

void LocalThreadScheduler::on_task_completed(int worker_id, const shared_ptr<SchedulerTask>& task)
{
  ++num_threads_free;
}

void LocalThreadScheduler::complete_pending()
{
  // wait for the queue to be empty
  while (true)
  {
    unique_lock<std::mutex> queue_lock(queue_mutex, std::try_to_lock);

    if (queue_lock && task_queue.empty())
      break;
  }

  // wait for all of the threads to be free
  while (num_threads_free != pool.size())
    std::this_thread::yield();
}

LocalThreadScheduler::~LocalThreadScheduler()
{
  for (auto& thread: pool)
    add_task(std::make_shared<SchedulerTask>());

  for (auto& thread: pool)
    thread.join();
}

////////////////////////////////////////////////////////////////////////////////

shared_ptr<Scheduler> make_scheduler(uint num_threads)
{
  assert(num_threads > 0);
  if (num_threads == 1)
  {
    return make_shared<BlockingScheduler>();
  }
  else
  {
    return make_shared<LocalThreadScheduler>(num_threads);
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2006, Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "sugar-browser.h"

#include <gtkmozembed_internal.h>
#include <nsCOMPtr.h>
#include <nsIPrefService.h>
#include <nsServiceManagerUtils.h>
#include <nsIWebBrowser.h>
#include <nsIWebBrowserFocus.h>
#include <nsIDOMWindow.h>

enum {
	PROP_0,
	PROP_PROGRESS,
	PROP_TITLE,
	PROP_ADDRESS,
	PROP_CAN_GO_BACK,
	PROP_CAN_GO_FORWARD,
	PROP_LOADING
};

void
sugar_browser_startup(void)
{
	nsCOMPtr<nsIPrefService> prefService;

	prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
	NS_ENSURE_TRUE(prefService, );

	nsCOMPtr<nsIPrefBranch> pref;
	prefService->GetBranch("", getter_AddRefs(pref));
	NS_ENSURE_TRUE(pref, );

	/* Block onload popups */
	pref->SetBoolPref("dom.disable_open_during_load", TRUE);

	/* Disable useless security warning */
	pref->SetBoolPref("security.warn_submit_insecure", FALSE);

	/* Style tweaks */
	pref->SetCharPref("ui.buttontext", "#000000");
	pref->SetCharPref("ui.buttonface", "#D3D3DD");
	pref->SetCharPref("ui.-moz-field", "#FFFFFF");
	pref->SetCharPref("ui.-moz-fieldtext", "#000000");
}

G_DEFINE_TYPE(SugarBrowser, sugar_browser, GTK_TYPE_MOZ_EMBED)

static void
sugar_browser_get_property(GObject         *object,
						   guint            prop_id,
						   GValue          *value,
						   GParamSpec      *pspec)
{
	SugarBrowser *browser = SUGAR_BROWSER(object);

	switch (prop_id) {
	    case PROP_PROGRESS:
			g_value_set_double(value, browser->progress);
		break;
	    case PROP_ADDRESS:
			g_value_set_string(value, browser->address);
		break;
	    case PROP_TITLE:
			g_value_set_string(value, browser->title);
		break;
	    case PROP_CAN_GO_BACK:
			g_value_set_boolean(value, browser->can_go_back);
		break;
	    case PROP_CAN_GO_FORWARD:
			g_value_set_boolean(value, browser->can_go_forward);
		break;
	    case PROP_LOADING:
			g_value_set_boolean(value, browser->loading);
		break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}

static void
sugar_browser_class_init(SugarBrowserClass *browser_class)
{
	GObjectClass *gobject_class = G_OBJECT_CLASS(browser_class);

	gobject_class->get_property = sugar_browser_get_property;

	g_object_class_install_property(gobject_class, PROP_PROGRESS,
                                    g_param_spec_double ("progress",
                                                         "Progress",
                                                         "Progress",
                                                         0.0, 1.0, 0.0,
                                                         G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_ADDRESS,
									 g_param_spec_string ("address",
														  "Address",
														  "Address",
                                                          "",
														  G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_TITLE,
									 g_param_spec_string ("title",
														  "Title",
														  "Title",
                                                          "",
														  G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_CAN_GO_BACK,
									 g_param_spec_boolean ("can-go-back",
														   "Can go back",
														   "Can go back",
														   FALSE,
														   G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_CAN_GO_FORWARD,
									 g_param_spec_boolean ("can-go-forward",
														   "Can go forward",
														   "Can go forward",
														   FALSE,
														   G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_LOADING,
									 g_param_spec_boolean ("loading",
														   "Loading",
														   "Loading",
														   FALSE,
														   G_PARAM_READABLE));
}

SugarBrowser *
sugar_browser_create_window(SugarBrowser *browser)
{
	return SUGAR_BROWSER_GET_CLASS(browser)->create_window(browser);
}

static void
update_navigation_properties(SugarBrowser *browser)
{
	GtkMozEmbed *embed = GTK_MOZ_EMBED(browser);
	gboolean can_go_back;
	gboolean can_go_forward;

	can_go_back = gtk_moz_embed_can_go_back(embed);
	if (can_go_back != browser->can_go_back) {
		browser->can_go_back = can_go_back;
		g_object_notify (G_OBJECT(browser), "can-go-back");
	}

	can_go_forward = gtk_moz_embed_can_go_forward(embed);
	if (can_go_forward != browser->can_go_forward) {
		browser->can_go_forward = can_go_forward;
		g_object_notify (G_OBJECT(browser), "can-go-forward");
	}
}

static void
new_window_cb(GtkMozEmbed  *embed,
			  GtkMozEmbed **newEmbed,
              guint         chromemask)
{
	SugarBrowser *browser;

	browser = sugar_browser_create_window(SUGAR_BROWSER(embed));

	*newEmbed = GTK_MOZ_EMBED(browser);
}

static void
sugar_browser_set_progress(SugarBrowser *browser, float progress)
{
	g_return_if_fail(SUGAR_IS_BROWSER(browser));

	browser->progress = progress;
	g_object_notify (G_OBJECT(browser), "progress");
}

static void
sugar_browser_set_loading(SugarBrowser *browser, gboolean loading)
{
	g_return_if_fail(SUGAR_IS_BROWSER(browser));

	browser->loading = loading;
	g_object_notify (G_OBJECT(browser), "loading");
}

static void
net_state_cb(GtkMozEmbed *embed, const char *aURI, gint state, guint status)
{
	SugarBrowser *browser = SUGAR_BROWSER(embed);

	if (state & GTK_MOZ_EMBED_FLAG_IS_NETWORK) {
		if (state & GTK_MOZ_EMBED_FLAG_START) {
			browser->total_requests = 0;
			browser->current_requests = 0;

			sugar_browser_set_progress(browser, 0.0);
			sugar_browser_set_loading(browser, TRUE);
		} else if (state & GTK_MOZ_EMBED_FLAG_STOP) {
			sugar_browser_set_loading(browser, FALSE);
		}
	}

	if (state & GTK_MOZ_EMBED_FLAG_IS_REQUEST) {
		float progress;

		if (state & GTK_MOZ_EMBED_FLAG_START) {
			browser->total_requests++;
		}
		else if (state & GTK_MOZ_EMBED_FLAG_STOP)
		{
			browser->current_requests++;
		}

		progress = float(browser->current_requests) /
				   float(browser->total_requests);
		if (progress > browser->progress) {
			sugar_browser_set_progress(browser, progress);
		}
	}
}

static void
title_cb(GtkMozEmbed *embed)
{
	SugarBrowser *browser = SUGAR_BROWSER(embed);

	g_free(browser->title);
	browser->title = gtk_moz_embed_get_title(embed);

	g_object_notify (G_OBJECT(browser), "title");
}

static void
location_cb(GtkMozEmbed *embed)
{
	SugarBrowser *browser = SUGAR_BROWSER(embed);

	g_free(browser->address);
	browser->address = gtk_moz_embed_get_location(embed);

	g_object_notify (G_OBJECT(browser), "address");

	update_navigation_properties(browser);
}

static void
sugar_browser_init(SugarBrowser *browser)
{
	browser->title = NULL;
	browser->address = NULL;
	browser->progress = 0.0;

	g_signal_connect(G_OBJECT(browser), "new-window",
					 G_CALLBACK(new_window_cb), NULL);
	g_signal_connect(G_OBJECT(browser), "net-state-all",
					 G_CALLBACK(net_state_cb), NULL);
	g_signal_connect(G_OBJECT(browser), "title",
					 G_CALLBACK(title_cb), NULL);
	g_signal_connect(G_OBJECT(browser), "location",
					 G_CALLBACK(location_cb), NULL);
}

void
sugar_browser_scroll_pixels(SugarBrowser *browser,
                            int           dx,
                            int           dy)
{
	nsCOMPtr<nsIWebBrowser> webBrowser;
	gtk_moz_embed_get_nsIWebBrowser (GTK_MOZ_EMBED(browser),
									 getter_AddRefs(webBrowser));
	NS_ENSURE_TRUE (webBrowser, );

	nsCOMPtr<nsIWebBrowserFocus> webBrowserFocus;
	webBrowserFocus = do_QueryInterface (webBrowser);
	NS_ENSURE_TRUE (webBrowserFocus, );

	nsCOMPtr<nsIDOMWindow> DOMWindow;
	webBrowserFocus->GetFocusedWindow (getter_AddRefs(DOMWindow));
	if (!DOMWindow) {
		webBrowser->GetContentDOMWindow (getter_AddRefs (DOMWindow));
	}
	NS_ENSURE_TRUE (DOMWindow, );

	DOMWindow->ScrollBy (dx, dy);
}
<commit_msg>Show a minimum amount of progress even when request count would be 0.<commit_after>/*
 * Copyright (C) 2006, Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "sugar-browser.h"

#include <gtkmozembed_internal.h>
#include <nsCOMPtr.h>
#include <nsIPrefService.h>
#include <nsServiceManagerUtils.h>
#include <nsIWebBrowser.h>
#include <nsIWebBrowserFocus.h>
#include <nsIDOMWindow.h>

enum {
	PROP_0,
	PROP_PROGRESS,
	PROP_TITLE,
	PROP_ADDRESS,
	PROP_CAN_GO_BACK,
	PROP_CAN_GO_FORWARD,
	PROP_LOADING
};

void
sugar_browser_startup(void)
{
	nsCOMPtr<nsIPrefService> prefService;

	prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
	NS_ENSURE_TRUE(prefService, );

	nsCOMPtr<nsIPrefBranch> pref;
	prefService->GetBranch("", getter_AddRefs(pref));
	NS_ENSURE_TRUE(pref, );

	/* Block onload popups */
	pref->SetBoolPref("dom.disable_open_during_load", TRUE);

	/* Disable useless security warning */
	pref->SetBoolPref("security.warn_submit_insecure", FALSE);

	/* Style tweaks */
	pref->SetCharPref("ui.buttontext", "#000000");
	pref->SetCharPref("ui.buttonface", "#D3D3DD");
	pref->SetCharPref("ui.-moz-field", "#FFFFFF");
	pref->SetCharPref("ui.-moz-fieldtext", "#000000");
}

G_DEFINE_TYPE(SugarBrowser, sugar_browser, GTK_TYPE_MOZ_EMBED)

static void
sugar_browser_get_property(GObject         *object,
						   guint            prop_id,
						   GValue          *value,
						   GParamSpec      *pspec)
{
	SugarBrowser *browser = SUGAR_BROWSER(object);

	switch (prop_id) {
	    case PROP_PROGRESS:
			g_value_set_double(value, browser->progress);
		break;
	    case PROP_ADDRESS:
			g_value_set_string(value, browser->address);
		break;
	    case PROP_TITLE:
			g_value_set_string(value, browser->title);
		break;
	    case PROP_CAN_GO_BACK:
			g_value_set_boolean(value, browser->can_go_back);
		break;
	    case PROP_CAN_GO_FORWARD:
			g_value_set_boolean(value, browser->can_go_forward);
		break;
	    case PROP_LOADING:
			g_value_set_boolean(value, browser->loading);
		break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}

static void
sugar_browser_class_init(SugarBrowserClass *browser_class)
{
	GObjectClass *gobject_class = G_OBJECT_CLASS(browser_class);

	gobject_class->get_property = sugar_browser_get_property;

	g_object_class_install_property(gobject_class, PROP_PROGRESS,
                                    g_param_spec_double ("progress",
                                                         "Progress",
                                                         "Progress",
                                                         0.0, 1.0, 0.0,
                                                         G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_ADDRESS,
									 g_param_spec_string ("address",
														  "Address",
														  "Address",
                                                          "",
														  G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_TITLE,
									 g_param_spec_string ("title",
														  "Title",
														  "Title",
                                                          "",
														  G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_CAN_GO_BACK,
									 g_param_spec_boolean ("can-go-back",
														   "Can go back",
														   "Can go back",
														   FALSE,
														   G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_CAN_GO_FORWARD,
									 g_param_spec_boolean ("can-go-forward",
														   "Can go forward",
														   "Can go forward",
														   FALSE,
														   G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_LOADING,
									 g_param_spec_boolean ("loading",
														   "Loading",
														   "Loading",
														   FALSE,
														   G_PARAM_READABLE));
}

SugarBrowser *
sugar_browser_create_window(SugarBrowser *browser)
{
	return SUGAR_BROWSER_GET_CLASS(browser)->create_window(browser);
}

static void
update_navigation_properties(SugarBrowser *browser)
{
	GtkMozEmbed *embed = GTK_MOZ_EMBED(browser);
	gboolean can_go_back;
	gboolean can_go_forward;

	can_go_back = gtk_moz_embed_can_go_back(embed);
	if (can_go_back != browser->can_go_back) {
		browser->can_go_back = can_go_back;
		g_object_notify (G_OBJECT(browser), "can-go-back");
	}

	can_go_forward = gtk_moz_embed_can_go_forward(embed);
	if (can_go_forward != browser->can_go_forward) {
		browser->can_go_forward = can_go_forward;
		g_object_notify (G_OBJECT(browser), "can-go-forward");
	}
}

static void
new_window_cb(GtkMozEmbed  *embed,
			  GtkMozEmbed **newEmbed,
              guint         chromemask)
{
	SugarBrowser *browser;

	browser = sugar_browser_create_window(SUGAR_BROWSER(embed));

	*newEmbed = GTK_MOZ_EMBED(browser);
}

static void
sugar_browser_set_progress(SugarBrowser *browser, float progress)
{
	g_return_if_fail(SUGAR_IS_BROWSER(browser));

	browser->progress = progress;
	g_object_notify (G_OBJECT(browser), "progress");
}

static void
sugar_browser_set_loading(SugarBrowser *browser, gboolean loading)
{
	g_return_if_fail(SUGAR_IS_BROWSER(browser));

	browser->loading = loading;
	g_object_notify (G_OBJECT(browser), "loading");
}

static void
net_state_cb(GtkMozEmbed *embed, const char *aURI, gint state, guint status)
{
	SugarBrowser *browser = SUGAR_BROWSER(embed);

	if (state & GTK_MOZ_EMBED_FLAG_IS_NETWORK) {
		if (state & GTK_MOZ_EMBED_FLAG_START) {
			browser->total_requests = 0;
			browser->current_requests = 0;

			sugar_browser_set_progress(browser, 0.03);
			sugar_browser_set_loading(browser, TRUE);
		} else if (state & GTK_MOZ_EMBED_FLAG_STOP) {
			sugar_browser_set_progress(browser, 100.0);
			sugar_browser_set_loading(browser, FALSE);
		}
	}

	if (state & GTK_MOZ_EMBED_FLAG_IS_REQUEST) {
		float progress;

		if (state & GTK_MOZ_EMBED_FLAG_START) {
			browser->total_requests++;
		}
		else if (state & GTK_MOZ_EMBED_FLAG_STOP)
		{
			browser->current_requests++;
		}

		progress = float(browser->current_requests) /
				   float(browser->total_requests);
		if (progress > browser->progress) {
			sugar_browser_set_progress(browser, progress);
		}
	}
}

static void
title_cb(GtkMozEmbed *embed)
{
	SugarBrowser *browser = SUGAR_BROWSER(embed);

	g_free(browser->title);
	browser->title = gtk_moz_embed_get_title(embed);

	g_object_notify (G_OBJECT(browser), "title");
}

static void
location_cb(GtkMozEmbed *embed)
{
	SugarBrowser *browser = SUGAR_BROWSER(embed);

	g_free(browser->address);
	browser->address = gtk_moz_embed_get_location(embed);

	g_object_notify (G_OBJECT(browser), "address");

	update_navigation_properties(browser);
}

static void
sugar_browser_init(SugarBrowser *browser)
{
	browser->title = NULL;
	browser->address = NULL;
	browser->progress = 0.0;

	g_signal_connect(G_OBJECT(browser), "new-window",
					 G_CALLBACK(new_window_cb), NULL);
	g_signal_connect(G_OBJECT(browser), "net-state-all",
					 G_CALLBACK(net_state_cb), NULL);
	g_signal_connect(G_OBJECT(browser), "title",
					 G_CALLBACK(title_cb), NULL);
	g_signal_connect(G_OBJECT(browser), "location",
					 G_CALLBACK(location_cb), NULL);
}

void
sugar_browser_scroll_pixels(SugarBrowser *browser,
                            int           dx,
                            int           dy)
{
	nsCOMPtr<nsIWebBrowser> webBrowser;
	gtk_moz_embed_get_nsIWebBrowser (GTK_MOZ_EMBED(browser),
									 getter_AddRefs(webBrowser));
	NS_ENSURE_TRUE (webBrowser, );

	nsCOMPtr<nsIWebBrowserFocus> webBrowserFocus;
	webBrowserFocus = do_QueryInterface (webBrowser);
	NS_ENSURE_TRUE (webBrowserFocus, );

	nsCOMPtr<nsIDOMWindow> DOMWindow;
	webBrowserFocus->GetFocusedWindow (getter_AddRefs(DOMWindow));
	if (!DOMWindow) {
		webBrowser->GetContentDOMWindow (getter_AddRefs (DOMWindow));
	}
	NS_ENSURE_TRUE (DOMWindow, );

	DOMWindow->ScrollBy (dx, dy);
}
<|endoftext|>


<commit_before>/*
    Kopete Utils.
    Copyright (c) 2005 Duncan Mac-Vicar Prett <duncan@kde.org>

      isHostReachable function code derived from KDE's HTTP kioslave
        Copyright (c) 2005 Waldo Bastian <bastian@kde.org>

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#include <qmap.h>

#include <kmessagebox.h>
#include <knotifyclient.h>

#include <kapplication.h>
#include <klocale.h>
#include <dcopclient.h>
#include <kdatastream.h>
#include <kdebug.h>
#include <kiconloader.h>

#include "kopeteaccount.h"
#include "knotification.h"
#include "kopeteutils_private.h"
#include "kopeteutils.h"
#include "kopeteuiglobal.h"

static const QString notifyConnectionLost_DefaultMessage = i18n("You have been disconnected.");
static const QString notifyConnectionLost_DefaultCaption = i18n("Connection Lost.");
static const QString notifyConnectionLost_DefaultExplanation = i18n("Kopete lost the channel used to talk to the instant messaging system.\nThis can be either your internet access went down, , the service is experimenting problems, or the service disconnected you because you tried to connect with the same account from another location. Try connecting again later.");

static const QString notifyCannotConnect_DefaultMessage = i18n("Can't connect with the instant messaging server or peers.");
static const QString notifyCannotConnect_DefaultCaption = i18n("Can't connect.");
static const QString notifyCannotConnect_DefaultExplanation = i18n("This means Kopete can't reach the instant messaging server or peers.\nThis can be either your internet access is down or the server is experimenting problems. Try connecting again later.");

namespace Kopete
{
namespace Utils
{

void notify( QPixmap pic, const QString &eventid, const QString &caption, const QString &message, const QString explanation, const QString debugInfo)
{
		QString action;
		if ( !explanation.isEmpty() )
			action = i18n( "More Information..." );
		kdDebug( 14010 ) << k_funcinfo <<  endl;
		KNotification *n = KNotification::event( eventid, message, pic , 0L , action );
		ErrorNotificationInfo info;
		info.explanation = explanation;
		info.debugInfo = debugInfo;

		NotifyHelper::self()->registerNotification(n, info);
		QObject::connect( n, SIGNAL(activated(unsigned int )) , NotifyHelper::self() , SLOT( slotEventActivated(unsigned int) ) );
		QObject::connect( n, SIGNAL(closed()) , NotifyHelper::self() , SLOT( slotEventClosed() ) );
}

void notifyConnectionLost( const Account *account, const QString caption, const QString message, const QString explanation, const QString debugInfo)
{
	if (!account)
		return;

	notify( account->accountIcon(32), QString::fromLatin1("connection_lost"), caption.isEmpty() ? notifyConnectionLost_DefaultCaption : caption, message.isEmpty() ? notifyConnectionLost_DefaultMessage : message, explanation.isEmpty() ? notifyConnectionLost_DefaultExplanation : explanation, debugInfo);
}

bool isHostReachable(const QString &host)
{
	const int NetWorkStatusUnknown = 1;
	const int NetWorkStatusOnline = 8;
	QCString replyType;
	QByteArray params;
	QByteArray reply;

	QDataStream stream(params, IO_WriteOnly);
	stream << host;

	if ( KApplication::kApplication()->dcopClient()->call( "kded", "networkstatus", "status(QString)", params, replyType, reply ) && (replyType == "int") )
	{
		int result;
		QDataStream stream2( reply, IO_ReadOnly );
		stream2 >> result;
		return (result != NetWorkStatusUnknown) && (result != NetWorkStatusOnline);
	}
	return false; // On error, assume we are online
}

void notifyCannotConnect( const Account *account, const QString explanation, const QString debugInfo)
{
	if (!account)
		return;

	notify( account->accountIcon(), QString::fromLatin1("cannot_connect"), notifyCannotConnect_DefaultCaption, notifyCannotConnect_DefaultMessage, notifyCannotConnect_DefaultExplanation, debugInfo);
}

} // end ns ErrorNotifier
} // end ns Kopete

#include "kopeteutils.moc"
<commit_msg><commit_after>/*
    Kopete Utils.
    Copyright (c) 2005 Duncan Mac-Vicar Prett <duncan@kde.org>

      isHostReachable function code derived from KDE's HTTP kioslave
        Copyright (c) 2005 Waldo Bastian <bastian@kde.org>

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#include <qmap.h>

#include <kmessagebox.h>
#include <knotifyclient.h>

#include <kapplication.h>
#include <klocale.h>
#include <dcopclient.h>
#include <kdatastream.h>
#include <kdebug.h>
#include <kiconloader.h>

#include "kopeteaccount.h"
#include "knotification.h"
#include "kopeteutils_private.h"
#include "kopeteutils.h"
#include "kopeteuiglobal.h"

static const QString notifyConnectionLost_DefaultMessage = i18n("You have been disconnected.");
static const QString notifyConnectionLost_DefaultCaption = i18n("Connection Lost.");
static const QString notifyConnectionLost_DefaultExplanation = i18n("Kopete lost the channel used to talk to the instant messaging system.\nThis can be either your internet access went down, , the service is experimenting problems, or the service disconnected you because you tried to connect with the same account from another location. Try connecting again later.");

static const QString notifyCannotConnect_DefaultMessage = i18n("Can't connect with the instant messaging server or peers.");
static const QString notifyCannotConnect_DefaultCaption = i18n("Can't connect.");
static const QString notifyCannotConnect_DefaultExplanation = i18n("This means Kopete can't reach the instant messaging server or peers.\nThis can be either your internet access is down or the server is experimenting problems. Try connecting again later.");

namespace Kopete
{
namespace Utils
{

void notify( QPixmap pic, const QString &eventid, const QString &caption, const QString &message, const QString explanation, const QString debugInfo)
{
		QString action;
		if ( !explanation.isEmpty() )
			action = i18n( "More Information..." );
		kdDebug( 14010 ) << k_funcinfo <<  endl;
		KNotification *n = KNotification::event( eventid, message, pic , 0L , action );
		ErrorNotificationInfo info;
		info.explanation = explanation;
		info.debugInfo = debugInfo;

		NotifyHelper::self()->registerNotification(n, info);
		QObject::connect( n, SIGNAL(activated(unsigned int )) , NotifyHelper::self() , SLOT( slotEventActivated(unsigned int) ) );
		QObject::connect( n, SIGNAL(closed()) , NotifyHelper::self() , SLOT( slotEventClosed() ) );
}

void notifyConnectionLost( const Account *account, const QString caption, const QString message, const QString explanation, const QString debugInfo)
{
	if (!account)
		return;

	notify( account->accountIcon(32), QString::fromLatin1("connection_lost"), caption.isEmpty() ? notifyConnectionLost_DefaultCaption : caption, message.isEmpty() ? notifyConnectionLost_DefaultMessage : message, explanation.isEmpty() ? notifyConnectionLost_DefaultExplanation : explanation, debugInfo);
}

bool isHostReachable(const QString &host)
{
	const int NetWorkStatusUnknown = 1;
	const int NetWorkStatusOnline = 8;
	QCString replyType;
	QByteArray params;
	QByteArray reply;

	QDataStream stream(params, IO_WriteOnly);
	stream << host;

	if ( KApplication::kApplication()->dcopClient()->call( "kded", "networkstatus", "status(QString)", params, replyType, reply ) && (replyType == "int") )
	{
		int result;
		QDataStream stream2( reply, IO_ReadOnly );
		stream2 >> result;
		return (result != NetWorkStatusUnknown) && (result != NetWorkStatusOnline);
	}
	return false; // On error, assume we are online
}

void notifyCannotConnect( const Account *account, const QString explanation, const QString debugInfo)
{
	if (!account)
		return;

	notify( account->accountIcon(), QString::fromLatin1("cannot_connect"), notifyCannotConnect_DefaultCaption, notifyCannotConnect_DefaultMessage, notifyCannotConnect_DefaultExplanation, debugInfo);
}

} // end ns ErrorNotifier
} // end ns Kopete

<|endoftext|>


<commit_before>#include "Arduino.h"
#include "Motor.h"

  /************************************************
  *       Implementacao da interface Motor.hpp    *
  *************************************************/

  /********************************************
  * Metodo construtor do objeto Motor         *
  * Ja e inicializado com os devidos valores  *
  * de configuracao.                          *
  *********************************************/
Motor::Motor(int mA, int mB, int mPWM, int vel)
: INA(mA), INB(mB), PWM(mPWM), velocidade(vel){

}

int   Motor::getINA(){return INA;}
int   Motor::getINB(){return INB;}
int   Motor::getPWM(){return PWM;}
int   Motor::getVelocidade(){return velocidade;}
void  Motor::config() {
  pinMode(getINA() ,OUTPUT);
  pinMode(getINB() ,OUTPUT);
  pinMode(getPWM() ,OUTPUT);
  analogWrite(getPWM(), getVelocidade());
}
<commit_msg>Update Motor.cpp<commit_after>#include "Arduino.h"
#include "Motor.h"

  /************************************************
  *       Implementacao da interface Motor.h    *
  *************************************************/

  /********************************************
  * Metodo construtor do objeto Motor         *
  * Ja e inicializado com os devidos valores  *
  * de configuracao.                          *
  *********************************************/
Motor::Motor(int mA, int mB, int mPWM, int vel)
: INA(mA), INB(mB), PWM(mPWM), velocidade(vel){

}

int   Motor::getINA(){return INA;}
int   Motor::getINB(){return INB;}
int   Motor::getPWM(){return PWM;}
int   Motor::getVelocidade(){return velocidade;}
void  Motor::config() {
  pinMode(getINA() ,OUTPUT);
  pinMode(getINB() ,OUTPUT);
  pinMode(getPWM() ,OUTPUT);
  analogWrite(getPWM(), getVelocidade());
}
<|endoftext|>