예제 #1
0
bool task_push_decompress(
      const char *source_file,
      const char *target_dir,
      const char *target_file,
      const char *subdir,
      const char *valid_ext,
      retro_task_callback_t cb,
      void *user_data)
{
   char tmp[PATH_MAX_LENGTH]  = {0};
   decompress_state_t *s      = NULL;
   retro_task_t *t            = NULL;

   if (string_is_empty(target_dir) || string_is_empty(source_file))
   {
      RARCH_WARN("[decompress] Empty or null source file or"
            " target directory arguments.\n");
      return false;
   }

   /* ZIP or APK only */
   if (!path_file_exists(source_file) || 
         msg_hash_to_file_type(msg_hash_calculate(path_get_extension(source_file))) 
         != FILE_TYPE_COMPRESSED)
   {
      RARCH_WARN("[decompress] File '%s' does not exist or is not a compressed file.\n",
            source_file);
      return false;
   }

   if (!valid_ext || !valid_ext[0])
      valid_ext   = NULL;

   if (task_check_decompress(source_file))
   {
      RARCH_LOG("[decompress] File '%s' already being decompressed.\n",
            source_file);
      return false;
   }

   RARCH_LOG("[decompress] File '%s.\n", source_file);

   s              = (decompress_state_t*)calloc(1, sizeof(*s));

   if (!s)
      goto error;

   s->source_file = strdup(source_file);
   s->target_dir  = strdup(target_dir);

   s->valid_ext   = valid_ext ? strdup(valid_ext) : NULL;
   s->zlib.type   = ZLIB_TRANSFER_INIT;

   t              = (retro_task_t*)calloc(1, sizeof(*t));

   if (!t)
      goto error;

   t->state       = s;
   t->handler     = task_decompress_handler;

   if (!string_is_empty(subdir))
   {
      s->subdir        = strdup(subdir);
      t->handler       = task_decompress_handler_subdir;
   }
   else if (!string_is_empty(target_file))
   {
      s->target_file   = strdup(target_file);
      t->handler       = task_decompress_handler_target_file;
   }

   t->callback    = cb;
   t->user_data   = user_data;

   snprintf(tmp, sizeof(tmp), "%s '%s'",
         msg_hash_to_str(MSG_EXTRACTING), path_basename(source_file));

   t->title       = strdup(tmp);

   task_queue_ctl(TASK_QUEUE_CTL_PUSH, t);

   return true;

error:
   if (s)
      free(s);
   return false;
}
예제 #2
0
void task_file_load_handler(retro_task_t *task)
{
   nbio_handle_t         *nbio  = (nbio_handle_t*)task->state;

   if (nbio)
   {
      switch (nbio->status)
      {
         case NBIO_STATUS_INIT:
            if (nbio && !string_is_empty(nbio->path))
            {
               struct nbio_t *handle = (struct nbio_t*)nbio_open(nbio->path, NBIO_READ);

               if (handle)
               {
                  nbio->handle       = handle;
                  nbio->status       = NBIO_STATUS_TRANSFER;

                  nbio_begin_read(handle);
                  return;
               }
               else
                  task_set_cancelled(task, true);
            }
            break;
         case NBIO_STATUS_TRANSFER_PARSE:
            if (!nbio || task_file_transfer_iterate_parse(nbio) == -1)
               task_set_cancelled(task, true);
            nbio->status = NBIO_STATUS_TRANSFER_FINISHED;
            break;
         case NBIO_STATUS_TRANSFER:
            if (!nbio || task_file_transfer_iterate_transfer(nbio) == -1)
               nbio->status = NBIO_STATUS_TRANSFER_PARSE;
            break;
         case NBIO_STATUS_TRANSFER_FINISHED:
            break;
      }

      switch (nbio->type)
      {
         case NBIO_TYPE_PNG:
         case NBIO_TYPE_JPEG:
         case NBIO_TYPE_TGA:
         case NBIO_TYPE_BMP:
            if (!task_image_load_handler(task))
               task_set_finished(task, true);
            break;
         case NBIO_TYPE_MP3:
         case NBIO_TYPE_FLAC:
         case NBIO_TYPE_OGG:
         case NBIO_TYPE_MOD:
         case NBIO_TYPE_WAV:
            if (!task_audio_mixer_load_handler(task))
               task_set_finished(task, true);
            break;
         case NBIO_TYPE_NONE:
         default:
            if (nbio->is_finished)
               task_set_finished(task, true);
            break;
      }
   }

   if (task_get_cancelled(task))
   {
      task_set_error(task, strdup("Task canceled."));
      task_set_finished(task, true);
   }
}
예제 #3
0
파일: chat.c 프로젝트: pineapplewank/toxic
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    ChatContext *ctx = (ChatContext *) self->x;
    StatusBar *statusbar = (StatusBar *) self->s;

    struct tm *timeinfo = get_time();

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    /* Add printable chars to buffer and print on input space */
#if HAVE_WIDECHAR
    if (iswprint(key)) {
#else
    if (isprint(key)) {
#endif
        if (ctx->pos < (MAX_STR_SIZE-1)) {
            mvwaddstr(self->window, y, x, wc_to_char(key));
            ctx->line[ctx->pos++] = key;
            ctx->line[ctx->pos] = L'\0';
        }
    }

    /* BACKSPACE key: Remove one character from line */
    else if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            ctx->line[--ctx->pos] = L'\0';

            if (x == 0)
                mvwdelch(self->window, y - 1, x2 - 1);
            else
                mvwdelch(self->window, y, x - 1);
        }
    }

    /* RETURN key: Execute command or print line */
    else if (key == '\n') {
        uint8_t *line = wcs_to_char(ctx->line);
        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        wclrtobot(self->window);
        bool close_win = false;

        if (line[0] == '/') {
            if (close_win = !strncmp(line, "/close", strlen("/close"))) {
                int f_num = self->friendnum;
                delwin(ctx->linewin);
                delwin(statusbar->topline);
                del_window(self);
                disable_chatwin(f_num);
            } else
                execute(self, ctx, statusbar, m, line);
        } else {
            /* make sure the string has at least non-space character */
            if (!string_is_empty(line)) {
                uint8_t selfname[TOX_MAX_NAME_LENGTH];
                tox_getselfname(m, selfname, TOX_MAX_NAME_LENGTH);

                wattron(ctx->history, COLOR_PAIR(CYAN));
                wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
                wattroff(ctx->history, COLOR_PAIR(CYAN));
                wattron(ctx->history, COLOR_PAIR(GREEN));
                wprintw(ctx->history, "%s: ", selfname);
                wattroff(ctx->history, COLOR_PAIR(GREEN));
                wprintw(ctx->history, "%s\n", line);

                if (!statusbar->is_online
                        || tox_sendmessage(m, self->friendnum, line, strlen(line) + 1) == 0) {
                    wattron(ctx->history, COLOR_PAIR(RED));
                    wprintw(ctx->history, " * Failed to send message.\n");
                    wattroff(ctx->history, COLOR_PAIR(RED));
                }
            }
        }

        if (close_win) {
            free(ctx);
            free(statusbar);
        } else {
            ctx->line[0] = L'\0';
            ctx->pos = 0;
        }

        free(line);
    }
}

static void chat_onDraw(ToxWindow *self, Tox *m)
{
    curs_set(1);

    int x, y;
    getmaxyx(self->window, y, x);

    ChatContext *ctx = (ChatContext *) self->x;

    /* Draw status bar */
    StatusBar *statusbar = (StatusBar *) self->s;
    mvwhline(statusbar->topline, 1, 0, '-', x);
    wmove(statusbar->topline, 0, 0);

    /* Draw name, status and note in statusbar */
    if (statusbar->is_online) {
        char *status_text = "Unknown";
        int colour = WHITE;

        TOX_USERSTATUS status = statusbar->status;

        switch(status) {
        case TOX_USERSTATUS_NONE:
            status_text = "Online";
            colour = GREEN;
            break;
        case TOX_USERSTATUS_AWAY:
            status_text = "Away";
            colour = YELLOW;
            break;
        case TOX_USERSTATUS_BUSY:
            status_text = "Busy";
            colour = RED;
            break;
        }

        wattron(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, " %s ", self->name);
        wattroff(statusbar->topline, A_BOLD);
        wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
        wprintw(statusbar->topline, "[%s]", status_text);
        wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);

    } else {
        wattron(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, " %s ", self->name);
        wattroff(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, "[Offline]");
    }

    /* Truncate note if it doesn't fit in statusbar */
    uint16_t maxlen = x - getcurx(statusbar->topline) - 5;
    if (statusbar->statusmsg_len > maxlen) {
        statusbar->statusmsg[maxlen] = '\0';
        statusbar->statusmsg_len = maxlen;
    }

    wattron(statusbar->topline, A_BOLD);
    wprintw(statusbar->topline, " | %s |", statusbar->statusmsg);
    wattroff(statusbar->topline, A_BOLD);

    wprintw(statusbar->topline, "\n");

    mvwhline(ctx->linewin, 0, 0, '_', x);
    wrefresh(self->window);
}
예제 #4
0
파일: chat.c 프로젝트: 1100110/toxic
static void chat_onKey(ToxWindow *self, Messenger *m, wint_t key)
{
    ChatContext *ctx = (ChatContext *) self->x;
    struct tm *timeinfo = get_time();

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    /* Add printable chars to buffer and print on input space */
#if HAVE_WIDECHAR
    if (iswprint(key)) {
#else
    if (isprint(key)) {
#endif
        if (ctx->pos != sizeof(ctx->line) - 1) {
            mvwaddstr(self->window, y, x, wc_to_char(key));
            ctx->line[ctx->pos++] = key;
            ctx->line[ctx->pos] = L'\0';
        }
    }

    /* BACKSPACE key: Remove one character from line */
    else if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            ctx->line[--ctx->pos] = L'\0';

            if (x == 0)
                mvwdelch(self->window, y - 1, x2 - 1);
            else
                mvwdelch(self->window, y, x - 1);
        }
    }

    /* RETURN key: Execute command or print line */
    else if (key == '\n') {
        char *line = wcs_to_char(ctx->line);
        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        wclrtobot(self->window);

        if (line[0] == '/')
            execute(self, ctx, m, line);
        else {
            /* make sure the string has at least non-space character */
            if (!string_is_empty(line)) {
                uint8_t selfname[MAX_NAME_LENGTH];
                getself_name(m, selfname, sizeof(selfname));

                wattron(ctx->history, COLOR_PAIR(2));
                wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
                wattroff(ctx->history, COLOR_PAIR(2));
                wattron(ctx->history, COLOR_PAIR(1));
                wprintw(ctx->history, "%s: ", selfname);
                wattroff(ctx->history, COLOR_PAIR(1));
                wprintw(ctx->history, "%s\n", line);

                if (m_sendmessage(m, ctx->friendnum, (uint8_t *) line, strlen(line) + 1) == 0) {
                    wattron(ctx->history, COLOR_PAIR(3));
                    wprintw(ctx->history, " * Failed to send message.\n");
                    wattroff(ctx->history, COLOR_PAIR(3));
                }
            }
        }

        ctx->line[0] = L'\0';
        ctx->pos = 0;
        free(line);
    }
}

void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd)
{
    if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
        wclear(self->window);
        wclear(ctx->history);
        int x, y;
        getmaxyx(self->window, y, x);
        (void) x;
        wmove(self->window, y - CURS_Y_OFFSET, 0);
    }

    else if (!strcmp(cmd, "/help") || !strcmp(cmd, "/h"))
        print_help(ctx);

    else if (!strcmp(cmd, "/quit") || !strcmp(cmd, "/exit") || !strcmp(cmd, "/q")) {
        endwin();
        exit(0);
    }

    else if (!strncmp(cmd, "/me ", strlen("/me "))) {
        struct tm *timeinfo = get_time();
        char *action = strchr(cmd, ' ');

        if (action == NULL) {
            wprintw(self->window, "Invalid syntax.\n");
            return;
        }

        action++;

        wattron(ctx->history, COLOR_PAIR(2));
        wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
        wattroff(ctx->history, COLOR_PAIR(2));

        uint8_t selfname[MAX_NAME_LENGTH];
        int len = getself_name(m, selfname, sizeof(selfname));
        char msg[MAX_STR_SIZE - len - 4];
        snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t *) selfname, action);

        wattron(ctx->history, COLOR_PAIR(5));
        wprintw(ctx->history, msg);
        wattroff(ctx->history, COLOR_PAIR(5));

        if (m_sendaction(m, ctx->friendnum, (uint8_t *) msg, strlen(msg) + 1) < 0) {
            wattron(ctx->history, COLOR_PAIR(3));
            wprintw(ctx->history, " * Failed to send action\n");
            wattroff(ctx->history, COLOR_PAIR(3));
        }
    }

    else if (!strncmp(cmd, "/status ", strlen("/status "))) {
        char *status = strchr(cmd, ' ');
        char *msg;
        char *status_text;

        if (status == NULL) {
            wprintw(ctx->history, "Invalid syntax.\n");
            return;
        }

        status++;
        USERSTATUS status_kind;

        if (!strncmp(status, "online", strlen("online"))) {
            status_kind = USERSTATUS_NONE;
            status_text = "ONLINE";
        }

        else if (!strncmp(status, "away", strlen("away"))) {
            status_kind = USERSTATUS_AWAY;
            status_text = "AWAY";
        }

        else if (!strncmp(status, "busy", strlen("busy"))) {
            status_kind = USERSTATUS_BUSY;
            status_text = "BUSY";
        }

        else {
            wprintw(ctx->history, "Invalid status.\n");
            return;
        }

        msg = strchr(status, ' ');

        if (msg == NULL) {
            m_set_userstatus(m, status_kind);
            wprintw(ctx->history, "Status set to: %s\n", status_text);
        } else {
            msg++;
            m_set_userstatus(m, status_kind);
            m_set_statusmessage(m, ( uint8_t *) msg, strlen(msg) + 1);
            wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg);
        }
    }

    else if (!strncmp(cmd, "/nick ", strlen("/nick "))) {
        char *nick;
        nick = strchr(cmd, ' ');

        if (nick == NULL) {
            wprintw(ctx->history, "Invalid syntax.\n");
            return;
        }

        nick++;
        setname(m, (uint8_t *) nick, strlen(nick) + 1);
        wprintw(ctx->history, "Nickname set to: %s\n", nick);
    }

    else if (!strcmp(cmd, "/myid")) {
        char id[FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
        uint8_t address[FRIEND_ADDRESS_SIZE];
        size_t i;
        getaddress(m, address);

        for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
            char xx[3];
            snprintf(xx, sizeof(xx), "%02X",  address[i] & 0xff);
            strcat(id, xx);
        }

        wprintw(ctx->history, "%s\n", id);
    }

    else if (strcmp(cmd, "/close") == 0) {
        int f_num = ctx->friendnum;
        delwin(ctx->linewin);
        del_window(self);
        disable_chatwin(f_num);
    }

    else
        wprintw(ctx->history, "Invalid command.\n");
}

