Another copy of my dotfiles. Because I don't completely trust GitHub.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.3 KiB

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <regex.h>
  5. #include <mpd/client.h>
  6. #define MPDHOST "localhost"
  7. #define MPDPORT 6600
  8. struct mpd_connection *get_conn()
  9. {
  10. struct mpd_connection *conn;
  11. conn = mpd_connection_new(MPDHOST, MPDPORT, 1000);
  12. if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
  13. fprintf(stderr, "Could not connect to mpd: %s\n", mpd_connection_get_error_message(conn));
  14. mpd_connection_free(conn);
  15. return NULL;
  16. }
  17. return conn;
  18. }
  19. void mpdchange(const Arg *direction)
  20. {
  21. struct mpd_connection *conn;
  22. conn = get_conn();
  23. if (conn == NULL) {
  24. return;
  25. }
  26. if (direction->i > 0) {
  27. mpd_run_next(conn);
  28. }
  29. else {
  30. mpd_run_previous(conn);
  31. }
  32. mpd_connection_free(conn);
  33. }
  34. char *get_regerror(int errcode, regex_t *compiled)
  35. {
  36. size_t length = regerror(errcode, compiled, NULL, 0);
  37. char *buffer = malloc(length);
  38. (void) regerror(errcode, compiled, buffer, length);
  39. return buffer;
  40. }
  41. void mpdcontrol()
  42. {
  43. struct mpd_connection *conn;
  44. struct mpd_status *status;
  45. struct mpd_song *song;
  46. enum mpd_state state;
  47. const char *filename;
  48. regex_t expr;
  49. conn = get_conn();
  50. if (conn == NULL) {
  51. return;
  52. }
  53. status = mpd_run_status(conn);
  54. if (status == NULL) {
  55. fprintf(stderr, "Could not get mpd status: %s\n", mpd_status_get_error(status));
  56. mpd_status_free(status);
  57. mpd_connection_free(conn);
  58. return;
  59. }
  60. state = mpd_status_get_state(status);
  61. if (state == MPD_STATE_STOP || state == MPD_STATE_PAUSE) {
  62. mpd_run_play(conn);
  63. mpd_status_free(status);
  64. mpd_connection_free(conn);
  65. }
  66. else if (state != MPD_STATE_UNKNOWN) { //playing some music
  67. song = mpd_run_current_song(conn);
  68. if (song == NULL){
  69. fprintf(stderr, "Error fetching current song!\n");
  70. mpd_song_free(song);
  71. mpd_status_free(status);
  72. mpd_connection_free(conn);
  73. return;
  74. }
  75. filename = mpd_song_get_uri(song);
  76. int errcode = regcomp(&expr, "^[[:alnum:]]+://", REG_EXTENDED|REG_NOSUB);
  77. if (errcode != 0) {
  78. char *err = get_regerror(errcode, &expr);
  79. fprintf(stderr, "Could not compile regexp: %s\n", err);
  80. mpd_song_free(song);
  81. mpd_status_free(status);
  82. mpd_connection_free(conn);
  83. free(err);
  84. regfree(&expr);
  85. return;
  86. }
  87. int matchcode = regexec(&expr, filename, 0, NULL, 0);
  88. if (matchcode == 0) {
  89. if (strstr(filename, "file://") == filename) { //match just at the start of the filename
  90. //this means that mpd is playing a file outside the music_dir,
  91. //but on disk, so we can safely pause
  92. mpd_run_toggle_pause(conn);
  93. }
  94. else {
  95. mpd_run_stop(conn);
  96. }
  97. }
  98. else if (matchcode == REG_NOMATCH) {
  99. mpd_run_toggle_pause(conn);
  100. }
  101. else {
  102. char *err = get_regerror(matchcode, &expr);
  103. fprintf(stderr, "Error while matching regexp: %s\n", err);
  104. free(err);
  105. }
  106. regfree(&expr);
  107. mpd_song_free(song);
  108. mpd_status_free(status);
  109. mpd_connection_free(conn);
  110. }
  111. }