Example #1
0
static char* dinput_err_str(long err)
{
   static char err_str[64];

   switch (err) {

      case DIERR_NOTACQUIRED:
         _al_sane_strncpy(err_str, "the device is not acquired", sizeof(err_str));
         break;

      case DIERR_INPUTLOST:
         _al_sane_strncpy(err_str, "access to the device was not granted", sizeof(err_str));
         break;

      case DIERR_INVALIDPARAM:
         _al_sane_strncpy(err_str, "the device does not have a selected data format", sizeof(err_str));
         break;

      case DIERR_OTHERAPPHASPRIO:
         _al_sane_strncpy(err_str, "can't acquire the device in background", sizeof(err_str));
         break;

      default:
         _al_sane_strncpy(err_str, "unknown error", sizeof(err_str));
   }

   return err_str;
}
Example #2
0
/* alsa_rawmidi_init:
 *  Inits the ALSA RawMIDI interface.
 */
static int alsa_rawmidi_init(int input, int voices)
{
   int ret = -1, err;
   char tmp1[128], tmp2[128], temp[256];
#if ALLEGRO_ALSA_VERSION == 9
   snd_rawmidi_info_t *info;
   const char *device = NULL;
#else  /* ALLEGRO_ALSA_VERSION == 5 */
   snd_rawmidi_info_t info;
   int card = -1;
   int device = -1;
#endif

   if (input) {
      ret = -1;
   }
   else {
#if ALLEGRO_ALSA_VERSION == 9
      device = get_config_string(uconvert_ascii("sound", tmp1),
				 uconvert_ascii("alsa_rawmidi_device", tmp2),
				 "default");

      err = snd_rawmidi_open(NULL, &rawmidi_handle, device, 0);
#else  /* ALLEGRO_ALSA_VERSION == 5 */
      card = get_config_int(uconvert_ascii("sound", tmp1),
			    uconvert_ascii("alsa_rawmidi_card", tmp2),
			    snd_defaults_rawmidi_card());

      device = get_config_int(uconvert_ascii("sound", tmp1),
			     uconvert_ascii("alsa_rawmidi_device", tmp2),
			     snd_defaults_rawmidi_device());

      err = snd_rawmidi_open(&rawmidi_handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND);
#endif
      if (err) {
	 snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
	 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
	 ret = -1;
      }

      ret = 0;
   }

   if (rawmidi_handle) {
#if ALLEGRO_ALSA_VERSION == 9
      snd_rawmidi_nonblock(rawmidi_handle, 0);
      snd_rawmidi_info_malloc(&info);
      snd_rawmidi_info(rawmidi_handle, info);
      _al_sane_strncpy(alsa_rawmidi_desc, snd_rawmidi_info_get_name(info), sizeof(alsa_rawmidi_desc));
#else  /* ALLEGRO_ALSA_VERSION == 5 */
      snd_rawmidi_block_mode(rawmidi_handle, 1);
      snd_rawmidi_info(rawmidi_handle, &info);
      _al_sane_strncpy(alsa_rawmidi_desc, info.name, sizeof(alsa_rawmidi_desc));
#endif
      midi_alsa.desc = alsa_rawmidi_desc;
      alsa_rawmidi_errors = 0;
   }

   return ret;
}
Example #3
0
/* Function: al_set_app_name
 */
void al_set_app_name(const char *app_name)
{
   if (app_name) {
      _al_sane_strncpy(_al_app_name, app_name, sizeof(_al_app_name));
   }
   else {
      ALLEGRO_PATH *path;
      path = al_get_standard_path(ALLEGRO_EXENAME_PATH);
      _al_sane_strncpy(_al_app_name, al_get_path_filename(path), sizeof(_al_app_name));
      al_destroy_path(path);
   }
}
/* object_enum_callback: [primary thread]
 *  Helper function to find out what objects we have on the device.
 */