static void chat_onDraw(ToxWindow *self, Messenger *m)
{
    curs_set(1);
    int x, y;
    getmaxyx(self->window, y, x);
    (void) y;
    ChatContext *ctx = (ChatContext *) self->x;
    mvwhline(ctx->linewin, 0, 0, '_', x);
    wrefresh(self->window);
}
예제 #5
0
void task_file_load_handler(retro_task_t *task)
{
   nbio_handle_t         *nbio  = (nbio_handle_t*)task->state;

   if (nbio)
   {
      switch (nbio->status)
      {
         case NBIO_STATUS_INIT:
            if (nbio && !string_is_empty(nbio->path))
            {
               const char *fullpath  = nbio->path;
               struct nbio_t *handle = nbio_open(fullpath, NBIO_READ);

               if (handle)
               {
                  nbio->handle       = handle;
                  nbio->status       = NBIO_STATUS_TRANSFER;

                  if (strstr(fullpath, file_path_str(FILE_PATH_PNG_EXTENSION)))
                     nbio->image_type = IMAGE_TYPE_PNG;
                  else if (strstr(fullpath, file_path_str(FILE_PATH_JPEG_EXTENSION)) 
                        || strstr(fullpath, file_path_str(FILE_PATH_JPG_EXTENSION)))
                     nbio->image_type = IMAGE_TYPE_JPEG;
                  else if (strstr(fullpath, file_path_str(FILE_PATH_BMP_EXTENSION)))
                     nbio->image_type = IMAGE_TYPE_BMP;
                  else if (strstr(fullpath, file_path_str(FILE_PATH_TGA_EXTENSION)))
                     nbio->image_type = IMAGE_TYPE_TGA;

                  nbio_begin_read(handle);
                  return;
               }
               else
                  task_set_cancelled(task, true);
            }
            break;
         case NBIO_STATUS_TRANSFER_PARSE:
            if (task_file_transfer_iterate_parse(nbio) == -1)
               task_set_cancelled(task, true);
            nbio->status = NBIO_STATUS_TRANSFER_PARSE_FREE;
            break;
         case NBIO_STATUS_TRANSFER:
            if (task_file_transfer_iterate_transfer(nbio) == -1)
               nbio->status = NBIO_STATUS_TRANSFER_PARSE;
            break;
         case NBIO_STATUS_TRANSFER_PARSE_FREE:
         case NBIO_STATUS_POLL:
         default:
            break;
      }

      switch (nbio->image_type)
      {
         case IMAGE_TYPE_PNG:
         case IMAGE_TYPE_JPEG:
         case IMAGE_TYPE_TGA:
         case IMAGE_TYPE_BMP:
            if (!task_image_load_handler(task))
               task_set_finished(task, true);
            break;
         case 0:
            if (nbio->is_finished)
               task_set_finished(task, true);
            break;
      }
   }

   if (task_get_cancelled(task))
   {
      task_set_error(task, strdup("Task canceled."));
      task_set_finished(task, true);
   }
}
예제 #6
0
void fill_pathname_application_special(char *s, size_t len, enum application_special_type type)
{
   switch (type)
   {
      case APPLICATION_SPECIAL_DIRECTORY_AUTOCONFIG:
         {
            settings_t *settings     = config_get_ptr();
            fill_pathname_join(s,
                  settings->directory.autoconfig,
                  settings->input.joypad_driver,
                  len);
         }
         break;
      case APPLICATION_SPECIAL_DIRECTORY_CONFIG:
         {
            settings_t *settings     = config_get_ptr();

            /* Try config directory setting first,
             * fallback to the location of the current configuration file. */
            if (!string_is_empty(settings->directory.menu_config))
               strlcpy(s, settings->directory.menu_config, len);
            else if (!path_is_empty(RARCH_PATH_CONFIG))
               fill_pathname_basedir(s, path_get(RARCH_PATH_CONFIG), len);
         }
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_ICONS:
#ifdef HAVE_ZARCH
         {
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_FONT:
#ifdef HAVE_ZARCH
         {
            char s1[PATH_MAX_LENGTH];
            s1[0] = '\0';

            fill_pathname_application_special(s1, sizeof(s1),
                  APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH);
            fill_pathname_join(s,
                  s1, "Roboto-Condensed.ttf", len);
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH:
#ifdef HAVE_ZARCH
         {
            settings_t *settings     = config_get_ptr();
            fill_pathname_join(s, 
                  settings->directory.assets,
                  "zarch",
                  len);
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_ICONS:
#ifdef HAVE_XMB
         {
            char s1[PATH_MAX_LENGTH];
            char s2[PATH_MAX_LENGTH];

            s1[0] = s2[0] = '\0';

            fill_pathname_application_special(s1, sizeof(s1),
                  APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB);
            fill_pathname_join(s2, s1, "png",
                  sizeof(s2));
            fill_pathname_slash(s2, sizeof(s2));
            strlcpy(s, s2, len);
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_BG:
#ifdef HAVE_XMB
         {
            settings_t *settings     = config_get_ptr();

            if (!string_is_empty(settings->path.menu_wallpaper))
               strlcpy(s, settings->path.menu_wallpaper, len);
            else
            {
               char s1[PATH_MAX_LENGTH];

               s1[0] = '\0';

               fill_pathname_application_special(s1, sizeof(s1),
                     APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_ICONS);
               fill_pathname_join(s, s1,
                     file_path_str(FILE_PATH_BACKGROUND_IMAGE),
                     len);
            }
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB:
#ifdef HAVE_XMB
         {
            char s1[PATH_MAX_LENGTH];
            char s2[PATH_MAX_LENGTH];
            settings_t *settings     = config_get_ptr();

            s1[0] = s2[0] = '\0';

            fill_pathname_join(
                  s1,
                  settings->directory.assets,
                  "xmb",
                  sizeof(s1));
            fill_pathname_join(s2,
                  s1, xmb_theme_ident(), sizeof(s2));
            strlcpy(s, s2, len);
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_MATERIALUI:
#ifdef HAVE_MATERIALUI
         {
            settings_t *settings = config_get_ptr();

            fill_pathname_join(
                  s,
                  settings->directory.assets,
                  "glui",
                  len);
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_MATERIALUI_ICONS:
#ifdef HAVE_MATERIALUI
         {
            char s1[PATH_MAX_LENGTH];

            s1[0] = '\0';

            fill_pathname_application_special(s1,
                  sizeof(s1), APPLICATION_SPECIAL_DIRECTORY_ASSETS_MATERIALUI);
            fill_pathname_slash(s1, sizeof(s1));
            strlcpy(s, s1, len);
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_MATERIALUI_FONT:
#ifdef HAVE_MATERIALUI
         {
            char s1[PATH_MAX_LENGTH];

            s1[0] = '\0';

            fill_pathname_application_special(s1, sizeof(s1),
                  APPLICATION_SPECIAL_DIRECTORY_ASSETS_MATERIALUI);
            fill_pathname_join(s, s1, "font.ttf", len);
         }
#endif
         break;
      case APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_FONT:
#ifdef HAVE_XMB
         {
            settings_t *settings = config_get_ptr();

            if (!string_is_empty(settings->menu.xmb.font))
               strlcpy(s, settings->menu.xmb.font, len);
            else
            {
               char s1[PATH_MAX_LENGTH];

               s1[0] = '\0';

               fill_pathname_application_special(s1, sizeof(s1),
                     APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB);
               fill_pathname_join(s, s1,
                     file_path_str(FILE_PATH_TTF_FONT),
                     len);
            }
         }
#endif
         break;
      case APPLICATION_SPECIAL_NONE:
      default:
         break;
   }
}
예제 #7
0
/**
 * load_content:
 * @special          : subsystem of content to be loaded. Can be NULL.
 * content           :
 *
 * Load content file (for libretro core).
 *
 * Returns : true if successful, otherwise false.
 **/
static bool load_content(
      struct string_list *temporary_content,
      struct retro_game_info *info,
      const struct string_list *content,
      const struct retro_subsystem_info *special,
      struct string_list* additional_path_allocs
      )
{
   unsigned i;
   retro_ctx_load_content_info_t load_info;

   if (!info || !additional_path_allocs)
      return false;

   for (i = 0; i < content->size; i++)
   {
      int         attr     = content->elems[i].attr.i;
      bool need_fullpath   = attr & 2;
      bool require_content = attr & 4;
      const char *path     = content->elems[i].data;

      if (require_content && string_is_empty(path))
      {
         RARCH_LOG("libretro core requires content, "
               "but nothing was provided.\n");
         return false;
      }

      info[i].path = NULL;

      if (*path)
         info[i].path = path;

      if (!need_fullpath && !string_is_empty(path))
      {
         if (!load_content_into_memory(&info[i], i, path))
            return false;
      }
      else
      {
         RARCH_LOG("Content loading skipped. Implementation will"
               " load it on its own.\n");

#ifdef HAVE_COMPRESSION
         if (!load_content_from_compressed_archive(
                  temporary_content,
                  &info[i], i,
                  additional_path_allocs, need_fullpath, path))
            return false;
#endif
      }
   }

   load_info.content = content;
   load_info.special = special;
   load_info.info    = info;

   if (!core_load_game(&load_info))
   {
      RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_CONTENT));
      return false;
   }

#ifdef HAVE_CHEEVOS
   if (!special)
   {
      const void *load_data = NULL;

      cheevos_set_cheats();

      if (*content->elems[0].data)
         load_data = info;
      cheevos_load(load_data);
   }
#endif

   return true;
}
예제 #8
0
/**
 * load_content:
 * @special          : subsystem of content to be loaded. Can be NULL.
 * content           :
 *
 * Load content file (for libretro core).
 *
 * Returns : true if successful, otherwise false.
 **/
static bool load_content(
      struct string_list *temporary_content,
      struct retro_game_info *info,
      const struct string_list *content,
      const struct retro_subsystem_info *special
      )
{
   unsigned i;
   retro_ctx_load_content_info_t load_info;
   struct string_list *additional_path_allocs = string_list_new();

   if (!additional_path_allocs)
      return false;

   for (i = 0; i < content->size; i++)
   {
      int         attr     = content->elems[i].attr.i;
      bool need_fullpath   = attr & 2;
      bool require_content = attr & 4;
      const char *path     = content->elems[i].data;

      if (require_content && string_is_empty(path))
      {
         RARCH_LOG("%s\n",
               msg_hash_to_str(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT));
         goto error;
      }

      info[i].path = NULL;

      if (!string_is_empty(path))
         info[i].path = path;

      if (!need_fullpath && !string_is_empty(path))
      {
         /* Load the content into memory. */

         ssize_t len = 0;

         if (!load_content_into_memory(i, path, (void**)&info[i].data, &len))
         {
            RARCH_ERR("%s \"%s\".\n",
                  msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE),
                  path);
            goto error;
         }

         info[i].size = len;
      }
      else
      {
         RARCH_LOG("%s\n",
               msg_hash_to_str(
                  MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT));

#ifdef HAVE_COMPRESSION
         if (!load_content_from_compressed_archive(
                  temporary_content,
                  &info[i], i,
                  additional_path_allocs, need_fullpath, path))
            goto error;
#endif
      }
   }

   load_info.content = content;
   load_info.special = special;
   load_info.info    = info;

   if (!core_load_game(&load_info))
   {
      RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_CONTENT));
      goto error;
   }

#ifdef HAVE_CHEEVOS
   if (!special)
   {
      const void *load_data = NULL;

      cheevos_set_cheats();

      if (!string_is_empty(content->elems[0].data))
         load_data = info;
      cheevos_load(load_data);
   }
#endif

   string_list_free(additional_path_allocs);

   return true;

error:
   if (additional_path_allocs)
      string_list_free(additional_path_allocs);
   
   return false;
}
예제 #9
0
/**
 * task_load_content:
 *
 * Loads content into currently selected core.
 * Will also optionally push the content entry to the history playlist.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
static bool task_load_content(content_ctx_info_t *content_info,
      bool launched_from_menu,
      enum content_mode_load mode)
{
   char name[256];
   char msg[256];

   name[0] = msg[0] = '\0';

   if (launched_from_menu)
   {
#ifdef HAVE_MENU
      /* redraw menu frame */
      menu_display_set_msg_force(true);
      menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL);

      if (!path_is_empty(RARCH_PATH_CONTENT))
         fill_pathname_base(name, path_get(RARCH_PATH_CONTENT), sizeof(name));
#endif

      /** Show loading OSD message */
      if (!string_is_empty(path_get(RARCH_PATH_CONTENT)))
      {
         snprintf(msg, sizeof(msg), "%s %s ...",
               msg_hash_to_str(MSG_LOADING),
               name);
         runloop_msg_queue_push(msg, 2, 1, true);
      }
   }

   if (!content_load(content_info))
      goto error;

   /* Push entry to top of history playlist */
   if (content_is_inited() || content_does_not_need_content())
   {
      char tmp[PATH_MAX_LENGTH];
      struct retro_system_info *info = NULL;
      rarch_system_info_t *system    = NULL;

      tmp[0] = '\0';

      runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);
      if (system)
         info = &system->info;

#ifdef HAVE_MENU
      if (launched_from_menu)
         menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &info);
#endif

      strlcpy(tmp, path_get(RARCH_PATH_CONTENT), sizeof(tmp));

      if (!launched_from_menu)
      {
         /* Path can be relative here.
          * Ensure we're pushing absolute path. */
         if (!string_is_empty(tmp))
            path_resolve_realpath(tmp, sizeof(tmp));
      }

      if (info && *tmp)
      {
         const char *core_path            = NULL;
         const char *core_name            = NULL;
         playlist_t *playlist_tmp         = g_defaults.content_history;

         switch (path_is_media_type(tmp))
         {
            case RARCH_CONTENT_MOVIE:
#ifdef HAVE_FFMPEG
               playlist_tmp = g_defaults.video_history;
               core_name = "movieplayer";
               core_path = "builtin";
#endif
               break;
            case RARCH_CONTENT_MUSIC:
#ifdef HAVE_FFMPEG
               playlist_tmp = g_defaults.music_history;
               core_name = "musicplayer";
               core_path = "builtin";
#endif
               break;
            case RARCH_CONTENT_IMAGE:
#ifdef HAVE_IMAGEVIEWER
               playlist_tmp = g_defaults.image_history;
               core_name = "imageviewer";
               core_path = "builtin";
#endif
               break;
            default:
               core_path            = path_get(RARCH_PATH_CORE);
               core_name            = info->library_name;
               break;
         }

         if (content_push_to_history_playlist(playlist_tmp, tmp,
                  core_name, core_path))
            playlist_write_file(playlist_tmp);
      }
   }

   return true;

error:
   if (launched_from_menu)
   {
      if (!path_is_empty(RARCH_PATH_CONTENT) && !string_is_empty(name))
      {
         snprintf(msg, sizeof(msg), "%s %s.\n",
               msg_hash_to_str(MSG_FAILED_TO_LOAD),
               name);
         runloop_msg_queue_push(msg, 2, 90, true);
      }
   }
   return false;
}
예제 #10
0
static void iohidmanager_hid_device_add(void *data, IOReturn result,
      void* sender, IOHIDDeviceRef device)
{
   int i;
   IOReturn ret;
   uint16_t dev_vid, dev_pid;
   CFArrayRef elements_raw;
   int count;
   CFMutableArrayRef elements;
   CFRange range;
   bool found_axis[6] =
   { false, false, false, false, false, false };
   apple_input_rec_t *tmp                   = NULL;
   apple_input_rec_t *tmpButtons            = NULL;
   apple_input_rec_t *tmpAxes               = NULL;
   iohidmanager_hid_t                  *hid = (iohidmanager_hid_t*)
      hid_driver_get_data();
   struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)
      calloc(1, sizeof(*adapter));

   if (!adapter)
      return;
   if (!hid)
      goto error;

   adapter->handle        = device;

   ret = IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);

   if (ret != kIOReturnSuccess)
      goto error;

   /* Move the device's run loop to this thread. */
   IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(),
         kCFRunLoopCommonModes);
   IOHIDDeviceRegisterRemovalCallback(device,
         iohidmanager_hid_device_remove, adapter);

#ifndef IOS
   iohidmanager_hid_device_get_product_string(device, adapter->name,
         sizeof(adapter->name));
#endif

   dev_vid = iohidmanager_hid_device_get_vendor_id  (device);
   dev_pid = iohidmanager_hid_device_get_product_id (device);

   adapter->slot = pad_connection_pad_init(hid->slots,
         adapter->name, dev_vid, dev_pid, adapter,
         &iohidmanager_hid);

   if (adapter->slot == -1)
      goto error;

   if (pad_connection_has_interface(hid->slots, adapter->slot))
      IOHIDDeviceRegisterInputReportCallback(device,
            adapter->data + 1, sizeof(adapter->data) - 1,
            iohidmanager_hid_device_report, adapter);
   else
      IOHIDDeviceRegisterInputValueCallback(device,
            iohidmanager_hid_device_input_callback, adapter);

   if (string_is_empty(adapter->name))
      goto error;

   /* scan for buttons, axis, hats */
   elements_raw = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
   count        = (int)CFArrayGetCount(elements_raw);
   elements     = CFArrayCreateMutableCopy(
         kCFAllocatorDefault,(CFIndex)count,elements_raw);
   range        = CFRangeMake(0,count);

   CFArraySortValues(elements,
         range, iohidmanager_sort_elements, NULL);

   for (i = 0; i < count; i++)
   {
      IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);

      if (!element)
         continue;

      IOHIDElementType type = IOHIDElementGetType(element);
      uint32_t page         = (uint32_t)IOHIDElementGetUsagePage(element);
      uint32_t use          = (uint32_t)IOHIDElementGetUsage(element);
      uint32_t cookie       = (uint32_t)IOHIDElementGetCookie(element);

      int detected_button = 0;

      switch (page)
      {
         case kHIDPage_GenericDesktop:
            switch (type)
            {
               case kIOHIDElementTypeCollection:
               case kIOHIDElementTypeInput_ScanCodes:
               case kIOHIDElementTypeFeature:
               case kIOHIDElementTypeInput_Button:
               case kIOHIDElementTypeOutput:
               case kIOHIDElementTypeInput_Axis:
                  /* TODO/FIXME */
                  break;
               case kIOHIDElementTypeInput_Misc:
                  switch (use)
                  {
                     case kHIDUsage_GD_Hatswitch:
                        {
                           /* as far as I can tell, OSX only reports one Hat */
                           apple_input_rec_t *hat = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t));
                           hat->id                = 0;
                           hat->cookie            = (IOHIDElementCookie)cookie;
                           hat->next              = NULL;
                           adapter->hats          = hat;
                        }
                        break;
                     default:
                        {
                           uint32_t i = 0;
                           static const uint32_t axis_use_ids[6] =
                           { 48, 49, 51, 52, 50, 53 };

                           while (i < 6 && axis_use_ids[i] != use)
                              i++;

                           if (i < 6)
                           {

                              apple_input_rec_t *axis = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t));
                              axis->id                = i;
                              axis->cookie            = (IOHIDElementCookie)cookie;
                              axis->next              = NULL;

                              if(iohidmanager_check_for_id(adapter->axes,i))
                              {
                                 /* axis ID already exists, save to tmp for appending later */
                                 if(tmpAxes)
                                    iohidmanager_append_record(tmpAxes, axis);
                                 else
                                    tmpAxes = axis;
                              }
                              else
                              {
                                 found_axis[axis->id] = true;
                                 if(adapter->axes)
                                    iohidmanager_append_record(adapter->axes, axis);
                                 else
                                    adapter->axes = axis;
                              }
                           }
                           else
                              detected_button = 1;
                        }
                        break;
                  }
                  break;
            }
            break;
         case kHIDPage_Consumer:
         case kHIDPage_Button:
            switch (type)
            {
               case kIOHIDElementTypeCollection:
               case kIOHIDElementTypeFeature:
               case kIOHIDElementTypeInput_ScanCodes:
               case kIOHIDElementTypeInput_Axis:
               case kIOHIDElementTypeOutput:
                  /* TODO/FIXME */
                  break;
               case kIOHIDElementTypeInput_Misc:
               case kIOHIDElementTypeInput_Button:
                  detected_button = 1;
                  break;
            }
            break;
      }

      if (detected_button)
      {
         apple_input_rec_t *btn = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t));
         btn->id                = (uint32_t)use;
         btn->cookie            = (IOHIDElementCookie)cookie;
         btn->next              = NULL;

         if(iohidmanager_check_for_id(adapter->buttons,btn->id))
         {
            if(tmpButtons)
               iohidmanager_append_record_ordered(&tmpButtons, btn);
            else
               tmpButtons = btn;
         }
         else
         {
            if(adapter->buttons)
               iohidmanager_append_record_ordered(&adapter->buttons, btn);
            else
               adapter->buttons = btn;
         }
      }
   }

   /* take care of buttons/axes with duplicate 'use' values */
   for (i = 0; i < 6; i++)
   {
      if(found_axis[i] == false && tmpAxes)
      {
         apple_input_rec_t *next = tmpAxes->next;
         tmpAxes->id             = i;
         tmpAxes->next           = NULL;
         iohidmanager_append_record(adapter->axes, tmpAxes);
         tmpAxes = next;
      }
   }

   tmp = adapter->buttons;

   if (tmp)
   {
      while(tmp->next)
         tmp = tmp->next;
   }

   while(tmpButtons)
   {
      apple_input_rec_t *next = tmpButtons->next;

      tmpButtons->id          = tmp->id;
      tmpButtons->next        = NULL;
      tmp->next               = tmpButtons;

      tmp                     = tmp->next;
      tmpButtons              = next;
   }


   iohidmanager_hid_device_add_autodetect(adapter->slot,
         adapter->name, iohidmanager_hid.ident, dev_vid, dev_pid);

   return;

error:
   {
      apple_input_rec_t *tmp = NULL;
      while(adapter->hats != NULL)
      {
         tmp           = adapter->hats;
         adapter->hats = adapter->hats->next;
         free(tmp);
      }
      while(adapter->axes != NULL)
      {
         tmp           = adapter->axes;
         adapter->axes = adapter->axes->next;
         free(tmp);
      }
      while(adapter->buttons != NULL)
      {
         tmp              = adapter->buttons;
         adapter->buttons = adapter->buttons->next;
         free(tmp);
      }
      while(tmpAxes != NULL)
      {
         tmp     = tmpAxes;
         tmpAxes = tmpAxes->next;
         free(tmp);
      }
      while(tmpButtons != NULL)
      {
         tmp        = tmpButtons;
         tmpButtons = tmpButtons->next;
         free(tmp);
      }
      free(adapter);
   }
}
예제 #11
0
void filebrowser_parse(void *data, unsigned type_data, bool extensions_honored)
{
   size_t i, list_size;
   struct string_list *str_list         = NULL;
   unsigned items_found                 = 0;
   unsigned files_count                 = 0;
   unsigned dirs_count                  = 0;
   settings_t *settings                 = config_get_ptr();
   menu_displaylist_info_t *info        = (menu_displaylist_info_t*)data;
   enum menu_displaylist_ctl_state type = (enum menu_displaylist_ctl_state)
                                          type_data;
   bool path_is_compressed              = path_is_compressed_file(info->path);
   bool filter_ext                      =
      settings->menu.navigation.browser.filter.supported_extensions_enable;

   if (string_is_equal(info->label,
            msg_hash_to_str(MENU_ENUM_LABEL_SCAN_FILE)))
      filter_ext = false;

   if (extensions_honored)
      filter_ext = true;

   if (path_is_compressed)
      str_list = file_archive_get_file_list(info->path, info->exts);
   else
      str_list = dir_list_new(info->path,
            filter_ext ? info->exts : NULL,
            true, settings->show_hidden_files, true, false);

#ifdef HAVE_LIBRETRODB
   if (filebrowser_types == FILEBROWSER_SCAN_DIR)
      menu_entries_prepend(info->list,
            msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY),
            msg_hash_to_str(MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY),
            MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY,
            FILE_TYPE_SCAN_DIRECTORY, 0 ,0);
