int sc_watch_nss_dir (const char *nss_dir, ScNssChangedCb func, gpointer data, GError **error) { GIOChannel *gio; ScNssChangedData *cb; if (!nss_dir) { nss_dir = SC_NSS_NSS_DB; } if (g_mkdir_with_parents (nss_dir, 0755) < 0) { sc_set_error (error, SC_NSS_ERROR, SC_NSS_ERROR_GENERIC, _("NSS directory %s could not be created"), nss_dir); return -1; } gio = sc_inotify_open (error); if (!gio) { return -1; } cb = g_new (ScNssChangedData, 1); cb->func = func; cb->data = data; cb->timeout = 0; sc_inotify_callback (gio, sc_nss_inotify_cb, cb, sc_nss_destroy_cb); return sc_inotify_add_watch (gio, nss_dir, IN_MODIFY | IN_CREATE | IN_MOVE, error); }
gboolean sc_log_add_fd (int fd, GError **err) { int i; CHECK_INIT; for (i = 0; i < SC_LOG_MAX_FDS; i++) { if (ScLog.fds[i] == -1) { ScLog.fds[i] = fd; return TRUE; } } sc_set_error (err, SC_LOG_ERROR, SC_LOG_ERROR_GENERIC, _("no logging slots available")); return FALSE; }
static int upscale_surface(SDL_Surface **surface_ptr, size_t width, size_t height) { SDL_Surface *img = *surface_ptr; SDL_Rect rect = {0, 0, img->w, img->h}; SDL_Surface *stored_img = SDL_CreateRGBSurface(img->flags, width, height, img->format->BitsPerPixel, img->format->Rmask, img->format->Gmask, img->format->Bmask, img->format->Amask); if (!stored_img) { sc_set_error(SC_EGRAPHIC, __FILE__, __LINE__, "Unable to resize texture"); return 0; } SDL_BlitSurface(img, &rect, stored_img, &rect); *surface_ptr = stored_img; SDL_FreeSurface(img); return 1; }
sc_texture_t * sc_texture_from_resource(const char *filename, int mipmaps) { char *path = sc_path_to_resource("textures", filename); sc_texture_t *rv; SDL_Surface *surface = IMG_Load(path); if (!surface) { sc_set_error(SC_ENOENT, path, 0, "Unable to load texture"); sc_free(path); return NULL; } rv = sc_texture_from_surface(surface, mipmaps); if (!rv) sc_augment_error_context(filename, 0); sc_free(path); SDL_FreeSurface(surface); return rv; }
gboolean sc_log_add_file_name (const char *filename, GError **err) { int fd; CHECK_INIT; fd = open (filename, O_WRONLY | O_APPEND | O_CREAT, 0600); if (fd < 0) { sc_set_error (err, SC_LOG_ERROR, SC_LOG_ERROR_GENERIC, _("error %d opening file %s: %s"), errno, filename, strerror (errno)); return FALSE; } if (!sc_log_add_fd (fd, err)) { close (fd); return FALSE; } return TRUE; }
SDL_Surface * sc_prepare_surface_for_upload(SDL_Surface *img, GLenum *format_out) { int yl, yh; uint8_t *data_in, *data_out; GLenum format; SDL_Surface *rv = SDL_CreateRGBSurface(img->flags, img->w, img->h, img->format->BitsPerPixel, img->format->Rmask, img->format->Gmask, img->format->Bmask, img->format->Amask); sc_memassert(rv); assert(rv->pitch == img->pitch); /* figure out format */ switch (img->format->BytesPerPixel) { case 4: format = (img->format->Rmask == 0x000000ff) ? GL_RGBA : GL_BGRA; break; case 3: format = (img->format->Rmask == 0x000000ff) ? GL_RGB : GL_BGR; break; default: sc_set_error(SC_EGRAPHIC, __FILE__, __LINE__, "Unsupported texture depth %d", img->format->BytesPerPixel); return NULL; } /* flip image data because of flipped opengl coordinate system into the new surface. */ data_in = (uint8_t *)img->pixels; data_out = (uint8_t *)rv->pixels; yl = 0; yh = img->h - 1; while (yl < yh) { memcpy(data_out + rv->pitch * yh, data_in + rv->pitch * yl, rv->pitch); memcpy(data_out + rv->pitch * yl, data_in + rv->pitch * yh, rv->pitch); yl++, yh--; } *format_out = format; return rv; }
const sc_texture_t * sc_arraytex_add_from_resource(sc_arraytex_t *arr, const char *filename) { char *path; const sc_texture_t *rv; SDL_Surface *surface; ASSERT_NOT_FINALIZED(arr); path = sc_path_to_resource("textures", filename); surface = IMG_Load(path); if (!surface) { sc_free(path); sc_set_error(SC_EGRAPHIC, path, 0, "Unable to load texture. " "Tried to feed texture array"); return NULL; } rv = sc_arraytex_add_from_surface(arr, surface); if (!rv) sc_augment_error_context(filename, 0); sc_free(path); SDL_FreeSurface(surface); return rv; }
const sc_texture_t * sc_arraytex_add_from_surface(sc_arraytex_t *arr, SDL_Surface *img) { size_t i; size_t w = arr->width, h = arr->height; sc_texture_t *rv; SDL_Surface *helper_img, *previous_img; GLenum format; ASSERT_NOT_FINALIZED(arr); img = sc_prepare_surface_for_upload(img, &format); if (!img) return NULL; /* we currently do not support resizing of the images on adding, so let's just make sure we add only images of the same size */ if (img->w != arr->height || img->h != arr->height) { if (!(arr->flags & SC_ARRAYTEX_NEAREST)) { SDL_FreeSurface(img); sc_set_error(SC_EGRAPHIC, __FILE__, __LINE__, "Texture size (%dx%d) does not match array size " "(%dx%d)", (int)img->w, (int)img->h, (int)arr->width, (int)arr->height); return NULL; } helper_img = img; img = sc_resize_surface_nearest(img, arr->width, arr->height); SDL_FreeSurface(helper_img); } /* same goes for the format. All images added to the array have to be of the same format. Currently not a big deal as we are only having RGBA images anyways, but it's important to check. */ if (arr->slices == 0) arr->format = format; else if (arr->format != format) { SDL_FreeSurface(img); sc_set_error(SC_EGRAPHIC, __FILE__, __LINE__, "Texture format mismatch when adding new texture " "to texture array. Array format is %d, added " "format is %d.", arr->format, format); return NULL; } rv = sc_xalloc(sc_texture_t); rv->id = 0; /* set later, we don't know it yet */ rv->stored_width = arr->width; rv->stored_height = arr->height; rv->off_x = 0; rv->off_y = 0; rv->index = arr->slices++; rv->width = arr->width; rv->height = arr->height; rv->target = TARGET; rv->shared = 1; /* first level is not resized */ append_image(arr->buffers[0], img); /* all other levels are scaled down */ helper_img = NULL; previous_img = NULL; for (i = 1; i < arr->mipmap_levels; i++) { if (w > 1) w /= 2; if (h > 1) h /= 2; helper_img = sc_resize_surface_nearest( previous_img ? previous_img : img, w, h); SDL_FreeSurface(previous_img); append_image(arr->buffers[i], helper_img); previous_img = helper_img; } SDL_FreeSurface(img); SDL_FreeSurface(helper_img); sc_list_append(arr->textures, rv); return rv; }