static BOOL CALLBACK object_enum_callback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
{
#define GUIDTYPE_EQ(x)  GUID_EQUAL(lpddoi->guidType, x)

   CAPS_AND_NAMES *can = pvRef;

   if (GUIDTYPE_EQ(__al_GUID_XAxis)) {
      can->have_x = true;
      _al_sane_strncpy(can->name_x, lpddoi->tszName, NAME_LEN);
   }
   else if (GUIDTYPE_EQ(__al_GUID_YAxis)) {
      can->have_y = true;
      _al_sane_strncpy(can->name_y, lpddoi->tszName, NAME_LEN);
   }
   else if (GUIDTYPE_EQ(__al_GUID_ZAxis)) {
      can->have_z = true;
      _al_sane_strncpy(can->name_z, lpddoi->tszName, NAME_LEN);
   }
   else if (GUIDTYPE_EQ(__al_GUID_RxAxis)) {
      can->have_rx = true;
      _al_sane_strncpy(can->name_rx, lpddoi->tszName, NAME_LEN);
   }
   else if (GUIDTYPE_EQ(__al_GUID_RyAxis)) {
      can->have_ry = true;
      _al_sane_strncpy(can->name_ry, lpddoi->tszName, NAME_LEN);
   }
   else if (GUIDTYPE_EQ(__al_GUID_RzAxis)) {
      can->have_rz = true;
      _al_sane_strncpy(can->name_rz, lpddoi->tszName, NAME_LEN);
   }
   else if (GUIDTYPE_EQ(__al_GUID_Slider)) {
      if (can->num_sliders < MAX_SLIDERS) {
         _al_sane_strncpy(can->name_slider[can->num_sliders], lpddoi->tszName,
            NAME_LEN);
         can->num_sliders++;
      }
   }
   else if (GUIDTYPE_EQ(__al_GUID_POV)) {
      if (can->num_povs < MAX_POVS) {
         _al_sane_strncpy(can->name_pov[can->num_povs], lpddoi->tszName,
            NAME_LEN);
         can->num_povs++;
      }
   }
   else if (GUIDTYPE_EQ(__al_GUID_Button)) {
      if (can->num_buttons < MAX_BUTTONS) {
         _al_sane_strncpy(can->name_button[can->num_buttons], lpddoi->tszName,
            NAME_LEN);
         can->num_buttons++;
      }
   }

   return DIENUM_CONTINUE;

#undef GUIDTYPE_EQ
}
/* _be_sys_get_executable_name:
 */
extern "C" void _be_sys_get_executable_name(char *output, int size)
{
    image_info info;
    int32 cookie;

    cookie = 0;

    if (get_next_image_info(0, &cookie, &info) == B_NO_ERROR) {
        _al_sane_strncpy(output, info.name, size);
    }
    else {
        _al_sane_strncpy(output, EXE_NAME_UNKNOWN, size);
    }

    output[size-1] = '\0';
}
Example #6
0
/* Function: al_set_org_name
 */
void al_set_org_name(const char *org_name)
{
   if (!org_name)
      org_name = "";

   _al_sane_strncpy(_al_org_name, org_name, sizeof(_al_org_name));
}
Example #7
0
/* al_findnext:
 *  Retrieves the next file from a directory search.
 */
int al_findnext(struct al_ffblk *info)
{
   char tempname[FF_MAXPATHLEN];
   char filename[FF_MAXPATHLEN];
   int attrib;
   struct dirent *entry;
   struct stat s;
   struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data;

   ASSERT(ff_data);

   /* if the pattern contained no wildcard */
   if (!ff_data->dir)
      return -1;

   while (TRUE) {
      /* read directory entry */
      entry = readdir(ff_data->dir);
      if (!entry) {
         *allegro_errno = (errno ? errno : ENOENT);
         return -1;
      }

      /* try to match file name with pattern */
      tempname[0] = 0;
      if (NAMLEN(entry) >= sizeof(tempname))
         strncat(tempname, entry->d_name, sizeof(tempname) - 1);
      else
         strncat(tempname, entry->d_name, NAMLEN(entry));

      if (ff_match(tempname, ff_data->pattern)) {
         _al_sane_strncpy(filename, ff_data->dirname, FF_MAXPATHLEN);
         ff_put_backslash(filename, sizeof(filename));
         strncat(filename, tempname, sizeof(filename) - strlen(filename) - 1);

         /* get file attributes */
         if (stat(filename, &s) == 0) {
            attrib = ff_get_attrib(tempname, &s);

            /* does it match ? */
            if ((attrib & ~ff_data->attrib) == 0)
               break;
         }
         else {
            /* evil! but no other way to avoid exiting for_each_file() */
            *allegro_errno = 0;
         }
      }
   }

   info->attrib = attrib;
   info->time = s.st_mtime;
   info->size = s.st_size; /* overflows at 2GB */
   ff_data->size = s.st_size;

   do_uconvert(tempname, U_UTF8, info->name, U_CURRENT, sizeof(info->name));

   return 0;
}
Example #8
0
/* Function: al_ustr_to_buffer
 */
void al_ustr_to_buffer(const ALLEGRO_USTR *us, char *buffer, int size)
{
   int need;

   if (size <= 0)
      return;
   /* add 1 for terminating 0 byte */
   need = _al_blength(us) + 1;
   if (size > need)
      size = need;
   _al_sane_strncpy(buffer, _al_bdata(us), size);
}
Example #9
0
/*
 * Calling LoadLibrary with a relative file name is a security risk:
 * see e.g. Microsoft Security Advisory (2269637)
 * "Insecure Library Loading Could Allow Remote Code Execution"
 */