#endif

   if (filebrowser_types == FILEBROWSER_SELECT_DIR)
      menu_entries_prepend(info->list,
            msg_hash_to_str(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY),
            msg_hash_to_str(MENU_ENUM_LABEL_USE_THIS_DIRECTORY),
            MENU_ENUM_LABEL_USE_THIS_DIRECTORY,
            FILE_TYPE_USE_DIRECTORY, 0 ,0);

   if (!str_list)
   {
      const char *str = path_is_compressed
         ? msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE)
         : msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND);

      menu_entries_append_enum(info->list, str, "",
            MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, 0, 0, 0);
      goto end;
   }

   dir_list_sort(str_list, true);

   list_size = str_list->size;

   if (list_size == 0)
   {
      string_list_free(str_list);
      str_list = NULL;
   }
   else
   {
      for (i = 0; i < list_size; i++)
      {
         char label[PATH_MAX_LENGTH];
         bool is_dir                   = false;
         enum msg_hash_enums enum_idx  = MSG_UNKNOWN;
         enum msg_file_type file_type  = FILE_TYPE_NONE;
         const char *path              = str_list->elems[i].data;

         label[0] = '\0';

         switch (str_list->elems[i].attr.i)
         {
            case RARCH_DIRECTORY:
               file_type = FILE_TYPE_DIRECTORY;
               break;
            case RARCH_COMPRESSED_ARCHIVE:
               file_type = FILE_TYPE_CARCHIVE;
               break;
            case RARCH_COMPRESSED_FILE_IN_ARCHIVE:
               file_type = FILE_TYPE_IN_CARCHIVE;
               break;
            case RARCH_PLAIN_FILE:
            default:
               file_type = (enum msg_file_type)info->type_default;
               switch (type)
               {
                  /* in case of deferred_core_list we have to interpret
                   * every archive as an archive to disallow instant loading
                   */
                  case DISPLAYLIST_CORES_DETECTED:
                     if (path_is_compressed_file(path))
                        file_type = FILE_TYPE_CARCHIVE;
                     break;
                  default:
                     break;
               }
               break;
         }

         is_dir = (file_type == FILE_TYPE_DIRECTORY);

         if (!is_dir)
         {
            if (filebrowser_types == FILEBROWSER_SELECT_DIR)
               continue;
            if (filebrowser_types == FILEBROWSER_SCAN_DIR)
               continue;
         }

         /* Need to preserve slash first time. */

         if (!string_is_empty(info->path) && !path_is_compressed)
            path = path_basename(path);

         if (filebrowser_types == FILEBROWSER_SELECT_COLLECTION)
         {
            if (is_dir)
               file_type = FILE_TYPE_DIRECTORY;
            else
               file_type = FILE_TYPE_PLAYLIST_COLLECTION;
         }

         if (!is_dir && 
               (settings->multimedia.builtin_mediaplayer_enable ||
                settings->multimedia.builtin_imageviewer_enable))
         {
            switch (path_is_media_type(path))
            {
               case RARCH_CONTENT_MOVIE:
#ifdef HAVE_FFMPEG
                  if (settings->multimedia.builtin_mediaplayer_enable)
                     file_type = FILE_TYPE_MOVIE;
#endif
                  break;
               case RARCH_CONTENT_MUSIC:
#ifdef HAVE_FFMPEG
                  if (settings->multimedia.builtin_mediaplayer_enable)
                     file_type = FILE_TYPE_MUSIC;
#endif
                  break;
               case RARCH_CONTENT_IMAGE:
#ifdef HAVE_IMAGEVIEWER
                  if (settings->multimedia.builtin_imageviewer_enable
                        && type != DISPLAYLIST_IMAGES)
                     file_type = FILE_TYPE_IMAGEVIEWER;
                  else
                     file_type = FILE_TYPE_IMAGE;
#endif
                  break;
               default:
                  break;
            }
         }

         switch (file_type)
         {
            case FILE_TYPE_PLAIN:
#if 0
               enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_PLAIN_FILE;
#endif
               files_count++;
               break;
            case FILE_TYPE_MOVIE:
               enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_MOVIE_OPEN;
               files_count++;
               break;
            case FILE_TYPE_MUSIC:
               enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_MUSIC_OPEN;
               files_count++;
               break;
            case FILE_TYPE_IMAGE:
               enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_IMAGE;
               files_count++;
               break;
            case FILE_TYPE_IMAGEVIEWER:
               enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_IMAGE_OPEN_WITH_VIEWER;
               files_count++;
               break;
            case FILE_TYPE_DIRECTORY:
               enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
               dirs_count++;
               break;
            default:
               break;
         }

         items_found++;
         menu_entries_append_enum(info->list, path, label,
               enum_idx,
               file_type, 0, 0);
      }
   }

   if (str_list && str_list->size > 0)
      string_list_free(str_list);

   if (items_found == 0)
   {
      menu_entries_append_enum(info->list,
            msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS),
            msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS),
            MENU_ENUM_LABEL_NO_ITEMS,
            MENU_SETTING_NO_ITEM, 0, 0);
   }

   /* We don't want to show 'filter by extension' for this. */
   if (filebrowser_types == FILEBROWSER_SELECT_DIR)
      goto end;
   if (filebrowser_types == FILEBROWSER_SCAN_DIR)
      goto end;

   if (!extensions_honored && files_count > 0)
      menu_entries_prepend(info->list,
            msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE),
            msg_hash_to_str(MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE),
            MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE,
            0, 0 ,0);

end:
   menu_entries_prepend(info->list,
         msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY),
         info->path,
         MENU_ENUM_LABEL_PARENT_DIRECTORY,
         FILE_TYPE_PARENT_DIRECTORY, 0, 0);
}
예제 #12
0
파일: XML.cpp 프로젝트: hnpilot/XCSoar
/**
 * Creates a control from the given XMLNode as a child of the given parent
 * ContainerControl.
 *
 * @param form the WndForm object
 * @param Parent The parent ContainerControl
 * @param LookUpTable The parent CallBackTable
 * @param node The XMLNode that represents the control
 * @param eDialogStyle The parent's dialog style
 */
static Window *
LoadChild(WndForm &form, ContainerControl &Parent,
          CallBackTableEntry *LookUpTable,
          XMLNode node, const DialogStyle eDialogStyle)
{
  Window *window = NULL;

  // Determine name, coordinates, width, height
  // and caption of the control
  const TCHAR* Name = GetName(node);
  const TCHAR* Caption = GetCaption(node);
  RECT rc = Parent.GetClientAreaWindow().get_client_rect();
  ControlPosition pos = GetPosition(node, rc);
  if (!pos.no_scaling)
    pos.x = ScaleWidth(pos.x, eDialogStyle);

  ControlSize size = GetSize(node, rc, pos);
  if (!size.no_scaling)
    size.cx = ScaleWidth(size.cx, eDialogStyle);

  WindowStyle style;

  if (!StringToIntDflt(node.getAttribute(_T("Visible")), 1))
    style.hide();

  if (StringToIntDflt(node.getAttribute(_T("Border")), 0))
    style.border();

  bool advanced = _tcschr(Caption, _T('*')) != NULL;

  // PropertyControl (WndProperty)
  if (_tcscmp(node.getName(), _T("Edit")) == 0) {
    WndProperty *W;
    int CaptionWidth;
    bool ReadOnly;
    bool MultiLine;

    // Determine the width of the caption field
    CaptionWidth = StringToIntDflt(node.getAttribute(_T("CaptionWidth")), 0);

    if (Layout::ScaleSupported())
      CaptionWidth = Layout::Scale(CaptionWidth);

    CaptionWidth = ScaleWidth(CaptionWidth, eDialogStyle);

    // Determine whether the control is multiline or readonly
    MultiLine = StringToIntDflt(node.getAttribute(_T("MultiLine")), 0);
    ReadOnly = StringToIntDflt(node.getAttribute(_T("ReadOnly")), 0);

    // Load the event callback properties
    WndProperty::DataChangeCallback_t DataNotifyCallback =
      (WndProperty::DataChangeCallback_t)
      GetCallBack(LookUpTable, node, _T("OnDataNotify"));

    WindowControl::OnHelpCallback_t OnHelpCallback =
      (WindowControl::OnHelpCallback_t)
      GetCallBack(LookUpTable, node, _T("OnHelp"));

    // Create the Property Control
    style.control_parent();

    EditWindowStyle edit_style;
    if (ReadOnly)
      edit_style.read_only();
    else
      edit_style.tab_stop();

    if (is_embedded() || Layout::scale_1024 < 2048)
      /* sunken edge doesn't fit well on the tiny screen of an
         embedded device */
      edit_style.border();
    else
      edit_style.sunken_edge();

    if (MultiLine) {
      edit_style.multiline();
      edit_style.vscroll();
    }

    window = W = new WndProperty(Parent, Caption, pos.x, pos.y, size.cx, size.cy,
                                 CaptionWidth, style, edit_style,
                                 DataNotifyCallback);

    // Set the fore- and background color
    LoadColors(*W, node);

    // Set the help function event callback
    W->SetOnHelpCallback(OnHelpCallback);

    // Load the help text
    W->SetHelpText(StringToStringDflt(node.getAttribute(_T("Help")), _T("")));

    // If the control has (at least) one DataField child control
    if (node.nChildNode(_T("DataField")) > 0){
      // -> Load the first DataField control
      DataField *data_field =
        LoadDataField(node.getChildNode(_T("DataField"), 0),
                      LookUpTable, eDialogStyle);

      if (data_field != NULL)
        // Tell the Property control about the DataField control
        W->SetDataField(data_field);
    }

  // ButtonControl (WndButton)
  } else if (_tcscmp(node.getName(), _T("Button")) == 0) {
    // Determine ClickCallback function
    WndButton::ClickNotifyCallback_t ClickCallback =
      (WndButton::ClickNotifyCallback_t)
      GetCallBack(LookUpTable, node, _T("OnClick"));

    // Create the ButtonControl

    style.tab_stop();

    window = new WndButton(Parent.GetClientAreaWindow(), Caption,
                           pos.x, pos.y, size.cx, size.cy,
                           style,
                           ClickCallback);

  } else if (_tcscmp(node.getName(), _T("CheckBox")) == 0) {
    // Determine ClickCallback function
    CheckBoxControl::ClickNotifyCallback_t ClickCallback =
      (CheckBoxControl::ClickNotifyCallback_t)
      GetCallBack(LookUpTable, node, _T("OnClick"));

    // Create the CheckBoxControl

    style.tab_stop();

    window = new CheckBoxControl(Parent.GetClientAreaWindow(), Caption,
                                 pos.x, pos.y, size.cx, size.cy,
                                 style,
                                 ClickCallback);

  // SymbolButtonControl (WndSymbolButton) not used yet
  } else if (_tcscmp(node.getName(), _T("SymbolButton")) == 0) {
    // Determine ClickCallback function
    WndButton::ClickNotifyCallback_t ClickCallback =
      (WndButton::ClickNotifyCallback_t)
      GetCallBack(LookUpTable, node, _T("OnClick"));

    // Create the SymbolButtonControl

    style.tab_stop();

    window = new WndSymbolButton(Parent.GetClientAreaWindow(), Caption,
                                 pos.x, pos.y, size.cx, size.cy,
                                 style, Parent.GetBackColor(),
                                 ClickCallback);

  // PanelControl (WndPanel)
  } else if (_tcscmp(node.getName(), _T("Panel")) == 0) {
    // Create the PanelControl

    style.control_parent();

    PanelControl *frame = new PanelControl(Parent, pos.x, pos.y, size.cx, size.cy, style);

    // Set the fore- and background color
    LoadColors(*frame, node);

    window = frame;

    // Load children controls from the XMLNode
    LoadChildrenFromXML(form, *frame, LookUpTable, &node, eDialogStyle);

  // KeyboardControl
  } else if (_tcscmp(node.getName(), _T("Keyboard")) == 0) {
    KeyboardControl::OnCharacterCallback_t CharacterCallback =
      (KeyboardControl::OnCharacterCallback_t)
      GetCallBack(LookUpTable, node, _T("OnCharacter"));

    // Create the KeyboardControl
    KeyboardControl *kb =
      new KeyboardControl(Parent.GetClientAreaWindow(),
                          pos.x, pos.y, size.cx, size.cy, Parent.GetBackColor(),
                          CharacterCallback, style);

    window = kb;
  // DrawControl (WndOwnerDrawFrame)
  } else if (_tcscmp(node.getName(), _T("Canvas")) == 0) {
    // Determine DrawCallback function
    WndOwnerDrawFrame::OnPaintCallback_t PaintCallback =
      (WndOwnerDrawFrame::OnPaintCallback_t)
      GetCallBack(LookUpTable, node, _T("OnPaint"));

    // Create the DrawControl
    WndOwnerDrawFrame* canvas =
        new WndOwnerDrawFrame(Parent, pos.x, pos.y, size.cx, size.cy,
                              style, PaintCallback);

    // Set the fore- and background color
    LoadColors(*canvas, node);

    window = canvas;

  // FrameControl (WndFrame)
  } else if (_tcscmp(node.getName(), _T("Label")) == 0){
    // Create the FrameControl
    WndFrame* frame = new WndFrame(Parent, pos.x, pos.y, size.cx, size.cy, style);

    // Set the fore- and background color
    LoadColors(*frame, node);

    // Set the caption
    frame->SetCaption(Caption);

    window = frame;

  // ListBoxControl (WndListFrame)
  } else if (_tcscmp(node.getName(), _T("List")) == 0){
    // Determine ItemHeight of the list items
    unsigned item_height =
      Layout::Scale(StringToIntDflt(node.getAttribute(_T("ItemHeight")), 18));

    // Create the ListBoxControl

    style.tab_stop();

    if (is_embedded() || Layout::scale_1024 < 2048)
      /* sunken edge doesn't fit well on the tiny screen of an
         embedded device */
      style.border();
    else
      style.sunken_edge();

    window = new WndListFrame(Parent.GetClientAreaWindow(),
                              pos.x, pos.y, size.cx, size.cy,
                              style,
                              item_height);

  // TabControl (Tabbed)
  } else if (_tcscmp(node.getName(), _T("Tabbed")) == 0) {
    // Create the TabControl

    style.control_parent();

    TabbedControl *tabbed = new TabbedControl(Parent,
                                              pos.x, pos.y, size.cx, size.cy, style);

    // Set the fore- and background color
    LoadColors(*tabbed, node);

    window = tabbed;

    const unsigned n = node.nChildNode();
    for (unsigned i = 0; i < n; ++i) {
      // Load each child control from the child nodes
      Window *child = LoadChild(form, *tabbed, LookUpTable,
                                node.getChildNode(i), eDialogStyle);
      if (child != NULL)
        tabbed->AddClient(child);
        continue;
    }
  } else if (_tcscmp(node.getName(), _T("Custom")) == 0) {
    // Create a custom Window object with a callback
    CreateWindowCallback_t create =
        (CreateWindowCallback_t)GetCallBack(LookUpTable, node, _T("OnCreate"));
    if (create == NULL)
      return NULL;

    window = create(Parent.GetClientAreaWindow(),
                    pos.x, pos.y, size.cx, size.cy, style);
  }

  if (window != NULL) {
    if (!string_is_empty(Name))
      form.AddNamed(Name, window);

    if (advanced)
      form.AddAdvanced(window);

    form.AddDestruct(window);
  }

  return window;
}
예제 #13
0
bool runloop_ctl(enum runloop_ctl_state state, void *data)
{
   settings_t *settings                             = config_get_ptr();

   switch (state)
   {
      case RUNLOOP_CTL_SHADER_DIR_DEINIT:
         shader_dir_free(&runloop_shader_dir);
         break;
      case RUNLOOP_CTL_SHADER_DIR_INIT:
         return shader_dir_init(&runloop_shader_dir);
      case RUNLOOP_CTL_SYSTEM_INFO_INIT:
         core_get_system_info(&runloop_system.info);

         if (!runloop_system.info.library_name)
            runloop_system.info.library_name = msg_hash_to_str(MSG_UNKNOWN);
         if (!runloop_system.info.library_version)
            runloop_system.info.library_version = "v0";

         video_driver_set_title_buf();

         strlcpy(runloop_system.valid_extensions,
               runloop_system.info.valid_extensions ?
               runloop_system.info.valid_extensions : DEFAULT_EXT,
               sizeof(runloop_system.valid_extensions));
         break;
      case RUNLOOP_CTL_GET_CORE_OPTION_SIZE:
         {
            unsigned *idx = (unsigned*)data;
            if (!idx)
               return false;
            *idx = core_option_manager_size(runloop_core_options);
         }
         break;
      case RUNLOOP_CTL_HAS_CORE_OPTIONS:
         return runloop_core_options;
      case RUNLOOP_CTL_CORE_OPTIONS_LIST_GET:
         {
            core_option_manager_t **coreopts = (core_option_manager_t**)data;
            if (!coreopts)
               return false;
            *coreopts = runloop_core_options;
         }
         break;
      case RUNLOOP_CTL_SYSTEM_INFO_GET:
         {
            rarch_system_info_t **system = (rarch_system_info_t**)data;
            if (!system)
               return false;
            *system = &runloop_system;
         }
         break;
      case RUNLOOP_CTL_SYSTEM_INFO_FREE:

         /* No longer valid. */
         if (runloop_system.subsystem.data)
            free(runloop_system.subsystem.data);
         runloop_system.subsystem.data = NULL;
         runloop_system.subsystem.size = 0;
         
         if (runloop_system.ports.data)
            free(runloop_system.ports.data);
         runloop_system.ports.data = NULL;
         runloop_system.ports.size = 0;
         
         if (runloop_system.mmaps.descriptors)
            free((void *)runloop_system.mmaps.descriptors);
         runloop_system.mmaps.descriptors     = NULL;
         runloop_system.mmaps.num_descriptors = 0;
         
         runloop_key_event          = NULL;
         runloop_frontend_key_event = NULL;

         audio_driver_unset_callback();
         memset(&runloop_system, 0, sizeof(rarch_system_info_t));
         break;
      case RUNLOOP_CTL_SET_FRAME_TIME_LAST:
         runloop_frame_time_last_enable = true;
         break;
      case RUNLOOP_CTL_UNSET_FRAME_TIME_LAST:
         if (!runloop_ctl(RUNLOOP_CTL_IS_FRAME_TIME_LAST, NULL))
            return false;
         runloop_frame_time_last        = 0;
         runloop_frame_time_last_enable = false;
         break;
      case RUNLOOP_CTL_SET_OVERRIDES_ACTIVE:
         runloop_overrides_active = true;
         break;
      case RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE:
         runloop_overrides_active = false; 
         break;
      case RUNLOOP_CTL_IS_OVERRIDES_ACTIVE:
         return runloop_overrides_active;
      case RUNLOOP_CTL_SET_GAME_OPTIONS_ACTIVE:
         runloop_game_options_active = true;
         break;
      case RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE:
         runloop_game_options_active = false;
         break;
      case RUNLOOP_CTL_IS_GAME_OPTIONS_ACTIVE:
         return runloop_game_options_active;
      case RUNLOOP_CTL_IS_FRAME_TIME_LAST:
         return runloop_frame_time_last_enable;
      case RUNLOOP_CTL_SET_FRAME_LIMIT:
         runloop_set_frame_limit = true;
         break;
      case RUNLOOP_CTL_UNSET_FRAME_LIMIT:
         runloop_set_frame_limit = false;
         break;
      case RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT:
         return runloop_set_frame_limit;
      case RUNLOOP_CTL_GET_PERFCNT:
         {
            bool **perfcnt = (bool**)data;
            if (!perfcnt)
               return false;
            *perfcnt = &runloop_perfcnt_enable;
         }
         break;
      case RUNLOOP_CTL_SET_PERFCNT_ENABLE:
         runloop_perfcnt_enable = true;
         break;
      case RUNLOOP_CTL_UNSET_PERFCNT_ENABLE:
         runloop_perfcnt_enable = false;
         break;
      case RUNLOOP_CTL_IS_PERFCNT_ENABLE:
         return runloop_perfcnt_enable;
      case RUNLOOP_CTL_SET_NONBLOCK_FORCED:
         runloop_force_nonblock = true;
         break;
      case RUNLOOP_CTL_UNSET_NONBLOCK_FORCED:
         runloop_force_nonblock = false;
         break;
      case RUNLOOP_CTL_IS_NONBLOCK_FORCED:
         return runloop_force_nonblock;
      case RUNLOOP_CTL_SET_FRAME_TIME:
         {
            const struct retro_frame_time_callback *info =
               (const struct retro_frame_time_callback*)data;
#ifdef HAVE_NETPLAY
            global_t *global = global_get_ptr();

            /* retro_run() will be called in very strange and
             * mysterious ways, have to disable it. */
            if (global->netplay.enable)
               return false;
#endif
            runloop_frame_time = *info;
         }
         break;
      case RUNLOOP_CTL_GET_WINDOWED_SCALE:
         {
            unsigned **scale = (unsigned**)data;
            if (!scale)
               return false;
            *scale       = (unsigned*)&runloop_pending_windowed_scale;
         }
         break;
      case RUNLOOP_CTL_SET_WINDOWED_SCALE:
         {
            unsigned *idx = (unsigned*)data;
            if (!idx)
               return false;
            runloop_pending_windowed_scale = *idx;
         }
         break;
      case RUNLOOP_CTL_SET_LIBRETRO_PATH:
         {
            const char *fullpath = (const char*)data;
            if (!fullpath)
               return false;
            strlcpy(
                  settings->path.libretro,
                  fullpath,
                  sizeof(settings->path.libretro));
         }
         break;
      case RUNLOOP_CTL_CLEAR_CONTENT_PATH:
         *runloop_fullpath = '\0';
         break;
      case RUNLOOP_CTL_GET_CONTENT_PATH:
         {
            char **fullpath = (char**)data;
            if (!fullpath)
               return false;
            *fullpath       = (char*)runloop_fullpath;
         }
         break;
      case RUNLOOP_CTL_SET_CONTENT_PATH:
         {
            const char *fullpath = (const char*)data;
            if (!fullpath)
               return false;
            strlcpy(runloop_fullpath, fullpath, sizeof(runloop_fullpath));
         }
         break;
      case RUNLOOP_CTL_FRAME_TIME_FREE:
         memset(&runloop_frame_time, 0, sizeof(struct retro_frame_time_callback));
         runloop_frame_time_last           = 0;
         runloop_max_frames                = 0;
         break;
      case RUNLOOP_CTL_STATE_FREE:
         runloop_perfcnt_enable            = false;
         runloop_idle                      = false;
         runloop_paused                    = false;
         runloop_slowmotion                = false;
         runloop_frame_time_last_enable    = false;
         runloop_set_frame_limit           = false;
         runloop_overrides_active          = false;
         runloop_ctl(RUNLOOP_CTL_FRAME_TIME_FREE, NULL);
         break;
      case RUNLOOP_CTL_GLOBAL_FREE:
         {
            global_t *global = NULL;
            command_event(CMD_EVENT_TEMPORARY_CONTENT_DEINIT, NULL);
            command_event(CMD_EVENT_SUBSYSTEM_FULLPATHS_DEINIT, NULL);
            command_event(CMD_EVENT_RECORD_DEINIT, NULL);
            command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL);

            rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL);
            runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH,  NULL);
            runloop_overrides_active   = false;

            core_unset_input_descriptors();

            global = global_get_ptr();
            memset(global, 0, sizeof(struct global));
         }
         break;
      case RUNLOOP_CTL_CLEAR_STATE:
         driver_ctl(RARCH_DRIVER_CTL_DEINIT,  NULL);
         runloop_ctl(RUNLOOP_CTL_STATE_FREE,  NULL);
         runloop_ctl(RUNLOOP_CTL_GLOBAL_FREE, NULL);
         break;
      case RUNLOOP_CTL_SET_MAX_FRAMES:
         {
            unsigned *ptr = (unsigned*)data;
            if (!ptr)
               return false;
            runloop_max_frames = *ptr;
         }
         break;
      case RUNLOOP_CTL_IS_IDLE:
         return runloop_idle;
      case RUNLOOP_CTL_SET_IDLE:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            runloop_idle = *ptr;
         }
         break;
      case RUNLOOP_CTL_IS_SLOWMOTION:
         return runloop_slowmotion;
      case RUNLOOP_CTL_SET_SLOWMOTION:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            runloop_slowmotion = *ptr;
         }
         break;
      case RUNLOOP_CTL_SET_PAUSED:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            runloop_paused = *ptr;
         }
         break;
      case RUNLOOP_CTL_IS_PAUSED:
         return runloop_paused;
      case RUNLOOP_CTL_MSG_QUEUE_PULL:
         runloop_msg_queue_lock();
         {
            const char **ret = (const char**)data;
            if (!ret)
               return false;
            *ret = msg_queue_pull(runloop_msg_queue);
         }
         runloop_msg_queue_unlock();
         break;
      case RUNLOOP_CTL_MSG_QUEUE_FREE:
