/* * profanity.c * * Copyright (C) 2012, 2013 James Booth * * This file is part of Profanity. * * Profanity is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Profanity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Profanity. If not, see . * */ #include "config.h" #include #include #include #include #include #include "profanity.h" #include "chat_session.h" #include "config/accounts.h" #include "config/preferences.h" #include "config/theme.h" #include "command/command.h" #include "common.h" #include "contact.h" #include "contact_list.h" #include "files.h" #include "log.h" #include "muc.h" #include "ui/ui.h" #include "xmpp/xmpp.h" static log_level_t _get_log_level(char *log_level); static gboolean _process_input(char *inp); static void _handle_idle_time(void); static void _init(const int disable_tls, char *log_level); static void _shutdown(void); static gboolean idle = FALSE; void prof_run(const int disable_tls, char *log_level) { _init(disable_tls, log_level); log_info("Starting main event loop"); inp_non_block(); GTimer *timer = g_timer_new(); gboolean cmd_result = TRUE; char inp[INP_WIN_MAX]; int size = 0; while(cmd_result == TRUE) { wint_t ch = ERR; size = 0; while(ch != '\n') { if (jabber_get_connection_status() == JABBER_CONNECTED) { _handle_idle_time(); } gdouble elapsed = g_timer_elapsed(timer, NULL); gint remind_period = prefs_get_notify_remind(); // 0 means to not remind if (remind_period > 0 && elapsed >= remind_period) { notify_remind(); g_timer_start(timer); } ui_handle_special_keys(&ch); if (ch == KEY_RESIZE) { ui_resize(ch, inp, size); } ui_refresh(); jabber_process_events(); ch = inp_get_char(inp, &size); if (ch != ERR) { ui_reset_idle_time(); } } inp[size++] = '\0'; cmd_result = _process_input(inp); } g_timer_destroy(timer); } void prof_handle_typing(char *from) { ui_show_typing(from); win_current_page_off(); } void prof_handle_incoming_message(char *from, char *message, gboolean priv) { ui_show_incoming_msg(from, message, NULL, priv); win_current_page_off(); if (prefs_get_chlog() && !priv) { Jid *from_jid = jid_create(from); const char *jid = jabber_get_jid(); Jid *jidp = jid_create(jid); chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, NULL); jid_destroy(jidp); jid_destroy(from_jid); } } void prof_handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, gboolean priv) { ui_show_incoming_msg(from, message, &tv_stamp, priv); win_current_page_off(); if (prefs_get_chlog() && !priv) { Jid *from_jid = jid_create(from); const char *jid = jabber_get_jid(); Jid *jidp = jid_create(jid); chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, &tv_stamp); jid_destroy(jidp); jid_destroy(from_jid); } } void prof_handle_error_message(const char *from, const char *err_msg) { if (err_msg == NULL) { cons_bad_show("Unknown error received from service."); } else if (strcmp(err_msg, "conflict") == 0) { if (win_current_is_groupchat()) { win_current_show("Nickname already in use."); } else { cons_bad_show("Error received from server: %s", err_msg); } } else { cons_bad_show("Error received from server: %s", err_msg); } win_show_error_msg(from, err_msg); } void prof_handle_subscription(const char *from, jabber_subscr_t type) { switch (type) { case PRESENCE_SUBSCRIBE: /* TODO: auto-subscribe if needed */ cons_show("Received authorization request from %s", from); log_info("Received authorization request from %s", from); win_show_system_msg(from, "Authorization request, type '/sub allow' to accept or '/sub deny' to reject"); win_current_page_off(); break; case PRESENCE_SUBSCRIBED: cons_show("Subscription received from %s", from); log_info("Subscription received from %s", from); win_show_system_msg(from, "Subscribed"); win_current_page_off(); break; case PRESENCE_UNSUBSCRIBED
//: Let's raise errors when students use real hardware in any recipes besides
//: 'main'. Part of the goal is to teach them testing hygiene and dependency
//: injection.
//:
//: This is easy to sidestep, it's for feedback rather than safety.

:(before "End Globals")
vector<type_tree*> Real_hardware_types;
:(before "Begin transform_all")
setup_real_hardware_types();
:(before "End transform_all")
teardown_real_hardware_types();
:(code)
void setup_real_hardware_types() {
  Real_hardware_types.push_back(parse_type("address:screen"));
  Real_hardware_types.push_back(parse_type("address:console"));
  Real_hardware_types.push_back(parse_type("address:resources"));
}
type_tree* parse_type(string s) {
  reagent x("x:"+s);
  type_tree* result = x.type;
  x.type = NULL;  // don't deallocate on return
  return result;
}
void teardown_real_hardware_types() {
  for (int i = 0;  i < SIZE(Real_hardware_types);  ++i)
    delete Real_hardware_types