HMODULE _al_win_safe_load_library(const char *filename)
{
    ALLEGRO_PATH *path1 = NULL;
    ALLEGRO_PATH *path2 = NULL;
    char buf[MAX_PATH];
    const char *other_dirs[3];
    HMODULE lib = NULL;
    bool msvc_only = false;

    /* MSVC only: if the executable is in the build configuration directory,
     * which is also just under the current directory, then also try to load the
     * library from the current directory.  This leads to less surprises when
     * running example programs.
     */
#if defined(ALLEGRO_MSVC)
    msvc_only = true;
#endif

    /* Try to load the library from the directory containing the running
     * executable, the Windows system directories, or directories on the PATH.
     * Do NOT try to load the library from the current directory.
     */

    if (al_is_system_installed()) {
        path1 = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
    }
    else if (GetModuleFileName(NULL, buf, sizeof(buf)) < sizeof(buf)) {
        path1 = al_create_path(buf);
    }
    if (msvc_only) {
        path2 = maybe_parent_dir(path1);
    }

    other_dirs[0] = path1 ? al_path_cstr(path1, '\\') : NULL;
    other_dirs[1] = path2 ? al_path_cstr(path2, '\\') : NULL;
    other_dirs[2] = NULL; /* sentinel */

    _al_sane_strncpy(buf, filename, sizeof(buf));
    if (PathFindOnPath(buf, other_dirs)) {
        ALLEGRO_DEBUG("PathFindOnPath found: %s\n", buf);
        lib = load_library_at_path(buf);
    }
    else {
        ALLEGRO_WARN("PathFindOnPath failed to find %s\n", filename);
    }

    al_destroy_path(path1);
    al_destroy_path(path2);

    return lib;
}
Example #10
0
static char *android_get_clipboard_text(ALLEGRO_DISPLAY *display)
{
   JNIEnv * env = (JNIEnv *)_al_android_get_jnienv();
   jobject jtext = _jni_callObjectMethod(env, _al_android_activity_object(), "getClipboardText", "()Ljava/lang/String;");
   jsize len = _jni_call(env, jsize, GetStringUTFLength, jtext);
   const char *str = _jni_call(env, const char *, GetStringUTFChars, jtext, NULL);
   char * text =  al_malloc(len+1);
   (void) display;

   text = _al_sane_strncpy(text, str, len);
   _jni_callv(env, ReleaseStringUTFChars, jtext, str);
   _jni_callv(env, DeleteLocalRef, jtext);

   return text;
}
Example #11
0
/* print_extensions:
 * Given a string containing extensions (i.e. a NULL terminated string where
 * each extension are separated by a space and which names do not contain any
 * space)
 */
static void print_extensions(char const *extension)
{
    char buf[80];
    char *start;
    ASSERT(extension);

    while (*extension != '\0') {
        start = buf;
        _al_sane_strncpy(buf, extension, 80);
        while ((*start != ' ') && (*start != '\0')) {
            extension++;
            start++;
        }
        *start = '\0';
        if (*extension != '\0')
            extension++;
        ALLEGRO_DEBUG("%s\n", buf);
    }
}
/* system_thread:
 */