#ifdef HAVE_THREADS
         slock_free(_runloop_msg_queue_lock);
         _runloop_msg_queue_lock = NULL;
#endif
         break;
      case RUNLOOP_CTL_MSG_QUEUE_CLEAR:
         msg_queue_clear(runloop_msg_queue);
         break;
      case RUNLOOP_CTL_MSG_QUEUE_DEINIT:
         if (!runloop_msg_queue)
            return true;

         runloop_msg_queue_lock();

         msg_queue_free(runloop_msg_queue);

         runloop_msg_queue_unlock();
         runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_FREE, NULL);

         runloop_msg_queue = NULL;
         break;
      case RUNLOOP_CTL_MSG_QUEUE_INIT:
         runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_DEINIT, NULL);
         runloop_msg_queue = msg_queue_new(8);
         retro_assert(runloop_msg_queue);

#ifdef HAVE_THREADS
         _runloop_msg_queue_lock = slock_new();
         retro_assert(_runloop_msg_queue_lock);
#endif
         break;
      case RUNLOOP_CTL_TASK_INIT:
         {
            bool threaded_enable = false;
#ifdef HAVE_THREADS
            threaded_enable = settings->threaded_data_runloop_enable;
#endif
            task_queue_ctl(TASK_QUEUE_CTL_INIT, &threaded_enable);
         }
         break;
      case RUNLOOP_CTL_SET_CORE_SHUTDOWN:
         runloop_core_shutdown_initiated = true;
         break;
      case RUNLOOP_CTL_UNSET_CORE_SHUTDOWN:
         runloop_core_shutdown_initiated = false;
         break;
      case RUNLOOP_CTL_IS_CORE_SHUTDOWN:
         return runloop_core_shutdown_initiated;
      case RUNLOOP_CTL_SET_SHUTDOWN:
         runloop_shutdown_initiated = true;
         break;
      case RUNLOOP_CTL_UNSET_SHUTDOWN:
         runloop_shutdown_initiated = false;
         break;
      case RUNLOOP_CTL_IS_SHUTDOWN:
         return runloop_shutdown_initiated;
      case RUNLOOP_CTL_SET_EXEC:
         runloop_exec = true;
         break;
      case RUNLOOP_CTL_UNSET_EXEC:
         runloop_exec = false;
         break;
      case RUNLOOP_CTL_IS_EXEC:
         return runloop_exec;
      case RUNLOOP_CTL_DATA_DEINIT:
         task_queue_ctl(TASK_QUEUE_CTL_DEINIT, NULL);
         break;
      case RUNLOOP_CTL_IS_CORE_OPTION_UPDATED:
         if (!runloop_core_options)
            return false;
         return  core_option_manager_updated(runloop_core_options);
      case RUNLOOP_CTL_CORE_OPTION_PREV:
         {
            unsigned *idx = (unsigned*)data;
            if (!idx)
               return false;
            core_option_manager_prev(runloop_core_options, *idx);
            if (ui_companion_is_on_foreground())
               ui_companion_driver_notify_refresh();
         }
         break;
      case RUNLOOP_CTL_CORE_OPTION_NEXT:
         {
            unsigned *idx = (unsigned*)data;
            if (!idx)
               return false;
            core_option_manager_next(runloop_core_options, *idx);
            if (ui_companion_is_on_foreground())
               ui_companion_driver_notify_refresh();
         }
         break;
      case RUNLOOP_CTL_CORE_OPTIONS_GET:
         {
            struct retro_variable *var = (struct retro_variable*)data;

            if (!runloop_core_options || !var)
               return false;

            RARCH_LOG("Environ GET_VARIABLE %s:\n", var->key);
            core_option_manager_get(runloop_core_options, var);
            RARCH_LOG("\t%s\n", var->value ? var->value : "N/A");
         }
         break;
      case RUNLOOP_CTL_CORE_OPTIONS_INIT:
         {
            char *game_options_path           = NULL;
            bool ret                          = false;
            char buf[PATH_MAX_LENGTH]         = {0};
            global_t *global                  = global_get_ptr();
            const char *options_path          = settings->path.core_options;
            const struct retro_variable *vars = 
               (const struct retro_variable*)data;

            if (!*options_path && *global->path.config)
            {
               fill_pathname_resolve_relative(buf, global->path.config,
                     "retroarch-core-options.cfg", sizeof(buf));
               options_path = buf;
            }


            if (settings->game_specific_options)
               ret = rarch_game_specific_options(&game_options_path);

            if(ret)
            {
               runloop_ctl(RUNLOOP_CTL_SET_GAME_OPTIONS_ACTIVE, NULL);
               runloop_core_options = 
                  core_option_manager_new(game_options_path, vars);
               free(game_options_path);
            }
            else
            {
               runloop_ctl(RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE, NULL);
               runloop_core_options = 
                  core_option_manager_new(options_path, vars);
            }

         }
         break;
      case RUNLOOP_CTL_CORE_OPTIONS_FREE:
         if (runloop_core_options)
            core_option_manager_free(runloop_core_options);
         runloop_core_options          = NULL;
         break;
      case RUNLOOP_CTL_CORE_OPTIONS_DEINIT:
         {
            global_t *global                  = global_get_ptr();
            if (!runloop_core_options)
               return false;

            /* check if game options file was just created and flush
               to that file instead */
            if(global && !string_is_empty(global->path.core_options_path))
            {
               core_option_manager_flush_game_specific(runloop_core_options,
                     global->path.core_options_path);
               global->path.core_options_path[0] = '\0';
            }
            else
               core_option_manager_flush(runloop_core_options);

            if (runloop_ctl(RUNLOOP_CTL_IS_GAME_OPTIONS_ACTIVE, NULL))
               runloop_ctl(RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE, NULL);

            runloop_ctl(RUNLOOP_CTL_CORE_OPTIONS_FREE, NULL);
         }
         break;
      case RUNLOOP_CTL_KEY_EVENT_GET:
         {
            retro_keyboard_event_t **key_event = 
               (retro_keyboard_event_t**)data;
            if (!key_event)
               return false;
            *key_event = &runloop_key_event;
         }
         break;
      case RUNLOOP_CTL_FRONTEND_KEY_EVENT_GET:
         {
            retro_keyboard_event_t **key_event = 
               (retro_keyboard_event_t**)data;
            if (!key_event)
               return false;
            *key_event = &runloop_frontend_key_event;
         }
         break;
      case RUNLOOP_CTL_NONE:
      default:
         break;
   }

   return true;
}
예제 #14
0
static int add_adapter(void *data, struct libusb_device *dev)
{
   int rc;
   struct libusb_device_descriptor desc;
   const char *device_name         = NULL;
   struct libusb_adapter *old_head = NULL;
   struct libusb_hid          *hid = (struct libusb_hid*)data;
   struct libusb_adapter *adapter  = (struct libusb_adapter*)
      calloc(1, sizeof(struct libusb_adapter));

   if (!adapter)
      return -1;

   if (!hid)
   {
      free(adapter);
      RARCH_ERR("Allocation of adapter failed.\n");
      return -1;
   }

   rc = libusb_get_device_descriptor(dev, &desc);

   if (rc != LIBUSB_SUCCESS)
   {
      RARCH_ERR("Error getting device descriptor.\n");
      goto error;
   }

   adapter->device = dev;

   libusb_get_description(adapter->device, adapter);

   if (adapter->endpoint_in == 0)
   {
      RARCH_ERR("Could not find HID config for device.\n");
      goto error;
   }

   rc = libusb_open (adapter->device, &adapter->handle);

   if (rc != LIBUSB_SUCCESS)
   {
      RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n",
            (void*)adapter->device, desc.idVendor, desc.idProduct);
      goto error;
   }

   if (desc.iManufacturer)
   {
      libusb_get_string_descriptor_ascii(adapter->handle,
            desc.iManufacturer, adapter->manufacturer_name,
            sizeof(adapter->manufacturer_name));
#if 0
      RARCH_ERR(" Adapter Manufacturer name: %s\n", adapter->manufacturer_name);
#endif
   }

   if (desc.iProduct)
   {
      libusb_get_string_descriptor_ascii(adapter->handle,
            desc.iProduct, adapter->name,
            sizeof(adapter->name));
#if 0
      RARCH_ERR(" Adapter name: %s\n", adapter->name);
#endif
   }

   device_name   = (const char*)adapter->name;

   if (string_is_empty((const char*)adapter->name))
      goto error;

   adapter->send_control_lock = slock_new();
   adapter->send_control_buffer = fifo_new(4096);

   if (!adapter->send_control_lock || !adapter->send_control_buffer)
   {
      RARCH_ERR("Error creating send control buffer.\n");
      goto error;
   }

   adapter->slot = pad_connection_pad_init(hid->slots,
         device_name, desc.idVendor, desc.idProduct,
         adapter, &libusb_hid_device_send_control);

   if (adapter->slot == -1)
      goto error;

   if (!pad_connection_has_interface(hid->slots, adapter->slot))
   {
      RARCH_ERR(" Interface not found (%s).\n", adapter->name);
      goto error;
   }

   RARCH_LOG("Interface found: [%s].\n", adapter->name);

   if (libusb_kernel_driver_active(adapter->handle, 0) == 1
         && libusb_detach_kernel_driver(adapter->handle, 0))
   {
      RARCH_ERR("Error detaching handle 0x%p from kernel.\n", adapter->handle);
      goto error;
   }

   rc = libusb_claim_interface(adapter->handle, adapter->interface_number);

   if (rc != LIBUSB_SUCCESS)
   {
      RARCH_ERR("Error claiming interface %d .\n", adapter->interface_number);
      goto error;
   }

   RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n",
         adapter->device, desc.idVendor, desc.idProduct);

   libusb_hid_device_add_autodetect(adapter->slot,
         device_name, libusb_hid.ident, desc.idVendor, desc.idProduct);

   adapter->hid = hid;
   adapter->thread = sthread_create(adapter_thread, adapter);

   if (!adapter->thread)
   {
      RARCH_ERR("Error initializing adapter thread.\n");
      goto error;
   }

   old_head      = adapters.next;
   adapters.next = adapter;
   adapter->next = old_head;

   return 0;

error:
   if (adapter->thread)
      sthread_join(adapter->thread);
   if (adapter->send_control_lock)
      slock_free(adapter->send_control_lock);
   if (adapter->send_control_buffer)
      fifo_free(adapter->send_control_buffer);
   if (adapter)
      free(adapter);
   return -1;
}
예제 #15
0
/**
 * video_shader_resolve_parameters:
 * @conf              : Preset file to read from.
 * @shader            : Shader passes handle.
 *
 * Resolves all shader parameters belonging to shaders.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool video_shader_resolve_parameters(config_file_t *conf,
      struct video_shader *shader)
{
   unsigned i;
   struct video_shader_parameter *param = &shader->parameters[0];

   shader->num_parameters = 0;

   /* Find all parameters in our shaders. */

   for (i = 0; i < shader->passes; i++)
   {
      intfstream_t *file = NULL;
      size_t line_size   = 4096 * sizeof(char);
      char *line         = NULL;
      const char *path   = shader->pass[i].source.path;

     if (string_is_empty(path))
        continue;

#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS)
      /* First try to use the more robust slang
       * implementation to support #includes. */
      /* FIXME: The check for slang can be removed
       * if it's sufficiently tested for
       * GLSL/Cg as well, it should be the same implementation. */
      if (string_is_equal(path_get_extension(path), "slang") &&
            slang_preprocess_parse_parameters(path, shader))
         continue;

      /* If that doesn't work, fallback to the old path.
       * Ideally, we'd get rid of this path sooner or later. */
#endif
      file = intfstream_open_file(path,
            RETRO_VFS_FILE_ACCESS_READ,
            RETRO_VFS_FILE_ACCESS_HINT_NONE);

      if (!file)
         continue;

      line    = (char*)malloc(4096 * sizeof(char));
      line[0] = '\0';

      /* even though the pass is set in the loop too, not all passes have parameters */
      param->pass = i;

      while (shader->num_parameters < ARRAY_SIZE(shader->parameters)
            && intfstream_gets(file, line, line_size))
      {
         int ret = sscanf(line,
               "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
               param->id,        param->desc,    &param->initial,
               &param->minimum, &param->maximum, &param->step);

         if (ret < 5)
            continue;

         param->id[63]   = '\0';
         param->desc[63] = '\0';

         if (ret == 5)
            param->step = 0.1f * (param->maximum - param->minimum);

         param->pass = i;

         RARCH_LOG("Found #pragma parameter %s (%s) %f %f %f %f in pass %d\n",
               param->desc,    param->id,      param->initial,
               param->minimum, param->maximum, param->step, param->pass);
         param->current = param->initial;

         shader->num_parameters++;
         param++;
      }

      free(line);
      intfstream_close(file);
      free(file);
   }

   if (conf && !video_shader_resolve_current_parameters(conf, shader))
      return false;

   return true;
}
예제 #16
0
/**
 * playlist_push:
 * @playlist        	   : Playlist handle.
 * @path                : Path of new playlist entry.
 * @core_path           : Core path of new playlist entry.
 * @core_name           : Core name of new playlist entry.
 *
 * Push entry to top of playlist.
 **/
