mirror of
https://github.com/chatmail/core.git
synced 2026-04-25 09:26:30 +03:00
refactor(chat): store rust strings in the chat struct
This commit is contained in:
193
src/chat.rs
193
src/chat.rs
@@ -26,9 +26,9 @@ pub struct Chat<'a> {
|
||||
pub context: &'a Context,
|
||||
pub id: u32,
|
||||
pub typ: Chattype,
|
||||
pub name: *mut libc::c_char,
|
||||
pub name: String,
|
||||
archived: bool,
|
||||
pub grpid: *mut libc::c_char,
|
||||
pub grpid: String,
|
||||
blocked: Blocked,
|
||||
pub param: Params,
|
||||
pub gossiped_timestamp: i64,
|
||||
@@ -43,30 +43,19 @@ impl<'a> Chat<'a> {
|
||||
FROM chats c WHERE c.id=?;",
|
||||
params![chat_id as i32],
|
||||
|row| {
|
||||
let mut c = Chat {
|
||||
let c = Chat {
|
||||
context,
|
||||
id: 0,
|
||||
typ: Chattype::Undefined,
|
||||
name: std::ptr::null_mut(),
|
||||
archived: false,
|
||||
grpid: std::ptr::null_mut(),
|
||||
blocked: Blocked::Not,
|
||||
param: Params::new(),
|
||||
gossiped_timestamp: 0,
|
||||
is_sending_locations: false,
|
||||
id: row.get(0)?,
|
||||
typ: row.get(1)?,
|
||||
name: row.get::<_, String>(2)?,
|
||||
grpid: row.get::<_, String>(3)?,
|
||||
param: row.get::<_, String>(4)?.parse().unwrap_or_default(),
|
||||
archived: row.get(5)?,
|
||||
blocked: row.get::<_, Option<_>>(6)?.unwrap_or_default(),
|
||||
gossiped_timestamp: row.get(7)?,
|
||||
is_sending_locations: row.get(8)?,
|
||||
};
|
||||
|
||||
c.id = row.get(0)?;
|
||||
c.typ = row.get(1)?;
|
||||
c.name = unsafe { row.get::<_, String>(2)?.strdup() };
|
||||
c.grpid = unsafe { row.get::<_, String>(3)?.strdup() };
|
||||
|
||||
c.param = row.get::<_, String>(4)?.parse().unwrap_or_default();
|
||||
c.archived = row.get(5)?;
|
||||
c.blocked = row.get::<_, Option<_>>(6)?.unwrap_or_default();
|
||||
c.gossiped_timestamp = row.get(7)?;
|
||||
c.is_sending_locations = row.get(8)?;
|
||||
|
||||
Ok(c)
|
||||
},
|
||||
);
|
||||
@@ -84,44 +73,33 @@ impl<'a> Chat<'a> {
|
||||
},
|
||||
Ok(mut chat) => {
|
||||
match chat.id {
|
||||
1 => unsafe {
|
||||
free(chat.name.cast());
|
||||
chat.name = chat.context.stock_str(StockMessage::DeadDrop).strdup();
|
||||
},
|
||||
6 => unsafe {
|
||||
free(chat.name.cast());
|
||||
1 => {
|
||||
chat.name = chat.context.stock_str(StockMessage::DeadDrop).into();
|
||||
}
|
||||
6 => {
|
||||
let tempname = chat.context.stock_str(StockMessage::ArchivedChats);
|
||||
let cnt = dc_get_archived_cnt(chat.context);
|
||||
chat.name = format!("{} ({})", tempname, cnt).strdup();
|
||||
},
|
||||
5 => unsafe {
|
||||
free(chat.name.cast());
|
||||
chat.name = chat.context.stock_str(StockMessage::StarredMsgs).strdup();
|
||||
},
|
||||
chat.name = format!("{} ({})", tempname, cnt);
|
||||
}
|
||||
5 => {
|
||||
chat.name = chat.context.stock_str(StockMessage::StarredMsgs).into();
|
||||
}
|
||||
_ => {
|
||||
unsafe {
|
||||
if chat.typ == Chattype::Single {
|
||||
free(chat.name.cast());
|
||||
let contacts = get_chat_contacts(chat.context, chat.id);
|
||||
let mut chat_name = "Err [Name not found]".to_owned();
|
||||
if chat.typ == Chattype::Single {
|
||||
let contacts = get_chat_contacts(chat.context, chat.id);
|
||||
let mut chat_name = "Err [Name not found]".to_owned();
|
||||
|
||||
if !(*contacts).is_empty() {
|
||||
if let Ok(contact) =
|
||||
Contact::get_by_id(chat.context, contacts[0])
|
||||
{
|
||||
chat_name = contact.get_display_name().to_owned();
|
||||
}
|
||||
if !(*contacts).is_empty() {
|
||||
if let Ok(contact) = Contact::get_by_id(chat.context, contacts[0]) {
|
||||
chat_name = contact.get_display_name().to_owned();
|
||||
}
|
||||
|
||||
chat.name = (&chat_name).strdup();
|
||||
}
|
||||
|
||||
chat.name = chat_name;
|
||||
}
|
||||
|
||||
if chat.param.exists(Param::Selftalk) {
|
||||
unsafe {
|
||||
free(chat.name as *mut libc::c_void);
|
||||
chat.name = chat.context.stock_str(StockMessage::SelfMsg).strdup();
|
||||
}
|
||||
chat.name = chat.context.stock_str(StockMessage::SelfMsg).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,29 +121,30 @@ impl<'a> Chat<'a> {
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn get_id(&self) -> u32 {
|
||||
pub fn get_id(&self) -> u32 {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub unsafe fn get_type(&self) -> Chattype {
|
||||
pub fn get_type(&self) -> Chattype {
|
||||
self.typ
|
||||
}
|
||||
|
||||
pub unsafe fn get_name(&self) -> *mut libc::c_char {
|
||||
dc_strdup(self.name)
|
||||
pub fn get_name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub unsafe fn get_subtitle(&self) -> *mut libc::c_char {
|
||||
/* returns either the address or the number of chat members */
|
||||
pub fn get_subtitle(&self) -> String {
|
||||
// returns either the address or the number of chat members
|
||||
|
||||
let mut ret: *mut libc::c_char = std::ptr::null_mut();
|
||||
if self.typ == Chattype::Single && self.param.exists(Param::Selftalk) {
|
||||
ret = self
|
||||
return self
|
||||
.context
|
||||
.stock_str(StockMessage::SelfTalkSubTitle)
|
||||
.strdup();
|
||||
} else if self.typ == Chattype::Single {
|
||||
let ret_raw: String = self
|
||||
.into();
|
||||
}
|
||||
|
||||
if self.typ == Chattype::Single {
|
||||
return self
|
||||
.context
|
||||
.sql
|
||||
.query_row_col(
|
||||
@@ -177,24 +156,22 @@ impl<'a> Chat<'a> {
|
||||
0,
|
||||
)
|
||||
.unwrap_or_else(|| "Err".into());
|
||||
ret = ret_raw.strdup();
|
||||
} else if self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup {
|
||||
}
|
||||
|
||||
if self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup {
|
||||
if self.id == 1 {
|
||||
ret = self.context.stock_str(StockMessage::DeadDrop).strdup();
|
||||
} else {
|
||||
let cnt = get_chat_contact_cnt(self.context, self.id);
|
||||
ret = self
|
||||
.context
|
||||
.stock_string_repl_int(StockMessage::Member, cnt)
|
||||
.strdup();
|
||||
return self.context.stock_str(StockMessage::DeadDrop).into();
|
||||
}
|
||||
let cnt = get_chat_contact_cnt(self.context, self.id);
|
||||
return self
|
||||
.context
|
||||
.stock_string_repl_int(StockMessage::Member, cnt)
|
||||
.into();
|
||||
}
|
||||
if !ret.is_null() {
|
||||
ret
|
||||
} else {
|
||||
dc_strdup(b"Err\x00" as *const u8 as *const libc::c_char)
|
||||
}
|
||||
|
||||
return "Err".into();
|
||||
}
|
||||
|
||||
unsafe fn get_parent_mime_headers(
|
||||
&self,
|
||||
parent_rfc724_mid: *mut *mut libc::c_char,
|
||||
@@ -264,7 +241,7 @@ impl<'a> Chat<'a> {
|
||||
}
|
||||
|
||||
pub fn get_color(&self) -> u32 {
|
||||
let mut color: u32 = 0i32 as u32;
|
||||
let mut color = 0;
|
||||
|
||||
if self.typ == Chattype::Single {
|
||||
let contacts = get_chat_contacts(self.context, self.id);
|
||||
@@ -274,7 +251,7 @@ impl<'a> Chat<'a> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
color = unsafe { dc_str_to_color(self.name) } as u32
|
||||
color = dc_str_to_color(&self.name);
|
||||
}
|
||||
|
||||
color
|
||||
@@ -338,7 +315,7 @@ impl<'a> Chat<'a> {
|
||||
let from_c = CString::yolo(from.unwrap());
|
||||
new_rfc724_mid = dc_create_outgoing_rfc724_mid(
|
||||
if self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup {
|
||||
self.grpid
|
||||
self.grpid.strdup()
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
},
|
||||
@@ -1663,7 +1640,7 @@ pub unsafe fn remove_contact_from_chat(
|
||||
if chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||
(*msg).type_0 = Viewtype::Text;
|
||||
if contact.id == DC_CONTACT_ID_SELF as u32 {
|
||||
set_group_explicitly_left(context, chat.grpid);
|
||||
set_group_explicitly_left(context, chat.grpid).unwrap();
|
||||
(*msg).text = Some(context.stock_system_msg(
|
||||
StockMessage::MsgGroupLeft,
|
||||
"",
|
||||
@@ -1707,41 +1684,38 @@ pub unsafe fn remove_contact_from_chat(
|
||||
success
|
||||
}
|
||||
|
||||
// Should return Result
|
||||
fn set_group_explicitly_left(context: &Context, grpid: *const libc::c_char) {
|
||||
if 0 == is_group_explicitly_left(context, grpid) {
|
||||
fn set_group_explicitly_left(context: &Context, grpid: impl AsRef<str>) -> Result<(), Error> {
|
||||
if !is_group_explicitly_left(context, grpid.as_ref())? {
|
||||
sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"INSERT INTO leftgrps (grpid) VALUES(?);",
|
||||
params![as_str(grpid)],
|
||||
)
|
||||
.ok();
|
||||
params![grpid.as_ref()],
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO should return bool /rtn
|
||||
pub fn is_group_explicitly_left(context: &Context, grpid: *const libc::c_char) -> libc::c_int {
|
||||
context
|
||||
.sql
|
||||
.exists(
|
||||
"SELECT id FROM leftgrps WHERE grpid=?;",
|
||||
params![as_str(grpid)],
|
||||
)
|
||||
.unwrap_or_default() as libc::c_int
|
||||
pub fn is_group_explicitly_left(context: &Context, grpid: impl AsRef<str>) -> Result<bool, Error> {
|
||||
context.sql.exists(
|
||||
"SELECT id FROM leftgrps WHERE grpid=?;",
|
||||
params![grpid.as_ref()],
|
||||
)
|
||||
}
|
||||
|
||||
// TODO should return bool /rtn
|
||||
pub unsafe fn set_chat_name(
|
||||
context: &Context,
|
||||
chat_id: u32,
|
||||
new_name: *const libc::c_char,
|
||||
new_name: impl AsRef<str>,
|
||||
) -> libc::c_int {
|
||||
/* the function only sets the names of group chats; normal chats get their names from the contacts */
|
||||
let mut success: libc::c_int = 0i32;
|
||||
let mut msg = dc_msg_new_untyped(context);
|
||||
|
||||
if new_name.is_null() || *new_name.offset(0isize) as libc::c_int == 0 || chat_id <= 9 {
|
||||
if new_name.as_ref().is_empty() || chat_id <= DC_CHAT_ID_LAST_SPECIAL as u32 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1749,9 +1723,9 @@ pub unsafe fn set_chat_name(
|
||||
|
||||
if !(0i32 == real_group_exists(context, chat_id) || chat.is_err()) {
|
||||
let chat = chat.unwrap();
|
||||
if strcmp(chat.name, new_name) == 0i32 {
|
||||
success = 1i32
|
||||
} else if !(is_contact_in_chat(context, chat_id, 1i32 as u32) == 1i32) {
|
||||
if &chat.name == new_name.as_ref() {
|
||||
success = 1;
|
||||
} else if !(is_contact_in_chat(context, chat_id, 1) == 1) {
|
||||
log_event!(
|
||||
context,
|
||||
Event::ERROR_SELF_NOT_IN_GROUP,
|
||||
@@ -1765,7 +1739,7 @@ pub unsafe fn set_chat_name(
|
||||
&context.sql,
|
||||
format!(
|
||||
"UPDATE chats SET name='{}' WHERE id={};",
|
||||
as_str(new_name),
|
||||
new_name.as_ref(),
|
||||
chat_id as i32
|
||||
),
|
||||
params![],
|
||||
@@ -1776,13 +1750,13 @@ pub unsafe fn set_chat_name(
|
||||
(*msg).type_0 = Viewtype::Text;
|
||||
(*msg).text = Some(context.stock_system_msg(
|
||||
StockMessage::MsgGrpName,
|
||||
as_str(chat.name),
|
||||
as_str(new_name),
|
||||
&chat.name,
|
||||
new_name.as_ref(),
|
||||
DC_CONTACT_ID_SELF as u32,
|
||||
));
|
||||
(*msg).param.set_int(Param::Cmd, 2);
|
||||
if !chat.name.is_null() {
|
||||
(*msg).param.set(Param::Arg, as_str(chat.name));
|
||||
if !chat.name.is_empty() {
|
||||
(*msg).param.set(Param::Arg, &chat.name);
|
||||
}
|
||||
(*msg).id = send_msg(context, chat_id, msg).unwrap_or_default();
|
||||
context.call_cb(
|
||||
@@ -2088,12 +2062,3 @@ pub fn add_device_msg(context: &Context, chat_id: u32, text: *const libc::c_char
|
||||
msg_id as uintptr_t,
|
||||
);
|
||||
}
|
||||
|
||||
impl<'a> Drop for Chat<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
free(self.name.cast());
|
||||
free(self.grpid.cast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,7 +791,7 @@ impl<'a> Contact<'a> {
|
||||
/// and can be used for an fallback avatar with white initials
|
||||
/// as well as for headlines in bubbles of group chats.
|
||||
pub fn get_color(&self) -> u32 {
|
||||
dc_str_to_color_safe(&self.addr)
|
||||
dc_str_to_color(&self.addr)
|
||||
}
|
||||
|
||||
/// Check if a contact was verified. E.g. by a secure-join QR code scan
|
||||
|
||||
@@ -548,14 +548,15 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
||||
imf_fields,
|
||||
mailimf_field_new_custom(
|
||||
strdup(b"Chat-Group-ID\x00" as *const u8 as *const libc::c_char),
|
||||
dc_strdup(chat.grpid),
|
||||
chat.grpid.strdup(),
|
||||
),
|
||||
);
|
||||
let name = CString::yolo(chat.name.as_bytes());
|
||||
mailimf_fields_add(
|
||||
imf_fields,
|
||||
mailimf_field_new_custom(
|
||||
strdup(b"Chat-Group-Name\x00" as *const u8 as *const libc::c_char),
|
||||
dc_encode_header_words(chat.name),
|
||||
dc_encode_header_words(name.as_ptr()),
|
||||
),
|
||||
);
|
||||
if command == 5 {
|
||||
@@ -1090,12 +1091,13 @@ unsafe fn get_subject(
|
||||
if (*msg).param.get_int(Param::Cmd).unwrap_or_default() == 6 {
|
||||
ret = context.stock_str(StockMessage::AcSetupMsgSubject).strdup()
|
||||
} else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||
ret = dc_mprintf(
|
||||
b"Chat: %s: %s%s\x00" as *const u8 as *const libc::c_char,
|
||||
ret = format!(
|
||||
"Chat: {}: {}{}",
|
||||
chat.name,
|
||||
fwd,
|
||||
raw_subject,
|
||||
to_string(fwd),
|
||||
to_string(raw_subject),
|
||||
)
|
||||
.strdup()
|
||||
} else {
|
||||
ret = dc_mprintf(
|
||||
b"Chat: %s%s\x00" as *const u8 as *const libc::c_char,
|
||||
|
||||
@@ -1041,7 +1041,7 @@ unsafe fn create_or_lookup_group(
|
||||
ret_chat_id: *mut uint32_t,
|
||||
ret_chat_id_blocked: &mut Blocked,
|
||||
) {
|
||||
let group_explicitly_left: libc::c_int;
|
||||
let group_explicitly_left: bool;
|
||||
let mut chat_id = 0;
|
||||
let mut chat_id_blocked = Blocked::Not;
|
||||
let mut chat_id_verified = 0;
|
||||
@@ -1252,7 +1252,8 @@ unsafe fn create_or_lookup_group(
|
||||
}
|
||||
|
||||
// check if the group does not exist but should be created
|
||||
group_explicitly_left = chat::is_group_explicitly_left(context, grpid);
|
||||
group_explicitly_left =
|
||||
chat::is_group_explicitly_left(context, as_str(grpid)).unwrap_or_default();
|
||||
|
||||
let self_addr = context
|
||||
.sql
|
||||
@@ -1265,7 +1266,7 @@ unsafe fn create_or_lookup_group(
|
||||
// otherwise, a pending "quit" message may pop up
|
||||
&& X_MrRemoveFromGrp.is_null()
|
||||
// re-create explicitly left groups only if ourself is re-added
|
||||
&& (0 == group_explicitly_left
|
||||
&& (!group_explicitly_left
|
||||
|| !X_MrAddToGrp.is_null() && addr_cmp(&self_addr, as_str(X_MrAddToGrp)))
|
||||
{
|
||||
let mut create_verified: libc::c_int = 0;
|
||||
@@ -1301,7 +1302,7 @@ unsafe fn create_or_lookup_group(
|
||||
// again, check chat_id
|
||||
if chat_id <= DC_CHAT_ID_LAST_SPECIAL as u32 {
|
||||
chat_id = 0;
|
||||
if 0 != group_explicitly_left {
|
||||
if group_explicitly_left {
|
||||
chat_id = DC_CHAT_ID_TRASH as u32;
|
||||
} else {
|
||||
create_or_lookup_adhoc_group(
|
||||
|
||||
@@ -14,7 +14,6 @@ use crate::dc_lot::*;
|
||||
use crate::dc_mimeparser::*;
|
||||
use crate::dc_msg::*;
|
||||
use crate::dc_qr::*;
|
||||
use crate::dc_strencode::*;
|
||||
use crate::dc_token::*;
|
||||
use crate::dc_tools::*;
|
||||
use crate::key::*;
|
||||
@@ -36,8 +35,6 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
let mut fingerprint = 0 as *mut libc::c_char;
|
||||
let mut invitenumber: *mut libc::c_char;
|
||||
let mut auth: *mut libc::c_char;
|
||||
let mut group_name = 0 as *mut libc::c_char;
|
||||
let mut group_name_urlencoded = 0 as *mut libc::c_char;
|
||||
let mut qr: Option<String> = None;
|
||||
|
||||
dc_ensure_secret_key_exists(context).ok();
|
||||
@@ -53,12 +50,10 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
}
|
||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
||||
|
||||
let cleanup = |fingerprint, group_name, group_name_urlencoded| {
|
||||
let cleanup = |fingerprint| {
|
||||
free(fingerprint as *mut libc::c_void);
|
||||
free(invitenumber as *mut libc::c_void);
|
||||
free(auth as *mut libc::c_void);
|
||||
free(group_name as *mut libc::c_void);
|
||||
free(group_name_urlencoded as *mut libc::c_void);
|
||||
|
||||
if let Some(qr) = qr {
|
||||
qr.strdup()
|
||||
@@ -69,7 +64,7 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
|
||||
if self_addr.is_none() {
|
||||
error!(context, 0, "Not configured, cannot generate QR code.",);
|
||||
return cleanup(fingerprint, group_name, group_name_urlencoded);
|
||||
return cleanup(fingerprint);
|
||||
}
|
||||
|
||||
let self_addr = self_addr.unwrap();
|
||||
@@ -81,7 +76,7 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
fingerprint = get_self_fingerprint(context);
|
||||
|
||||
if fingerprint.is_null() {
|
||||
return cleanup(fingerprint, group_name, group_name_urlencoded);
|
||||
return cleanup(fingerprint);
|
||||
}
|
||||
|
||||
let self_addr_urlencoded = utf8_percent_encode(&self_addr, NON_ALPHANUMERIC).to_string();
|
||||
@@ -89,15 +84,16 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
|
||||
qr = if 0 != group_chat_id {
|
||||
if let Ok(chat) = Chat::load_from_db(context, group_chat_id) {
|
||||
group_name = chat.get_name();
|
||||
group_name_urlencoded = dc_urlencode(group_name);
|
||||
let group_name = chat.get_name();
|
||||
let group_name_urlencoded =
|
||||
utf8_percent_encode(&group_name, NON_ALPHANUMERIC).to_string();
|
||||
|
||||
Some(format!(
|
||||
"OPENPGP4FPR:{}#a={}&g={}&x={}&i={}&s={}",
|
||||
as_str(fingerprint),
|
||||
self_addr_urlencoded,
|
||||
as_str(group_name_urlencoded),
|
||||
as_str(chat.grpid),
|
||||
&group_name_urlencoded,
|
||||
&chat.grpid,
|
||||
as_str(invitenumber),
|
||||
as_str(auth),
|
||||
))
|
||||
@@ -106,7 +102,7 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
context,
|
||||
0, "Cannot get QR-code for chat-id {}", group_chat_id,
|
||||
);
|
||||
return cleanup(fingerprint, group_name, group_name_urlencoded);
|
||||
return cleanup(fingerprint);
|
||||
}
|
||||
} else {
|
||||
Some(format!(
|
||||
@@ -121,7 +117,7 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
|
||||
info!(context, 0, "Generated QR code: {}", qr.as_ref().unwrap());
|
||||
|
||||
cleanup(fingerprint, group_name, group_name_urlencoded)
|
||||
cleanup(fingerprint)
|
||||
}
|
||||
|
||||
fn get_self_fingerprint(context: &Context) -> *mut libc::c_char {
|
||||
|
||||
@@ -532,7 +532,7 @@ const COLORS: [u32; 16] = [
|
||||
0x39b249, 0xbb243b, 0x964078, 0x66874f, 0x308ab9, 0x127ed0, 0xbe450c,
|
||||
];
|
||||
|
||||
pub fn dc_str_to_color_safe(s: impl AsRef<str>) -> u32 {
|
||||
pub fn dc_str_to_color(s: impl AsRef<str>) -> u32 {
|
||||
let str_lower = s.as_ref().to_lowercase();
|
||||
let mut checksum = 0;
|
||||
let bytes = str_lower.as_bytes();
|
||||
@@ -545,10 +545,6 @@ pub fn dc_str_to_color_safe(s: impl AsRef<str>) -> u32 {
|
||||
COLORS[color_index]
|
||||
}
|
||||
|
||||
pub unsafe fn dc_str_to_color(str: *const libc::c_char) -> libc::c_int {
|
||||
dc_str_to_color_safe(as_str(str)) as libc::c_int
|
||||
}
|
||||
|
||||
/* clist tools */
|
||||
/* calls free() for each item content */
|
||||
pub unsafe fn clist_free_content(haystack: *const clist) {
|
||||
|
||||
Reference in New Issue
Block a user