static int32 system_thread(void *data)
{
    (void)data;

    if (_be_allegro_app == NULL) {
        char sig[MAXPATHLEN] = "application/x-vnd.Allegro-";
        char exe[MAXPATHLEN];
        char *term, *p;

        _be_sys_get_executable_name(exe, sizeof(exe));

        strncat(sig, get_filename(exe), sizeof(sig)-1);
        sig[sizeof(sig)-1] = '\0';

        _be_allegro_app = new BeAllegroApp(sig);

        using_custom_allegro_app = false;

        term = getenv("TERM");
        if (!strcmp(term, "dumb")) {
            /* The TERM environmental variable is set to "dumb" if the app was
             * not started from a terminal.
             */
            p = &exe[strlen(exe) - 1];
            while (*p != '/') p--;
            *(p + 1) = '\0';
            _al_sane_strncpy(app_path, exe, MAXPATHLEN);
        }
    }
    else {
        using_custom_allegro_app = true;
    }

    _be_allegro_app->Run();

    /* XXX commented out due to conflicting TRACE in Haiku
    TRACE(PREFIX_I "system thread exited\n");
    */

    return 0;
}
static char *add_string(char *buf, const char *src, int *pos, int bufsize)
{
   char *dest = buf + *pos;

   if (*pos >= bufsize - 1) {
      /* Out of space. */
      ASSERT(dest[0] == '\0');
      return dest;
   }

   if (*pos > 0) {
      /* Skip over NUL separator. */
      dest++;
      (*pos)++;
   }

   _al_sane_strncpy(dest, src, bufsize - *pos);
   (*pos) += strlen(dest);
   ASSERT(*pos < bufsize);

   return dest;
}
Example #14
0
static char *dd_err(long err)
{
   static char err_str[64];

   switch (err) {

      case DD_OK:
         _al_sane_strncpy(err_str, "DD_OK", sizeof(err_str));
         break;

      case DDERR_GENERIC:
         _al_sane_strncpy(err_str, "DDERR_GENERIC", sizeof(err_str));
         break;

     case DDERR_INCOMPATIBLEPRIMARY:
         _al_sane_strncpy(err_str, "DDERR_INCOMPATIBLEPRIMARY", sizeof(err_str));
         break;

     case DDERR_INVALIDCAPS:
         _al_sane_strncpy(err_str, "DDERR_INVALIDCAPS", sizeof(err_str));
         break;

      case DDERR_INVALIDOBJECT:
         _al_sane_strncpy(err_str, "DDERR_INVALIDOBJECT", sizeof(err_str));
         break;

      case DDERR_INVALIDPARAMS:
         _al_sane_strncpy(err_str, "DDERR_INVALIDPARAMS", sizeof(err_str));
         break;

     case DDERR_INVALIDPIXELFORMAT:
         _al_sane_strncpy(err_str, "DDERR_INVALIDPIXELFORMAT", sizeof(err_str));
         break;

      case DDERR_NOFLIPHW:
         _al_sane_strncpy(err_str, "DDERR_NOFLIPHW", sizeof(err_str));
         break;

      case DDERR_NOTFLIPPABLE:
         _al_sane_strncpy(err_str, "DDERR_NOTFLIPPABLE", sizeof(err_str));
         break;

      case DDERR_OUTOFMEMORY:
         _al_sane_strncpy(err_str, "DDERR_OUTOFMEMORY", sizeof(err_str));
         break;

      case DDERR_OUTOFVIDEOMEMORY:
         _al_sane_strncpy(err_str, "DDERR_OUTOFVIDEOMEMORY", sizeof(err_str));
         break;

     case DDERR_PRIMARYSURFACEALREADYEXISTS:
         _al_sane_strncpy(err_str, "DDERR_PRIMARYSURFACEALREADYEXISTS", sizeof(err_str));
         break;

      case DDERR_SURFACEBUSY:
         _al_sane_strncpy(err_str, "DDERR_SURFACEBUSY", sizeof(err_str));
         break;

      case DDERR_SURFACELOST:
         _al_sane_strncpy(err_str, "DDERR_SURFACELOST", sizeof(err_str));
         break;

     case DDERR_UNSUPPORTED:
         _al_sane_strncpy(err_str, "DDERR_UNSUPPORTED", sizeof(err_str));
         break;

     case DDERR_UNSUPPORTEDMODE:
         _al_sane_strncpy(err_str, "DDERR_UNSUPPORTEDMODE", sizeof(err_str));
         break;

     case DDERR_WASSTILLDRAWING:
         _al_sane_strncpy(err_str, "DDERR_WASSTILLDRAWING", sizeof(err_str));
         break;

      default:
         _al_sane_strncpy(err_str, "DDERR_UNKNOWN", sizeof(err_str));
         break;
   }

   return err_str;
}
Example #15
0
/* al_findfirst:
 *  Initiates a directory search.
 */
int al_findfirst(AL_CONST char *pattern, struct al_ffblk *info, int attrib)
{
   struct FF_DATA *ff_data;
   struct stat s;
   int actual_attrib;
   char tmp[1024];
   char *p;

   /* allocate ff_data structure */
   ff_data = _AL_MALLOC(sizeof(struct FF_DATA));
   if (!ff_data) {
      *allegro_errno = ENOMEM;
      return -1;
   }

   memset(ff_data, 0, sizeof *ff_data);
   info->ff_data = (void *) ff_data;

   /* if the pattern contains no wildcard, we use stat() */
   if (!ustrpbrk(pattern, uconvert("?*", U_ASCII, tmp, U_CURRENT, sizeof(tmp)))) {
      /* start the search */
      errno = *allegro_errno = 0;

      if (stat(uconvert(pattern, U_CURRENT, tmp, U_UTF8, sizeof(tmp)), &s) == 0) {
         /* get file attributes */
         actual_attrib = ff_get_attrib(ff_get_filename(uconvert(pattern, U_CURRENT, tmp, U_UTF8, sizeof(tmp))), &s);

         /* does it match ? */
         if ((actual_attrib & ~attrib) == 0) {
            info->attrib = actual_attrib;
            info->time = s.st_mtime;
            info->size = s.st_size; /* overflows at 2GB */
            ff_data->size = s.st_size;
            ustrzcpy(info->name, sizeof(info->name), get_filename(pattern));
            return 0;
         }
      }

       _AL_FREE(ff_data);
      info->ff_data = NULL;
      *allegro_errno = (errno ? errno : ENOENT);
      return -1;
   }

   ff_data->attrib = attrib;

   do_uconvert(pattern, U_CURRENT, ff_data->dirname, U_UTF8, sizeof(ff_data->dirname));
   p = ff_get_filename(ff_data->dirname);
   _al_sane_strncpy(ff_data->pattern, p, sizeof(ff_data->pattern));
   if (p == ff_data->dirname)
      _al_sane_strncpy(ff_data->dirname, "./", FF_MAXPATHLEN);
   else
      *p = 0;

   /* nasty bodge, but gives better compatibility with DOS programs */
   if (strcmp(ff_data->pattern, "*.*") == 0)
      _al_sane_strncpy(ff_data->pattern, "*", FF_MAXPATHLEN);

   /* start the search */
   errno = *allegro_errno = 0;

   ff_data->dir = opendir(ff_data->dirname);

   if (!ff_data->dir) {
      *allegro_errno = (errno ? errno : ENOENT);
      _AL_FREE(ff_data);
      info->ff_data = NULL;
      return -1;
   }

   if (al_findnext(info) != 0) {
      al_findclose(info);
      return -1;
   }

   return 0;
}
Example #16
0
/* be_joy_init:
 *  Initializes BeOS joystick driver.
 */