bool playlist_push(playlist_t *playlist,
      const char *path, const char *label,
      const char *core_path, const char *core_name,
      const char *crc32,
      const char *db_name)
{
   size_t i;

   if (string_is_empty(core_path) || string_is_empty(core_name))
   {
      if (string_is_empty(core_name) && !string_is_empty(core_path))
      {
         static char base_path[255] = {0};
         fill_pathname_base_noext(base_path, core_path, sizeof(base_path));
         core_name = base_path;
         RARCH_LOG("core_name is now: %s\n", core_name);
      }

      RARCH_LOG("core_name: %s.\n", string_is_empty(core_name) ? "N/A" : core_name);
      RARCH_LOG("core_path: %s.\n", string_is_empty(core_path) ? "N/A" : core_path);

      if (string_is_empty(core_path) || string_is_empty(core_name))
      {
         RARCH_ERR("cannot push NULL or empty core name into the playlist.\n");
         return false;
      }
   }

   if (string_is_empty(path))
      path = NULL;

   if (!playlist)
      return false;

   for (i = 0; i < playlist->size; i++)
   {
      struct playlist_entry tmp;
      bool equal_path = (!path && !playlist->entries[i].path) ||
         (path && playlist->entries[i].path &&
          string_is_equal(path,playlist->entries[i].path));

      /* Core name can have changed while still being the same core.
       * Differentiate based on the core path only. */
      if (!equal_path)
         continue;

      if (!string_is_equal(playlist->entries[i].core_path, core_path))
         continue;

      /* If top entry, we don't want to push a new entry since
       * the top and the entry to be pushed are the same. */
      if (i == 0)
         return false;

      /* Seen it before, bump to top. */
      tmp = playlist->entries[i];
      memmove(playlist->entries + 1, playlist->entries,
            i * sizeof(struct playlist_entry));
      playlist->entries[0] = tmp;

      return true;
   }

   if (playlist->size == playlist->cap)
   {
      struct playlist_entry *entry = &playlist->entries[playlist->cap - 1];

      if (entry)
         playlist_free_entry(entry);
      playlist->size--;
   }

   memmove(playlist->entries + 1, playlist->entries,
         (playlist->cap - 1) * sizeof(struct playlist_entry));

   playlist->entries[0].path      = NULL;
   playlist->entries[0].label     = NULL;
   playlist->entries[0].core_path = NULL;
   playlist->entries[0].core_name = NULL;
   playlist->entries[0].db_name   = NULL;
   playlist->entries[0].crc32     = NULL;
   if (!string_is_empty(path))
      playlist->entries[0].path   = strdup(path);
   if (!string_is_empty(label))
      playlist->entries[0].label  = strdup(label);
   if (!string_is_empty(core_path))
      playlist->entries[0].core_path = strdup(core_path);
   if (!string_is_empty(core_name))
      playlist->entries[0].core_name = strdup(core_name);
   if (!string_is_empty(db_name))
      playlist->entries[0].db_name   = strdup(db_name);
   if (!string_is_empty(crc32))
      playlist->entries[0].crc32     = strdup(crc32);

   playlist->size++;

   return true;
}
예제 #17
0
파일: drawobj.c 프로젝트: astrotycoon/grace
void draw_atext(Canvas *canvas, Quark *q)
{
    VPoint anchor;
    AText *at = atext_get_data(q);
    TextFrame *tf;
    view bbox;

    if (!at || string_is_empty(at->s)) {
        return;
    }

    if (Apoint2Vpoint(q, &at->ap, &anchor) != RETURN_SUCCESS) {
        return;
    }
    anchor.x += at->offset.x;
    anchor.y += at->offset.y;

    setclipping(canvas, FALSE);

    tf = &at->frame;

    drawtext(canvas, &anchor, &at->text_props, tf, at->s, &bbox);

    at->bb = bbox;

    if ((tf->line.pen.pattern || tf->fillpen.pattern) &&
            at->arrow_flag && tf->line.style) {
        VPoint vp1, vp2;

        vp2.x = anchor.x - at->offset.x;
        vp2.y = anchor.y - at->offset.y;

        switch (tf->decor) {
        case FRAME_DECOR_LINE:
            if (vp2.x < bbox.xv1) {
                vp1.x = bbox.xv1;
            } else if (vp2.x > bbox.xv2) {
                vp1.x = bbox.xv2;
            } else {
                vp1.x = vp2.x;
            }
            vp1.y = bbox.yv1;
            break;
        case FRAME_DECOR_OVAL:
            if (vp2.x < bbox.xv1) {
                vp1.x = bbox.xv1;
            } else if (vp2.x > bbox.xv2) {
                vp1.x = bbox.xv2;
            } else {
                vp1.x = (bbox.xv1 + bbox.xv2)/2;
            }
            if (vp2.y < bbox.yv1) {
                vp1.y = bbox.yv1;
            } else if (vp2.y > bbox.yv2) {
                vp1.y = bbox.yv2;
            } else {
                vp1.y = (bbox.yv1 + bbox.yv2)/2;
            }
            break;
        default:
            if (vp2.x < bbox.xv1) {
                vp1.x = bbox.xv1;
            } else if (vp2.x > bbox.xv2) {
                vp1.x = bbox.xv2;
            } else {
                vp1.x = vp2.x;
            }
            if (vp2.y < bbox.yv1) {
                vp1.y = bbox.yv1;
            } else if (vp2.y > bbox.yv2) {
                vp1.y = bbox.yv2;
            } else {
                vp1.y = vp2.y;
            }
        }

        setline(canvas, &tf->line);
        DrawLine(canvas, &vp1, &vp2);
        draw_arrowhead(canvas, &vp1, &vp2, &at->arrow,
                       &tf->line.pen, &tf->line.pen);
    }
}
예제 #18
0
bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
{
   static struct retro_system_info menu_driver_system;
   static bool menu_driver_pending_quick_menu      = false;
   static bool menu_driver_pending_action          = false;
   static bool menu_driver_prevent_populate        = false;
   static bool menu_driver_load_no_content         = false;
   static bool menu_driver_alive                   = false;
   static bool menu_driver_data_own                = false;
   static bool menu_driver_pending_quit            = false;
   static bool menu_driver_pending_shutdown        = false;
   static content_playlist_t *menu_driver_playlist = NULL;
   static struct video_shader *menu_driver_shader  = NULL;
   static menu_handle_t *menu_driver_data          = NULL;
   static const menu_ctx_driver_t *menu_driver_ctx = NULL;
   static void *menu_userdata                      = NULL;
   settings_t *settings                            = config_get_ptr();

   switch (state)
   {
      case RARCH_MENU_CTL_IS_PENDING_ACTION:
         if (!menu_driver_pending_action)
            return false;
         menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_ACTION, NULL);
         break;
      case RARCH_MENU_CTL_SET_PENDING_ACTION:
         menu_driver_pending_action = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_ACTION:
         menu_driver_pending_action = false;
         break;
      case RARCH_MENU_CTL_DRIVER_DATA_GET:
         {
            menu_handle_t **driver_data = (menu_handle_t**)data;
            if (!driver_data)
               return false;
            *driver_data = menu_driver_data;
         }
         break;
      case RARCH_MENU_CTL_IS_PENDING_QUICK_MENU:
         return menu_driver_pending_quick_menu;
      case RARCH_MENU_CTL_SET_PENDING_QUICK_MENU:
         menu_driver_pending_quick_menu = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU:
         menu_driver_pending_quick_menu = false;
         break;
      case RARCH_MENU_CTL_IS_PENDING_QUIT:
         return menu_driver_pending_quit;
      case RARCH_MENU_CTL_SET_PENDING_QUIT:
         menu_driver_pending_quit     = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_QUIT:
         menu_driver_pending_quit     = false;
         break;
      case RARCH_MENU_CTL_IS_PENDING_SHUTDOWN:
         return menu_driver_pending_shutdown;
      case RARCH_MENU_CTL_SET_PENDING_SHUTDOWN:
         menu_driver_pending_shutdown = true;
         break;
      case RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN:
         menu_driver_pending_shutdown = false;
         break;
      case RARCH_MENU_CTL_DESTROY:
         menu_driver_pending_quick_menu = false;
         menu_driver_pending_action     = false;
         menu_driver_pending_quit       = false;
         menu_driver_pending_shutdown   = false;
         menu_driver_prevent_populate   = false;
         menu_driver_load_no_content    = false;
         menu_driver_alive              = false;
         menu_driver_data_own           = false;
         menu_driver_ctx                = NULL;
         menu_userdata                  = NULL;
         break;
      case RARCH_MENU_CTL_PLAYLIST_FREE:
         if (menu_driver_playlist)
            content_playlist_free(menu_driver_playlist);
         menu_driver_playlist = NULL;
         break;
      case RARCH_MENU_CTL_FIND_DRIVER:
         {
            int i;
            driver_ctx_info_t drv;
            settings_t *settings = config_get_ptr();

            drv.label = "menu_driver";
            drv.s     = settings->menu.driver;

            driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv);

            i = drv.len;

            if (i >= 0)
               menu_driver_ctx = (const menu_ctx_driver_t*)
                  menu_driver_find_handle(i);
            else
            {
               unsigned d;
               RARCH_WARN("Couldn't find any menu driver named \"%s\"\n",
                     settings->menu.driver);
               RARCH_LOG_OUTPUT("Available menu drivers are:\n");
               for (d = 0; menu_driver_find_handle(d); d++)
                  RARCH_LOG_OUTPUT("\t%s\n", menu_driver_find_ident(d));
               RARCH_WARN("Going to default to first menu driver...\n");

               menu_driver_ctx = (const menu_ctx_driver_t*)
                  menu_driver_find_handle(0);

               if (!menu_driver_ctx)
               {
                  retro_fail(1, "find_menu_driver()");
                  return false;
               }
            }
         }
         break;
      case RARCH_MENU_CTL_PLAYLIST_INIT:
         {
            const char *path = (const char*)data;
            if (string_is_empty(path))
               return false;
            menu_driver_playlist  = content_playlist_init(path,
                  COLLECTION_SIZE);
         }
         break;
      case RARCH_MENU_CTL_PLAYLIST_GET:
         {
            content_playlist_t **playlist = (content_playlist_t**)data;
            if (!playlist)
               return false;
            *playlist = menu_driver_playlist;
         }
         break;
      case RARCH_MENU_CTL_SYSTEM_INFO_GET:
         {
            struct retro_system_info **system = 
               (struct retro_system_info**)data;
            if (!system)
               return false;
            *system = &menu_driver_system;
         }
         break;
      case RARCH_MENU_CTL_SYSTEM_INFO_DEINIT:
#ifdef HAVE_DYNAMIC
         libretro_free_system_info(&menu_driver_system);
         memset(&menu_driver_system, 0, sizeof(struct retro_system_info));
#endif
         break;
      case RARCH_MENU_CTL_RENDER_MESSAGEBOX:
         if (menu_driver_ctx->render_messagebox)
            menu_driver_ctx->render_messagebox(menu_userdata,
                  menu_driver_data->menu_state.msg);
         break;
      case RARCH_MENU_CTL_BLIT_RENDER:
         if (menu_driver_ctx->render)
            menu_driver_ctx->render(menu_userdata);
         break;
      case RARCH_MENU_CTL_RENDER:
         if (!menu_driver_data)
            return false;

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER) 
               != BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX))
            BIT64_SET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER);

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER))
            menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL);

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX) 
               && !string_is_empty(menu_driver_data->menu_state.msg))
         {
            menu_driver_ctl(RARCH_MENU_CTL_RENDER_MESSAGEBOX, NULL);

            if (ui_companion_is_on_foreground())
            {
               const ui_companion_driver_t *ui = ui_companion_get_ptr();
               if (ui->render_messagebox)
                  ui->render_messagebox(menu_driver_data->menu_state.msg);
            }
         }

         if (BIT64_GET(menu_driver_data->state, MENU_STATE_BLIT))
         {
            menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE_TIME, NULL);
            menu_driver_ctl(RARCH_MENU_CTL_BLIT_RENDER, NULL);
         }

         if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) 
               && !runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL))
            menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO, NULL);

         menu_driver_ctl(RARCH_MENU_CTL_SET_TEXTURE, NULL);

         menu_driver_data->state               = 0;
         break;
      case RARCH_MENU_CTL_SHADER_DEINIT:
#ifdef HAVE_SHADER_MANAGER
         if (menu_driver_shader)
            free(menu_driver_shader);
         menu_driver_shader = NULL;
#endif
         break;
      case RARCH_MENU_CTL_SHADER_INIT:
#ifdef HAVE_SHADER_MANAGER
         menu_driver_shader = (struct video_shader*)
            calloc(1, sizeof(struct video_shader));
         if (!menu_driver_shader)
            return false;
#endif
         break;
      case RARCH_MENU_CTL_SHADER_GET:
         {
            struct video_shader **shader = (struct video_shader**)data;
            if (!shader)
               return false;
            *shader = menu_driver_shader;
         }
         break;
      case RARCH_MENU_CTL_FRAME:
         if (!menu_driver_alive)
            return false;
         if (menu_driver_ctx->frame)
            menu_driver_ctx->frame(menu_userdata);
         break;
      case RARCH_MENU_CTL_SET_PREVENT_POPULATE:
         menu_driver_prevent_populate = true;
         break;
      case RARCH_MENU_CTL_UNSET_PREVENT_POPULATE:
         menu_driver_prevent_populate = false;
         break;
      case RARCH_MENU_CTL_IS_PREVENT_POPULATE:
         return menu_driver_prevent_populate;
      case RARCH_MENU_CTL_SET_TOGGLE:
         menu_driver_toggle(true);
         break;
      case RARCH_MENU_CTL_UNSET_TOGGLE:
         menu_driver_toggle(false);
         break;
      case RARCH_MENU_CTL_SET_ALIVE:
         menu_driver_alive = true;
         break;
      case RARCH_MENU_CTL_UNSET_ALIVE:
         menu_driver_alive = false;
         break;
      case RARCH_MENU_CTL_IS_ALIVE:
         return menu_driver_alive;
      case RARCH_MENU_CTL_SET_OWN_DRIVER:
         menu_driver_data_own = true;
         break;
      case RARCH_MENU_CTL_UNSET_OWN_DRIVER:
         if (!content_ctl(CONTENT_CTL_IS_INITED, NULL))
            return false;
         menu_driver_data_own = false;
         break;
      case RARCH_MENU_CTL_SET_TEXTURE:
         if (menu_driver_ctx->set_texture)
            menu_driver_ctx->set_texture();
         break;
      case RARCH_MENU_CTL_IS_SET_TEXTURE:
         if (!menu_driver_ctx)
            return false;
         return menu_driver_ctx->set_texture;
      case RARCH_MENU_CTL_OWNS_DRIVER:
         return menu_driver_data_own;
      case RARCH_MENU_CTL_DEINIT:
         menu_driver_ctl(RARCH_MENU_CTL_CONTEXT_DESTROY, NULL);
         if (menu_driver_ctl(RARCH_MENU_CTL_OWNS_DRIVER, NULL))
            return true;
         if (menu_driver_data)
         {
            menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_FREE, NULL);
            menu_shader_free(menu_driver_data);
            menu_input_ctl(MENU_INPUT_CTL_DEINIT, NULL);
            menu_navigation_ctl(MENU_NAVIGATION_CTL_DEINIT, NULL);

            if (menu_driver_ctx && menu_driver_ctx->free)
               menu_driver_ctx->free(menu_userdata);

            if (menu_userdata)
               free(menu_userdata);
            menu_userdata = NULL;

            menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL);
            menu_display_ctl(MENU_DISPLAY_CTL_DEINIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_DEINIT, NULL);

            event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL);

            core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL);
            core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_FREE, NULL);

            free(menu_driver_data);
         }
         menu_driver_data = NULL;
         break;
      case RARCH_MENU_CTL_INIT:
         if (menu_driver_data)
            return true;

         menu_driver_data = (menu_handle_t*)
            menu_driver_ctx->init(&menu_userdata);

         if (!menu_driver_data || !menu_init(menu_driver_data))
         {
            retro_fail(1, "init_menu()");
            return false;
         }

         strlcpy(settings->menu.driver, menu_driver_ctx->ident,
               sizeof(settings->menu.driver));

         if (menu_driver_ctx->lists_init)
         {
            if (!menu_driver_ctx->lists_init(menu_driver_data))
            {
               retro_fail(1, "init_menu()");
               return false;
            }
         }
         break;
      case RARCH_MENU_CTL_LOAD_NO_CONTENT_GET:
         {
            bool **ptr = (bool**)data;
            if (!ptr)
               return false;
            *ptr = (bool*)&menu_driver_load_no_content;
         }
         break;
      case RARCH_MENU_CTL_HAS_LOAD_NO_CONTENT:
         return menu_driver_load_no_content;
      case RARCH_MENU_CTL_SET_LOAD_NO_CONTENT:
         menu_driver_load_no_content = true;
         break;
      case RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT:
         menu_driver_load_no_content = false;
         break;
      case RARCH_MENU_CTL_NAVIGATION_INCREMENT:
         if (menu_driver_ctx->navigation_increment)
            menu_driver_ctx->navigation_increment(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_DECREMENT:
         if (menu_driver_ctx->navigation_decrement)
            menu_driver_ctx->navigation_decrement(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_SET:
         {
            bool *scroll = (bool*)data;

            if (!scroll)
               return false;
            if (menu_driver_ctx->navigation_set)
               menu_driver_ctx->navigation_set(menu_userdata, *scroll);
         }
         break;
      case RARCH_MENU_CTL_NAVIGATION_SET_LAST:
         if (menu_driver_ctx->navigation_set_last)
            menu_driver_ctx->navigation_set_last(menu_userdata);
         break;
      case RARCH_MENU_CTL_NAVIGATION_ASCEND_ALPHABET:
         {
            size_t *ptr_out = (size_t*)data;

            if (!ptr_out)
               return false;

            if (menu_driver_ctx->navigation_ascend_alphabet)
               menu_driver_ctx->navigation_ascend_alphabet(
                     menu_userdata, ptr_out);
         }
      case RARCH_MENU_CTL_NAVIGATION_DESCEND_ALPHABET:
         {
            size_t *ptr_out = (size_t*)data;

            if (!ptr_out)
               return false;

            if (menu_driver_ctx->navigation_descend_alphabet)
               menu_driver_ctx->navigation_descend_alphabet(
                     menu_userdata, ptr_out);
         }
         break;
      case RARCH_MENU_CTL_NAVIGATION_CLEAR:
         {
            bool *pending_push = (bool*)data;

            if (!pending_push)
               return false;
            if (menu_driver_ctx->navigation_clear)
               menu_driver_ctx->navigation_clear(
                     menu_userdata, pending_push);
         }
         break;
      case RARCH_MENU_CTL_POPULATE_ENTRIES:
         {
            menu_displaylist_info_t *info = (menu_displaylist_info_t*)data;

            if (!info)
               return false;
            if (menu_driver_ctx->populate_entries)
               menu_driver_ctx->populate_entries(
                     menu_userdata, info->path,
                     info->label, info->type);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_ENTRY:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->list_get_entry)
            {
               list->entry = NULL;
               return false;
            }
            list->entry = menu_driver_ctx->list_get_entry(menu_userdata,
                  list->type, list->idx);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_SIZE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->list_get_size)
            {
               list->size = 0;
               return false;
            }
            list->size = menu_driver_ctx->list_get_size(menu_userdata, list->type);
         }
         break;
      case RARCH_MENU_CTL_LIST_GET_SELECTION:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->list_get_selection)
            {
               list->selection = 0;
               return false;
            }
            list->selection = menu_driver_ctx->list_get_selection(menu_userdata);
         }
         break;
      case RARCH_MENU_CTL_LIST_FREE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;

            if (menu_driver_ctx)
            {
               if (menu_driver_ctx->list_free)
                  menu_driver_ctx->list_free(list->list, list->idx, list->list_size);
            }

            if (list->list)
            {
               file_list_free_userdata  (list->list, list->idx);
               file_list_free_actiondata(list->list, list->idx);
            }
         }
         break;
      case RARCH_MENU_CTL_LIST_PUSH:
         {
            menu_ctx_displaylist_t *disp_list = (menu_ctx_displaylist_t*)data;

            if (menu_driver_ctx->list_push)
               if (menu_driver_ctx->list_push(menu_driver_data,
                        menu_userdata, disp_list->info, disp_list->type) == 0)
                  return true;
         }
         return false;
      case RARCH_MENU_CTL_LIST_CLEAR:
         {
            file_list_t *list = (file_list_t*)data;
            if (!list)
               return false;
            if (menu_driver_ctx->list_clear)
               menu_driver_ctx->list_clear(list);
         }
         break;
      case RARCH_MENU_CTL_TOGGLE:
         {
            bool *latch = (bool*)data;
            if (!latch)
               return false;

            if (menu_driver_ctx->toggle)
               menu_driver_ctx->toggle(menu_userdata, *latch);
         }
         break;
      case RARCH_MENU_CTL_REFRESH:
         {
#if 0
            bool refresh = false;
            menu_entries_ctl(MENU_ENTRIES_CTL_LIST_DEINIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_DEINIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_INIT, NULL);
            menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
#endif
         }
         break;
      case RARCH_MENU_CTL_CONTEXT_RESET:
         if (!menu_driver_ctx || !menu_driver_ctx->context_reset)
            return false;
         menu_driver_ctx->context_reset(menu_userdata);
         break;
      case RARCH_MENU_CTL_CONTEXT_DESTROY:
         if (!menu_driver_ctx || !menu_driver_ctx->context_destroy)
            return false;
         menu_driver_ctx->context_destroy(menu_userdata);
         break;
      case RARCH_MENU_CTL_SHADER_MANAGER_INIT:
         menu_shader_manager_init(menu_driver_data);
         break;
      case RARCH_MENU_CTL_LIST_SET_SELECTION:
         {
            file_list_t *list = (file_list_t*)data;

            if (!list)
               return false;

            if (!menu_driver_ctx || !menu_driver_ctx->list_set_selection)
               return false;

            menu_driver_ctx->list_set_selection(menu_userdata, list);
         }
         break;
      case RARCH_MENU_CTL_LIST_CACHE:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!list || !menu_driver_ctx || !menu_driver_ctx->list_cache)
               return false;
            menu_driver_ctx->list_cache(menu_userdata,
                  list->type, list->action);
         }
         break;
      case RARCH_MENU_CTL_LIST_INSERT:
         {
            menu_ctx_list_t *list = (menu_ctx_list_t*)data;
            if (!list || !menu_driver_ctx || !menu_driver_ctx->list_insert)
               return false;
            menu_driver_ctx->list_insert(menu_userdata,
                  list->list, list->path, list->label, list->idx);
         }
         break;
      case RARCH_MENU_CTL_LOAD_IMAGE:
         {
            menu_ctx_load_image_t *load_image_info = 
               (menu_ctx_load_image_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->load_image)
               return false;
            return menu_driver_ctx->load_image(menu_userdata,
                  load_image_info->data, load_image_info->type);
         }
      case RARCH_MENU_CTL_ITERATE:
         {
            bool retcode = false;
            menu_ctx_iterate_t *iterate = (menu_ctx_iterate_t*)data;

            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUICK_MENU, NULL))
            {
               bool msg_force               = true;

               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU, NULL);
               menu_entries_flush_stack(NULL, MENU_SETTINGS);
               menu_display_ctl(MENU_DISPLAY_CTL_SET_MSG_FORCE, &msg_force);

               generic_action_ok_displaylist_push("",
                     "", 0, 0, 0, ACTION_OK_DL_CONTENT_SETTINGS);

               if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL))
               {
                  menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL);
                  return false;
               }

               return true;
            }

            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL))
            {
               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL);
               return false;
            }
            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_SHUTDOWN, NULL))
            {
               menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN, NULL);
               if (!event_cmd_ctl(EVENT_CMD_QUIT, NULL))
                  return false;
               return true;
            }
            if (!menu_driver_ctx || !menu_driver_ctx->iterate)
               return false;
             
            if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_ACTION, &retcode))
            {
                iterate->action = pending_iter.action;
                pending_iter.action = MENU_ACTION_NOOP;
            }
            if (menu_driver_ctx->iterate(menu_driver_data,
                     menu_userdata, iterate->action) == -1)
               return false;
         }
         break;
      case RARCH_MENU_CTL_ENVIRONMENT:
         {
            menu_ctx_environment_t *menu_environ = 
               (menu_ctx_environment_t*)data;

            if (menu_driver_ctx->environ_cb)
            {
               if (menu_driver_ctx->environ_cb(menu_environ->type,
                        menu_environ->data, menu_userdata) == 0)
                  return true;
            }
         }
         return false;
      case RARCH_MENU_CTL_POINTER_TAP:
         {
            menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data;
            if (!menu_driver_ctx || !menu_driver_ctx->pointer_tap)
            {
               point->retcode = 0;
               return false;
            }
            point->retcode = menu_driver_ctx->pointer_tap(menu_userdata,
                  point->x, point->y, point->ptr,
                  point->cbs, point->entry, point->action);
         }
         break;
      case RARCH_MENU_CTL_BIND_INIT:
         {
            menu_ctx_bind_t *bind = (menu_ctx_bind_t*)data;

            if (!menu_driver_ctx || !menu_driver_ctx->bind_init)
            {
               bind->retcode = 0;
               return false;
            }
            bind->retcode = menu_driver_ctx->bind_init(
                  bind->cbs,
                  bind->path,
                  bind->label,
                  bind->type,
                  bind->idx,
                  bind->elem0,
                  bind->elem1,
                  bind->label_hash,
                  bind->menu_label_hash);
         }
         break;
      default:
      case RARCH_MENU_CTL_NONE:
         break;
   }

   return true;
}
예제 #19
0
static bool load_content_from_compressed_archive(
      struct string_list *temporary_content,
      struct retro_game_info *info, unsigned i,
      struct string_list* additional_path_allocs,
      bool need_fullpath, const char *path)
{
   union string_list_elem_attr attributes;
   char new_path[PATH_MAX_LENGTH];
   char new_basedir[PATH_MAX_LENGTH];
   ssize_t new_path_len              = 0;
   bool ret                          = false;
   settings_t *settings              = config_get_ptr();
   rarch_system_info_t      *sys_info= NULL;

   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &sys_info);

   if (sys_info && sys_info->info.block_extract)
      return true;
   if (!need_fullpath || !path_contains_compressed_file(path))
      return true;

   RARCH_LOG("Compressed file in case of need_fullpath."
         " Now extracting to temporary directory.\n");

   strlcpy(new_basedir, settings->directory.cache,
         sizeof(new_basedir));

   if (string_is_empty(new_basedir) || !path_is_directory(new_basedir))
   {
      RARCH_WARN("Tried extracting to cache directory, but "
            "cache directory was not set or found. "
            "Setting cache directory to directory "
            "derived by basename...\n");
      fill_pathname_basedir(new_basedir, path,
            sizeof(new_basedir));
   }

   attributes.i = 0;
   fill_pathname_join(new_path, new_basedir,
         path_basename(path), sizeof(new_path));

   ret = content_file_compressed_read(path, NULL, new_path, &new_path_len);

   if (!ret || new_path_len < 0)
   {
      RARCH_ERR("%s \"%s\".\n",
            msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE),
            path);
      return false;
   }

   RARCH_LOG("New path is: [%s]\n", new_path);

   string_list_append(additional_path_allocs, new_path, attributes);
   info[i].path = 
      additional_path_allocs->elems[additional_path_allocs->size -1 ].data;

   if (!string_list_append(temporary_content, new_path, attributes))
      return false;

   return true;
}
예제 #20
0
void fill_pathname_abbreviate_special(char *out_path,
      const char *in_path, size_t size)
{
#if !defined(RARCH_CONSOLE)
   unsigned i;
   const char *candidates[3];
   const char *notations[3];
   char *application_dir     = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   const char *home          = getenv("HOME");

   application_dir[0] = '\0';

   /* application_dir could be zero-string. Safeguard against this.
    *
    * Keep application dir in front of home, moving app dir to a
    * new location inside home would break otherwise. */

   /* ugly hack - use application_dir pointer
    * before filling it in. C89 reasons */
   candidates[0] = application_dir;
   candidates[1] = home;
   candidates[2] = NULL;

   notations [0] = ":";
   notations [1] = "~";
   notations [2] = NULL;

   fill_pathname_application_path(application_dir,
         PATH_MAX_LENGTH * sizeof(char));
   path_basedir_wrapper(application_dir);

   for (i = 0; candidates[i]; i++)
   {
      if (!string_is_empty(candidates[i]) &&
            strstr(in_path, candidates[i]) == in_path)
      {
         size_t src_size  = strlcpy(out_path, notations[i], size);

         retro_assert(src_size < size);

         out_path        += src_size;
         size            -= src_size;
         in_path         += strlen(candidates[i]);

         if (!path_char_is_slash(*in_path))
         {
            retro_assert(strlcpy(out_path,
                     path_default_slash(), size) < size);
            out_path++;
            size--;
         }

         break; /* Don't allow more abbrevs to take place. */
      }
   }

   free(application_dir);
#endif

   retro_assert(strlcpy(out_path, in_path, size) < size);
}
예제 #21
0
static bool content_load_wrapper(
      content_ctx_info_t *content_info,
      bool launched_from_menu)
{
   char name[PATH_MAX_LENGTH];
   char msg[PATH_MAX_LENGTH];
   char *fullpath       = NULL;

   runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath);

#ifdef HAVE_MENU
   if (launched_from_menu)
   {
      /* redraw menu frame */
      menu_display_set_msg_force(true);
      menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL);

      fill_pathname_base(name, fullpath, sizeof(name));
   }
#endif

   if (!content_load(content_info))
      goto error;

   if (launched_from_menu)
   {
      /** Show loading OSD message */
      if (*fullpath)
      {
         snprintf(msg, sizeof(msg), "INFO - Loading %s ...", name);
         runloop_msg_queue_push(msg, 1, 1, false);
      }
   }
   
   /* Push entry to top of history playlist */
   if (content_is_inited() || content_does_not_need_content())
   {
      char tmp[PATH_MAX_LENGTH];
      struct retro_system_info *info = NULL;
      rarch_system_info_t *system    = NULL;

      runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);
      if (system)
         info = &system->info;

#ifdef HAVE_MENU
      if (launched_from_menu)
         menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &info);
#endif

      strlcpy(tmp, fullpath, sizeof(tmp));

      if (!launched_from_menu)
      {
         /* Path can be relative here.
          * Ensure we're pushing absolute path. */
         if (*tmp)
            path_resolve_realpath(tmp, sizeof(tmp));
      }

      if (info && *tmp)
      {
         content_push_to_history_playlist(
               true, tmp, info);
         playlist_write_file(g_defaults.history);
      }
   }

   return true;

error:
   if (launched_from_menu)
   {
      if (!string_is_empty(fullpath) && !string_is_empty(name))
      {
         snprintf(msg, sizeof(msg), "Failed to load %s.\n", name);
         runloop_msg_queue_push(msg, 1, 90, false);
      }
   }
   return false;
}
예제 #22
0
void *rarch_task_push_http_transfer(const char *url, const char *type,
                                    retro_task_callback_t cb, void *user_data)
{
    char tmp[PATH_MAX_LENGTH];
    task_finder_data_t find_data;
    struct http_connection_t *conn = NULL;
    retro_task_t  *t               = NULL;
    http_handle_t *http            = NULL;

    if (string_is_empty(url))
        return NULL;

    find_data.func     = rarch_task_http_finder;
    find_data.userdata = (void*)url;

    /* Concurrent download of the same file is not allowed */
    if (task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data))
    {
        RARCH_LOG("[http] '%s'' is already being downloaded.\n", url);
        return NULL;
    }

    conn = net_http_connection_new(url);

    if (!conn)
        return NULL;

    http                    = (http_handle_t*)calloc(1, sizeof(*http));

    if (!http)
        goto error;

    http->connection.handle = conn;
    http->connection.cb     = &cb_http_conn_default;

    if (type)
        strlcpy(http->connection.elem1, type, sizeof(http->connection.elem1));

    strlcpy(http->connection.url, url, sizeof(http->connection.url));

    http->status            = HTTP_STATUS_CONNECTION_TRANSFER;
    t                       = (retro_task_t*)calloc(1, sizeof(*t));

    if (!t)
        goto error;

    t->handler              = rarch_task_http_transfer_handler;
    t->state                = http;
    t->callback             = cb;
    t->user_data            = user_data;
    t->progress             = -1;

    snprintf(tmp, sizeof(tmp), "%s '%s'",
             msg_hash_to_str(MSG_DOWNLOADING), path_basename(url));

    t->title                = strdup(tmp);

    task_queue_ctl(TASK_QUEUE_CTL_PUSH, t);

    return t;

error:
    if (conn)
        net_http_connection_free(conn);
    if (http)
        free(http);

    return NULL;
}
예제 #23
0
파일: prompt.c 프로젝트: SmoothDude/toxic
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{
    ChatContext *ctx = self->chatwin;

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    if (x2 <= 0)
        return;

    /* ignore non-menu related input if active */
    if (self->help->active) {
        help_onKey(self, key);
        return;
    }

    if (ltr) {    /* char is printable */
        input_new_char(self, key, x, y, x2, y2);
        return;
    }

    if (line_info_onKey(self, key))
        return;

    input_handle(self, key, x, y, x2, y2);

    if (key == '\t') {    /* TAB key: auto-completes command */
        if (ctx->len > 1 && ctx->line[0] == '/') {
            int diff = -1;

            if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0)
                diff = dir_match(self, m, ctx->line, L"/avatar");
            else if (wcsncmp(ctx->line, L"/status ", wcslen(L"/status ")) == 0){
                const char status_cmd_list[3][8] = {
                  {"online"},
                  {"away"},
                  {"busy"},
                };
                diff = complete_line(self, status_cmd_list, 3, 8);
            } else
                diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);

            if (diff != -1) {
                if (x + diff > x2 - 1) {
                    int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
                    ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
                }
            } else {
                sound_notify(self, notif_error, 0, NULL);
            }
        } else {
            sound_notify(self, notif_error, 0, NULL);
        }
    } else if (key == '\n') {
        rm_trailing_spaces_buf(ctx);

        char line[MAX_STR_SIZE] = {0};

        if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
            memset(&line, 0, sizeof(line));

        if (!string_is_empty(line))
            add_line_to_hist(ctx);

        line_info_add(self, NULL, NULL, NULL, PROMPT, 0, 0, "%s", line);
        execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);

        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        reset_buf(ctx);
    }
}
예제 #24
0
파일: zarch.c 프로젝트: KitoHo/RetroArch
static int zarch_zui_render_lay_root_load(zui_t *zui,
      struct zui_tabbed *tabbed)
{
   char parent_dir[PATH_MAX_LENGTH] = {0};
   settings_t           *settings   = config_get_ptr();
   core_info_list_t           *list = NULL;

   if (zarch_zui_tab(zui, tabbed, "Load", 1))
   {
      unsigned cwd_offset;

      if (!zui->load_cwd)
         zui->load_cwd = strdup(settings->directory.menu_content);

      if (!zui->load_dlist)
      {
         core_info_t *core_info = NULL;
         core_info_get_current_core(&core_info);

         zui->load_dlist = dir_list_new(zui->load_cwd,
               core_info->supported_extensions, true, true, false, true);
         dir_list_sort(zui->load_dlist, true);
         zui->load_dlist_first  = 0;
      }

      cwd_offset = MIN(strlen(zui->load_cwd), 60);

      zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15,
            tabbed->tabline_size + 5 + 41,
            &zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);

      if (zarch_zui_button(zui, zui->width - 290 - 129,
               tabbed->tabline_size + 5, "Home"))
         zarch_zui_render_lay_root_load_free(zui);