extern "C" int be_joy_init(void)
{
   const char *device_config;
   char device_name[B_OS_NAME_LENGTH + 1];
   static char desc[30];
   static char name_x[10];
   static char name_y[10];
   static char name_stick[] = "stick";
   static char name_hat[] = "hat";
   static char name_throttle[] = "throttle";
   static char name_hat_lr[] = "left/right";
   static char name_hat_ud[] = "up/down";
   static char *name_b[] =
   {"B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8"};
   int32 i, j, stick;
   BString *temp;
   char *name;
   
   temp = new BString;
   be_joy = new BJoystick;
   num_devices = be_joy->CountDevices();
   
   /* no joysticks available */
   if (num_devices == 0) {
      goto cleanup;
   }
   
   /* Scans if the joystick_device config variable is set */
   device_config = get_config_string("joystick", "joystick_device", "");
   
   /* Let's try to open selected device */
   if ((device_config[0] == '\0') || (be_joy->Open(device_config) < 0)) {
      /* ok, let's try to open first available device */
      if (be_joy->GetDeviceName(0, device_name) != B_OK) {
         goto cleanup;
      }
      if (be_joy->Open(device_name) == B_ERROR) {
         goto cleanup;
      }
   }
   be_joy->GetControllerName(temp);
   name = temp->LockBuffer(0);
   _al_sane_strncpy(desc, name, sizeof(desc));
   temp->UnlockBuffer();
   joystick_beos.desc = desc;

   num_axes = be_joy->CountAxes();
   num_hats = be_joy->CountHats();
   num_buttons = be_joy->CountButtons();
   if (num_axes) {
      axis_value = (int16 *)malloc(sizeof(int16) * num_axes);
      hat_value = (int8 *)malloc(sizeof(int8) * num_axes);
   }
   
   num_joysticks = be_joy->CountSticks();
   for (i = 0; i < num_joysticks; i++) {
      joy[i].flags = JOYFLAG_DIGITAL | JOYFLAG_ANALOGUE;
      
      stick = 0;
      if (num_axes >= 2) {
         joy[i].stick[0].flags = JOYFLAG_DIGITAL | JOYFLAG_ANALOGUE | JOYFLAG_SIGNED;
         joy[i].stick[0].num_axis = 2;
         joy[i].stick[0].name = name_stick;
         be_joy->GetAxisNameAt(0, temp);
         name = temp->LockBuffer(0);
         _al_sane_strncpy(name_x, name, sizeof(name_x));
         temp->UnlockBuffer();
         joy[i].stick[0].axis[0].name = name_x;
         be_joy->GetAxisNameAt(1, temp);
         name = temp->LockBuffer(0);
         _al_sane_strncpy(name_y, name, sizeof(name_y));
         temp->UnlockBuffer();
         joy[i].stick[0].axis[1].name = name_y;
         
         stick++;
         for (j = 2; j < num_axes; j++) {
            joy[i].stick[stick].flags = JOYFLAG_DIGITAL | JOYFLAG_ANALOGUE | JOYFLAG_UNSIGNED;
            joy[i].stick[stick].num_axis = 1;
            joy[i].stick[stick].axis[0].name = "";
            joy[i].stick[stick].name = name_throttle;
            stick++;
         }
         for (j = 0; j < num_hats; j++) {
            joy[i].stick[stick].flags = JOYFLAG_DIGITAL | JOYFLAG_SIGNED;
            joy[i].stick[stick].num_axis = 2;
            joy[i].stick[stick].axis[0].name = name_hat_lr;
            joy[i].stick[stick].axis[1].name = name_hat_ud;
            joy[i].stick[stick].name = name_hat;
            stick++;
         }
      }
      joy[i].num_sticks = stick;
      joy[i].num_buttons = num_buttons;
      
      for (j = 0; j < num_buttons; j++)
         joy[i].button[j].name = name_b[j];
   }
   
   delete temp;
   be_joy_poll();
   return 0;
   
   cleanup: {
       delete temp;
       delete be_joy;
       return -1;
   } 
}
/* joystick_enum_callback: [primary thread]
 *  Helper function to find out how many joysticks we have and set them up.
 *  At the end joydx_num_joysticks and joydx_joystick[] will be initialised.
 */