      if (zui->load_dlist)
      {
         fill_pathname_parent_dir(parent_dir,
               zui->load_cwd, sizeof(parent_dir));
         if (!string_is_empty(parent_dir) &&
               zarch_zui_list_item(zui, tabbed, 0,
                  tabbed->tabline_size + 73, " ..", 0, NULL, false /* TODO/FIXME */))
         {
            zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir);
         }
         else
         {
            static int gamepad_index = 0;
            unsigned size = zui->load_dlist->size;
            unsigned i, j = 1;
            unsigned skip = 0;

            for (i = 0; i < size; ++i)
            {
               const char *basename = 
                  path_basename(zui->load_dlist->elems[i].data);
               if (basename[0] != '.')
                  break;
               skip++;
            }

            if (zarch_zui_gamepad_input(zui, &gamepad_index,
                     &zui->load_dlist_first, skip))
               zui->load_dlist_first = gamepad_index;

            for (i = skip + zui->load_dlist_first; i < size; ++i)
            {
               char label[PATH_MAX_LENGTH] = {0};
               const char        *path     = NULL;
               const char        *basename = NULL;

               if (j > 10)
                  break;

               path = zui->load_dlist->elems[i].data;
               basename = path_basename(path);

               *label = 0;
               strncat(label, "  ", sizeof(label)-1);
               strncat(label, basename, sizeof(label)-1);

               if (path_is_directory(path))
                  strncat(label, "/", sizeof(label)-1);

               if (zarch_zui_list_item(zui, tabbed, 0,
                        tabbed->tabline_size + 73 + j * ZUI_ITEM_SIZE_PX,
                        label, i, NULL, gamepad_index == (signed)(i-skip)))
               {
                  if (path_is_directory(path))
                  {
                     zarch_zui_render_lay_root_load_set_new_path(zui, path);
                     break;
                  }

                  zui->pick_cores     = NULL;
                  zui->pick_supported = 0;
                  strlcpy(zui->pick_content,
                        path, sizeof(zui->pick_content));

                  core_info_get_list(&list);

                  core_info_list_get_supported_cores(list, path,
                        &zui->pick_cores, &zui->pick_supported);
                  zarch_layout = LAY_PICK_CORE;
                  break;
               }
               j++;
            }
         }
      }
   }
   else if (zui->load_dlist)
   {
      dir_list_free(zui->load_dlist);
      zui->load_dlist = NULL;
   }

   return 0;
}
예제 #25
0
static void frontend_ps3_get_environment_settings(int *argc, char *argv[],
      void *args, void *params_data)
{
#ifndef IS_SALAMANDER
   bool original_verbose = verbosity_is_enabled();
   verbosity_enable();
#endif

   (void)args;
#ifndef IS_SALAMANDER
#if defined(HAVE_LOGGER)
   logger_init();
#elif defined(HAVE_FILE_LOGGER)
   retro_main_log_file_init("/retroarch-log.txt");
#endif
#endif

   int ret;
   unsigned int get_type;
   unsigned int get_attributes;
   CellGameContentSize size;
   char dirName[CELL_GAME_DIRNAME_SIZE]  = {0};

#ifdef HAVE_MULTIMAN
   /* not launched from external launcher, set default path */
   // second param is multiMAN SELF file
   if(path_file_exists(argv[2]) && *argc > 1
         && (!strcmp(argv[2], EMULATOR_CONTENT_DIR)))
   {
      multiman_detected = true;
      RARCH_LOG("Started from multiMAN, auto-game start enabled.\n");
   }
   else
#endif
#ifndef IS_SALAMANDER
      if (*argc > 1 && !string_is_empty(argv[1]))
      {
         static char path[PATH_MAX_LENGTH];
         *path = '\0';
         struct rarch_main_wrap *args = (struct rarch_main_wrap*)params_data;

         if (args)
         {
            strlcpy(path, argv[1], sizeof(path));

            args->touched        = true;
            args->no_content     = false;
            args->verbose        = false;
            args->config_path    = NULL;
            args->sram_path      = NULL;
            args->state_path     = NULL;
            args->content_path   = path;
            args->libretro_path  = NULL;

            RARCH_LOG("argv[0]: %s\n", argv[0]);
            RARCH_LOG("argv[1]: %s\n", argv[1]);
            RARCH_LOG("argv[2]: %s\n", argv[2]);

            RARCH_LOG("Auto-start game %s.\n", argv[1]);
         }
      }
      else
         RARCH_WARN("Started from Salamander, auto-game start disabled.\n");
#endif

   memset(&size, 0x00, sizeof(CellGameContentSize));

   ret = cellGameBootCheck(&get_type, &get_attributes, &size, dirName);
   if(ret < 0)
   {
      RARCH_ERR("cellGameBootCheck() Error: 0x%x.\n", ret);
   }
   else
   {
      char content_info_path[PATH_MAX_LENGTH] = {0};

      RARCH_LOG("cellGameBootCheck() OK.\n");
      RARCH_LOG("Directory name: [%s].\n", dirName);
      RARCH_LOG(" HDD Free Size (in KB) = [%d] Size (in KB) = [%d] System Size (in KB) = [%d].\n",
            size.hddFreeSizeKB, size.sizeKB, size.sysSizeKB);

      switch(get_type)
      {
         case CELL_GAME_GAMETYPE_DISC:
            RARCH_LOG("RetroArch was launched on Optical Disc Drive.\n");
            break;
         case CELL_GAME_GAMETYPE_HDD:
            RARCH_LOG("RetroArch was launched on HDD.\n");
            break;
      }

      if((get_attributes & CELL_GAME_ATTRIBUTE_APP_HOME) 
            == CELL_GAME_ATTRIBUTE_APP_HOME)
         RARCH_LOG("RetroArch was launched from host machine (APP_HOME).\n");

      ret = cellGameContentPermit(content_info_path, g_defaults.dir.port);

#ifdef HAVE_MULTIMAN
      if (multiman_detected)
      {
         fill_pathname_join(content_info_path, "/dev_hdd0/game/",
               EMULATOR_CONTENT_DIR, sizeof(content_info_path));
         fill_pathname_join(g_defaults.dir.port, content_info_path,
               "USRDIR", sizeof(g_defaults.dir.port));
      }
#endif

      if(ret < 0)
         RARCH_ERR("cellGameContentPermit() Error: 0x%x\n", ret);
      else
      {
         RARCH_LOG("cellGameContentPermit() OK.\n");
         RARCH_LOG("content_info_path : [%s].\n", content_info_path);
         RARCH_LOG("usrDirPath : [%s].\n", g_defaults.dir.port);
      }

      fill_pathname_join(g_defaults.dir.core, g_defaults.dir.port,
            "cores", sizeof(g_defaults.dir.core));
      fill_pathname_join(g_defaults.dir.core_info, g_defaults.dir.port,
            "cores", sizeof(g_defaults.dir.core_info));
      fill_pathname_join(g_defaults.dir.savestate, g_defaults.dir.core,
            "savestates", sizeof(g_defaults.dir.savestate));
      fill_pathname_join(g_defaults.dir.sram, g_defaults.dir.core,
            "savefiles", sizeof(g_defaults.dir.sram));
      fill_pathname_join(g_defaults.dir.system, g_defaults.dir.core,
            "system", sizeof(g_defaults.dir.system));
      fill_pathname_join(g_defaults.dir.shader,  g_defaults.dir.core,
            "shaders_cg", sizeof(g_defaults.dir.shader));
      fill_pathname_join(g_defaults.path.config, g_defaults.dir.port,
            "retroarch.cfg",  sizeof(g_defaults.path.config));
      fill_pathname_join(g_defaults.dir.overlay, g_defaults.dir.core,
            "overlays", sizeof(g_defaults.dir.overlay));
      fill_pathname_join(g_defaults.dir.assets,   g_defaults.dir.core,
            "assets", sizeof(g_defaults.dir.assets));
      fill_pathname_join(g_defaults.dir.cursor,   g_defaults.dir.core,
            "database/cursors", sizeof(g_defaults.dir.cursor));
      fill_pathname_join(g_defaults.dir.database,   g_defaults.dir.core,
            "database/rdb", sizeof(g_defaults.dir.database));
      fill_pathname_join(g_defaults.dir.playlist,   g_defaults.dir.core,
            "playlists", sizeof(g_defaults.dir.playlist));
   }

#ifndef IS_SALAMANDER
   if (original_verbose)
      verbosity_enable();
   else
      verbosity_disable();
#endif
}
예제 #26
0
static bool vita2d_gfx_frame(void *data, const void *frame,
      unsigned width, unsigned height, uint64_t frame_count,
      unsigned pitch, const char *msg)
{
   void *tex_p;
   vita_video_t *vita = (vita_video_t *)data;

   (void)frame;
   (void)width;
   (void)height;
   (void)pitch;
   (void)msg;

   if (frame)
   {
      unsigned i, j;
      unsigned int stride;

      if ((width != vita->width || height != vita->height) && vita->texture)
      {
         vita2d_free_texture(vita->texture);
         vita->texture = NULL;
      }

      if (!vita->texture)
      {
         RARCH_LOG("Creating texture: %ix%i\n", width, height);
         vita->width = width;
         vita->height = height;
         vita->texture = vita2d_create_empty_texture_format(width, height, vita->format);
         vita2d_texture_set_filters(vita->texture,vita->tex_filter,vita->tex_filter);
      }
      tex_p = vita2d_texture_get_datap(vita->texture);
      stride = vita2d_texture_get_stride(vita->texture);

      if (vita->format == SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1RGB)
      {
         stride                     /= 4;
         pitch                      /= 4;
         uint32_t             *tex32 = tex_p;
         const uint32_t     *frame32 = frame;

         for (i = 0; i < height; i++)
            for (j = 0; j < width; j++)
               tex32[j + i*stride] = frame32[j + i*pitch];
      }
      else
      {
         stride                 /= 2;
         pitch                  /= 2;
         uint16_t *tex16         = tex_p;
         const uint16_t *frame16 = frame;

         for (i = 0; i < height; i++)
            for (j = 0; j < width; j++)
               tex16[j + i*stride] = frame16[j + i*pitch];
      }
   }

   if (vita->should_resize)
      vita2d_gfx_update_viewport(vita);

   vita2d_start_drawing();
   vita2d_clear_screen();

   if (vita->texture)
   {
      if (vita->fullscreen)
         vita2d_draw_texture_scale(vita->texture,
               0, 0,
               PSP_FB_WIDTH  / (float)vita->width,
               PSP_FB_HEIGHT / (float)vita->height);
      else
      {
         const float radian = 90 * 0.0174532925f;
         const float rad = vita->rotation * radian;
         float scalex = vita->vp.width / (float)vita->width;
         float scaley = vita->vp.height / (float)vita->height;
         vita2d_draw_texture_scale_rotate(vita->texture, vita->vp.x,
               vita->vp.y, scalex, scaley, rad);
      }
   }

#ifdef HAVE_OVERLAY
   if (vita->overlay_enable)
      vita2d_render_overlay(vita);
#endif

   if (vita->menu.active && vita->menu.texture)
   {
      if (vita->fullscreen)
         vita2d_draw_texture_scale(vita->menu.texture,
               0, 0,
               PSP_FB_WIDTH  / (float)vita->menu.width,
               PSP_FB_HEIGHT / (float)vita->menu.height);
      else
      {
         if (vita->menu.width > vita->menu.height)
         {
            float scale = PSP_FB_HEIGHT / (float)vita->menu.height;
            float w = vita->menu.width * scale;
            vita2d_draw_texture_scale(vita->menu.texture,
                  PSP_FB_WIDTH / 2.0f - w/2.0f, 0.0f,
                  scale, scale);
         }
         else
         {
            float scale = PSP_FB_WIDTH / (float)vita->menu.width;
            float h = vita->menu.height * scale;
            vita2d_draw_texture_scale(vita->menu.texture,
                  0.0f, PSP_FB_HEIGHT / 2.0f - h/2.0f,
                  scale, scale);
         }
      }
   }
   
   if(!string_is_empty(msg))
     font_driver_render_msg(NULL, msg, NULL);
   
   vita2d_end_drawing();
   vita2d_swap_buffers();

   return true;
}
예제 #27
0
void path_set_redirect(void)
{
   char new_savefile_dir[PATH_MAX_LENGTH];
   char new_savestate_dir[PATH_MAX_LENGTH];
   uint32_t library_name_hash                  = 0;
   bool check_library_name_hash                = false;
   rarch_system_info_t      *info              = NULL;
   global_t                *global             = global_get_ptr();
   const char *old_savefile_dir                = dir_get(RARCH_DIR_SAVEFILE);
   const char *old_savestate_dir               = dir_get(RARCH_DIR_SAVESTATE);

   new_savefile_dir[0] = new_savestate_dir[0]  = '\0';

   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info);

   if (info && info->info.library_name &&
         !string_is_empty(info->info.library_name))
      library_name_hash =
         msg_hash_calculate(info->info.library_name);

   /* Initialize current save directories
    * with the values from the config. */
   strlcpy(new_savefile_dir,
         old_savefile_dir,
         sizeof(new_savefile_dir));

   strlcpy(new_savestate_dir,
         old_savestate_dir,
         sizeof(new_savestate_dir));

   check_library_name_hash = (library_name_hash != 0);
#ifdef HAVE_MENU
   check_library_name_hash = check_library_name_hash &&
      (library_name_hash != MENU_VALUE_NO_CORE);
#endif

   if (check_library_name_hash)
   {
      settings_t *settings = config_get_ptr();

      /* per-core saves: append the library_name to the save location */
      if (      settings->sort_savefiles_enable
            && !string_is_empty(old_savefile_dir))
      {
         fill_pathname_join(
               new_savefile_dir,
               old_savefile_dir,
               info->info.library_name,
               sizeof(new_savefile_dir));

         /* If path doesn't exist, try to create it,
          * if everything fails revert to the original path. */
         if(!path_is_directory(new_savefile_dir)
               && !string_is_empty(new_savefile_dir))
         {
            path_mkdir(new_savefile_dir);
            if(!path_is_directory(new_savefile_dir))
            {
               RARCH_LOG("%s %s\n",
                     msg_hash_to_str(MSG_REVERTING_SAVEFILE_DIRECTORY_TO),
                     old_savefile_dir);

               strlcpy(new_savefile_dir,
                     old_savefile_dir,
                     sizeof(new_savefile_dir));
            }
         }
      }

      /* per-core states: append the library_name to the save location */
      if (settings->sort_savestates_enable
            && !string_is_empty(old_savestate_dir))
      {
         fill_pathname_join(
               new_savestate_dir,
               old_savestate_dir,
               info->info.library_name,
               sizeof(new_savestate_dir));

         /* If path doesn't exist, try to create it.
          * If everything fails, revert to the original path. */
         if(!path_is_directory(new_savestate_dir) &&
               !string_is_empty(new_savestate_dir))
         {
            path_mkdir(new_savestate_dir);
            if(!path_is_directory(new_savestate_dir))
            {
               RARCH_LOG("%s %s\n",
                     msg_hash_to_str(MSG_REVERTING_SAVESTATE_DIRECTORY_TO),
                     old_savestate_dir);
               strlcpy(new_savestate_dir,
                     old_savestate_dir,
                     sizeof(new_savestate_dir));
            }
         }
      }
   }

   /* Set savefile directory if empty based on content directory */
   if (string_is_empty(new_savefile_dir))
   {
      strlcpy(new_savefile_dir, path_main_basename,
            sizeof(new_savefile_dir));
      path_basedir(new_savefile_dir);
   }

   if (global)
   {
      if(path_is_directory(new_savefile_dir))
         strlcpy(global->name.savefile, new_savefile_dir,
               sizeof(global->name.savefile));

      if(path_is_directory(new_savestate_dir))
         strlcpy(global->name.savestate, new_savestate_dir,
               sizeof(global->name.savestate));

      if (path_is_directory(global->name.savefile))
      {
         fill_pathname_dir(global->name.savefile, path_main_basename,
               file_path_str(FILE_PATH_SRM_EXTENSION),
               sizeof(global->name.savefile));
         RARCH_LOG("%s \"%s\".\n",
               msg_hash_to_str(MSG_REDIRECTING_SAVEFILE_TO),
               global->name.savefile);
      }

      if (path_is_directory(global->name.savestate))
      {
         fill_pathname_dir(global->name.savestate, path_main_basename,
               file_path_str(FILE_PATH_STATE_EXTENSION),
               sizeof(global->name.savestate));
         RARCH_LOG("%s \"%s\".\n",
               msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO),
               global->name.savestate);
      }

      if (path_is_directory(global->name.cheatfile))
      {
         fill_pathname_dir(global->name.cheatfile, path_main_basename,
               file_path_str(FILE_PATH_STATE_EXTENSION),
               sizeof(global->name.cheatfile));
         RARCH_LOG("%s \"%s\".\n",
               msg_hash_to_str(MSG_REDIRECTING_CHEATFILE_TO),
               global->name.cheatfile);
      }
   }

   dir_set(RARCH_DIR_CURRENT_SAVEFILE,  new_savefile_dir);
   dir_set(RARCH_DIR_CURRENT_SAVESTATE, new_savestate_dir);
}
예제 #28
0
enum rarch_shader_type video_shader_get_type_from_ext(
      const char *ext, bool *is_preset)
{
   enum gfx_ctx_api api = video_context_driver_get_api();

   if (string_is_empty(ext))
      return RARCH_SHADER_NONE;

   if (strlen(ext) > 1 && ext[0] == '.')
      ext++;

   *is_preset           = false;

   if (
         string_is_equal_case_insensitive(ext, "cg")
         )
   {
      switch (api)
      {
         case GFX_CTX_DIRECT3D9_API:
            return RARCH_SHADER_CG;
         case GFX_CTX_OPENGL_API:
         case GFX_CTX_OPENGL_ES_API:
            {
               struct retro_hw_render_callback *hwr =
                  video_driver_get_hw_context();
               if (hwr)
               {
                  switch (hwr->context_type)
                  {
                     case RETRO_HW_CONTEXT_OPENGLES2:
                     case RETRO_HW_CONTEXT_OPENGL_CORE:
                     case RETRO_HW_CONTEXT_OPENGLES3:
                        return RARCH_SHADER_NONE;
                     default:
                        break;
                  }
               }
            }
            return RARCH_SHADER_CG;
         default:
            break;
      }
   }
   if (
         string_is_equal_case_insensitive(ext, "cgp")
         )
   {
      *is_preset = true;
      switch (api)
      {
         case GFX_CTX_DIRECT3D9_API:
            return RARCH_SHADER_CG;
         case GFX_CTX_OPENGL_API:
         case GFX_CTX_OPENGL_ES_API:
            {
               struct retro_hw_render_callback *hwr =
                  video_driver_get_hw_context();
               if (hwr)
               {
                  switch (hwr->context_type)
                  {
                     case RETRO_HW_CONTEXT_OPENGLES2:
                     case RETRO_HW_CONTEXT_OPENGL_CORE:
                     case RETRO_HW_CONTEXT_OPENGLES3:
                        return RARCH_SHADER_NONE;
                     default:
                        break;
                  }
               }
            }
            return RARCH_SHADER_CG;
         default:
            break;
      }
   }
   if (
         string_is_equal_case_insensitive(ext, "glsl")
         )
   {
      switch (api)
      {
         case GFX_CTX_OPENGL_API:
         case GFX_CTX_OPENGL_ES_API:
            return RARCH_SHADER_GLSL;
         default:
            break;
      }
   }
   if (
         string_is_equal_case_insensitive(ext, "glslp")
         )
   {
      *is_preset = true;
      switch (api)
      {
         case GFX_CTX_OPENGL_API:
         case GFX_CTX_OPENGL_ES_API:
            return RARCH_SHADER_GLSL;
         default:
            break;
      }
   }
   if (
         string_is_equal_case_insensitive(ext, "slang")
         )
   {
      switch (api)
      {
         case GFX_CTX_DIRECT3D10_API:
         case GFX_CTX_DIRECT3D11_API:
         case GFX_CTX_DIRECT3D12_API:
         case GFX_CTX_GX2_API:
         case GFX_CTX_VULKAN_API:
         case GFX_CTX_METAL_API:
            return RARCH_SHADER_SLANG;
         default:
            break;
      }
   }
   if (
         string_is_equal_case_insensitive(ext, "slangp")
         )
   {
      *is_preset = true;

      switch (api)
      {
         case GFX_CTX_DIRECT3D10_API:
         case GFX_CTX_DIRECT3D11_API:
         case GFX_CTX_DIRECT3D12_API:
         case GFX_CTX_GX2_API:
         case GFX_CTX_VULKAN_API:
         case GFX_CTX_METAL_API:
            return RARCH_SHADER_SLANG;
         default:
            break;
      }
   }

   return RARCH_SHADER_NONE;
}
예제 #29
0
/**
 * rarch_environment_cb:
 * @cmd                          : Identifier of command.
 * @data                         : Pointer to data.
 *
 * Environment callback function implementation.
 *
 * Returns: true (1) if environment callback command could
 * be performed, otherwise false (0).
 **/