static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
   DIPROPRANGE property_range =
   {
      /* the header */
      {
	 sizeof(DIPROPRANGE),   // diph.dwSize
	 sizeof(DIPROPHEADER),  // diph.dwHeaderSize
	 0,                     // diph.dwObj
	 DIPH_DEVICE,           // diph.dwHow
      },

      /* the data */
      -32767,                   // lMin
      +32767                    // lMax
   };

   DIPROPDWORD property_deadzone =
   {
      /* the header */
      {
	 sizeof(DIPROPDWORD),   // diph.dwSize
	 sizeof(DIPROPHEADER),  // diph.dwHeaderSize
	 0,                     // diph.dwObj
	 DIPH_DEVICE,           // diph.dwHow
      },

      /* the data */
      2000,                     // dwData
   };

   DIPROPDWORD property_buffersize =
   {
      /* the header */
      {
	 sizeof(DIPROPDWORD),   // diph.dwSize
	 sizeof(DIPROPHEADER),  // diph.dwHeaderSize
	 0,                     // diph.dwObj
	 DIPH_DEVICE,           // diph.dwHow
      },

      /* the data */
      DEVICE_BUFFER_SIZE        // number of data items
   };

   LPDIRECTINPUTDEVICE _dinput_device1;
   LPDIRECTINPUTDEVICE2 dinput_device = NULL;
   HRESULT hr;
   LPVOID temp;
   CAPS_AND_NAMES caps_and_names;
   ALLEGRO_JOYSTICK_DIRECTX *joy;
   int num;

   (void)pvRef;

   /* check if the joystick already existed before */
   joy = joydx_by_guid(lpddi->guidInstance);
   if (joy) {
      ALLEGRO_DEBUG("Device %s still exists\n", joydx_guid_string(joy));
      joy->marked = true;
      return DIENUM_CONTINUE;
   }

   /* create the DirectInput joystick device */
   hr = IDirectInput8_CreateDevice(joystick_dinput, &lpddi->guidInstance, &_dinput_device1, NULL);
   if (FAILED(hr))
      goto Error;

   /* query the DirectInputDevice2 interface needed for the poll() method */
   hr = IDirectInputDevice8_QueryInterface(_dinput_device1, &__al_IID_IDirectInputDevice8A, &temp);
   IDirectInputDevice8_Release(_dinput_device1);
   if (FAILED(hr))
      goto Error;

   dinput_device = temp;

   /* enumerate objects available on the device */
   memset(&caps_and_names, 0, sizeof(caps_and_names));
   hr = IDirectInputDevice8_EnumObjects(dinput_device, object_enum_callback,
      &caps_and_names, DIDFT_PSHBUTTON | DIDFT_AXIS | DIDFT_POV);
   if (FAILED(hr))
      goto Error;

   /* set data format */
   hr = IDirectInputDevice8_SetDataFormat(dinput_device, &__al_c_dfDIJoystick);
   if (FAILED(hr))
      goto Error;

   /* set the range of axes */
   hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_RANGE, &property_range.diph);
   if (FAILED(hr))
      goto Error;

   /* set the dead zone of axes */
   hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_DEADZONE, &property_deadzone.diph);
   if (FAILED(hr))
      goto Error;

   /* set the buffer size */
   hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_BUFFERSIZE, &property_buffersize.diph);
   if (FAILED(hr))
      goto Error;

   /* set up the joystick structure */
   joy = joydx_allocate_structure(&num);
   if (!joy) {
      ALLEGRO_ERROR("Joystick array full\n");
      goto Error;
   }

   joy->config_state = STATE_BORN;
   joy->marked = true;
   joy->device = dinput_device;
   memcpy(&joy->guid, &lpddi->guidInstance, sizeof(GUID));

   _al_sane_strncpy(joy->name, lpddi->tszInstanceName, sizeof(joy->name));

   /* fill in the joystick structure */
   fill_joystick_info_using_caps_and_names(joy, &caps_and_names);

   /* create a thread event for this joystick, unless it was already created */
   joy->waker_event = CreateEvent(NULL, false, false, NULL);

   /* tell the joystick background thread to wake up when this joystick
    * device's state changes
    */
   hr = IDirectInputDevice8_SetEventNotification(joy->device, joy->waker_event);

   if (FAILED(hr)) {
      ALLEGRO_ERROR("SetEventNotification failed for joystick %d: %s\n",
         num, dinput_err_str(hr));
      goto Error;
   }

   if (hr == DI_POLLEDDEVICE) {
      /* This joystick device must be polled -- replace the Event with
       * a Waitable Timer object.
       *
       * Theoretically all polled devices could share a single
       * waitable timer object.  But, really, how many such devices
       * are there going to be on a system?
       */

      CloseHandle(joy->waker_event);
 
      joy->waker_event = CreateWaitableTimer(NULL, false, NULL);
      if (joy->waker_event == NULL) {
         ALLEGRO_ERROR("CreateWaitableTimer failed for polled device.\n");
         goto Error;
      }

      {
         LARGE_INTEGER due_time;
         due_time.HighPart = 0;
         due_time.LowPart = 150; /* 15 ms (arbitrary) */
         SetWaitableTimer(joy->waker_event,
                          &due_time, true, /* periodic */
                          NULL, NULL, false);
      }
   }

   ALLEGRO_INFO("Joystick %d initialized, GUID: %s\n",
      num, joydx_guid_string(joy));

   config_needs_merging = true;

   return DIENUM_CONTINUE;

 Error:

   if (dinput_device)
      IDirectInputDevice8_Release(dinput_device);

   if (joy) {
      joy->device = NULL;
      joydx_inactivate_joy(joy);
   }

   return DIENUM_CONTINUE;
}
Example #18
0
/* _unix_read_os_type:
 *  Set the os_type variable to something sensible.
 */
void _unix_read_os_type(void)
{
   #ifdef ALLEGRO_HAVE_SYS_UTSNAME_H

      struct utsname utsn;
      char *tmpstr, *tmpstr2;
      size_t pos;
      
      uname(&utsn);

      /* fetch OS version and revision */
      tmpstr = _AL_MALLOC_ATOMIC(strlen(utsn.release)+1);
      _al_sane_strncpy(tmpstr, utsn.release, strlen(utsn.release)+1);
      tmpstr2 = NULL;

      for (pos = 0; pos <= strlen(utsn.release); pos++) {
         if (tmpstr[pos] == '.') {
	    tmpstr[pos] = '\0';
	    if (!tmpstr2)
	       tmpstr2 = tmpstr + pos + 1;
	 }
      }

      os_version = atoi(tmpstr);
      os_revision = atoi(tmpstr2);

      _AL_FREE(tmpstr);

      /* try to detect Unix systems we know of */
      if (!strcmp(utsn.sysname, "Linux")) {
	 os_type = OSTYPE_LINUX;
      }
      else if (!strcmp(utsn.sysname, "SunOS")) {
	 os_type = OSTYPE_SUNOS;
      }
      else if (!strcmp(utsn.sysname, "FreeBSD")) {
	 os_type = OSTYPE_FREEBSD;
      }
      else if (!strcmp(utsn.sysname, "NetBSD")) {
	 os_type = OSTYPE_NETBSD;
      }
      else if (!strcmp(utsn.sysname, "OpenBSD")) {
	 os_type = OSTYPE_OPENBSD;
      }
      else if ((!strcmp(utsn.sysname, "IRIX"))
	       || (!strcmp(utsn.sysname, "IRIX64"))) {
	 os_type = OSTYPE_IRIX;
      }
      else if (!strcmp(utsn.sysname, "Darwin")) {
	 os_type = OSTYPE_DARWIN;
      }
      else if (!strcmp(utsn.sysname, "QNX")) {
	 os_type = OSTYPE_QNX;
      }
      else {
	 os_type = OSTYPE_UNIX;     /* that's all we can say for now */
      }

   #else

      os_type = OSTYPE_UNIX;

   #endif
   
   os_multitasking = TRUE;
}
Example #19
0
/* _find_executable_file:
 *  Helper function: searches path and current directory for executable.
 *  Returns 1 on succes, 0 on failure.
 */
static int _find_executable_file(const char *filename, char *output, int size)
{
   char *path;

   /* If filename has an explicit path, search current directory */
   if (strchr (filename, '/')) {
      if (filename[0] == '/') {
         /* Full path; done */
         do_uconvert (filename, U_ASCII, output, U_CURRENT, size);
         return 1;
      }
      else {
         struct stat finfo;
         char pathname[1024];
         int len;
            
	 /* Prepend current directory */
	 getcwd(pathname, sizeof(pathname));
	 len = strlen(pathname);
	 pathname[len] = '/';
	 _al_sane_strncpy (pathname+len+1, filename, strlen(filename));
            
	 if ((stat(pathname, &finfo)==0) && (!S_ISDIR (finfo.st_mode))) {
	    do_uconvert (pathname, U_ASCII, output, U_CURRENT, size);
	    return 1;
	 }
      }
   }
   /* If filename has no explicit path, but we do have $PATH, search there */
   else if ((path = getenv("PATH"))) {
      char *start = path, *end = path, *buffer = NULL, *temp;
      struct stat finfo;

      while (*end) {
	 end = strchr (start, ':');
	 if (!end) end = strchr (start, '\0');

	 /* Resize `buffer' for path component, slash, filename and a '\0' */
	 temp = _AL_REALLOC (buffer, end - start + 1 + strlen (filename) + 1);
	 if (temp) {
	    buffer = temp;

	    _al_sane_strncpy (buffer, start, end - start);
	    *(buffer + (end - start)) = '/';
	    _al_sane_strncpy (buffer + (end - start) + 1, filename, end - start + 1 + strlen (filename) + 1);

	    if ((stat(buffer, &finfo)==0) && (!S_ISDIR (finfo.st_mode))) {
	       do_uconvert (buffer, U_ASCII, output, U_CURRENT, size);
	       _AL_FREE (buffer);
	       return 1;
	    }
	 } /* else... ignore the failure; `buffer' is still valid anyway. */

	 start = end + 1;
      }
      /* Path search failed */
      _AL_FREE (buffer);
   }
   
   return 0;
}
Example #20
0
/* _unix_get_executable_name:
 *  Return full path to the current executable, use proc fs if available.
 */