bool rarch_environment_cb(unsigned cmd, void *data)
{
   unsigned p;
   settings_t         *settings = config_get_ptr();
   global_t         *global     = global_get_ptr();
   rarch_system_info_t *system  = NULL;
   
   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);

   if (ignore_environment_cb)
      return false;

   switch (cmd)
   {
      case RETRO_ENVIRONMENT_GET_OVERSCAN:
         *(bool*)data = !settings->video.crop_overscan;
         RARCH_LOG("Environ GET_OVERSCAN: %u\n",
               (unsigned)!settings->video.crop_overscan);
         break;

      case RETRO_ENVIRONMENT_GET_CAN_DUPE:
         *(bool*)data = true;
         RARCH_LOG("Environ GET_CAN_DUPE: true\n");
         break;

      case RETRO_ENVIRONMENT_GET_VARIABLE:
      {

         if (!runloop_ctl(RUNLOOP_CTL_CORE_OPTIONS_GET, data))
         {
            struct retro_variable *var = (struct retro_variable*)data;

            if (var) {
               RARCH_LOG("Environ GET_VARIABLE %s: not implemented.\n", var->key);
               var->value = NULL;
            }
         }

         break;
      }

      case RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE:
         *(bool*)data = runloop_ctl(RUNLOOP_CTL_IS_CORE_OPTION_UPDATED, NULL);
         break;

      case RETRO_ENVIRONMENT_SET_VARIABLES:
      {
         RARCH_LOG("Environ SET_VARIABLES.\n");

         runloop_ctl(RUNLOOP_CTL_CORE_OPTIONS_DEINIT, NULL);
         runloop_ctl(RUNLOOP_CTL_CORE_OPTIONS_INIT,   data);

         break;
      }

      case RETRO_ENVIRONMENT_SET_MESSAGE:
      {
         const struct retro_message *msg = (const struct retro_message*)data;
         RARCH_LOG("Environ SET_MESSAGE: %s\n", msg->msg);
         runloop_msg_queue_push(msg->msg, 1, msg->frames, true);
         break;
      }

      case RETRO_ENVIRONMENT_SET_ROTATION:
      {
         unsigned rotation = *(const unsigned*)data;
         RARCH_LOG("Environ SET_ROTATION: %u\n", rotation);
         if (!settings->video.allow_rotate)
            break;

         system->rotation = rotation;

         if (!video_driver_set_rotation(rotation))
            return false;
         break;
      }

      case RETRO_ENVIRONMENT_SHUTDOWN:
         RARCH_LOG("Environ SHUTDOWN.\n");
         runloop_ctl(RUNLOOP_CTL_SET_SHUTDOWN,      NULL);
         runloop_ctl(RUNLOOP_CTL_SET_CORE_SHUTDOWN, NULL);
         break;

      case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL:
         system->performance_level = *(const unsigned*)data;
         RARCH_LOG("Environ PERFORMANCE_LEVEL: %u.\n",
               system->performance_level);
         break;

      case RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY:
         if (string_is_empty(settings->system_directory))
         {
            char *fullpath = NULL;
            runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath);

            RARCH_WARN("SYSTEM DIR is empty, assume CONTENT DIR %s\n", fullpath);
            fill_pathname_basedir(global->dir.systemdir, fullpath,
                  sizeof(global->dir.systemdir));

            *(const char**)data = global->dir.systemdir;
            RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n",
               global->dir.systemdir);
         }
         else
         {
            *(const char**)data = settings->system_directory;
            RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n",
               settings->system_directory);
         }

         break;

      case RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY:
         *(const char**)data = rarch_get_current_savefile_dir();
         break;

      case RETRO_ENVIRONMENT_GET_USERNAME:
         *(const char**)data = *settings->username ?
            settings->username : NULL;
         RARCH_LOG("Environ GET_USERNAME: \"%s\".\n",
               settings->username);
         break;

      case RETRO_ENVIRONMENT_GET_LANGUAGE:
         *(unsigned *)data = settings->user_language;
         RARCH_LOG("Environ GET_LANGUAGE: \"%u\".\n",
               settings->user_language);
         break;

      case RETRO_ENVIRONMENT_SET_PIXEL_FORMAT:
      {
         enum retro_pixel_format pix_fmt =
            *(const enum retro_pixel_format*)data;

         switch (pix_fmt)
         {
            case RETRO_PIXEL_FORMAT_0RGB1555:
               RARCH_LOG("Environ SET_PIXEL_FORMAT: 0RGB1555.\n");
               break;

            case RETRO_PIXEL_FORMAT_RGB565:
               RARCH_LOG("Environ SET_PIXEL_FORMAT: RGB565.\n");
               break;
            case RETRO_PIXEL_FORMAT_XRGB8888:
               RARCH_LOG("Environ SET_PIXEL_FORMAT: XRGB8888.\n");
               break;
            default:
               return false;
         }

         video_driver_set_pixel_format(pix_fmt);
         break;
      }

      case RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS:
      {
         unsigned retro_id, retro_port;
         const struct retro_input_descriptor *desc = NULL;

         static const char *libretro_btn_desc[] = {
            "B (bottom)", "Y (left)", "Select", "Start",
            "D-Pad Up", "D-Pad Down", "D-Pad Left", "D-Pad Right",
            "A (right)", "X (up)",
            "L", "R", "L2", "R2", "L3", "R3",
         };

         memset(system->input_desc_btn, 0,
               sizeof(system->input_desc_btn));

         desc = (const struct retro_input_descriptor*)data;

         for (; desc->description; desc++)
         {
            retro_port = desc->port;
            retro_id   = desc->id;

            if (desc->port >= MAX_USERS)
               continue;

            /* Ignore all others for now. */
            if (desc->device != RETRO_DEVICE_JOYPAD  &&
                  desc->device != RETRO_DEVICE_ANALOG)
               continue;

            if (desc->id >= RARCH_FIRST_CUSTOM_BIND)
               continue;

            if (desc->device == RETRO_DEVICE_ANALOG)
            {
               switch (retro_id)
               {
                  case RETRO_DEVICE_ID_ANALOG_X:
                     switch (desc->index)
                     {
                        case RETRO_DEVICE_INDEX_ANALOG_LEFT:
                           system->input_desc_btn[retro_port][RARCH_ANALOG_LEFT_X_PLUS] = desc->description;
                           system->input_desc_btn[retro_port][RARCH_ANALOG_LEFT_X_MINUS] = desc->description;
                           break;
                        case RETRO_DEVICE_INDEX_ANALOG_RIGHT:
                           system->input_desc_btn[retro_port][RARCH_ANALOG_RIGHT_X_PLUS] = desc->description;
                           system->input_desc_btn[retro_port][RARCH_ANALOG_RIGHT_X_MINUS] = desc->description;
                           break;
                     }
                     break;
                  case RETRO_DEVICE_ID_ANALOG_Y:
                     switch (desc->index)
                     {
                        case RETRO_DEVICE_INDEX_ANALOG_LEFT:
                           system->input_desc_btn[retro_port][RARCH_ANALOG_LEFT_Y_PLUS] = desc->description;
                           system->input_desc_btn[retro_port][RARCH_ANALOG_LEFT_Y_MINUS] = desc->description;
                           break;
                        case RETRO_DEVICE_INDEX_ANALOG_RIGHT:
                           system->input_desc_btn[retro_port][RARCH_ANALOG_RIGHT_Y_PLUS] = desc->description;
                           system->input_desc_btn[retro_port][RARCH_ANALOG_RIGHT_Y_MINUS] = desc->description;
                           break;
                     }
                     break;
               }
            }
            else
               system->input_desc_btn[retro_port][retro_id] = desc->description;
         }

         RARCH_LOG("Environ SET_INPUT_DESCRIPTORS:\n");
         for (p = 0; p < settings->input.max_users; p++)
         {
            for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND; retro_id++)
            {
               const char *description = system->input_desc_btn[p][retro_id];

               if (!description)
                  continue;

               RARCH_LOG("\tRetroPad, User %u, Button \"%s\" => \"%s\"\n",
                     p + 1, libretro_btn_desc[retro_id], description);
            }
         }

         global->has_set.input_descriptors = true;

         break;
      }

      case RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK:
      {
         retro_keyboard_event_t *key_event = NULL;
         const struct retro_keyboard_callback *info =
            (const struct retro_keyboard_callback*)data;

         runloop_ctl(RUNLOOP_CTL_KEY_EVENT_GET, &key_event);

         if (!key_event)
            return false;

         RARCH_LOG("Environ SET_KEYBOARD_CALLBACK.\n");
         *key_event                  = info->callback;
         global->frontend_key_event  = *key_event;
         break;
      }

      case RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE:
         RARCH_LOG("Environ SET_DISK_CONTROL_INTERFACE.\n");
         system->disk_control =
            *(const struct retro_disk_control_callback*)data;
         break;

      case RETRO_ENVIRONMENT_SET_HW_RENDER:
      case RETRO_ENVIRONMENT_SET_HW_RENDER | RETRO_ENVIRONMENT_EXPERIMENTAL:
      {
         struct retro_hw_render_callback *hw_render = video_driver_callback();
         struct retro_hw_render_callback *cb =
            (struct retro_hw_render_callback*)data;

         RARCH_LOG("Environ SET_HW_RENDER.\n");

         switch (cb->context_type)
         {
            case RETRO_HW_CONTEXT_NONE:
               RARCH_LOG("Requesting no HW context.\n");
               break;

#if defined(HAVE_OPENGLES2)
            case RETRO_HW_CONTEXT_OPENGLES2:
#if defined(HAVE_OPENGLES3)
            case RETRO_HW_CONTEXT_OPENGLES3:
#endif
               RARCH_LOG("Requesting OpenGLES%u context.\n",
                     cb->context_type == RETRO_HW_CONTEXT_OPENGLES2 ? 2 : 3);
               break;

#if defined(HAVE_OPENGLES3)
            case RETRO_HW_CONTEXT_OPENGLES_VERSION:
               RARCH_LOG("Requesting OpenGLES%u.%u context.\n",
                     cb->version_major, cb->version_minor);
               break;
#endif

            case RETRO_HW_CONTEXT_OPENGL:
            case RETRO_HW_CONTEXT_OPENGL_CORE:
               RARCH_ERR("Requesting OpenGL context, but RetroArch is compiled against OpenGLES2. Cannot use HW context.\n");
               return false;
#elif defined(HAVE_OPENGL)
            case RETRO_HW_CONTEXT_OPENGLES2:
            case RETRO_HW_CONTEXT_OPENGLES3:
               RARCH_ERR("Requesting OpenGLES%u context, but RetroArch is compiled against OpenGL. Cannot use HW context.\n",
                     cb->context_type == RETRO_HW_CONTEXT_OPENGLES2 ? 2 : 3);
               return false;

            case RETRO_HW_CONTEXT_OPENGLES_VERSION:
               RARCH_ERR("Requesting OpenGLES%u.%u context, but RetroArch is compiled against OpenGL. Cannot use HW context.\n",
                     cb->version_major, cb->version_minor);
               return false;

            case RETRO_HW_CONTEXT_OPENGL:
               RARCH_LOG("Requesting OpenGL context.\n");
               break;

            case RETRO_HW_CONTEXT_OPENGL_CORE:
               RARCH_LOG("Requesting core OpenGL context (%u.%u).\n",
                     cb->version_major, cb->version_minor);
               break;
#endif

            default:
               RARCH_LOG("Requesting unknown context.\n");
               return false;
         }
         cb->get_current_framebuffer = video_driver_get_current_framebuffer;
         cb->get_proc_address        = video_driver_get_proc_address;

         if (cmd & RETRO_ENVIRONMENT_EXPERIMENTAL) /* Old ABI. Don't copy garbage. */
            memcpy(hw_render,
                  cb, offsetof(struct retro_hw_render_callback, stencil));
         else
            memcpy(hw_render, cb, sizeof(*cb));
         break;
      }

      case RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME:
      {
         bool state = *(const bool*)data;
         RARCH_LOG("Environ SET_SUPPORT_NO_GAME: %s.\n", state ? "yes" : "no");
         system->no_content = state;
         break;
      }

      case RETRO_ENVIRONMENT_GET_LIBRETRO_PATH:
      {
         const char **path = (const char**)data;
#ifdef HAVE_DYNAMIC
         *path = settings->libretro;
#else
         *path = NULL;
#endif
         break;
      }

      /* FIXME - PS3 audio driver needs to be fixed so that threaded
       * audio works correctly (audio is already on a thread for PS3
       * audio driver so that's probably the problem) */
#if defined(HAVE_THREADS) && !defined(__CELLOS_LV2__)
      case RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK:
      {
         const struct retro_audio_callback *info =
            (const struct retro_audio_callback*)data;
         RARCH_LOG("Environ SET_AUDIO_CALLBACK.\n");

         if (recording_driver_get_data_ptr()) /* A/V sync is a must. */
            return false;

#ifdef HAVE_NETPLAY
         if (global->netplay.enable)
            return false;
#endif

         audio_driver_set_callback(info);
         break;
      }
#endif

      case RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK:
      {
         const struct retro_frame_time_callback *info =
            (const struct retro_frame_time_callback*)data;

         RARCH_LOG("Environ SET_FRAME_TIME_CALLBACK.\n");

#ifdef HAVE_NETPLAY
         /* retro_run() will be called in very strange and
          * mysterious ways, have to disable it. */
         if (global->netplay.enable)
            return false;
#endif

         system->frame_time = *info;
         break;
      }

      case RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE:
      {
         struct retro_rumble_interface *iface =
            (struct retro_rumble_interface*)data;

         RARCH_LOG("Environ GET_RUMBLE_INTERFACE.\n");
         iface->set_rumble_state = input_driver_set_rumble_state;
         break;
      }

      case RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES:
      {
         uint64_t *mask = (uint64_t*)data;

         RARCH_LOG("Environ GET_INPUT_DEVICE_CAPABILITIES.\n");
         if (input_driver_ctl(RARCH_INPUT_CTL_HAS_CAPABILITIES, NULL))
            *mask = input_driver_get_capabilities();
         else
            return false;
         break;
      }

      case RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE:
      {
         struct retro_sensor_interface *iface =
            (struct retro_sensor_interface*)data;

         RARCH_LOG("Environ GET_SENSOR_INTERFACE.\n");
         iface->set_sensor_state = input_sensor_set_state;
         iface->get_sensor_input = input_sensor_get_input;
         break;
      }

      case RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE:
      {
         struct retro_camera_callback *cb =
            (struct retro_camera_callback*)data;

         RARCH_LOG("Environ GET_CAMERA_INTERFACE.\n");
         cb->start                         = driver_camera_start;
         cb->stop                          = driver_camera_stop;
         system->camera_callback           = *cb;
         if (cb->caps != 0)
            camera_driver_ctl(RARCH_CAMERA_CTL_SET_ACTIVE, NULL);
         else
            camera_driver_ctl(RARCH_CAMERA_CTL_UNSET_ACTIVE, NULL);
         break;
      }

      case RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE:
      {
         struct retro_location_callback *cb =
            (struct retro_location_callback*)data;

         RARCH_LOG("Environ GET_LOCATION_INTERFACE.\n");
         cb->start                 = driver_location_start;
         cb->stop                  = driver_location_stop;
         cb->get_position          = driver_location_get_position;
         cb->set_interval          = driver_location_set_interval;
         system->location_callback = *cb;

         location_driver_ctl(RARCH_LOCATION_CTL_UNSET_ACTIVE, NULL);
         break;
      }

      case RETRO_ENVIRONMENT_GET_LOG_INTERFACE:
      {
         struct retro_log_callback *cb = (struct retro_log_callback*)data;

         RARCH_LOG("Environ GET_LOG_INTERFACE.\n");
         cb->log = rarch_log_libretro;
         break;
      }

      case RETRO_ENVIRONMENT_GET_PERF_INTERFACE:
      {
         struct retro_perf_callback *cb = (struct retro_perf_callback*)data;

         RARCH_LOG("Environ GET_PERF_INTERFACE.\n");
         cb->get_time_usec    = retro_get_time_usec;
         cb->get_cpu_features = retro_get_cpu_features;
         cb->get_perf_counter = retro_get_perf_counter;
         cb->perf_register    = retro_perf_register; /* libretro specific path. */
         cb->perf_start       = retro_perf_start;
         cb->perf_stop        = retro_perf_stop;
         cb->perf_log         = retro_perf_log; /* libretro specific path. */
         break;
      }

      case RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY:
      {
         const char **dir = (const char**)data;

         *dir = *settings->core_assets_directory ?
            settings->core_assets_directory : NULL;
         RARCH_LOG("Environ CORE_ASSETS_DIRECTORY: \"%s\".\n",
               settings->core_assets_directory);
         break;
      }

      case RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO:
      {
         RARCH_LOG("Environ SET_SYSTEM_AV_INFO.\n");
         return driver_ctl(RARCH_DRIVER_CTL_UPDATE_SYSTEM_AV_INFO,
               (void**)&data);
      }

      case RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO:
      {
         unsigned i, j;
         const struct retro_subsystem_info *info =
            (const struct retro_subsystem_info*)data;

         RARCH_LOG("Environ SET_SUBSYSTEM_INFO.\n");

         for (i = 0; info[i].ident; i++)
         {
            RARCH_LOG("Special game type: %s\n", info[i].desc);
            RARCH_LOG("  Ident: %s\n", info[i].ident);
            RARCH_LOG("  ID: %u\n", info[i].id);
            RARCH_LOG("  Content:\n");
            for (j = 0; j < info[i].num_roms; j++)
            {
               RARCH_LOG("    %s (%s)\n",
                     info[i].roms[j].desc, info[i].roms[j].required ?
                     "required" : "optional");
            }
         }

         free(system->special);
         system->special = (struct retro_subsystem_info*)
            calloc(i, sizeof(*system->special));

         if (!system->special)
            return false;

         memcpy(system->special, info,
               i * sizeof(*system->special));
         system->num_special = i;
         break;
      }

      case RETRO_ENVIRONMENT_SET_CONTROLLER_INFO:
      {
         unsigned i, j;
         const struct retro_controller_info *info =
            (const struct retro_controller_info*)data;

         RARCH_LOG("Environ SET_CONTROLLER_INFO.\n");

         for (i = 0; info[i].types; i++)
         {
            RARCH_LOG("Controller port: %u\n", i + 1);
            for (j = 0; j < info[i].num_types; j++)
               RARCH_LOG("   %s (ID: %u)\n", info[i].types[j].desc,
                     info[i].types[j].id);
         }

         free(system->ports);
         system->ports = (struct retro_controller_info*)
            calloc(i, sizeof(*system->ports));
         if (!system->ports)
            return false;

         memcpy(system->ports, info,
               i * sizeof(*system->ports));
         system->num_ports = i;
         break;
      }

      case RETRO_ENVIRONMENT_SET_GEOMETRY:
      {
         struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
         const struct retro_game_geometry *in_geom =
            (const struct retro_game_geometry*)data;
         struct retro_game_geometry *geom = av_info ?
            (struct retro_game_geometry*)&av_info->geometry : NULL;

         if (!geom)
            return false;

         RARCH_LOG("Environ SET_GEOMETRY.\n");

         /* Can potentially be called every frame,
          * don't do anything unless required. */
         if (geom->base_width != in_geom->base_width ||
               geom->base_height != in_geom->base_height ||
               geom->aspect_ratio != in_geom->aspect_ratio)
         {
            geom->base_width   = in_geom->base_width;
            geom->base_height  = in_geom->base_height;
            geom->aspect_ratio = in_geom->aspect_ratio;
            RARCH_LOG("SET_GEOMETRY: %ux%u, aspect: %.3f.\n",
                  geom->base_width, geom->base_height, geom->aspect_ratio);

            /* Forces recomputation of aspect ratios if
             * using core-dependent aspect ratios. */
            event_command(EVENT_CMD_VIDEO_SET_ASPECT_RATIO);

            /* TODO: Figure out what to do, if anything, with recording. */
         }
         break;
      }

      case RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER:
         return video_driver_get_current_software_framebuffer((struct retro_framebuffer*)data);

      /* Private extensions for internal use, not part of libretro API. */
      case RETRO_ENVIRONMENT_SET_LIBRETRO_PATH:
         RARCH_LOG("Environ (Private) SET_LIBRETRO_PATH.\n");

         if (!path_file_exists((const char*)data))
            return false;
         runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, data);
         break;

      case RETRO_ENVIRONMENT_EXEC:
      case RETRO_ENVIRONMENT_EXEC_ESCAPE:
         {
            char *fullpath = NULL;
            runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath);

            if (fullpath != data)
            {
               runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL);
               if (data)
                  runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH, data);
            }

#if defined(RARCH_CONSOLE)
            frontend_driver_set_fork(true, true, false);
#elif defined(HAVE_DYNAMIC)
            rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL);
#endif

            if (cmd == RETRO_ENVIRONMENT_EXEC_ESCAPE)
            {
               RARCH_LOG("Environ (Private) EXEC_ESCAPE.\n");
               runloop_ctl(RUNLOOP_CTL_SET_EXEC, NULL);
            }
            else
               RARCH_LOG("Environ (Private) EXEC.\n");
         }
         break;

      default:
         RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
         return false;
   }

   return true;
}
예제 #30
0
파일: prompt.c 프로젝트: jin-eld/toxic
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{
    ChatContext *ctx = self->chatwin;

    int x, y, y2, x2;
    getyx(ctx->history, y, x);
    getmaxyx(ctx->history, y2, x2);

    if (ltr) {
        if (ctx->len < (MAX_STR_SIZE - 1)) {
            add_char_to_buf(ctx, key);
        }
    } else { /* if (!ltr) */

        /* BACKSPACE key: Remove one character from line */
        if (key == 0x107 || key == 0x8 || key == 0x7f) {
            if (ctx->pos > 0) {
                del_char_buf_bck(ctx);
                wmove(ctx->history, y, x - 1);  /* not necessary but fixes a display glitch */
            } else {
                beep();
            }
        }

        else if (key == KEY_DC) {      /* DEL key: Remove character at pos */
            if (ctx->pos != ctx->len) {
                del_char_buf_frnt(ctx);
            } else {
                beep();
            }
        }

        else if (key == T_KEY_DISCARD) {    /* CTRL-U: Delete entire line behind pos */
            if (ctx->pos > 0) {
                wmove(ctx->history, ctx->orig_y, X_OFST);
                wclrtobot(ctx->history);
                discard_buf(ctx);
            } else {
                beep();
            }
        }

        else if (key == T_KEY_KILL) {    /* CTRL-K: Delete entire line in front of pos */
            if (ctx->len != ctx->pos)
                kill_buf(ctx);
            else
                beep();
        }

        else if (key == KEY_HOME || key == T_KEY_C_A) {  /* HOME/C-a key: Move cursor to start of line */
            if (ctx->pos != 0)
                ctx->pos = 0;
        }

        else if (key == KEY_END || key == T_KEY_C_E) {   /* END/C-e key: move cursor to end of line */
            if (ctx->pos != ctx->len)
                ctx->pos = ctx->len;
        }

        else if (key == KEY_LEFT) {
            if (ctx->pos > 0)
                --ctx->pos;
            else
                beep();
        }

        else if (key == KEY_RIGHT) {
            if (ctx->pos < ctx->len)
                ++ctx->pos;
            else
                beep();
        }

        else if (key == KEY_UP) {     /* fetches previous item in history */
            wmove(ctx->history, ctx->orig_y, X_OFST);
            fetch_hist_item(ctx, MOVE_UP);

            /* adjust line y origin appropriately when window scrolls down */
            if (ctx->at_bottom && ctx->len >= x2 - X_OFST) {
                int px2 = ctx->len >= x2 ? x2 : x2 - X_OFST;
                int p_ofst = px2 != x2 ? 0 : X_OFST;

                if (px2 <= 0)
                    return;

                int k = ctx->orig_y + ((ctx->len + p_ofst) / px2);

                if (k >= y2) {
                    --ctx->orig_y;
                }
            }
        }

        else if (key == KEY_DOWN) {    /* fetches next item in history */
            wmove(ctx->history, ctx->orig_y, X_OFST);
            fetch_hist_item(ctx, MOVE_DOWN);
        }

        else if (key == '\t') {    /* TAB key: completes command */
            if (ctx->len > 1 && ctx->line[0] == '/') {
                if (complete_line(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE) == -1)
                    beep();
            } else {
                beep();
            }
        }

        /* RETURN key: execute command */
        else if (key == '\n') {
            rm_trailing_spaces_buf(ctx);

            wprintw(ctx->history, "\n");
            uint8_t line[MAX_STR_SIZE] = {0};

            if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
                memset(&line, 0, sizeof(line));

            if (!string_is_empty(line))
                add_line_to_hist(ctx);

            line_info_add(self, NULL, NULL, NULL, line, PROMPT, 0, 0);
            execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);
            reset_buf(ctx);
        }
    }
}