void _unix_get_executable_name(char *output, int size)
{
   #ifdef ALLEGRO_HAVE_SV_PROCFS_H
      struct prpsinfo psinfo;
      int fd;
   #endif
   char linkname[1024];
   char filename[1024];
   struct stat finfo;
   FILE *pipe;
   pid_t pid;
   int len;
   
   #ifdef ALLEGRO_HAVE_GETEXECNAME
   {
      const char *s = getexecname();
      if (s) {
         if (s[0] == '/') {   /* Absolute path */
            do_uconvert (s, U_ASCII, output, U_CURRENT, size);
            return;
         }
         else {               /* Not an absolute path */
            if (_find_executable_file(s, output, size))
               return;
         }
      }
   }
   #endif

   /* We need the PID in order to query procfs */
   pid = getpid();

   /* Try a Linux-like procfs */   
   /* get symolic link to executable from proc fs */
   sprintf (linkname, "/proc/%d/exe", (int)pid);
   if (stat (linkname, &finfo) == 0) {
      len = readlink (linkname, filename, sizeof(filename)-1);
      if (len>-1) {
	 filename[len] = '\0';
         
	 do_uconvert (filename, U_ASCII, output, U_CURRENT, size);
	 return;
      }
   }
   
   /* Use System V procfs calls if available */
   #ifdef ALLEGRO_HAVE_SV_PROCFS_H
      sprintf (linkname, "/proc/%d/exe", (int)pid);
      fd = open(linkname, O_RDONLY);
      if (!fd == -1) {
         ioctl(fd, PIOCPSINFO, &psinfo);
         close(fd);
   
         /* Use argv[0] directly if we can */
      #ifdef ALLEGRO_HAVE_PROCFS_ARGCV
	 if (psinfo.pr_argv && psinfo.pr_argc) {
	    if (_find_executable_file(psinfo.pr_argv[0], output, size))
	       return;
	 }
	 else
      #endif
	 {
	    /* Emulate it */
	    /* We use the pr_psargs field to find argv[0]
	     * This is better than using the pr_fname field because we need
	     * the additional path information that may be present in argv[0]
	     */
	 
	    /* Skip other args */
	    char *s = strchr(psinfo.pr_psargs, ' ');
	    if (s) s[0] = '\0';
	    if (_find_executable_file(psinfo.pr_psargs, output, size))
	       return;
	 }

         /* Try the pr_fname just for completeness' sake if argv[0] fails */
         if (_find_executable_file(psinfo.pr_fname, output, size))
            return;
      }
   #endif
   
   /* Last resort: try using the output of the ps command to at least find */
   /* the name of the file if not the full path */
   uszprintf (linkname, sizeof(linkname), "ps -p %d", (int)pid);
   do_uconvert (linkname, U_CURRENT, filename, U_ASCII, size);
   pipe = popen(filename, "r");
   if (pipe) {
      /* The first line of output is a header */
      fgets(linkname, sizeof(linkname), pipe);
      
      /* The information we want is in the last column; find it */
      len = strlen(linkname);
      while (linkname[len] != ' ' && linkname[len] != '\t')
         len--;
      
      /* The second line contains the info we want */
      fgets(linkname, sizeof(linkname), pipe);
      pclose(pipe);
      
      /* Treat special cases: filename between [] and - for login shell */
      if (linkname[len] == '-')
         len++;

      if (linkname[len] == '[' && linkname[strlen(linkname)] == ']') {
         len++;
         linkname[strlen(linkname)] = '\0';
      }         
      
      /* Now, the filename should be in the last column */
      _al_sane_strncpy (filename, linkname+len+1, strlen(linkname)-len+1);
            
      if (_find_executable_file(filename, output, size))
         return;

      /* Just return the output from ps... */         
      do_uconvert (filename, U_ASCII, output, U_CURRENT, size);
      return;
   }

#ifdef ALLEGRO_WITH_MAGIC_MAIN
   /* Try the captured argv[0] */   
   if (_find_executable_file(__crt0_argv[0], output, size))
      return;
#endif

   /* Give up; return empty string */
   do_uconvert ("", U_ASCII, output, U_CURRENT, size);
}